This diff allows iked(8) to optionally negotiate Child SAs with IPsec transport mode instead of tunnel mode.
Ok? Index: iked.conf.5 =================================================================== RCS file: /cvs/src/sbin/iked/iked.conf.5,v retrieving revision 1.55 diff -u -p -u -r1.55 iked.conf.5 --- iked.conf.5 11 May 2019 16:30:23 -0000 1.55 +++ iked.conf.5 17 Jul 2019 20:26:54 -0000 @@ -268,6 +268,15 @@ specifies that .Xr ipcomp 4 , the IP Payload Compression protocol, is negotiated in addition to encapsulation. The optional compression is applied before packets are encapsulated. +.It Op Ar tmode +.Ar tmode +describes the encapsulation mode to be used. +Possible modes are +.Ar tunnel +and +.Ar transport ; +the default is +.Ar tunnel . .It Op Ar encap .Ar encap specifies the encapsulation protocol to be used. @@ -277,15 +286,6 @@ and .Ar ah ; the default is .Ar esp . -.\" .It Op Ar tmode -.\" .Ar tmode -.\" describes the encapsulation mode to be used. -.\" Possible modes are -.\" .Ar tunnel -.\" and -.\" .Ar transport ; -.\" the default is -.\" .Ar tunnel . .It Op Ar af This policy only applies to endpoints of the specified address family which can be either Index: iked.h =================================================================== RCS file: /cvs/src/sbin/iked/iked.h,v retrieving revision 1.121 diff -u -p -u -r1.121 iked.h --- iked.h 11 May 2019 16:30:23 -0000 1.121 +++ iked.h 17 Jul 2019 20:26:55 -0000 @@ -251,6 +251,7 @@ struct iked_policy { #define IKED_POLICY_QUICK 0x08 #define IKED_POLICY_SKIP 0x10 #define IKED_POLICY_IPCOMP 0x20 +#define IKED_POLICY_TRANSPORT 0x40 int pol_refcnt; @@ -465,6 +466,7 @@ struct iked_sa { int sa_mobike; /* MOBIKE */ int sa_frag; /* fragmentation */ + int sa_use_transport_mode; /* should be reset */ struct iked_timer sa_timer; /* SA timeouts */ #define IKED_IKE_SA_EXCHANGE_TIMEOUT 300 /* 5 minutes */ Index: ikev2.c =================================================================== RCS file: /cvs/src/sbin/iked/ikev2.c,v retrieving revision 1.171 diff -u -p -u -r1.171 ikev2.c --- ikev2.c 11 May 2019 16:30:23 -0000 1.171 +++ ikev2.c 17 Jul 2019 20:26:57 -0000 @@ -148,8 +148,12 @@ ssize_t ikev2_add_nat_detection(struct i ssize_t ikev2_add_fragmentation(struct iked *, struct ibuf *, struct ikev2_payload **, struct iked_message *, ssize_t); +ssize_t ikev2_add_notify(struct iked *, struct ibuf *, + struct ikev2_payload **, ssize_t, struct iked_sa *, uint16_t); ssize_t ikev2_add_mobike(struct iked *, struct ibuf *, struct ikev2_payload **, ssize_t, struct iked_sa *); +ssize_t ikev2_add_transport_mode(struct iked *, struct ibuf *, + struct ikev2_payload **, ssize_t, struct iked_sa *); int ikev2_update_sa_addresses(struct iked *, struct iked_sa *); int ikev2_resp_informational(struct iked *, struct iked_sa *, struct iked_message *); @@ -1670,8 +1674,9 @@ ikev2_add_ipcompnotify(struct iked *env, } ssize_t -ikev2_add_mobike(struct iked *env, struct ibuf *e, - struct ikev2_payload **pld, ssize_t len, struct iked_sa *sa) +ikev2_add_notify(struct iked *env, struct ibuf *e, + struct ikev2_payload **pld, ssize_t len, struct iked_sa *sa, + uint16_t notify) { struct ikev2_notify *n; uint8_t *ptr; @@ -1687,13 +1692,27 @@ ikev2_add_mobike(struct iked *env, struc n = (struct ikev2_notify *)ptr; n->n_protoid = 0; n->n_spisize = 0; - n->n_type = htobe16(IKEV2_N_MOBIKE_SUPPORTED); + n->n_type = htobe16(notify); log_debug("%s: done", __func__); return (len); } ssize_t +ikev2_add_mobike(struct iked *env, struct ibuf *e, + struct ikev2_payload **pld, ssize_t len, struct iked_sa *sa) +{ + return ikev2_add_notify(env, e, pld, len, sa, IKEV2_N_MOBIKE_SUPPORTED); +} + +ssize_t +ikev2_add_transport_mode(struct iked *env, struct ibuf *e, + struct ikev2_payload **pld, ssize_t len, struct iked_sa *sa) +{ + return ikev2_add_notify(env, e, pld, len, sa, IKEV2_N_USE_TRANSPORT_MODE); +} + +ssize_t ikev2_add_fragmentation(struct iked *env, struct ibuf *buf, struct ikev2_payload **pld, struct iked_message *msg, ssize_t len) { @@ -5209,6 +5228,7 @@ ikev2_childsa_negotiate(struct iked *env csa->csa_spi.spi_protoid = prop->prop_protoid; csa->csa_esn = esn; csa->csa_acquired = acquired; + csa->csa_transport = sa->sa_use_transport_mode; /* Set up responder's SPIs */ if (initiator) { @@ -5295,6 +5315,7 @@ ikev2_childsa_negotiate(struct iked *env ret = 0; done: + sa->sa_use_transport_mode = 0; /* reset state after use */ ibuf_release(dhsecret); ibuf_release(keymat); ibuf_release(seed); Index: ikev2_pld.c =================================================================== RCS file: /cvs/src/sbin/iked/ikev2_pld.c,v retrieving revision 1.71 diff -u -p -u -r1.71 ikev2_pld.c --- ikev2_pld.c 11 May 2019 16:30:23 -0000 1.71 +++ ikev2_pld.c 17 Jul 2019 20:26:57 -0000 @@ -1198,6 +1198,20 @@ ikev2_pld_notify(struct iked *env, struc /* enforce natt */ msg->msg_sa->sa_natt = 1; break; + case IKEV2_N_USE_TRANSPORT_MODE: + if (!msg->msg_e) { + log_debug("%s: N_USE_TRANSPORT_MODE not encrypted", + __func__); + return (-1); + } + if (len != 0) { + log_debug("%s: ignoring malformed transport mode" + " notification: %zu", __func__, len); + return (0); + } + if (msg->msg_policy->pol_flags & IKED_POLICY_TRANSPORT) + msg->msg_sa->sa_use_transport_mode = 1; + break; case IKEV2_N_UPDATE_SA_ADDRESSES: if (!msg->msg_e) { log_debug("%s: N_UPDATE_SA_ADDRESSES not encrypted", Index: parse.y =================================================================== RCS file: /cvs/src/sbin/iked/parse.y,v retrieving revision 1.81 diff -u -p -u -r1.81 parse.y --- parse.y 28 Jun 2019 13:32:44 -0000 1.81 +++ parse.y 17 Jul 2019 20:26:58 -0000 @@ -414,7 +414,7 @@ typedef struct { %type <v.id> id %type <v.transforms> transforms %type <v.filters> filters -%type <v.ikemode> ikeflags ikematch ikemode ipcomp +%type <v.ikemode> ikeflags ikematch ikemode ipcomp tmode %type <v.ikeauth> ikeauth %type <v.ikekey> keyspec %type <v.mode> ike_sas child_sas @@ -851,7 +851,7 @@ child_sa : CHILDSA { } ; -ikeflags : ikematch ikemode ipcomp { $$ = $1 | $2 | $3; } +ikeflags : ikematch ikemode ipcomp tmode { $$ = $1 | $2 | $3 | $4; } ; ikematch : /* empty */ { $$ = 0; } @@ -867,6 +867,11 @@ ikemode : /* empty */ { $$ = IKED_POL ipcomp : /* empty */ { $$ = 0; } | IPCOMP { $$ = IKED_POLICY_IPCOMP; } + ; + +tmode : /* empty */ { $$ = 0; } + | TUNNEL { $$ = 0; } + | TRANSPORT { $$ = IKED_POLICY_TRANSPORT; } ; ikeauth : /* empty */ {