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 via email to