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: