From 459d17bb7d051566c587c4f963014fdbbe99ff6a Mon Sep 17 00:00:00 2001 From: Filip Tehlar Date: Mon, 6 Jul 2020 15:40:08 +0000 Subject: [PATCH] ikev2: refactor and test profile dump API Type: refactor Change-Id: I6b8dc68e5d4a452776fbaf5a69fbd7f53a8abb75 Signed-off-by: Filip Tehlar --- src/plugins/ikev2/ikev2.api | 43 ++------- src/plugins/ikev2/ikev2.c | 2 - src/plugins/ikev2/ikev2.h | 3 +- src/plugins/ikev2/ikev2_api.c | 72 +++++++------- src/plugins/ikev2/ikev2_cli.c | 5 +- src/plugins/ikev2/ikev2_test.c | 79 ++++++++-------- src/plugins/ikev2/ikev2_types.api | 24 +++-- src/plugins/ikev2/test/test_ikev2.py | 177 ++++++++++++++++++++++++++++++++++- src/plugins/ikev2/test/vpp_ikev2.py | 64 ++++++++++++- 9 files changed, 340 insertions(+), 129 deletions(-) diff --git a/src/plugins/ikev2/ikev2.api b/src/plugins/ikev2/ikev2.api index 53f4d7736c5..2a1a6d6365b 100644 --- a/src/plugins/ikev2/ikev2.api +++ b/src/plugins/ikev2/ikev2.api @@ -132,12 +132,7 @@ autoreply define ikev2_profile_set_id @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @param name - IKEv2 profile name - @param is_local - Traffic selector is local if non-zero, else remote - @param proto - Traffic selector IP protocol (if zero not relevant) - @param start_port - The smallest port number allowed by traffic selector - @param end_port - The largest port number allowed by traffic selector - @param start_addr - The smallest address included in traffic selector - @param end_addr - The largest address included in traffic selector + @param ts - traffic selector data */ autoreply define ikev2_profile_set_ts { @@ -145,12 +140,7 @@ autoreply define ikev2_profile_set_ts u32 context; string name[64]; - bool is_local; - u8 proto; - u16 start_port; - u16 end_port; - u32 start_addr; - u32 end_addr; + vl_api_ikev2_ts_t ts; option vat_help = "name protocol start_port end_port start_addr end_addr (local|remote)"; option status="in_progress"; }; @@ -158,7 +148,6 @@ autoreply define ikev2_profile_set_ts /** \brief IKEv2: Set IKEv2 local RSA private key @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request - @param key_file - Key file absolute path */ autoreply define ikev2_set_local_key @@ -192,8 +181,7 @@ autoreply define ikev2_set_tunnel_interface @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @param name - IKEv2 profile name - @param sw_if_index - interface index - @param address - interface address + @param responder - responder data */ autoreply define ikev2_set_responder { @@ -201,8 +189,7 @@ autoreply define ikev2_set_responder u32 context; string name[64]; - vl_api_interface_index_t sw_if_index; - vl_api_ip4_address_t address; + vl_api_ikev2_responder_t responder; option vat_help = " interface address "; option status="in_progress"; }; @@ -211,10 +198,7 @@ autoreply define ikev2_set_responder @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @param name - IKEv2 profile name - @param crypto_alg - encryption algorithm - @param crypto_key_size - encryption key size - @param integ_alg - integrity algorithm - @param dh_group - Diffie-Hellman group + @param tr - IKE transforms */ autoreply define ikev2_set_ike_transforms { @@ -222,10 +206,7 @@ autoreply define ikev2_set_ike_transforms u32 context; string name[64]; - u32 crypto_alg; - u32 crypto_key_size; - u32 integ_alg; - u32 dh_group; + vl_api_ikev2_ike_transforms_t tr; option vat_help = " "; option status="in_progress"; }; @@ -234,10 +215,7 @@ autoreply define ikev2_set_ike_transforms @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @param name - IKEv2 profile name - @param crypto_alg - encryption algorithm - @param crypto_key_size - encryption key size - @param integ_alg - integrity algorithm - @param dh_group - Diffie-Hellman group + @param tr - ESP transforms */ autoreply define ikev2_set_esp_transforms { @@ -245,11 +223,8 @@ autoreply define ikev2_set_esp_transforms u32 context; string name[64]; - u32 crypto_alg; - u32 crypto_key_size; - u32 integ_alg; - u32 dh_group; - option vat_help = " "; + vl_api_ikev2_esp_transforms_t tr; + option vat_help = " "; option status="in_progress"; }; diff --git a/src/plugins/ikev2/ikev2.c b/src/plugins/ikev2/ikev2.c index 173323b8158..0842125ca70 100644 --- a/src/plugins/ikev2/ikev2.c +++ b/src/plugins/ikev2/ikev2.c @@ -3547,7 +3547,6 @@ clib_error_t * ikev2_set_profile_esp_transforms (vlib_main_t * vm, u8 * name, ikev2_transform_encr_type_t crypto_alg, ikev2_transform_integ_type_t integ_alg, - ikev2_transform_dh_type_t dh_type, u32 crypto_key_size) { ikev2_profile_t *p; @@ -3563,7 +3562,6 @@ ikev2_set_profile_esp_transforms (vlib_main_t * vm, u8 * name, p->esp_ts.crypto_alg = crypto_alg; p->esp_ts.integ_alg = integ_alg; - p->esp_ts.dh_type = dh_type; p->esp_ts.crypto_key_size = crypto_key_size; return 0; } diff --git a/src/plugins/ikev2/ikev2.h b/src/plugins/ikev2/ikev2.h index dd1c646e6f2..d435179275a 100644 --- a/src/plugins/ikev2/ikev2.h +++ b/src/plugins/ikev2/ikev2.h @@ -395,8 +395,7 @@ clib_error_t *ikev2_set_profile_esp_transforms (vlib_main_t * vm, u8 * name, crypto_alg, ikev2_transform_integ_type_t integ_alg, - ikev2_transform_dh_type_t - dh_type, u32 crypto_key_size); + u32 crypto_key_size); clib_error_t *ikev2_set_profile_sa_lifetime (vlib_main_t * vm, u8 * name, u64 lifetime, u32 jitter, u32 handover, u64 maxdata); diff --git a/src/plugins/ikev2/ikev2_api.c b/src/plugins/ikev2/ikev2_api.c index 7bac98f9b4f..f1ff40a8a0a 100644 --- a/src/plugins/ikev2/ikev2_api.c +++ b/src/plugins/ikev2/ikev2_api.c @@ -21,7 +21,7 @@ #include #include #include - +#include #include #include @@ -43,12 +43,21 @@ extern ikev2_main_t ikev2_main; #include static void -cp_transforms (vl_api_ikev2_transforms_set_t * vl_api_ts, - ikev2_transforms_set * ts) +cp_ike_transforms (vl_api_ikev2_ike_transforms_t * vl_api_ts, + ikev2_transforms_set * ts) +{ + vl_api_ts->crypto_alg = ts->crypto_alg; + vl_api_ts->integ_alg = ts->integ_alg; + vl_api_ts->dh_group = ts->dh_type; + vl_api_ts->crypto_key_size = ts->crypto_key_size; +} + +static void +cp_esp_transforms (vl_api_ikev2_esp_transforms_t * vl_api_ts, + ikev2_transforms_set * ts) { vl_api_ts->crypto_alg = ts->crypto_alg; vl_api_ts->integ_alg = ts->integ_alg; - vl_api_ts->dh_type = ts->dh_type; vl_api_ts->crypto_key_size = ts->crypto_key_size; } @@ -69,16 +78,14 @@ cp_id (vl_api_ikev2_id_t * vl_api_id, ikev2_id_t * id) } static void -cp_ts (vl_api_ikev2_ts_t * vl_api_ts, ikev2_ts_t * ts) +cp_ts (vl_api_ikev2_ts_t * vl_api_ts, ikev2_ts_t * ts, u8 is_local) { - vl_api_ts->ts_type = ts->ts_type; + vl_api_ts->is_local = is_local; vl_api_ts->protocol_id = ts->protocol_id; - vl_api_ts->selector_len = ts->selector_len; vl_api_ts->start_port = ts->start_port; vl_api_ts->end_port = ts->end_port; - clib_memcpy (&vl_api_ts->start_addr, &ts->start_addr, - sizeof (ip4_address_t)); - clib_memcpy (&vl_api_ts->end_addr, &ts->end_addr, sizeof (ip4_address_t)); + ip4_address_encode (&ts->start_addr, vl_api_ts->start_addr); + ip4_address_encode (&ts->end_addr, vl_api_ts->end_addr); } static void @@ -95,8 +102,7 @@ cp_responder (vl_api_ikev2_responder_t * vl_api_responder, ikev2_responder_t * responder) { vl_api_responder->sw_if_index = responder->sw_if_index; - clib_memcpy (&vl_api_responder->ip4, &responder->ip4, - sizeof (ip4_address_t)); + ip4_address_encode (&responder->ip4, vl_api_responder->ip4); } static void @@ -116,14 +122,14 @@ send_profile (ikev2_profile_t * profile, vl_api_registration_t * reg, size_data = vec_len (profile->name); clib_memcpy (rmp->profile.name, profile->name, size_data); - cp_transforms (&rmp->profile.ike_ts, &profile->ike_ts); - cp_transforms (&rmp->profile.esp_ts, &profile->esp_ts); + cp_ike_transforms (&rmp->profile.ike_ts, &profile->ike_ts); + cp_esp_transforms (&rmp->profile.esp_ts, &profile->esp_ts); cp_id (&rmp->profile.loc_id, &profile->loc_id); cp_id (&rmp->profile.rem_id, &profile->rem_id); - cp_ts (&rmp->profile.rem_ts, &profile->rem_ts); - cp_ts (&rmp->profile.loc_ts, &profile->loc_ts); + cp_ts (&rmp->profile.rem_ts, &profile->rem_ts, 0 /* is_local */ ); + cp_ts (&rmp->profile.loc_ts, &profile->loc_ts, 1 /* is_local */ ); cp_auth (&rmp->profile.auth, &profile->auth); @@ -297,7 +303,7 @@ static void rv = VNET_API_ERROR_UNIMPLEMENTED; #endif - REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_UDP_ENCAP); + REPLY_MACRO (VL_API_IKEV2_PROFILE_SET_UDP_ENCAP_REPLY); } static void @@ -310,12 +316,14 @@ vl_api_ikev2_profile_set_ts_t_handler (vl_api_ikev2_profile_set_ts_t * mp) vlib_main_t *vm = vlib_get_main (); clib_error_t *error; u8 *tmp = format (0, "%s", mp->name); + ip4_address_t start_addr, end_addr; + ip4_address_decode (mp->ts.start_addr, &start_addr); + ip4_address_decode (mp->ts.end_addr, &end_addr); error = - ikev2_set_profile_ts (vm, tmp, mp->proto, - clib_net_to_host_u16 (mp->start_port), - clib_net_to_host_u16 (mp->end_port), - (ip4_address_t) mp->start_addr, - (ip4_address_t) mp->end_addr, mp->is_local); + ikev2_set_profile_ts (vm, tmp, mp->ts.protocol_id, + clib_net_to_host_u16 (mp->ts.start_port), + clib_net_to_host_u16 (mp->ts.end_port), + start_addr, end_addr, mp->ts.is_local); vec_free (tmp); if (error) rv = VNET_API_ERROR_UNSPECIFIED; @@ -358,9 +366,10 @@ vl_api_ikev2_set_responder_t_handler (vl_api_ikev2_set_responder_t * mp) u8 *tmp = format (0, "%s", mp->name); ip4_address_t ip4; - clib_memcpy (&ip4, mp->address, sizeof (ip4)); + ip4_address_decode (mp->responder.ip4, &ip4); + u32 sw_if_index = clib_net_to_host_u32 (mp->responder.sw_if_index); - error = ikev2_set_profile_responder (vm, tmp, ntohl (mp->sw_if_index), ip4); + error = ikev2_set_profile_responder (vm, tmp, sw_if_index, ip4); vec_free (tmp); if (error) rv = VNET_API_ERROR_UNSPECIFIED; @@ -385,10 +394,10 @@ vl_api_ikev2_set_ike_transforms_t_handler (vl_api_ikev2_set_ike_transforms_t * u8 *tmp = format (0, "%s", mp->name); error = - ikev2_set_profile_ike_transforms (vm, tmp, ntohl (mp->crypto_alg), - ntohl (mp->integ_alg), - ntohl (mp->dh_group), - ntohl (mp->crypto_key_size)); + ikev2_set_profile_ike_transforms (vm, tmp, mp->tr.crypto_alg, + mp->tr.integ_alg, + mp->tr.dh_group, + ntohl (mp->tr.crypto_key_size)); vec_free (tmp); if (error) rv = VNET_API_ERROR_UNSPECIFIED; @@ -413,10 +422,9 @@ vl_api_ikev2_set_esp_transforms_t_handler (vl_api_ikev2_set_esp_transforms_t * u8 *tmp = format (0, "%s", mp->name); error = - ikev2_set_profile_esp_transforms (vm, tmp, ntohl (mp->crypto_alg), - ntohl (mp->integ_alg), - ntohl (mp->dh_group), - ntohl (mp->crypto_key_size)); + ikev2_set_profile_esp_transforms (vm, tmp, mp->tr.crypto_alg, + mp->tr.integ_alg, + ntohl (mp->tr.crypto_key_size)); vec_free (tmp); if (error) rv = VNET_API_ERROR_UNSPECIFIED; diff --git a/src/plugins/ikev2/ikev2_cli.c b/src/plugins/ikev2/ikev2_cli.c index 30de10b6d95..687e6f24d87 100644 --- a/src/plugins/ikev2/ikev2_cli.c +++ b/src/plugins/ikev2/ikev2_cli.c @@ -379,7 +379,6 @@ ikev2_profile_add_del_command_fn (vlib_main_t * vm, { r = ikev2_set_profile_esp_transforms (vm, name, crypto_alg, integ_alg, - IKEV2_TRANSFORM_DH_TYPE_NONE, tmp1); goto done; } @@ -390,9 +389,7 @@ ikev2_profile_add_del_command_fn (vlib_main_t * vm, unformat_ikev2_transform_encr_type, &crypto_alg, &tmp1)) { r = - ikev2_set_profile_esp_transforms (vm, name, crypto_alg, 0, - IKEV2_TRANSFORM_DH_TYPE_NONE, - tmp1); + ikev2_set_profile_esp_transforms (vm, name, crypto_alg, 0, tmp1); goto done; } else if (unformat (line_input, "set %U sa-lifetime %lu %u %u %lu", diff --git a/src/plugins/ikev2/ikev2_test.c b/src/plugins/ikev2/ikev2_test.c index 91722ec2b9a..fae47726783 100644 --- a/src/plugins/ikev2/ikev2_test.c +++ b/src/plugins/ikev2/ikev2_test.c @@ -23,6 +23,7 @@ #include #include #include +#include #define __plugin_msg_base ikev2_test_main.msg_id_base #include @@ -169,6 +170,7 @@ static void vl_api_ikev2_profile_details_t_handler { vat_main_t *vam = ikev2_test_main.vat_main; vl_api_ikev2_profile_t *p = &mp->profile; + ip4_address_t start_addr, end_addr; fformat (vam->ofp, "profile %s\n", p->name); @@ -199,23 +201,23 @@ static void vl_api_ikev2_profile_details_t_handler format_ikev2_id_type_and_data, &p->rem_id); } - if (*((u32 *) & p->loc_ts.end_addr)) - fformat (vam->ofp, " local traffic-selector addr %U - %U port %u - %u" - " protocol %u\n", - format_ip4_address, &p->loc_ts.start_addr, - format_ip4_address, &p->loc_ts.end_addr, - clib_net_to_host_u16 (p->loc_ts.start_port), - clib_net_to_host_u16 (p->loc_ts.end_port), - p->loc_ts.protocol_id); - - if (*((u32 *) & p->rem_ts.end_addr)) - fformat (vam->ofp, " remote traffic-selector addr %U - %U port %u - %u" - " protocol %u\n", - format_ip4_address, &p->rem_ts.start_addr, - format_ip4_address, &p->rem_ts.end_addr, - clib_net_to_host_u16 (p->rem_ts.start_port), - clib_net_to_host_u16 (p->rem_ts.end_port), - p->rem_ts.protocol_id); + ip4_address_decode (p->loc_ts.start_addr, &start_addr); + ip4_address_decode (p->loc_ts.end_addr, &end_addr); + fformat (vam->ofp, " local traffic-selector addr %U - %U port %u - %u" + " protocol %u\n", + format_ip4_address, &start_addr, + format_ip4_address, &end_addr, + clib_net_to_host_u16 (p->loc_ts.start_port), + clib_net_to_host_u16 (p->loc_ts.end_port), p->loc_ts.protocol_id); + + ip4_address_decode (p->rem_ts.start_addr, &start_addr); + ip4_address_decode (p->rem_ts.end_addr, &end_addr); + fformat (vam->ofp, " remote traffic-selector addr %U - %U port %u - %u" + " protocol %u\n", + format_ip4_address, &start_addr, + format_ip4_address, &end_addr, + clib_net_to_host_u16 (p->rem_ts.start_port), + clib_net_to_host_u16 (p->rem_ts.end_port), p->rem_ts.protocol_id); u32 tun_itf = clib_net_to_host_u32 (p->tun_itf); if (~0 != tun_itf) fformat (vam->ofp, " protected tunnel idx %d\n", tun_itf); @@ -233,16 +235,16 @@ static void vl_api_ikev2_profile_details_t_handler fformat (vam->ofp, " ipsec-over-udp port %d\n", ipsec_over_udp_port); u32 crypto_key_size = clib_net_to_host_u32 (p->ike_ts.crypto_key_size); - if (p->ike_ts.crypto_alg || p->ike_ts.integ_alg || p->ike_ts.dh_type + if (p->ike_ts.crypto_alg || p->ike_ts.integ_alg || p->ike_ts.dh_group || crypto_key_size) fformat (vam->ofp, " ike-crypto-alg %U %u ike-integ-alg %U ike-dh %U\n", format_ikev2_transform_encr_type, p->ike_ts.crypto_alg, crypto_key_size, format_ikev2_transform_integ_type, p->ike_ts.integ_alg, format_ikev2_transform_dh_type, - p->ike_ts.dh_type); + p->ike_ts.dh_group); crypto_key_size = clib_net_to_host_u32 (p->esp_ts.crypto_key_size); - if (p->esp_ts.crypto_alg || p->esp_ts.integ_alg || p->esp_ts.dh_type) + if (p->esp_ts.crypto_alg || p->esp_ts.integ_alg) fformat (vam->ofp, " esp-crypto-alg %U %u esp-integ-alg %U\n", format_ikev2_transform_encr_type, p->esp_ts.crypto_alg, crypto_key_size, @@ -574,12 +576,12 @@ api_ikev2_profile_set_ts (vat_main_t * vam) M (IKEV2_PROFILE_SET_TS, mp); - mp->is_local = is_local; - mp->proto = (u8) proto; - mp->start_port = (u16) start_port; - mp->end_port = (u16) end_port; - mp->start_addr = start_addr.as_u32; - mp->end_addr = end_addr.as_u32; + mp->ts.is_local = is_local; + mp->ts.protocol_id = (u8) proto; + mp->ts.start_port = clib_host_to_net_u16 ((u16) start_port); + mp->ts.end_port = clib_host_to_net_u16 ((u16) end_port); + ip4_address_encode (&start_addr, mp->ts.start_addr); + ip4_address_encode (&end_addr, mp->ts.end_addr); clib_memcpy (mp->name, name, vec_len (name)); vec_free (name); @@ -720,8 +722,8 @@ api_ikev2_set_responder (vat_main_t * vam) clib_memcpy (mp->name, name, vec_len (name)); vec_free (name); - mp->sw_if_index = sw_if_index; - clib_memcpy (mp->address, &address, sizeof (address)); + mp->responder.sw_if_index = clib_host_to_net_u32 (sw_if_index); + ip4_address_encode (&address, mp->responder.ip4); S (mp); W (ret); @@ -767,10 +769,10 @@ api_ikev2_set_ike_transforms (vat_main_t * vam) clib_memcpy (mp->name, name, vec_len (name)); vec_free (name); - mp->crypto_alg = crypto_alg; - mp->crypto_key_size = crypto_key_size; - mp->integ_alg = integ_alg; - mp->dh_group = dh_group; + mp->tr.crypto_alg = crypto_alg; + mp->tr.crypto_key_size = clib_host_to_net_u32 (crypto_key_size); + mp->tr.integ_alg = integ_alg; + mp->tr.dh_group = dh_group; S (mp); W (ret); @@ -785,14 +787,14 @@ api_ikev2_set_esp_transforms (vat_main_t * vam) vl_api_ikev2_set_esp_transforms_t *mp; int ret; u8 *name = 0; - u32 crypto_alg, crypto_key_size, integ_alg, dh_group; + u32 crypto_alg, crypto_key_size, integ_alg; const char *valid_chars = "a-zA-Z0-9_"; while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) { - if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name, - &crypto_alg, &crypto_key_size, &integ_alg, &dh_group)) + if (unformat (i, "%U %d %d %d", unformat_token, valid_chars, &name, + &crypto_alg, &crypto_key_size, &integ_alg)) vec_add1 (name, 0); else { @@ -817,10 +819,9 @@ api_ikev2_set_esp_transforms (vat_main_t * vam) clib_memcpy (mp->name, name, vec_len (name)); vec_free (name); - mp->crypto_alg = crypto_alg; - mp->crypto_key_size = crypto_key_size; - mp->integ_alg = integ_alg; - mp->dh_group = dh_group; + mp->tr.crypto_alg = crypto_alg; + mp->tr.crypto_key_size = clib_host_to_net_u32 (crypto_key_size); + mp->tr.integ_alg = integ_alg; S (mp); W (ret); diff --git a/src/plugins/ikev2/ikev2_types.api b/src/plugins/ikev2/ikev2_types.api index 1dc4fdc8b88..bee48f8cef0 100644 --- a/src/plugins/ikev2/ikev2_types.api +++ b/src/plugins/ikev2/ikev2_types.api @@ -16,7 +16,7 @@ import "vnet/ip/ip_types.api"; - +import "vnet/interface_types.api"; typedef ikev2_id { @@ -27,9 +27,8 @@ typedef ikev2_id typedef ikev2_ts { - u8 ts_type; + bool is_local; u8 protocol_id; - u16 selector_len; u16 start_port; u16 end_port; vl_api_ip4_address_t start_addr; @@ -46,16 +45,23 @@ typedef ikev2_auth typedef ikev2_responder { - u32 sw_if_index; + vl_api_interface_index_t sw_if_index; vl_api_ip4_address_t ip4; }; -typedef ikev2_transforms_set +typedef ikev2_ike_transforms { u8 crypto_alg; + u32 crypto_key_size; u8 integ_alg; - u8 dh_type; + u8 dh_group; +}; + +typedef ikev2_esp_transforms +{ + u8 crypto_alg; u32 crypto_key_size; + u8 integ_alg; }; typedef ikev2_profile @@ -66,14 +72,14 @@ typedef ikev2_profile vl_api_ikev2_ts_t loc_ts; vl_api_ikev2_ts_t rem_ts; vl_api_ikev2_responder_t responder; - vl_api_ikev2_transforms_set_t ike_ts; - vl_api_ikev2_transforms_set_t esp_ts; + vl_api_ikev2_ike_transforms_t ike_ts; + vl_api_ikev2_esp_transforms_t esp_ts; u64 lifetime; u64 lifetime_maxdata; u32 lifetime_jitter; u32 handover; u16 ipsec_over_udp_port; u32 tun_itf; - u8 udp_encap; + bool udp_encap; vl_api_ikev2_auth_t auth; }; diff --git a/src/plugins/ikev2/test/test_ikev2.py b/src/plugins/ikev2/test/test_ikev2.py index 77698d6a5ed..02d1bde8f3d 100644 --- a/src/plugins/ikev2/test/test_ikev2.py +++ b/src/plugins/ikev2/test/test_ikev2.py @@ -9,6 +9,7 @@ from cryptography.hazmat.primitives.ciphers import ( algorithms, modes, ) +from ipaddress import IPv4Address from scapy.layers.ipsec import ESP from scapy.layers.inet import IP, UDP, Ether from scapy.packet import raw, Raw @@ -494,8 +495,14 @@ class TemplateResponder(VppTestCase): super(TemplateResponder, self).setUp() self.config_tc() self.p.add_vpp_config() + self.assertIsNotNone(self.p.query_vpp_config()) self.sa.generate_dh_data() + def tearDown(self): + super(TemplateResponder, self).tearDown() + self.p.remove_vpp_config() + self.assertIsNone(self.p.query_vpp_config()) + def create_ike_msg(self, src_if, msg, sport=500, dport=500, natt=False): res = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) / IP(src=src_if.remote_ip4, dst=src_if.local_ip4) / @@ -769,8 +776,8 @@ class Ikev2Params(object): self.p.add_local_id(id_type='fqdn', data=b'vpp.home') self.p.add_remote_id(id_type='fqdn', data=b'roadwarrior.example.com') - self.p.add_local_ts(start_addr=0x0a0a0a0, end_addr=0x0a0a0aff) - self.p.add_remote_ts(start_addr=0xa000000, end_addr=0xa0000ff) + self.p.add_local_ts(start_addr='10.10.10.0', end_addr='10.10.10.255') + self.p.add_remote_ts(start_addr='10.0.0.0', end_addr='10.0.0.255') self.sa = IKEv2SA(self, i_id=self.p.remote_id['data'], r_id=self.p.local_id['data'], @@ -798,6 +805,172 @@ class Ikev2Params(object): integ=esp_integ) +class TestApi(VppTestCase): + """ Test IKEV2 API """ + @classmethod + def setUpClass(cls): + super(TestApi, cls).setUpClass() + + @classmethod + def tearDownClass(cls): + super(TestApi, cls).tearDownClass() + + def tearDown(self): + super(TestApi, self).tearDown() + self.p1.remove_vpp_config() + self.p2.remove_vpp_config() + r = self.vapi.ikev2_profile_dump() + self.assertEqual(len(r), 0) + + def configure_profile(self, cfg): + p = Profile(self, cfg['name']) + p.add_local_id(id_type=cfg['loc_id'][0], data=cfg['loc_id'][1]) + p.add_remote_id(id_type=cfg['rem_id'][0], data=cfg['rem_id'][1]) + p.add_local_ts(**cfg['loc_ts']) + p.add_remote_ts(**cfg['rem_ts']) + p.add_responder(cfg['responder']) + p.add_ike_transforms(cfg['ike_ts']) + p.add_esp_transforms(cfg['esp_ts']) + p.add_auth(**cfg['auth']) + p.set_udp_encap(cfg['udp_encap']) + p.set_ipsec_over_udp_port(cfg['ipsec_over_udp_port']) + if 'lifetime_data' in cfg: + p.set_lifetime_data(cfg['lifetime_data']) + if 'tun_itf' in cfg: + p.set_tunnel_interface(cfg['tun_itf']) + p.add_vpp_config() + return p + + def test_profile_api(self): + """ test profile dump API """ + loc_ts = { + 'proto': 8, + 'start_port': 1, + 'end_port': 19, + 'start_addr': '3.3.3.2', + 'end_addr': '3.3.3.3', + } + rem_ts = { + 'proto': 9, + 'start_port': 10, + 'end_port': 119, + 'start_addr': '4.5.76.80', + 'end_addr': '2.3.4.6', + } + + conf = { + 'p1': { + 'name': 'p1', + 'loc_id': ('fqdn', b'vpp.home'), + 'rem_id': ('fqdn', b'roadwarrior.example.com'), + 'loc_ts': loc_ts, + 'rem_ts': rem_ts, + 'responder': {'sw_if_index': 0, 'ip4': '5.6.7.8'}, + 'ike_ts': { + 'crypto_alg': 20, + 'crypto_key_size': 32, + 'integ_alg': 1, + 'dh_group': 1}, + 'esp_ts': { + 'crypto_alg': 13, + 'crypto_key_size': 24, + 'integ_alg': 2}, + 'auth': {'method': 'shared-key', 'data': b'sharedkeydata'}, + 'udp_encap': True, + 'ipsec_over_udp_port': 4501, + 'lifetime_data': { + 'lifetime': 123, + 'lifetime_maxdata': 20192, + 'lifetime_jitter': 9, + 'handover': 132}, + }, + 'p2': { + 'name': 'p2', + 'loc_id': ('ip4-addr', b'192.168.2.1'), + 'rem_id': ('ip4-addr', b'192.168.2.2'), + 'loc_ts': loc_ts, + 'rem_ts': rem_ts, + 'responder': {'sw_if_index': 4, 'ip4': '5.6.7.99'}, + 'ike_ts': { + 'crypto_alg': 12, + 'crypto_key_size': 16, + 'integ_alg': 3, + 'dh_group': 3}, + 'esp_ts': { + 'crypto_alg': 9, + 'crypto_key_size': 24, + 'integ_alg': 4}, + 'auth': {'method': 'shared-key', 'data': b'sharedkeydata'}, + 'udp_encap': False, + 'ipsec_over_udp_port': 4600, + 'tun_itf': 0} + } + self.p1 = self.configure_profile(conf['p1']) + self.p2 = self.configure_profile(conf['p2']) + + r = self.vapi.ikev2_profile_dump() + self.assertEqual(len(r), 2) + self.verify_profile(r[0].profile, conf['p1']) + self.verify_profile(r[1].profile, conf['p2']) + + def verify_id(self, api_id, cfg_id): + self.assertEqual(api_id.type, IDType.value(cfg_id[0])) + self.assertEqual(bytes(api_id.data, 'ascii'), cfg_id[1]) + + def verify_ts(self, api_ts, cfg_ts): + self.assertEqual(api_ts.protocol_id, cfg_ts['proto']) + self.assertEqual(api_ts.start_port, cfg_ts['start_port']) + self.assertEqual(api_ts.end_port, cfg_ts['end_port']) + self.assertEqual(api_ts.start_addr, IPv4Address(cfg_ts['start_addr'])) + self.assertEqual(api_ts.end_addr, IPv4Address(cfg_ts['end_addr'])) + + def verify_responder(self, api_r, cfg_r): + self.assertEqual(api_r.sw_if_index, cfg_r['sw_if_index']) + self.assertEqual(api_r.ip4, IPv4Address(cfg_r['ip4'])) + + def verify_transforms(self, api_ts, cfg_ts): + self.assertEqual(api_ts.crypto_alg, cfg_ts['crypto_alg']) + self.assertEqual(api_ts.crypto_key_size, cfg_ts['crypto_key_size']) + self.assertEqual(api_ts.integ_alg, cfg_ts['integ_alg']) + + def verify_ike_transforms(self, api_ts, cfg_ts): + self.verify_transforms(api_ts, cfg_ts) + self.assertEqual(api_ts.dh_group, cfg_ts['dh_group']) + + def verify_esp_transforms(self, api_ts, cfg_ts): + self.verify_transforms(api_ts, cfg_ts) + + def verify_auth(self, api_auth, cfg_auth): + self.assertEqual(api_auth.method, AuthMethod.value(cfg_auth['method'])) + self.assertEqual(api_auth.data, cfg_auth['data']) + self.assertEqual(api_auth.data_len, len(cfg_auth['data'])) + + def verify_lifetime_data(self, p, ld): + self.assertEqual(p.lifetime, ld['lifetime']) + self.assertEqual(p.lifetime_maxdata, ld['lifetime_maxdata']) + self.assertEqual(p.lifetime_jitter, ld['lifetime_jitter']) + self.assertEqual(p.handover, ld['handover']) + + def verify_profile(self, ap, cp): + self.assertEqual(ap.name, cp['name']) + self.assertEqual(ap.udp_encap, cp['udp_encap']) + self.verify_id(ap.loc_id, cp['loc_id']) + self.verify_id(ap.rem_id, cp['rem_id']) + self.verify_ts(ap.loc_ts, cp['loc_ts']) + self.verify_ts(ap.rem_ts, cp['rem_ts']) + self.verify_responder(ap.responder, cp['responder']) + self.verify_ike_transforms(ap.ike_ts, cp['ike_ts']) + self.verify_esp_transforms(ap.esp_ts, cp['esp_ts']) + self.verify_auth(ap.auth, cp['auth']) + if 'lifetime_data' in cp: + self.verify_lifetime_data(ap, cp['lifetime_data']) + self.assertEqual(ap.ipsec_over_udp_port, cp['ipsec_over_udp_port']) + if 'tun_itf' in cp: + self.assertEqual(ap.tun_itf, cp['tun_itf']) + else: + self.assertEqual(ap.tun_itf, 0xffffffff) + + class TestResponderNATT(TemplateResponder, Ikev2Params): """ test ikev2 responder - nat traversal """ def config_tc(self): diff --git a/src/plugins/ikev2/test/vpp_ikev2.py b/src/plugins/ikev2/test/vpp_ikev2.py index 67df1d53b5e..5a2a51eb607 100644 --- a/src/plugins/ikev2/test/vpp_ikev2.py +++ b/src/plugins/ikev2/test/vpp_ikev2.py @@ -24,6 +24,7 @@ class Profile(VppObject): self.test = test self.vapi = test.vapi self.profile_name = profile_name + self.udp_encap = False def add_auth(self, method, data, is_hex=False): if isinstance(method, int): @@ -53,7 +54,7 @@ class Profile(VppObject): def add_local_ts(self, start_addr, end_addr, start_port=0, end_port=0xffff, proto=0): self.local_ts = {'is_local': True, - 'proto': proto, + 'protocol_id': proto, 'start_port': start_port, 'end_port': end_port, 'start_addr': start_addr, @@ -62,12 +63,34 @@ class Profile(VppObject): def add_remote_ts(self, start_addr, end_addr, start_port=0, end_port=0xffff, proto=0): self.remote_ts = {'is_local': False, - 'proto': proto, + 'protocol_id': proto, 'start_port': start_port, 'end_port': end_port, 'start_addr': start_addr, 'end_addr': end_addr} + def add_responder(self, responder): + self.responder = responder + + def add_ike_transforms(self, tr): + self.ike_transforms = tr + + def add_esp_transforms(self, tr): + self.esp_transforms = tr + + def set_udp_encap(self, udp_encap): + self.udp_encap = udp_encap + + def set_lifetime_data(self, data): + self.lifetime_data = data + + def set_ipsec_over_udp_port(self, port): + self.ipsec_udp_port = {'is_set': 1, + 'port': port} + + def set_tunnel_interface(self, sw_if_index): + self.tun_itf = sw_if_index + def object_id(self): return 'ikev2-profile-%s' % self.profile_name @@ -92,10 +115,41 @@ class Profile(VppObject): **self.remote_id) if hasattr(self, 'local_ts'): self.vapi.ikev2_profile_set_ts(name=self.profile_name, - **self.local_ts) + ts={**self.local_ts}) + if hasattr(self, 'remote_ts'): self.vapi.ikev2_profile_set_ts(name=self.profile_name, - **self.remote_ts) + ts={**self.remote_ts}) + + if hasattr(self, 'responder'): + self.vapi.ikev2_set_responder(name=self.profile_name, + responder={**self.responder}) + + if hasattr(self, 'ike_transforms'): + self.vapi.ikev2_set_ike_transforms(name=self.profile_name, + tr={**self.ike_transforms}) + + if hasattr(self, 'esp_transforms'): + self.vapi.ikev2_set_esp_transforms(name=self.profile_name, + tr=self.esp_transforms) + + if self.udp_encap: + self.vapi.ikev2_profile_set_udp_encap(name=self.profile_name) + + if hasattr(self, 'lifetime_data'): + self.vapi.ikev2_set_sa_lifetime(name=self.profile_name, + **self.lifetime_data) + + if hasattr(self, 'ipsec_udp_port'): + self.vapi.ikev2_profile_set_ipsec_udp_port(name=self.profile_name, + **self.ipsec_udp_port) + if hasattr(self, 'tun_itf'): + self.vapi.ikev2_set_tunnel_interface(name=self.profile_name, + sw_if_index=self.tun_itf) def query_vpp_config(self): - raise NotImplementedError() + res = self.vapi.ikev2_profile_dump() + for r in res: + if r.profile.name == self.profile_name: + return r.profile + return None -- 2.16.6