iked(8): add transport mode for childsas

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

iked(8): add transport mode for childsas

Tobias Heider-2
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 */ {

Reply | Threaded
Open this post in threaded view
|

Re: iked(8): add transport mode for childsas

Tobias Heider-2
Update: Having the use_transport_mode flag attached to the SA is
not the best idea, so now it is given down to the child SA as soon as
possible and then only looked up from there (and cleared in the parent).
A simple setup looks as follows:

For A (/etc/iked.conf):
ikev2 "test" active transport esp from A to B \
        peer B

For B (/etc/iked.conf):
ikev2 "test" active transport esp from B to A \
        peer A

If successful ipsecctl -ssa (on both hosts) shows:

esp transport from A to B spi 0xedf7b2e6 auth hmac-sha2-256 enc aes-256
esp transport from B to A spi 0xedf7b2e6 auth hmac-sha2-256 enc aes-256

ok?

Here's the diff:

Index: iked.conf.5
===================================================================
RCS file: /mount/openbsd/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 13 Aug 2019 12:23:48 -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: /mount/openbsd/cvs/src/sbin/iked/iked.h,v
retrieving revision 1.122
diff -u -p -u -r1.122 iked.h
--- iked.h 12 Aug 2019 07:40:45 -0000 1.122
+++ iked.h 13 Aug 2019 12:23:48 -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: /mount/openbsd/cvs/src/sbin/iked/ikev2.c,v
retrieving revision 1.172
diff -u -p -u -r1.172 ikev2.c
--- ikev2.c 12 Aug 2019 07:40:45 -0000 1.172
+++ ikev2.c 13 Aug 2019 12:47:49 -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 *);
@@ -1238,10 +1242,13 @@ ikev2_init_ike_auth(struct iked *env, st
  goto done;
  }
 
- /* compression */
+ /* compression, transport mode */
  if ((pol->pol_flags & IKED_POLICY_IPCOMP) &&
     (len = ikev2_add_ipcompnotify(env, e, &pld, len, sa)) == -1)
  goto done;
+ if ((pol->pol_flags & IKED_POLICY_TRANSPORT) &&
+    (len = ikev2_add_transport_mode(env, e, &pld, len, sa)) == -1)
+ goto done;
 
  if (ikev2_next_payload(pld, len, IKEV2_PAYLOAD_SA) == -1)
  goto done;
