summaryrefslogtreecommitdiff
path: root/sbin/ipsecctl
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/ipsecctl')
-rw-r--r--sbin/ipsecctl/ike.c45
-rw-r--r--sbin/ipsecctl/ipsecctl.h6
-rw-r--r--sbin/ipsecctl/parse.y68
-rw-r--r--sbin/ipsecctl/pfkdump.c22
4 files changed, 121 insertions, 20 deletions
diff --git a/sbin/ipsecctl/ike.c b/sbin/ipsecctl/ike.c
index aef204b308f..6c3d0f338b7 100644
--- a/sbin/ipsecctl/ike.c
+++ b/sbin/ipsecctl/ike.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ike.c,v 1.83 2022/06/25 20:33:40 mbuhl Exp $ */
+/* $OpenBSD: ike.c,v 1.84 2023/08/07 04:10:08 dlg Exp $ */
/*
* Copyright (c) 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org>
*
@@ -148,6 +148,10 @@ ike_section_ipsec(struct ipsec_rule *r, FILE *fd)
if (r->tag)
fprintf(fd, SET "[%s]:PF-Tag=%s force\n", r->p2name, r->tag);
+ if (r->flags & IPSEC_RULE_F_IFACE) {
+ fprintf(fd, SET "[%s]:Interface=%u force\n", r->p2name,
+ r->iface);
+ }
}
static int
@@ -842,21 +846,30 @@ ike_setup_ids(struct ipsec_rule *r)
err(1, "ike_setup_ids");
/* Phase 2 name is from and to network, protocol, port*/
- sproto[0] = ssport[0] = sdport[0] = 0;
- if (r->proto)
- snprintf(sproto, sizeof sproto, "=%u", r->proto);
- if (r->sport)
- snprintf(ssport, sizeof ssport, ":%u", ntohs(r->sport));
- if (r->dport)
- snprintf(sdport, sizeof sdport, ":%u", ntohs(r->dport));
- /* from-network/masklen=proto:port */
- if (asprintf(&r->p2lid, "from-%s%s%s", r->src->name, sproto, ssport)
- == -1)
- err(1, "ike_setup_ids");
- /* to-network/masklen=proto:port */
- if (asprintf(&r->p2rid, "to-%s%s%s", r->dst->name, sproto, sdport)
- == -1)
- err(1, "ike_setup_ids");
+ if (r->flags & IPSEC_RULE_F_IFACE) {
+ if (asprintf(&r->p2lid, "from-sec%u", r->iface) == -1)
+ err(1, "ike_setup_ids");
+ if (asprintf(&r->p2rid, "to-sec%u", r->iface) == -1)
+ err(1, "ike_setup_ids");
+ } else {
+ sproto[0] = ssport[0] = sdport[0] = 0;
+ if (r->proto)
+ snprintf(sproto, sizeof sproto, "=%u", r->proto);
+ if (r->sport)
+ snprintf(ssport, sizeof ssport, ":%u", ntohs(r->sport));
+ if (r->dport)
+ snprintf(sdport, sizeof sdport, ":%u", ntohs(r->dport));
+
+ /* from-network/masklen=proto:port */
+ if (asprintf(&r->p2lid, "from-%s%s%s", r->src->name,
+ sproto, ssport) == -1)
+ err(1, "ike_setup_ids");
+ /* to-network/masklen=proto:port */
+ if (asprintf(&r->p2rid, "to-%s%s%s", r->dst->name,
+ sproto, sdport) == -1)
+ err(1, "ike_setup_ids");
+ }
+
/* from-network/masklen=proto:port-to-network/masklen=proto:port */
if (asprintf(&r->p2name, "%s-%s", r->p2lid , r->p2rid) == -1)
err(1, "ike_setup_ids");
diff --git a/sbin/ipsecctl/ipsecctl.h b/sbin/ipsecctl/ipsecctl.h
index 0959c9b2641..c7f92d7d41c 100644
--- a/sbin/ipsecctl/ipsecctl.h
+++ b/sbin/ipsecctl/ipsecctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsecctl.h,v 1.75 2021/10/22 12:30:54 bluhm Exp $ */
+/* $OpenBSD: ipsecctl.h,v 1.76 2023/08/07 04:10:08 dlg Exp $ */
/*
* Copyright (c) 2004, 2005 Hans-Joerg Hoexer <hshoexer@openbsd.org>
*
@@ -178,6 +178,9 @@ TAILQ_HEAD(dst_bundle_queue, ipsec_rule);
struct ipsec_rule {
u_int8_t type;
+ unsigned int flags;
+#define IPSEC_RULE_F_IFACE (1 << 0) /* iface is valid */
+
struct ipsec_addr_wrap *src;
struct ipsec_addr_wrap *dst;
struct ipsec_addr_wrap *dst2;
@@ -215,6 +218,7 @@ struct ipsec_rule {
u_int32_t spi;
u_int32_t spi2;
u_int32_t nr;
+ unsigned int iface;
TAILQ_ENTRY(ipsec_rule) rule_entry;
TAILQ_ENTRY(ipsec_rule) bundle_entry;
diff --git a/sbin/ipsecctl/parse.y b/sbin/ipsecctl/parse.y
index 5ad108382b1..e1c6d47447f 100644
--- a/sbin/ipsecctl/parse.y
+++ b/sbin/ipsecctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.182 2023/04/19 13:33:37 jsg Exp $ */
+/* $OpenBSD: parse.y,v 1.183 2023/08/07 04:10:08 dlg Exp $ */
/*
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -232,6 +232,7 @@ struct ipsec_transforms *ipsec_transforms;
typedef struct {
union {
int64_t number;
+ uint32_t unit;
u_int8_t ikemode;
u_int8_t dir;
u_int8_t satype; /* encapsulating prococol */
@@ -284,9 +285,10 @@ typedef struct {
%token AUTHKEY ENCKEY FILENAME AUTHXF ENCXF ERROR IKE MAIN QUICK AGGRESSIVE
%token PASSIVE ACTIVE ANY IPIP IPCOMP COMPXF TUNNEL TRANSPORT DYNAMIC LIFETIME
%token TYPE DENY BYPASS LOCAL PROTO USE ACQUIRE REQUIRE DONTACQ GROUP PORT TAG
-%token INCLUDE BUNDLE UDPENCAP
+%token INCLUDE BUNDLE UDPENCAP INTERFACE
%token <v.string> STRING
%token <v.number> NUMBER
+%type <v.unit> iface
%type <v.string> string
%type <v.dir> dir
%type <v.satype> satype
@@ -401,6 +403,41 @@ ikerule : IKE ikemode satype tmode proto hosts peers
if (expand_rule(r, &$7, 0, 0, NULL, NULL, NULL))
errx(1, "ikerule: expand_rule");
}
+
+ /* ike interface sec0 local $h_self peer $h_s2s1 ... */
+ | IKE ikemode iface peers
+ phase1mode phase2mode ids ikeauth {
+ uint8_t proto = 0; // IPPROTO_IPIP;
+ struct ipsec_hosts hosts;
+ struct ike_mode *phase1mode = $5;
+ struct ike_mode *phase2mode = $6;
+ uint8_t satype = IPSEC_ESP;
+ uint8_t tmode = IPSEC_TUNNEL;
+ uint8_t mode = $2;
+ struct ike_auth *authtype = &$8;
+ char *tag = NULL;
+
+ struct ipsec_rule *r;
+
+ hosts.src = host_v4("0.0.0.0/0", 1);
+ hosts.sport = htons(0);
+ hosts.dst = host_v4("0.0.0.0/0", 1);
+ hosts.dport = htons(0);
+
+ r = create_ike(proto, &hosts, phase1mode, phase2mode,
+ satype, tmode, mode, $7.srcid, $7.dstid,
+ authtype, tag);
+ if (r == NULL) {
+ YYERROR;
+ }
+
+ r->flags |= IPSEC_RULE_F_IFACE;
+ r->iface = $3;
+
+ if (expand_rule(r, &$4, 0, 0, NULL, NULL, NULL))
+ errx(1, "ikerule: expand interface rule");
+
+ }
;
satype : /* empty */ { $$ = IPSEC_ESP; }
@@ -909,6 +946,30 @@ tag : /* empty */
}
;
+iface : INTERFACE STRING {
+ static const char prefix[] = "sec";
+ const char *errstr = NULL;
+ size_t len, plen;
+
+ plen = strlen(prefix);
+ len = strlen($2);
+
+ if (len <= plen || memcmp($2, prefix, plen) != 0) {
+ yyerror("invalid %s interface name", prefix);
+ free($2);
+ YYERROR;
+ }
+
+ $$ = strtonum($2 + plen, 0, UINT_MAX, &errstr);
+ free($2);
+ if (errstr != NULL) {
+ yyerror("invalid %s interface unit: %s",
+ prefix, errstr);
+ YYERROR;
+ }
+ }
+ ;
+
string : string STRING
{
if (asprintf(&$$, "%s %s", $1, $2) == -1)
@@ -1009,6 +1070,7 @@ lookup(char *s)
{ "ike", IKE },
{ "in", IN },
{ "include", INCLUDE },
+ { "interface", INTERFACE },
{ "ipcomp", IPCOMP },
{ "ipip", IPIP },
{ "lifetime", LIFETIME },
@@ -2216,6 +2278,7 @@ copyrule(struct ipsec_rule *rule)
r->enckey = copykey(rule->enckey);
r->tag = copytag(rule->tag);
+ r->flags = rule->flags;
r->p1ie = rule->p1ie;
r->p2ie = rule->p2ie;
r->type = rule->type;
@@ -2231,6 +2294,7 @@ copyrule(struct ipsec_rule *rule)
r->udpencap = rule->udpencap;
r->udpdport = rule->udpdport;
r->nr = rule->nr;
+ r->iface = rule->iface;
return (r);
}
diff --git a/sbin/ipsecctl/pfkdump.c b/sbin/ipsecctl/pfkdump.c
index b2bd5825c63..9bd728398de 100644
--- a/sbin/ipsecctl/pfkdump.c
+++ b/sbin/ipsecctl/pfkdump.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkdump.c,v 1.56 2023/03/07 17:43:59 guenther Exp $ */
+/* $OpenBSD: pfkdump.c,v 1.57 2023/08/07 04:10:08 dlg Exp $ */
/*
* Copyright (c) 2003 Markus Friedl. All rights reserved.
@@ -62,6 +62,7 @@ static void print_mtu(struct sadb_ext *, struct sadb_msg *, int);
static void print_tap(struct sadb_ext *, struct sadb_msg *, int);
static void print_satype(struct sadb_ext *, struct sadb_msg *, int);
static void print_counter(struct sadb_ext *, struct sadb_msg *, int);
+static void print_iface(struct sadb_ext *, struct sadb_msg *, int);
static struct idname *lookup(struct idname *, u_int32_t);
static char *lookup_name(struct idname *, u_int32_t);
@@ -115,6 +116,7 @@ struct idname ext_types[] = {
{ SADB_X_EXT_TAP, "tap", print_tap },
{ SADB_X_EXT_SATYPE2, "satype2", print_satype },
{ SADB_X_EXT_COUNTER, "counter", print_counter },
+ { SADB_X_EXT_IFACE, "interface", print_iface },
{ 0, NULL, NULL }
};
@@ -463,6 +465,24 @@ print_counter(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
#undef plural
}
+static void
+print_iface(struct sadb_ext *ext, struct sadb_msg *msg, int opts)
+{
+ struct sadb_x_iface *siface = (struct sadb_x_iface *)ext;
+ const char *dir = "unknown";
+
+ switch (siface->sadb_x_iface_direction) {
+ case IPSP_DIRECTION_IN:
+ dir = "in";
+ break;
+ case IPSP_DIRECTION_OUT:
+ dir = "out";
+ break;
+ }
+
+ printf("sec%u direction %s", siface->sadb_x_iface_unit, dir);
+}
+
static char *
alg_by_ext(u_int8_t ext_type, u_int8_t id)
{