summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/ikev2/ikev2.api13
-rw-r--r--src/plugins/ikev2/ikev2.c24
-rw-r--r--src/plugins/ikev2/ikev2.h1
-rw-r--r--src/plugins/ikev2/ikev2_api.c22
-rw-r--r--src/plugins/ikev2/ikev2_cli.c9
-rw-r--r--src/plugins/ikev2/ikev2_priv.h2
-rw-r--r--src/plugins/ikev2/ikev2_test.c43
7 files changed, 114 insertions, 0 deletions
diff --git a/src/plugins/ikev2/ikev2.api b/src/plugins/ikev2/ikev2.api
index aa9f1b3e554..c872c6f0088 100644
--- a/src/plugins/ikev2/ikev2.api
+++ b/src/plugins/ikev2/ikev2.api
@@ -317,6 +317,19 @@ autoreply define ikev2_initiate_rekey_child_sa
option vat_help = "<ispi>";
};
+/** \brief IKEv2: Set UDP encapsulation
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param name - IKEv2 profile name
+*/
+autoreply define ikev2_profile_set_udp_encap
+{
+ u32 client_index;
+ u32 context;
+
+ string name[64];
+};
+
/*
* Local Variables:
* eval: (c-set-style "gnu")
diff --git a/src/plugins/ikev2/ikev2.c b/src/plugins/ikev2/ikev2.c
index b0ed4f2a1f5..db68135db42 100644
--- a/src/plugins/ikev2/ikev2.c
+++ b/src/plugins/ikev2/ikev2.c
@@ -398,6 +398,7 @@ ikev2_complete_sa_data (ikev2_sa_t * sa, ikev2_sa_t * sai)
sa->i_auth.key = _(sai->i_auth.key);
sa->last_sa_init_req_packet_data = _(sai->last_sa_init_req_packet_data);
sa->childs = _(sai->childs);
+ sa->udp_encap = sai->udp_encap;
#undef _
@@ -1372,6 +1373,9 @@ ikev2_sa_auth (ikev2_sa_t * sa)
}
}
+ if (sel_p)
+ sa->udp_encap = sel_p->udp_encap;
+
vec_free(auth);
vec_free(psk);
}));
@@ -1608,6 +1612,9 @@ ikev2_create_tunnel_interface (vnet_main_t * vnm,
}
a.flags = IPSEC_SA_FLAG_USE_ANTI_REPLAY;
+ a.flags |= IPSEC_SA_FLAG_IS_TUNNEL;
+ if (sa->udp_encap)
+ a.flags |= IPSEC_SA_FLAG_UDP_ENCAP;
a.is_rekey = is_rekey;
tr = ikev2_sa_get_td_for_type (proposals, IKEV2_TRANSFORM_TYPE_ESN);
@@ -3152,6 +3159,22 @@ ikev2_set_profile_tunnel_interface (vlib_main_t * vm,
}
clib_error_t *
+ikev2_set_profile_udp_encap (vlib_main_t * vm, u8 * name)
+{
+ ikev2_profile_t *p = ikev2_profile_index_by_name (name);
+ clib_error_t *r;
+
+ if (!p)
+ {
+ r = clib_error_return (0, "unknown profile %v", name);
+ return r;
+ }
+
+ p->udp_encap = 1;
+ return 0;
+}
+
+clib_error_t *
ikev2_set_profile_sa_lifetime (vlib_main_t * vm, u8 * name,
u64 lifetime, u32 jitter, u32 handover,
u64 maxdata)
@@ -3235,6 +3258,7 @@ ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name)
sa.is_profile_index_set = 1;
sa.state = IKEV2_STATE_SA_INIT;
sa.tun_itf = p->tun_itf;
+ sa.udp_encap = p->udp_encap;
sa.is_tun_itf_set = 1;
sa.initial_contact = 1;
ikev2_generate_sa_init_data (&sa);
diff --git a/src/plugins/ikev2/ikev2.h b/src/plugins/ikev2/ikev2.h
index d4222d28c2e..c73df152909 100644
--- a/src/plugins/ikev2/ikev2.h
+++ b/src/plugins/ikev2/ikev2.h
@@ -394,6 +394,7 @@ clib_error_t *ikev2_set_profile_sa_lifetime (vlib_main_t * vm, u8 * name,
u32 handover, u64 maxdata);
clib_error_t *ikev2_set_profile_tunnel_interface (vlib_main_t * vm, u8 * name,
u32 sw_if_index);
+clib_error_t *ikev2_set_profile_udp_encap (vlib_main_t * vm, u8 * name);
clib_error_t *ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name);
clib_error_t *ikev2_initiate_delete_child_sa (vlib_main_t * vm, u32 ispi);
clib_error_t *ikev2_initiate_delete_ike_sa (vlib_main_t * vm, u64 ispi);
diff --git a/src/plugins/ikev2/ikev2_api.c b/src/plugins/ikev2/ikev2_api.c
index bfcfa64cb28..f846bfab9f0 100644
--- a/src/plugins/ikev2/ikev2_api.c
+++ b/src/plugins/ikev2/ikev2_api.c
@@ -134,6 +134,28 @@ vl_api_ikev2_profile_set_id_t_handler (vl_api_ikev2_profile_set_id_t * mp)
}
static void
+ vl_api_ikev2_profile_set_udp_encap_t_handler
+ (vl_api_ikev2_profile_set_udp_encap_t * mp)
+{
+ vl_api_ikev2_profile_set_udp_encap_reply_t *rmp;
+ int rv = 0;
+
+#if WITH_LIBSSL > 0
+ vlib_main_t *vm = vlib_get_main ();
+ clib_error_t *error;
+ u8 *tmp = format (0, "%s", mp->name);
+ error = ikev2_set_profile_udp_encap (vm, tmp);
+ vec_free (tmp);
+ if (error)
+ rv = VNET_API_ERROR_UNSPECIFIED;
+#else
+ rv = VNET_API_ERROR_UNIMPLEMENTED;
+#endif
+
+ REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_UDP_ENCAP);
+}
+
+static void
vl_api_ikev2_profile_set_ts_t_handler (vl_api_ikev2_profile_set_ts_t * mp)
{
vl_api_ikev2_profile_set_ts_reply_t *rmp;
diff --git a/src/plugins/ikev2/ikev2_cli.c b/src/plugins/ikev2/ikev2_cli.c
index a48828d3499..6b9876b4ead 100644
--- a/src/plugins/ikev2/ikev2_cli.c
+++ b/src/plugins/ikev2/ikev2_cli.c
@@ -370,6 +370,12 @@ ikev2_profile_add_del_command_fn (vlib_main_t * vm,
ikev2_set_profile_sa_lifetime (vm, name, tmp4, tmp1, tmp2, tmp5);
goto done;
}
+ else if (unformat (line_input, "set %U udp-encap",
+ unformat_token, valid_chars, &name))
+ {
+ r = ikev2_set_profile_udp_encap (vm, name);
+ goto done;
+ }
else
break;
}
@@ -393,6 +399,7 @@ VLIB_CLI_COMMAND (ikev2_profile_add_del_command, static) = {
" <data>\n"
"ikev2 profile set <id> id <local|remote> <type> <data>\n"
"ikev2 profile set <id> tunnel <interface>\n"
+ "ikev2 profile set <id> udp-encap\n"
"ikev2 profile set <id> traffic-selector <local|remote> ip-range "
"<start-addr> - <end-addr> port-range <start-port> - <end-port> "
"protocol <protocol-number>\n"
@@ -477,6 +484,8 @@ show_ikev2_profile_command_fn (vlib_main_t * vm,
if (~0 != p->tun_itf)
vlib_cli_output(vm, " protected tunnel %U",
format_vnet_sw_if_index_name, vnet_get_main(), p->tun_itf);
+ if (p->udp_encap)
+ vlib_cli_output(vm, " udp-encap");
}));
/* *INDENT-ON* */
diff --git a/src/plugins/ikev2/ikev2_priv.h b/src/plugins/ikev2/ikev2_priv.h
index 8fddb7d401c..7609166cb6a 100644
--- a/src/plugins/ikev2/ikev2_priv.h
+++ b/src/plugins/ikev2/ikev2_priv.h
@@ -360,6 +360,7 @@ typedef struct
u32 handover;
u32 tun_itf;
+ u8 udp_encap;
} ikev2_profile_t;
typedef struct
@@ -422,6 +423,7 @@ typedef struct
u32 profile_index;
u8 is_tun_itf_set;
u32 tun_itf;
+ u8 udp_encap;
f64 old_id_expiration;
u32 current_remote_id_mask;
diff --git a/src/plugins/ikev2/ikev2_test.c b/src/plugins/ikev2/ikev2_test.c
index cd9445d2f38..9ff4bbcc58c 100644
--- a/src/plugins/ikev2/ikev2_test.c
+++ b/src/plugins/ikev2/ikev2_test.c
@@ -407,6 +407,49 @@ api_ikev2_set_local_key (vat_main_t * vam)
}
static int
+api_ikev2_profile_set_udp_encap (vat_main_t * vam)
+{
+ unformat_input_t *i = vam->input;
+ vl_api_ikev2_set_responder_t *mp;
+ int ret;
+ u8 *name = 0;
+
+ const char *valid_chars = "a-zA-Z0-9_";
+
+ while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (i, "%U udp-encap", unformat_token, valid_chars, &name))
+ vec_add1 (name, 0);
+ else
+ {
+ errmsg ("parse error '%U'", format_unformat_error, i);
+ return -99;
+ }
+ }
+
+ if (!vec_len (name))
+ {
+ errmsg ("profile name must be specified");
+ return -99;
+ }
+
+ if (vec_len (name) > 64)
+ {
+ errmsg ("profile name too long");
+ return -99;
+ }
+
+ M (IKEV2_PROFILE_SET_UDP_ENCAP, mp);
+
+ clib_memcpy (mp->name, name, vec_len (name));
+ vec_free (name);
+
+ S (mp);
+ W (ret);
+ return ret;
+}
+
+static int
api_ikev2_set_tunnel_interface (vat_main_t * vam)
{
return (0);