@@ -1685,8 +1692,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;
@@ -1702,13 +1710,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)
 {
@@ -2735,6 +2757,7 @@ ikev2_resp_ike_auth(struct iked *env, st
  struct ikev2_auth *auth;
  struct iked_id *id, *certid;
  struct ibuf *e = NULL;
+ struct iked_childsa *csa = NULL;
  uint8_t firstpayload;
  int ret = -1;
  ssize_t len;
@@ -2825,10 +2848,14 @@ ikev2_resp_ike_auth(struct iked *env, st
  goto done;
  }
 
- /* compression */
+ /* compression, transport mode */
  if (sa->sa_ipcomp &&
     (len = ikev2_add_ipcompnotify(env, e, &pld, len, sa)) == -1)
  goto done;
+ if ((csa = TAILQ_FIRST(&sa->sa_childsas)) != NULL &&
+    csa->csa_transport &&
+    (len = ikev2_add_transport_mode(env, e, &pld, len, sa)) == -1)
+ goto done;
 
  /* MOBIKE */
  if (sa->sa_mobike &&
@@ -3068,10 +3095,13 @@ ikev2_send_create_child_sa(struct iked *
  if ((e = ibuf_static()) == NULL)
  goto done;
 
- /* compression */
+ /* compression, transport mode */
  if ((pol->pol_flags & IKED_POLICY_IPCOMP) &&
     (len = ikev2_add_ipcompnotify(env, e, &pld, 0, sa)) == -1)
  goto done;
+ if ((pol->pol_flags & IKED_POLICY_TRANSPORT) &&
+    (len = ikev2_add_transport_mode(env, e, &pld, 0, sa)) == -1)
+ goto done;
 
  if (pld) {
  firstpayload = IKEV2_PAYLOAD_NOTIFY;
@@ -3684,7 +3714,7 @@ ikev2_ikesa_recv_delete(struct iked *env
 int
 ikev2_resp_create_child_sa(struct iked *env, struct iked_message *msg)
 {
- struct iked_childsa *csa = NULL;
+ struct iked_childsa *csa = NULL, *newcsa = NULL;
  struct iked_proposal *prop;
  struct iked_proposals proposals;
  struct iked_kex *kex, *kextmp = NULL;
@@ -3852,10 +3882,14 @@ ikev2_resp_create_child_sa(struct iked *
  if ((e = ibuf_static()) == NULL)
  goto done;
 
- /* compression (unless IKE rekeying) */
+ /* compression, transport mode (unless IKE rekeying) */
  if (!nsa && sa->sa_ipcomp &&
     (len = ikev2_add_ipcompnotify(env, e, &pld, 0, sa)) == -1)
  goto done;
+ if (!nsa && (newcsa = TAILQ_FIRST(&sa->sa_childsas)) != NULL &&
+    newcsa->csa_transport &&
+    (len = ikev2_add_transport_mode(env, e, &pld, 0, sa)) == -1)
+ goto done;
 
  if (pld) {
  firstpayload = IKEV2_PAYLOAD_NOTIFY;
@@ -5224,6 +5258,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) {
@@ -5310,6 +5345,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: /mount/openbsd/cvs/src/sbin/iked/ikev2_pld.c,v
retrieving revision 1.72
diff -u -p -u -r1.72 ikev2_pld.c
--- ikev2_pld.c 12 Aug 2019 07:40:45 -0000 1.72
+++ ikev2_pld.c 13 Aug 2019 12:30:01 -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_parent->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: /mount/openbsd/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 13 Aug 2019 12:23:48 -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 */ {

Reply | Threaded
Open this post in threaded view
|

Re: iked(8): add transport mode for childsas

Joerg Goltermann
Hello,

I have this patch in production for more than 2 weeks without any
problems. Please try to put it in.

  - Joerg

On 13.08.2019 15:51, Tobias Heider wrote:

> Update: Having the use_transport_mode flag attached to the SA is
> not the best idea, so now it is given down to the child SA as soon as
> possible and then only looked up from there (and cleared in the parent).
> A simple setup looks as follows:
>
> For A (/etc/iked.conf):
> ikev2 "test" active transport esp from A to B \
> peer B
>
> For B (/etc/iked.conf):
> ikev2 "test" active transport esp from B to A \
> peer A
>
> If successful ipsecctl -ssa (on both hosts) shows:
>
> esp transport from A to B spi 0xedf7b2e6 auth hmac-sha2-256 enc aes-256
> esp transport from B to A spi 0xedf7b2e6 auth hmac-sha2-256 enc aes-256
>
> ok?
>
> Here's the diff:
>
> Index: iked.conf.5
> ===================================================================
> RCS file: /mount/openbsd/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 13 Aug 2019 12:23:48 -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: /mount/openbsd/cvs/src/sbin/iked/iked.h,v
> retrieving revision 1.122
> diff -u -p -u -r1.122 iked.h
> --- iked.h 12 Aug 2019 07:40:45 -0000 1.122
> +++ iked.h 13 Aug 2019 12:23:48 -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: /mount/openbsd/cvs/src/sbin/iked/ikev2.c,v
> retrieving revision 1.172
> diff -u -p -u -r1.172 ikev2.c
> --- ikev2.c 12 Aug 2019 07:40:45 -0000 1.172
> +++ ikev2.c 13 Aug 2019 12:47:49 -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 *);
> @@ -1238,10 +1242,13 @@ ikev2_init_ike_auth(struct iked *env, st
>   goto done;
>   }
>  
> - /* compression */
> + /* compression, transport mode */
>   if ((pol->pol_flags & IKED_POLICY_IPCOMP) &&
>      (len = ikev2_add_ipcompnotify(env, e, &pld, len, sa)) == -1)
>   goto done;
> + if ((pol->pol_flags & IKED_POLICY_TRANSPORT) &&
> +    (len = ikev2_add_transport_mode(env, e, &pld, len, sa)) == -1)
> + goto done;
>  
>   if (ikev2_next_payload(pld, len, IKEV2_PAYLOAD_SA) == -1)
>   goto done;
> @@ -1685,8 +1692,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;
> @@ -1702,13 +1710,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)
>   {
> @@ -2735,6 +2757,7 @@ ikev2_resp_ike_auth(struct iked *env, st
>   struct ikev2_auth *auth;
>   struct iked_id *id, *certid;
>   struct ibuf *e = NULL;
> + struct iked_childsa *csa = NULL;
>   uint8_t firstpayload;
>   int ret = -1;
>   ssize_t len;
> @@ -2825,10 +2848,14 @@ ikev2_resp_ike_auth(struct iked *env, st
>   goto done;
>   }
>  
> - /* compression */
> + /* compression, transport mode */
>   if (sa->sa_ipcomp &&
>      (len = ikev2_add_ipcompnotify(env, e, &pld, len, sa)) == -1)
>   goto done;
> + if ((csa = TAILQ_FIRST(&sa->sa_childsas)) != NULL &&
> +    csa->csa_transport &&
> +    (len = ikev2_add_transport_mode(env, e, &pld, len, sa)) == -1)
> + goto done;
>  
>   /* MOBIKE */
>   if (sa->sa_mobike &&
> @@ -3068,10 +3095,13 @@ ikev2_send_create_child_sa(struct iked *
>   if ((e = ibuf_static()) == NULL)
>   goto done;
>  
> - /* compression */
> + /* compression, transport mode */
>   if ((pol->pol_flags & IKED_POLICY_IPCOMP) &&
>      (len = ikev2_add_ipcompnotify(env, e, &pld, 0, sa)) == -1)
>   goto done;
> + if ((pol->pol_flags & IKED_POLICY_TRANSPORT) &&
> +    (len = ikev2_add_transport_mode(env, e, &pld, 0, sa)) == -1)
> + goto done;
>  
>   if (pld) {
>   firstpayload = IKEV2_PAYLOAD_NOTIFY;
> @@ -3684,7 +3714,7 @@ ikev2_ikesa_recv_delete(struct iked *env
>   int
>   ikev2_resp_create_child_sa(struct iked *env, struct iked_message *msg)
>   {
> - struct iked_childsa *csa = NULL;
> + struct iked_childsa *csa = NULL, *newcsa = NULL;
>   struct iked_proposal *prop;
>   struct iked_proposals proposals;
>   struct iked_kex *kex, *kextmp = NULL;
> @@ -3852,10 +3882,14 @@ ikev2_resp_create_child_sa(struct iked *
>   if ((e = ibuf_static()) == NULL)
>   goto done;
>  
> - /* compression (unless IKE rekeying) */
> + /* compression, transport mode (unless IKE rekeying) */
>   if (!nsa && sa->sa_ipcomp &&
>      (len = ikev2_add_ipcompnotify(env, e, &pld, 0, sa)) == -1)
>   goto done;
> + if (!nsa && (newcsa = TAILQ_FIRST(&sa->sa_childsas)) != NULL &&
> +    newcsa->csa_transport &&
> +    (len = ikev2_add_transport_mode(env, e, &pld, 0, sa)) == -1)
> + goto done;
>  
>   if (pld) {
>   firstpayload = IKEV2_PAYLOAD_NOTIFY;
> @@ -5224,6 +5258,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) {
> @@ -5310,6 +5345,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: /mount/openbsd/cvs/src/sbin/iked/ikev2_pld.c,v
> retrieving revision 1.72
> diff -u -p -u -r1.72 ikev2_pld.c
> --- ikev2_pld.c 12 Aug 2019 07:40:45 -0000 1.72
> +++ ikev2_pld.c 13 Aug 2019 12:30:01 -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_parent->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: /mount/openbsd/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 13 Aug 2019 12:23:48 -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 */ {
>

Reply | Threaded
Open this post in threaded view
|

Re: iked(8): add transport mode for childsas

Tobias Heider-2
Hi,

here is an update of the last diff rebased onto current with minor fixes. There
were some problems when multiple transport and non-transport policies were
configured, which should now be fixed.
I also have a test case for the new regression test which runs successfully.

ok?

diff --git a/sbin/iked/iked.conf.5 b/sbin/iked/iked.conf.5
index 671cb5c7955..5af0a2e6d63 100644
--- a/sbin/iked/iked.conf.5
+++ b/sbin/iked/iked.conf.5
@@ -271,6 +271,15 @@ The optional compression is applied before packets are encapsulated.
 IPcomp must be enabled in the kernel:
 .Pp
 .Dl # sysctl net.inet.ipcomp.enable=1
+.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.
@@ -280,15 +289,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
diff --git a/sbin/iked/iked.h b/sbin/iked/iked.h
index d99d52ff77c..7b4c2075810 100644
--- a/sbin/iked/iked.h
+++ b/sbin/iked/iked.h
@@ -254,6 +254,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;
 
@@ -481,6 +482,9 @@ struct iked_sa {
  int sa_mobike; /* MOBIKE */
  int sa_frag; /* fragmentation */
 
+ int sa_use_transport_mode; /* peer requested */
+ int sa_used_transport_mode; /* we enabled */
+
  struct iked_timer sa_timer; /* SA timeouts */
 #define IKED_IKE_SA_EXCHANGE_TIMEOUT 300 /* 5 minutes */
 #define IKED_IKE_SA_REKEY_TIMEOUT 120 /* 2 minutes */
diff --git a/sbin/iked/ikev2.c b/sbin/iked/ikev2.c
index 842e8da110f..505cd31a204 100644
--- a/sbin/iked/ikev2.c
+++ b/sbin/iked/ikev2.c
@@ -142,15 +142,17 @@ int ikev2_cp_setaddr(struct iked *, struct iked_sa *, sa_family_t);
 int ikev2_cp_fixaddr(struct iked_sa *, struct iked_addr *,
     struct iked_addr *);
 
-ssize_t ikev2_add_sighashnotify(struct ibuf *, struct ikev2_payload **,
+ssize_t ikev2_add_sighashnotify(struct ibuf *, struct ikev2_payload **,
     ssize_t);
-ssize_t ikev2_add_nat_detection(struct iked *, struct ibuf *,
+ssize_t ikev2_add_nat_detection(struct iked *, struct ibuf *,
     struct ikev2_payload **, struct iked_message *, ssize_t);
 ssize_t ikev2_add_notify(struct ibuf *, struct ikev2_payload **, ssize_t,
-    uint16_t);
+    uint16_t);
 ssize_t ikev2_add_mobike(struct ibuf *, struct ikev2_payload **, ssize_t);
-ssize_t ikev2_add_fragmentation(struct ibuf *, struct ikev2_payload **,
-    struct iked_message *, ssize_t);
+ssize_t ikev2_add_fragmentation(struct ibuf *, struct ikev2_payload **,
+    struct iked_message *, ssize_t);
+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 *);
@@ -1246,10 +1248,13 @@ ikev2_init_ike_auth(struct iked *env, struct iked_sa *sa)
  goto done;
  }
 
- /* compression */
+ /* compression, transport mode */
  if ((pol->pol_flags & IKED_POLICY_IPCOMP) &&
     (len = ikev2_add_ipcompnotify(env, e, &pld, len, sa, 1)) == -1)
  goto done;
+ if ((pol->pol_flags & IKED_POLICY_TRANSPORT) &&
+    (len = ikev2_add_transport_mode(env, e, &pld, len, sa)) == -1)
+ goto done;
 
  if (ikev2_next_payload(pld, len, IKEV2_PAYLOAD_SA) == -1)
  goto done;
@@ -1786,6 +1791,13 @@ ikev2_add_sighashnotify(struct ibuf *e, struct ikev2_payload **pld,
  return (len);
 }
 
+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(e, pld, len, IKEV2_N_USE_TRANSPORT_MODE);
+}
+
 int
 ikev2_next_payload(struct ikev2_payload *pld, size_t length,
     uint8_t nextpayload)
@@ -2990,10 +3002,13 @@ ikev2_resp_ike_auth(struct iked *env, struct iked_sa *sa)
  goto done;
  }
 
- /* compression */
+ /* compression, transport mode */
  if (sa->sa_ipcompr.ic_transform &&
     (len = ikev2_add_ipcompnotify(env, e, &pld, len, sa, 0)) == -1)
  goto done;
+ if (sa->sa_used_transport_mode &&
+    (len = ikev2_add_transport_mode(env, e, &pld, len, sa)) == -1)
+ goto done;
 
  /* MOBIKE */
  if (sa->sa_mobike &&
@@ -3233,10 +3248,13 @@ ikev2_send_create_child_sa(struct iked *env, struct iked_sa *sa,
  if ((e = ibuf_static()) == NULL)
  goto done;
 
- /* compression */
+ /* compression, transport mode */
  if ((pol->pol_flags & IKED_POLICY_IPCOMP) &&
     (len = ikev2_add_ipcompnotify(env, e, &pld, 0, sa, 1)) == -1)
  goto done;
+ if ((pol->pol_flags & IKED_POLICY_TRANSPORT) &&
+    (len = ikev2_add_transport_mode(env, e, &pld, len, sa)) == -1)
+ goto done;
 
  if (pld) {
  firstpayload = IKEV2_PAYLOAD_NOTIFY;
@@ -4055,10 +4073,13 @@ ikev2_resp_create_child_sa(struct iked *env, struct iked_message *msg)
  if ((e = ibuf_static()) == NULL)
  goto done;
 
- /* compression (unless IKE rekeying) */
+ /* compression, transport mode (unless IKE rekeying) */
  if (!nsa && sa->sa_ipcompr.ic_transform &&
     (len = ikev2_add_ipcompnotify(env, e, &pld, 0, sa, 0)) == -1)
  goto done;
+ if (!nsa && sa->sa_used_transport_mode &&
+    (len = ikev2_add_transport_mode(env, e, &pld, len, sa)) == -1)
+ goto done;
 
  if (pld) {
  firstpayload = IKEV2_PAYLOAD_NOTIFY;
@@ -5320,6 +5341,9 @@ ikev2_childsa_negotiate(struct iked *env, struct iked_sa *sa,
     (initiator && ic->ic_cpi_in == 0))
  ic = NULL;
 
+ /* reset state */
+ sa->sa_used_transport_mode = 0;
+
  /* We need to determine the key material length first */
  TAILQ_FOREACH(prop, proposals, prop_entry) {
  if (prop->prop_protoid == IKEV2_SAPROTO_IKE)
@@ -5460,6 +5484,8 @@ ikev2_childsa_negotiate(struct iked *env, struct iked_sa *sa,
  csa->csa_spi.spi_protoid = prop->prop_protoid;
  csa->csa_esn = esn;
  csa->csa_acquired = acquired;
+ csa->csa_transport = sa->sa_use_transport_mode;
+ sa->sa_used_transport_mode = sa->sa_use_transport_mode;
 
  /* Set up responder's SPIs */
  if (initiator) {
@@ -5597,6 +5623,7 @@ ikev2_childsa_negotiate(struct iked *env, struct iked_sa *sa,
 
  ret = 0;
  done:
+ sa->sa_use_transport_mode = 0; /* reset state after use */
  ibuf_release(dhsecret);
  ibuf_release(keymat);
  ibuf_release(seed);
diff --git a/sbin/iked/ikev2_pld.c b/sbin/iked/ikev2_pld.c
index 5cf0dee6615..c13a7e11158 100644
--- a/sbin/iked/ikev2_pld.c
+++ b/sbin/iked/ikev2_pld.c
@@ -1172,6 +1172,24 @@ ikev2_pld_notify(struct iked *env, struct ikev2_payload *pld,
  }
  msg->msg_parent->msg_flags |= IKED_MSG_FLAGS_MOBIKE;
  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)) {
+ log_debug("%s: ignoring transport mode"
+    " notification (policy)", __func__);
+ return (0);
+ }
+ 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",
diff --git a/sbin/iked/parse.y b/sbin/iked/parse.y
index fe052068922..3ca68e2fd7a 100644
--- a/sbin/iked/parse.y
+++ b/sbin/iked/parse.y
@@ -426,7 +426,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
@@ -890,7 +890,7 @@ child_sa : CHILDSA {
  }
  ;
 
-ikeflags : ikematch ikemode ipcomp { $$ = $1 | $2 | $3; }
+ikeflags : ikematch ikemode ipcomp tmode { $$ = $1 | $2 | $3 | $4; }
  ;
 
 ikematch : /* empty */ { $$ = 0; }
@@ -908,6 +908,11 @@ ipcomp : /* empty */ { $$ = 0; }
  | IPCOMP { $$ = IKED_POLICY_IPCOMP; }
  ;
 
+tmode : /* empty */ { $$ = 0; }
+ | TUNNEL { $$ = 0; }
+ | TRANSPORT { $$ = IKED_POLICY_TRANSPORT; }
+ ;
+
 ikeauth : /* empty */ {
  $$.auth_method = IKEV2_AUTH_SIG_ANY; /* default */
  $$.auth_eap = 0;
@@ -2465,6 +2470,9 @@ print_policy(struct iked_policy *pol)
  else
  print_verbose(" passive");
 
+ if (pol->pol_flags & IKED_POLICY_TRANSPORT)
+ print_verbose(" transport");
+
  print_verbose(" %s", print_xf(pol->pol_saproto, 0, saxfs));
 
  if (pol->pol_ipproto)

Reply | Threaded
Open this post in threaded view
|

Re: iked(8): add transport mode for childsas

Klemens Nanni-2
On Tue, Feb 18, 2020 at 12:09:10PM +0100, Tobias Heider wrote:
> here is an update of the last diff rebased onto current with minor fixes. There
> were some problems when multiple transport and non-transport policies were
> configured, which should now be fixed.
> I also have a test case for the new regression test which runs successfully.
Thanks, as already discussed off-list this is working as advertised.

This is useful for scenarios such as GRE over IPsec where double
encapsulation is neither necessary nor desired.

OK kn,
nits inline

> index d99d52ff77c..7b4c2075810 100644
> --- a/sbin/iked/iked.h
> +++ b/sbin/iked/iked.h
 
> - /* compression */
> + /* compression, transport mode */
I'd drop these useless comments.

>   if ((pol->pol_flags & IKED_POLICY_IPCOMP) &&
>      (len = ikev2_add_ipcompnotify(env, e, &pld, len, sa, 1)) == -1)
>   goto done;
> + if ((pol->pol_flags & IKED_POLICY_TRANSPORT) &&
> +    (len = ikev2_add_transport_mode(env, e, &pld, len, sa)) == -1)
> + goto done;
>  
>   if (ikev2_next_payload(pld, len, IKEV2_PAYLOAD_SA) == -1)
>   goto done;
> @@ -1786,6 +1791,13 @@ ikev2_add_sighashnotify(struct ibuf *e, struct ikev2_payload **pld,
>   return (len);
>  }

> diff --git a/sbin/iked/parse.y b/sbin/iked/parse.y
> index fe052068922..3ca68e2fd7a 100644
> --- a/sbin/iked/parse.y
> +++ b/sbin/iked/parse.y
> @@ -426,7 +426,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
> @@ -890,7 +890,7 @@ child_sa : CHILDSA {
>   }
>   ;
>  
> -ikeflags : ikematch ikemode ipcomp { $$ = $1 | $2 | $3; }
> +ikeflags : ikematch ikemode ipcomp tmode { $$ = $1 | $2 | $3 | $4; }
>   ;
>  
>  ikematch : /* empty */ { $$ = 0; }
> @@ -908,6 +908,11 @@ ipcomp : /* empty */ { $$ = 0; }
>   | IPCOMP { $$ = IKED_POLICY_IPCOMP; }
>   ;
>  
> +tmode : /* empty */ { $$ = 0; }
> + | TUNNEL { $$ = 0; }
This should probably be explicit just like TRANSPORT.
Although unlikely, in the default for tmode changes this 0 for TUNNEL
would case an explicit `tunnel' in the config to change to the new
default as well.

> + | TRANSPORT { $$ = IKED_POLICY_TRANSPORT; }
> + ;
> +
>  ikeauth : /* empty */ {
>   $$.auth_method = IKEV2_AUTH_SIG_ANY; /* default */
>   $$.auth_eap = 0;
> @@ -2465,6 +2470,9 @@ print_policy(struct iked_policy *pol)
>   else
>   print_verbose(" passive");
>  
> + if (pol->pol_flags & IKED_POLICY_TRANSPORT)
> + print_verbose(" transport");
> +
What about printing "tunnel"?  Omitting it makes existing config and
output stay the same with your diff, on the other hand we do have options
that are printed already even when being the default and/or omitted from
the config.

>   print_verbose(" %s", print_xf(pol->pol_saproto, 0, saxfs));
>  
>   if (pol->pol_ipproto)
>