Download raw body.
diff: deleting flow/sa by ipsecctl
Hello,
When we have flows and SAs like following,
% doas ipsecctl -sa
FLOWS:
flow esp in proto udp from 203.0.113.80 port l2tp to 192.0.2.51 port l2tp peer 203.0.113.80 srcid 192.0.2.51/32 dstid 10.0.2.15/32 type require
flow esp out proto udp from 192.0.2.51 port l2tp to 203.0.113.80 port l2tp peer 203.0.113.80 srcid 192.0.2.51/32 dstid 10.0.2.15/32 type require
SAD:
esp transport from 203.0.113.80 to 192.0.2.51 spi 0x94194be1 auth hmac-sha1 enc aes
esp transport from 192.0.2.51 to 203.0.113.80 spi 0xc1c584a2 auth hmac-sha1 enc aes
%
if deleting the first flow is desired,
% doas ipsecctl -ndf -
flow esp in proto udp from 203.0.113.80 port l2tp to 192.0.2.51 port l2tp peer 203.0.113.80 srcid 192.0.2.51/32 dstid 10.0.2.15/32 type require
stdin: 1: syntax error
ipsecctl: Syntax error in config file: ipsec rules not loaded
%
error. Because ipsecctl doesn't accept address/mask format for
{src,dst}id.
also, deleting the first SA is desired,
% doas ipsecctl -ndf -
esp transport from 203.0.113.80 to 192.0.2.51 spi 0x94194be1 auth hmac-sha1 enc aes
stdin: 1: no authentication key specified
ipsecctl: Syntax error in config file: ipsec rules not loaded
%
fails because ipsecctl requires authentication and encryption key
always.
The diff changes ipsecctl to accept addr/mask of flow id and SA
without keys when deleting.
As for the ID, /32 can be deleted when show. I didn't take that way
because IP address/mask is valid in RFC and pfkey seems to support
that.
ok?
Index: ipsecctl.c
===================================================================
RCS file: /disk/cvs/openbsd/src/sbin/ipsecctl/ipsecctl.c,v
diff -u -p -r1.88 ipsecctl.c
--- ipsecctl.c 6 Feb 2024 05:39:28 -0000 1.88
+++ ipsecctl.c 26 Jul 2024 02:06:57 -0000
@@ -112,7 +112,7 @@ ipsecctl_rules(char *filename, int opts)
TAILQ_INIT(&ipsec.rule_queue);
TAILQ_INIT(&ipsec.bundle_queue);
- if (parse_rules(filename, &ipsec) < 0) {
+ if (parse_rules(filename, &ipsec, opts) < 0) {
warnx("Syntax error in config file: ipsec rules not loaded");
error = 1;
} else {
Index: ipsecctl.h
===================================================================
RCS file: /disk/cvs/openbsd/src/sbin/ipsecctl/ipsecctl.h,v
diff -u -p -r1.77 ipsecctl.h
--- ipsecctl.h 9 Oct 2023 15:32:14 -0000 1.77
+++ ipsecctl.h 26 Jul 2024 02:06:57 -0000
@@ -242,7 +242,7 @@ struct ipsecctl {
struct ipsec_bundle_queue bundle_queue;
};
-int parse_rules(const char *, struct ipsecctl *);
+int parse_rules(const char *, struct ipsecctl *, int);
int cmdline_symset(char *);
int ipsecctl_add_rule(struct ipsecctl *, struct ipsec_rule *);
void ipsecctl_free_rule(struct ipsec_rule *);
Index: parse.y
===================================================================
RCS file: /disk/cvs/openbsd/src/sbin/ipsecctl/parse.y,v
diff -u -p -r1.183 parse.y
--- parse.y 7 Aug 2023 04:10:08 -0000 1.183
+++ parse.y 26 Jul 2024 02:06:57 -0000
@@ -87,6 +87,7 @@ int cmdline_symset(char *);
static struct ipsecctl *ipsec = NULL;
static int debug = 0;
+static int delete = 0;
const struct ipsec_xf authxfs[] = {
{ "unknown", AUTHXF_UNKNOWN, 0, 0 },
@@ -668,6 +669,22 @@ type : /* empty */ {
;
id : STRING { $$ = $1; }
+ | STRING '/' NUMBER {
+ struct in6_addr ia;
+ char *str;
+
+ if (!(0 <= $3 &&
+ ((inet_pton(AF_INET, $1, &ia) == 1 && $3 <= 32) ||
+ (inet_pton(AF_INET6, $1, &ia) == 1 && $3 <= 128)))){
+ free($1);
+ yyerror("invalid ip address/mask");
+ YYERROR;
+ }
+ if (asprintf(&str, "%s/%d", $1, (int)$3) == -1)
+ err(1, "id: asprintf");
+ free($1);
+ $$ = str;
+ }
;
spispec : SPI STRING {
@@ -1432,12 +1449,13 @@ popfile(void)
}
int
-parse_rules(const char *filename, struct ipsecctl *ipsecx)
+parse_rules(const char *filename, struct ipsecctl *ipsecx, int opts)
{
struct sym *sym;
int errors = 0;
ipsec = ipsecx;
+ delete = (opts & IPSECCTL_OPT_DELETE)? 1 : 0;
if ((file = pushfile(filename, 1)) == NULL) {
return (-1);
@@ -2412,7 +2430,8 @@ validate_sa(u_int32_t spi, u_int8_t saty
return (0);
}
if (xfs && xfs->authxf) {
- if (!authkey && xfs->authxf != &authxfs[AUTHXF_NONE]) {
+ if (!delete &&
+ !authkey && xfs->authxf != &authxfs[AUTHXF_NONE]) {
yyerror("no authentication key specified");
return (0);
}
@@ -2423,7 +2442,7 @@ validate_sa(u_int32_t spi, u_int8_t saty
}
}
if (xfs && xfs->encxf) {
- if (!enckey && xfs->encxf != &encxfs[ENCXF_NULL]) {
+ if (!delete && !enckey && xfs->encxf != &encxfs[ENCXF_NULL]) {
yyerror("no encryption key specified");
return (0);
}
diff: deleting flow/sa by ipsecctl