diff options
-rw-r--r-- | sbin/ipsecctl/ike.c | 45 | ||||
-rw-r--r-- | sbin/ipsecctl/ipsecctl.h | 6 | ||||
-rw-r--r-- | sbin/ipsecctl/parse.y | 68 | ||||
-rw-r--r-- | sbin/ipsecctl/pfkdump.c | 22 |
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) { |