Index | Thread | Search

From:
Asa Yeamans <asa.yeamans@rivin.net>
Subject:
IPv6 support for ipsec with sec interfaces
To:
"tech@openbsd.org" <tech@openbsd.org>
Date:
Wed, 25 Mar 2026 14:47:32 +0000

Download raw body.

Thread
  • Asa Yeamans:

    IPv6 support for ipsec with sec interfaces

I recently discovered that ipsecctl does not properly configure IPv6 IPSec tunnels when using secX interfaces. When running ipsecctl in verbose mode, one can see that for secX interfaces, ipsecctl only configures tunnels for IPv4 0.0.0.0/0 endpoints.

Digging into ipsecctl we find the source of the bug in parse.y on line 420 where it hard-codes IPv4 0.0.0.0/0 for source and 422 hard-codes IPv4 0.0.0.0/0 for destination.

I have included a diff that automatically adds either IPv4 or IPv6 endpoints depending on the configured address on the secX interface.


Index: parse.y
===================================================================
RCS file: /cvs/src/sbin/ipsecctl/parse.y,v diff -u -p -u -p -r1.184 parse.y
--- parse.y     30 Apr 2025 03:54:09 -0000      1.184
+++ parse.y     25 Mar 2026 14:28:48 -0000
@@ -414,13 +414,33 @@ ikerule           : IKE ikemode satype tmode prot
                        uint8_t                  mode = $2;
                        struct ike_auth         *authtype = &$8;
                        char                    *tag = NULL;
+                       char                    ifname[14];
+                       struct ipsec_addr_wrap  *ifa;

                        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);
+                       snprintf(ifname, sizeof(ifname), "sec%d", $3);
+                       ifa = ifa_lookup(ifname);
+                       if (ifa == NULL) {
+                               YYERROR;
+                       }
+
+                       switch (ifa->af) {
+                               case AF_INET:
+                                       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);
+                                       break;
+                               case AF_INET6:
+                                       hosts.src = host_v6("::", 1);
+                                       hosts.sport = htons(0);
+                                       hosts.dst = host_v6("::", 1);
+                                       hosts.dport = htons(0);
+                                       break;
+                               default:
+                                       YYERROR;
+                       }

                        r = create_ike(proto, &hosts, phase1mode, phase2mode,
                            satype, tmode, mode, $7.srcid, $7.dstid,