Hi,

ipsecctl groups sa bundles together automatically.  I got confused
by this feature, especially as there is no way in user land to see
this.

I think we should extend the kernel interface to export the bundle
information.  Unfortunately the header SADB_X_EXT_PROTOCOL is reused
by SADB_X_GRPSPIS, so it cannot be used to transfer the second sa
type to user land with sysctl.

I think introducing a new SADB_X_EXT_SATYPE2 and using it everywhere,
is the best fix as the sa type is not a protocol anyway.

# ipsecctl -ss -v
esp tunnel from 10.188.100.17 to 10.188.100.70 spi 0x10000841 auth hmac-sha2-256
 enc aes-256
        sa: spi 0x10000841 auth hmac-sha2-256 enc aes
                state mature replay 0 flags 0x4<tunnel>
        lifetime_cur: alloc 0 bytes 2432 add 1487971378 first 1487971378
        address_src: 10.188.100.17
        address_dst: 10.188.100.70
        sa2: spi 0x10002841 auth hmac-sha2-256 enc none
                state mature replay 0 flags 0x4<tunnel>
        dst2: 10.188.100.70
        lifetime_lastuse: alloc 0 bytes 0 add 0 first 1487971389
        satype2: type ah

ok?

bluhm

Index: sys/net/pfkeyv2.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/pfkeyv2.c,v
retrieving revision 1.152
diff -u -p -r1.152 pfkeyv2.c
--- sys/net/pfkeyv2.c   24 Feb 2017 18:36:33 -0000      1.152
+++ sys/net/pfkeyv2.c   24 Feb 2017 20:17:37 -0000
@@ -556,6 +556,13 @@ pfkeyv2_get(struct tdb *sa, void **heade
                }
        }
 
+       if (sa->tdb_onext) {
+               i += sizeof(struct sadb_sa);
+               i += sizeof(struct sadb_address) +
+                   PADUP(SA_LEN(&sa->tdb_onext->tdb_dst.sa));
+               i += sizeof(struct sadb_protocol);
+       }
+
        if (sa->tdb_udpencap_port)
                i += sizeof(struct sadb_x_udpencap);
 
