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)