@@ -634,6 +641,15 @@ pfkeyv2_get(struct tdb *sa, void **heade
                export_flow(&p, IPSP_IPSEC_USE, &sa->tdb_filter,
                    &sa->tdb_filtermask, headers);
 
+       if (sa->tdb_onext) {
+               headers[SADB_X_EXT_SA2] = p;
+               export_sa(&p, sa->tdb_onext);
+               headers[SADB_X_EXT_DST2] = p;
+               export_address(&p, &sa->tdb_onext->tdb_dst.sa);
+               headers[SADB_X_EXT_SATYPE2] = p;
+               export_satype(&p, sa->tdb_onext);
+       }
+
        /* Export UDP encapsulation port, if present */
        if (sa->tdb_udpencap_port) {
                headers[SADB_X_EXT_UDPENCAP] = p;
@@ -1368,7 +1384,7 @@ pfkeyv2_send(struct socket *socket, void
                ssa = (struct sadb_sa *) headers[SADB_X_EXT_SA2];
                sunionp = (union sockaddr_union *) (headers[SADB_X_EXT_DST2] +
                    sizeof(struct sadb_address));
-               sa_proto = ((struct sadb_protocol *) 
headers[SADB_X_EXT_PROTOCOL]);
+               sa_proto = (struct sadb_protocol *) headers[SADB_X_EXT_SATYPE2];
 
                tdb2 = gettdb(rdomain, ssa->sadb_sa_spi, sunionp,
                    SADB_X_GETSPROTO(sa_proto->sadb_protocol_proto));
Index: sys/net/pfkeyv2.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/pfkeyv2.h,v
retrieving revision 1.73
diff -u -p -r1.73 pfkeyv2.h
--- sys/net/pfkeyv2.h   24 Jan 2017 10:08:30 -0000      1.73
+++ sys/net/pfkeyv2.h   24 Feb 2017 20:13:53 -0000
@@ -261,7 +261,8 @@ struct sadb_x_tap {
 #define SADB_X_EXT_LIFETIME_LASTUSE   32
 #define SADB_X_EXT_TAG                33
 #define SADB_X_EXT_TAP                34
-#define SADB_EXT_MAX                  34
+#define SADB_X_EXT_SATYPE2            35
+#define SADB_EXT_MAX                  35
 
 /* Fix pfkeyv2.c struct pfkeyv2_socket if SATYPE_MAX > 31 */
 #define SADB_SATYPE_UNSPEC              0
@@ -427,6 +428,7 @@ void export_key(void **, struct tdb *, i
 void export_udpencap(void **, struct tdb *);
 void export_tag(void **, struct tdb *);
 void export_tap(void **, struct tdb *);
+void export_satype(void **, struct tdb *);
 
 void import_address(struct sockaddr *, struct sadb_address *);
 void import_identities(struct ipsec_ids **, int, struct sadb_ident *,
Index: sys/net/pfkeyv2_convert.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/pfkeyv2_convert.c,v
retrieving revision 1.58
diff -u -p -r1.58 pfkeyv2_convert.c
--- sys/net/pfkeyv2_convert.c   24 Jan 2017 10:08:30 -0000      1.58
+++ sys/net/pfkeyv2_convert.c   24 Feb 2017 20:12:45 -0000
@@ -887,4 +887,14 @@ export_tap(void **p, struct tdb *tdb)
        stag->sadb_x_tap_len = sizeof(struct sadb_x_tap) / sizeof(uint64_t);
        *p += sizeof(struct sadb_x_tap);
 }
+
+void
+export_satype(void **p, struct tdb *tdb)
+{
+       struct sadb_protocol *sab = *p;
+
+       sab->sadb_protocol_len = sizeof(struct sadb_protocol) /
+           sizeof(uint64_t);
+       sab->sadb_protocol_proto = tdb->tdb_satype;
+}
 #endif
Index: sys/net/pfkeyv2_parsemessage.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/pfkeyv2_parsemessage.c,v
retrieving revision 1.50
diff -u -p -r1.50 pfkeyv2_parsemessage.c
--- sys/net/pfkeyv2_parsemessage.c      24 Jan 2017 10:08:30 -0000      1.50
+++ sys/net/pfkeyv2_parsemessage.c      24 Feb 2017 19:53:40 -0000
@@ -125,6 +125,7 @@
 #define BITMAP_X_LIFETIME_LASTUSE      (1LL << SADB_X_EXT_LIFETIME_LASTUSE)
 #define BITMAP_X_TAG                   (1LL << SADB_X_EXT_TAG)
 #define BITMAP_X_TAP                   (1LL << SADB_X_EXT_TAP)
+#define BITMAP_X_SATYPE2               (1LL << SADB_X_EXT_SATYPE2)
 
 uint64_t sadb_exts_allowed_in[SADB_MAX+1] =
 {
@@ -157,7 +158,7 @@ uint64_t sadb_exts_allowed_in[SADB_MAX+1
        /* X_DELFLOW */
        BITMAP_X_FLOW,
        /* X_GRPSPIS */
-       BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | 
BITMAP_X_PROTOCOL,
+       BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | 
BITMAP_X_SATYPE2,
        /* X_ASKPOLICY */
        BITMAP_X_POLICY,
 };
@@ -193,7 +194,7 @@ uint64_t sadb_exts_required_in[SADB_MAX+
        /* X_DELFLOW */
        BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | 
BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE,
        /* X_GRPSPIS */
-       BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | 
BITMAP_X_PROTOCOL,
+       BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | 
BITMAP_X_SATYPE2,
        /* X_ASKPOLICY */
        BITMAP_X_POLICY,
 };
@@ -229,7 +230,7 @@ uint64_t sadb_exts_allowed_out[SADB_MAX+
        /* X_DELFLOW */
        BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_PROTOCOL | 
BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE,
        /* X_GRPSPIS */
-       BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | 
BITMAP_X_PROTOCOL,
+       BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | 
BITMAP_X_SATYPE2,
        /* X_ASKPOLICY */
        BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_SRC_MASK | 
BITMAP_X_DST_MASK | BITMAP_X_FLOW_TYPE | BITMAP_X_POLICY,
 };
@@ -265,7 +266,7 @@ uint64_t sadb_exts_required_out[SADB_MAX
        /* X_DELFLOW */
        BITMAP_X_SRC_MASK | BITMAP_X_DST_MASK | BITMAP_X_SRC_FLOW | 
BITMAP_X_DST_FLOW | BITMAP_X_FLOW_TYPE,
        /* X_GRPSPIS */
-       BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | 
BITMAP_X_PROTOCOL,
+       BITMAP_SA | BITMAP_X_SA2 | BITMAP_X_DST2 | BITMAP_ADDRESS_DST | 
BITMAP_X_SATYPE2,
        /* X_REPPOLICY */
        BITMAP_X_SRC_FLOW | BITMAP_X_DST_FLOW | BITMAP_X_SRC_MASK | 
BITMAP_X_DST_MASK | BITMAP_X_FLOW_TYPE,
 };
@@ -434,9 +435,10 @@ pfkeyv2_parsemessage(void *p, int len, v
                break;
                case SADB_X_EXT_PROTOCOL:
                case SADB_X_EXT_FLOW_TYPE:
+               case SADB_X_EXT_SATYPE2:
                        if (i != sizeof(struct sadb_protocol)) {
-                               DPRINTF(("pfkeyv2_parsemessage: bad "
-                                   "PROTOCOL/FLOW header length in extension "
+                               DPRINTF(("pfkeyv2_parsemessage: bad PROTOCOL/"
+                                   "FLOW/SATYPE2 header length in extension "
                                    "header %d\n", sadb_ext->sadb_ext_type));
                                return (EINVAL);
                        }
Index: sbin/ipsecctl/pfkdump.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sbin/ipsecctl/pfkdump.c,v
retrieving revision 1.42
diff -u -p -r1.42 pfkdump.c
--- sbin/ipsecctl/pfkdump.c     9 Dec 2015 21:41:50 -0000       1.42
+++ sbin/ipsecctl/pfkdump.c     24 Feb 2017 20:58:34 -0000
@@ -55,6 +55,7 @@ static void   print_ident(struct sadb_ext 
 static void    print_udpenc(struct sadb_ext *, struct sadb_msg *);
 static void    print_tag(struct sadb_ext *, struct sadb_msg *);
 static void    print_tap(struct sadb_ext *, struct sadb_msg *);
+static void    print_satype(struct sadb_ext *, struct sadb_msg *);
 
 static struct idname *lookup(struct idname *, u_int32_t);
 static char    *lookup_name(struct idname *, u_int32_t);
@@ -103,6 +104,7 @@ struct idname ext_types[] = {
        { SADB_X_EXT_LIFETIME_LASTUSE,  "lifetime_lastuse",     print_life },
        { SADB_X_EXT_TAG,               "tag",                  print_tag },
        { SADB_X_EXT_TAP,               "tap",                  print_tap },
+       { SADB_X_EXT_SATYPE2,           "satype2",              print_satype },
        { 0,                            NULL,                   NULL }
 };
 
@@ -402,6 +404,14 @@ print_tap(struct sadb_ext *ext, struct s
        struct sadb_x_tap *stap = (struct sadb_x_tap *)ext;
 
        printf("enc%u", stap->sadb_x_tap_unit);
+}
+
+static void
+print_satype(struct sadb_ext *ext, struct sadb_msg *msg)
+{
+       struct sadb_protocol *proto = (struct sadb_protocol *)ext;
+
+       printf("type %s", lookup_name(sa_types, proto->sadb_protocol_proto));
 }
 
 static char *
Index: sbin/ipsecctl/pfkey.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sbin/ipsecctl/pfkey.c,v
retrieving revision 1.57
diff -u -p -r1.57 pfkey.c
--- sbin/ipsecctl/pfkey.c       10 Dec 2015 17:27:00 -0000      1.57
+++ sbin/ipsecctl/pfkey.c       24 Feb 2017 19:59:44 -0000
@@ -701,7 +701,7 @@ pfkey_sagroup(int sd, u_int8_t satype, u
        sa_dst2.sadb_address_len = (sizeof(sa_dst2) + ROUNDUP(sdst2.ss_len)) / 
8;
 
        bzero(&sa_proto, sizeof(sa_proto));
-       sa_proto.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
+       sa_proto.sadb_protocol_exttype = SADB_X_EXT_SATYPE2;
        sa_proto.sadb_protocol_len = sizeof(sa_proto) / 8;
        sa_proto.sadb_protocol_direction = 0;
        sa_proto.sadb_protocol_proto = satype2;
Index: sbin/iked/pfkey.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sbin/iked/pfkey.c,v
retrieving revision 1.52
diff -u -p -r1.52 pfkey.c
--- sbin/iked/pfkey.c   3 Sep 2016 09:20:07 -0000       1.52
+++ sbin/iked/pfkey.c   24 Feb 2017 21:06:34 -0000
@@ -1019,7 +1019,7 @@ pfkey_sagroup(int sd, uint8_t satype1, u
            (sizeof(sa_dst2) + ROUNDUP(sdst2.ss_len)) / 8;
 
        bzero(&sa_proto, sizeof(sa_proto));
-       sa_proto.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
+       sa_proto.sadb_protocol_exttype = SADB_X_EXT_SATYPE2;
        sa_proto.sadb_protocol_len = sizeof(sa_proto) / 8;
        sa_proto.sadb_protocol_direction = 0;
        sa_proto.sadb_protocol_proto = satype2;
Index: sbin/isakmpd/pf_key_v2.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sbin/isakmpd/pf_key_v2.c,v
retrieving revision 1.197
diff -u -p -r1.197 pf_key_v2.c
--- sbin/isakmpd/pf_key_v2.c    10 Dec 2015 17:27:00 -0000      1.197
+++ sbin/isakmpd/pf_key_v2.c    24 Feb 2017 21:25:25 -0000
@@ -3303,8 +3303,8 @@ pf_key_v2_group_spis(struct sa *sa, stru
                goto cleanup;
        addr = 0;
 
-       /* Setup the PROTOCOL extension.  */
-       protocol.sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
+       /* Setup the sa type extension.  */
+       protocol.sadb_protocol_exttype = SADB_X_EXT_SATYPE2;
        protocol.sadb_protocol_len = sizeof protocol / PF_KEY_V2_CHUNK;
        switch (proto2->proto) {
        case IPSEC_PROTO_IPSEC_ESP:

Reply via email to