diff options
Diffstat (limited to 'src/plugins')
62 files changed, 1592 insertions, 508 deletions
diff --git a/src/plugins/acl/CMakeLists.txt b/src/plugins/acl/CMakeLists.txt index c43dd23ea51..1bb60d94fbe 100644 --- a/src/plugins/acl/CMakeLists.txt +++ b/src/plugins/acl/CMakeLists.txt @@ -30,4 +30,15 @@ add_vpp_plugin(acl API_TEST_SOURCES acl_test.c + + INSTALL_HEADERS + exports.h + exported_types.h + acl.h + fa_node.h + public_inlines.h + types.h + hash_lookup_types.h + lookup_context.h + hash_lookup_private.h ) diff --git a/src/plugins/acl/acl_test.c b/src/plugins/acl/acl_test.c index 0c218687bdf..98803a916cb 100644 --- a/src/plugins/acl/acl_test.c +++ b/src/plugins/acl/acl_test.c @@ -18,6 +18,8 @@ *------------------------------------------------------------------ */ +#include <byteswap.h> + #include <vat/vat.h> #include <vlibapi/api.h> #include <vlibmemory/api.h> @@ -112,7 +114,7 @@ static void vl_api_acl_interface_list_details_t_handler int i; vat_main_t * vam = acl_test_main.vat_main; u8 *out = 0; - vl_api_acl_interface_list_details_t_endian(mp); + vl_api_acl_interface_list_details_t_endian (mp, 0 /* from network */); out = format(out, "sw_if_index: %d, count: %d, n_input: %d\n", mp->sw_if_index, mp->count, mp->n_input); out = format(out, " input "); for(i=0; i<mp->count; i++) { @@ -139,7 +141,8 @@ static void vl_api_acl_interface_etype_whitelist_details_t_handler int i; vat_main_t * vam = acl_test_main.vat_main; u8 *out = 0; - vl_api_acl_interface_etype_whitelist_details_t_endian(mp); + vl_api_acl_interface_etype_whitelist_details_t_endian ( + mp, 0 /* from network */); out = format(out, "sw_if_index: %d, count: %d, n_input: %d\n", mp->sw_if_index, mp->count, mp->n_input); out = format(out, " input "); for(i=0; i<mp->count; i++) { @@ -157,9 +160,9 @@ static void vl_api_acl_plugin_get_conn_table_max_entries_reply_t_handler (vl_api_acl_plugin_get_conn_table_max_entries_reply_t * mp) { vat_main_t * vam = acl_test_main.vat_main; - clib_warning("\nConn table max entries: %d", - __bswap_64(mp->conn_table_max_entries) ); - vam->result_ready = 1; + clib_warning ("\nConn table max entries: %d", + clib_net_to_host_u64 (mp->conn_table_max_entries)); + vam->result_ready = 1; } static inline u8 * @@ -171,15 +174,15 @@ vl_api_acl_rule_t_pretty_format (u8 *out, vl_api_acl_rule_t * a) inet_ntop(af, &a->src_prefix.address.un, (void *)src, sizeof(src)); inet_ntop(af, &a->dst_prefix.address.un, (void *)dst, sizeof(dst)); - out = format(out, "%s action %d src %s/%d dst %s/%d proto %d sport %d-%d dport %d-%d tcpflags %d mask %d", - a->src_prefix.address.af ? "ipv6" : "ipv4", a->is_permit, - src, a->src_prefix.len, - dst, a->dst_prefix.len, - a->proto, - a->srcport_or_icmptype_first, a->srcport_or_icmptype_last, - a->dstport_or_icmpcode_first, a->dstport_or_icmpcode_last, - a->tcp_flags_value, a->tcp_flags_mask); - return(out); + out = format (out, + "%s action %d src %s/%d dst %s/%d proto %d sport %d-%d dport " + "%d-%d tcpflags %d mask %d", + a->src_prefix.address.af ? "ipv6" : "ipv4", a->is_permit, src, + a->src_prefix.len, dst, a->dst_prefix.len, a->proto, + a->srcport_or_icmptype_first, a->srcport_or_icmptype_last, + a->dstport_or_icmpcode_first, a->dstport_or_icmpcode_last, + a->tcp_flags_value, a->tcp_flags_mask); + return (out); } @@ -189,9 +192,10 @@ static void vl_api_acl_details_t_handler { int i; vat_main_t * vam = acl_test_main.vat_main; - vl_api_acl_details_t_endian(mp); - u8 *out = 0; - out = format(0, "acl_index: %d, count: %d\n tag {%s}\n", mp->acl_index, mp->count, mp->tag); + vl_api_acl_details_t_endian (mp, 0 /* from network */); + u8 *out = 0; + out = format (0, "acl_index: %d, count: %d\n tag {%s}\n", + mp->acl_index, mp->count, mp->tag); for(i=0; i<mp->count; i++) { out = format(out, " "); out = vl_api_acl_rule_t_pretty_format(out, &mp->r[i]); @@ -223,8 +227,9 @@ static void vl_api_macip_acl_details_t_handler { int i; vat_main_t * vam = acl_test_main.vat_main; - vl_api_macip_acl_details_t_endian(mp); - u8 *out = format(0,"MACIP acl_index: %d, count: %d\n tag {%s}\n", mp->acl_index, mp->count, mp->tag); + vl_api_macip_acl_details_t_endian (mp, 0 /* from network */); + u8 *out = format (0, "MACIP acl_index: %d, count: %d\n tag {%s}\n", + mp->acl_index, mp->count, mp->tag); for(i=0; i<mp->count; i++) { out = format(out, " "); out = vl_api_macip_acl_rule_t_pretty_format(out, &mp->r[i]); diff --git a/src/plugins/acl/exports.h b/src/plugins/acl/exports.h index d904ad3bbae..04159aa052d 100644 --- a/src/plugins/acl/exports.h +++ b/src/plugins/acl/exports.h @@ -24,8 +24,8 @@ #include <vlib/unix/plugin.h> -#include <plugins/acl/acl.h> -#include <plugins/acl/fa_node.h> -#include <plugins/acl/public_inlines.h> +#include "acl.h" +#include "fa_node.h" +#include "public_inlines.h" #endif /* included_acl_exports_h */ diff --git a/src/plugins/acl/fa_node.h b/src/plugins/acl/fa_node.h index c969377ded7..c4a971aada3 100644 --- a/src/plugins/acl/fa_node.h +++ b/src/plugins/acl/fa_node.h @@ -5,7 +5,7 @@ #include <vppinfra/bihash_16_8.h> #include <vppinfra/bihash_40_8.h> -#include <plugins/acl/exported_types.h> +#include "exported_types.h" // #define FA_NODE_VERBOSE_DEBUG 3 diff --git a/src/plugins/acl/public_inlines.h b/src/plugins/acl/public_inlines.h index 6b69bcef61e..eb9f0de920f 100644 --- a/src/plugins/acl/public_inlines.h +++ b/src/plugins/acl/public_inlines.h @@ -19,11 +19,11 @@ #include <stdint.h> #include <vlib/unix/plugin.h> -#include <plugins/acl/acl.h> -#include <plugins/acl/fa_node.h> -#include <plugins/acl/hash_lookup_private.h> +#include "acl.h" +#include "fa_node.h" +#include "hash_lookup_private.h" -#include <plugins/acl/exported_types.h> +#include "exported_types.h" #define LOAD_SYMBOL_FROM_PLUGIN_TO(p, s, st) \ ({ \ diff --git a/src/plugins/acl/sess_mgmt_node.c b/src/plugins/acl/sess_mgmt_node.c index e049a3ffa85..418baef9b6b 100644 --- a/src/plugins/acl/sess_mgmt_node.c +++ b/src/plugins/acl/sess_mgmt_node.c @@ -371,8 +371,9 @@ send_one_worker_interrupt (vlib_main_t * vm, acl_main_t * am, } void -aclp_post_session_change_request (acl_main_t * am, u32 target_thread, - u32 target_session, u32 request_type) +aclp_post_session_change_request (acl_main_t *am, u32 target_thread, + u32 target_session, + acl_fa_sess_req_t request_type) { acl_fa_per_worker_data_t *pw_me = &am->per_worker_data[os_get_thread_index ()]; diff --git a/src/plugins/crypto_native/CMakeLists.txt b/src/plugins/crypto_native/CMakeLists.txt index 9b6091610d9..5499ed4608a 100644 --- a/src/plugins/crypto_native/CMakeLists.txt +++ b/src/plugins/crypto_native/CMakeLists.txt @@ -12,8 +12,8 @@ # limitations under the License. if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*") - list(APPEND VARIANTS "slm\;-march=silvermont") - list(APPEND VARIANTS "hsw\;-march=haswell") + list(APPEND VARIANTS "slm\;-march=silvermont -maes") + list(APPEND VARIANTS "hsw\;-march=haswell -maes") if(compiler_flag_march_skylake_avx512 AND compiler_flag_mprefer_vector_width_256) list(APPEND VARIANTS "skx\;-march=skylake-avx512 -mprefer-vector-width=256") endif() @@ -23,16 +23,15 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*") if(compiler_flag_march_alderlake) list(APPEND VARIANTS "adl\;-march=alderlake -mprefer-vector-width=256") endif() - set (COMPILE_FILES aes_cbc.c aes_gcm.c aes_ctr.c) - set (COMPILE_OPTS -Wall -fno-common -maes) endif() if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*)") list(APPEND VARIANTS "armv8\;-march=armv8.1-a+crc+crypto") - set (COMPILE_FILES aes_cbc.c aes_gcm.c aes_ctr.c) - set (COMPILE_OPTS -Wall -fno-common) endif() +set (COMPILE_FILES aes_cbc.c aes_gcm.c aes_ctr.c sha2.c) +set (COMPILE_OPTS -Wall -fno-common) + if (NOT VARIANTS) return() endif() diff --git a/src/plugins/crypto_native/aes_cbc.c b/src/plugins/crypto_native/aes_cbc.c index c84390c3108..dd7ca3f1cf1 100644 --- a/src/plugins/crypto_native/aes_cbc.c +++ b/src/plugins/crypto_native/aes_cbc.c @@ -249,18 +249,30 @@ decrypt: return n_ops; } -#define foreach_aes_cbc_handler_type _(128) _(192) _(256) - -#define _(x) \ -static u32 aes_ops_dec_aes_cbc_##x \ -(vlib_main_t * vm, vnet_crypto_op_t * ops[], u32 n_ops) \ -{ return aes_ops_dec_aes_cbc (vm, ops, n_ops, AES_KEY_##x); } \ -static u32 aes_ops_enc_aes_cbc_##x \ -(vlib_main_t * vm, vnet_crypto_op_t * ops[], u32 n_ops) \ -{ return aes_ops_enc_aes_cbc (vm, ops, n_ops, AES_KEY_##x); } \ - -foreach_aes_cbc_handler_type; -#undef _ +static int +aes_cbc_cpu_probe () +{ +#if defined(__VAES__) && defined(__AVX512F__) + if (clib_cpu_supports_vaes () && clib_cpu_supports_avx512f ()) + return 50; +#elif defined(__VAES__) + if (clib_cpu_supports_vaes ()) + return 40; +#elif defined(__AVX512F__) + if (clib_cpu_supports_avx512f ()) + return 30; +#elif defined(__AVX2__) + if (clib_cpu_supports_avx2 ()) + return 20; +#elif __AES__ + if (clib_cpu_supports_aes ()) + return 10; +#elif __aarch64__ + if (clib_cpu_supports_aarch64_aes ()) + return 10; +#endif + return -1; +} static void * aes_cbc_key_exp_128 (vnet_crypto_key_t *key) @@ -289,43 +301,39 @@ aes_cbc_key_exp_256 (vnet_crypto_key_t *key) return kd; } -#include <fcntl.h> - -clib_error_t * -#if defined(__VAES__) && defined(__AVX512F__) -crypto_native_aes_cbc_init_icl (vlib_main_t *vm) -#elif defined(__VAES__) -crypto_native_aes_cbc_init_adl (vlib_main_t *vm) -#elif __AVX512F__ -crypto_native_aes_cbc_init_skx (vlib_main_t * vm) -#elif __aarch64__ -crypto_native_aes_cbc_init_neon (vlib_main_t * vm) -#elif __AVX2__ -crypto_native_aes_cbc_init_hsw (vlib_main_t * vm) -#else -crypto_native_aes_cbc_init_slm (vlib_main_t * vm) -#endif -{ - crypto_native_main_t *cm = &crypto_native_main; +#define foreach_aes_cbc_handler_type _ (128) _ (192) _ (256) + +#define _(x) \ + static u32 aes_ops_enc_aes_cbc_##x (vlib_main_t *vm, \ + vnet_crypto_op_t *ops[], u32 n_ops) \ + { \ + return aes_ops_enc_aes_cbc (vm, ops, n_ops, AES_KEY_##x); \ + } \ + \ + CRYPTO_NATIVE_OP_HANDLER (aes_##x##_cbc_enc) = { \ + .op_id = VNET_CRYPTO_OP_AES_##x##_CBC_ENC, \ + .fn = aes_ops_enc_aes_cbc_##x, \ + .probe = aes_cbc_cpu_probe, \ + }; \ + \ + static u32 aes_ops_dec_aes_cbc_##x (vlib_main_t *vm, \ + vnet_crypto_op_t *ops[], u32 n_ops) \ + { \ + return aes_ops_dec_aes_cbc (vm, ops, n_ops, AES_KEY_##x); \ + } \ + \ + CRYPTO_NATIVE_OP_HANDLER (aes_##x##_cbc_dec) = { \ + .op_id = VNET_CRYPTO_OP_AES_##x##_CBC_DEC, \ + .fn = aes_ops_dec_aes_cbc_##x, \ + .probe = aes_cbc_cpu_probe, \ + }; \ + \ + CRYPTO_NATIVE_KEY_HANDLER (aes_##x##_cbc) = { \ + .alg_id = VNET_CRYPTO_ALG_AES_##x##_CBC, \ + .key_fn = aes_cbc_key_exp_##x, \ + .probe = aes_cbc_cpu_probe, \ + }; -#define _(x) \ - vnet_crypto_register_ops_handler (vm, cm->crypto_engine_index, \ - VNET_CRYPTO_OP_AES_##x##_CBC_ENC, \ - aes_ops_enc_aes_cbc_##x); \ - vnet_crypto_register_ops_handler (vm, cm->crypto_engine_index, \ - VNET_CRYPTO_OP_AES_##x##_CBC_DEC, \ - aes_ops_dec_aes_cbc_##x); \ - cm->key_fn[VNET_CRYPTO_ALG_AES_##x##_CBC] = aes_cbc_key_exp_##x; - foreach_aes_cbc_handler_type; +foreach_aes_cbc_handler_type; #undef _ - return 0; -} - -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/src/plugins/crypto_native/aes_ctr.c b/src/plugins/crypto_native/aes_ctr.c index 3a219510419..d02a7b69b9d 100644 --- a/src/plugins/crypto_native/aes_ctr.c +++ b/src/plugins/crypto_native/aes_ctr.c @@ -81,32 +81,50 @@ aes_ctr_key_exp (vnet_crypto_key_t *key, aes_key_size_t ks) foreach_aes_ctr_handler_type; #undef _ -clib_error_t * +static int +probe () +{ #if defined(__VAES__) && defined(__AVX512F__) -crypto_native_aes_ctr_init_icl (vlib_main_t *vm) + if (clib_cpu_supports_vaes () && clib_cpu_supports_avx512f ()) + return 50; #elif defined(__VAES__) -crypto_native_aes_ctr_init_adl (vlib_main_t *vm) -#elif __AVX512F__ -crypto_native_aes_ctr_init_skx (vlib_main_t *vm) -#elif __AVX2__ -crypto_native_aes_ctr_init_hsw (vlib_main_t *vm) + if (clib_cpu_supports_vaes ()) + return 40; +#elif defined(__AVX512F__) + if (clib_cpu_supports_avx512f ()) + return 30; +#elif defined(__AVX2__) + if (clib_cpu_supports_avx2 ()) + return 20; +#elif __AES__ + if (clib_cpu_supports_aes ()) + return 10; #elif __aarch64__ -crypto_native_aes_ctr_init_neon (vlib_main_t *vm) -#else -crypto_native_aes_ctr_init_slm (vlib_main_t *vm) + if (clib_cpu_supports_aarch64_aes ()) + return 10; #endif -{ - crypto_native_main_t *cm = &crypto_native_main; + return -1; +} -#define _(x) \ - vnet_crypto_register_ops_handlers ( \ - vm, cm->crypto_engine_index, VNET_CRYPTO_OP_AES_##x##_CTR_ENC, \ - aes_ops_aes_ctr_##x, aes_ops_aes_ctr_##x##_chained); \ - vnet_crypto_register_ops_handlers ( \ - vm, cm->crypto_engine_index, VNET_CRYPTO_OP_AES_##x##_CTR_DEC, \ - aes_ops_aes_ctr_##x, aes_ops_aes_ctr_##x##_chained); \ - cm->key_fn[VNET_CRYPTO_ALG_AES_##x##_CTR] = aes_ctr_key_exp_##x; - foreach_aes_ctr_handler_type; +#define _(b) \ + CRYPTO_NATIVE_OP_HANDLER (aes_##b##_ctr_enc) = { \ + .op_id = VNET_CRYPTO_OP_AES_##b##_CTR_ENC, \ + .fn = aes_ops_aes_ctr_##b, \ + .cfn = aes_ops_aes_ctr_##b##_chained, \ + .probe = probe, \ + }; \ + \ + CRYPTO_NATIVE_OP_HANDLER (aes_##b##_ctr_dec) = { \ + .op_id = VNET_CRYPTO_OP_AES_##b##_CTR_DEC, \ + .fn = aes_ops_aes_ctr_##b, \ + .cfn = aes_ops_aes_ctr_##b##_chained, \ + .probe = probe, \ + }; \ + CRYPTO_NATIVE_KEY_HANDLER (aes_##b##_ctr) = { \ + .alg_id = VNET_CRYPTO_ALG_AES_##b##_CTR, \ + .key_fn = aes_ctr_key_exp_##b, \ + .probe = probe, \ + }; + +_ (128) _ (192) _ (256) #undef _ - return 0; -} diff --git a/src/plugins/crypto_native/aes_gcm.c b/src/plugins/crypto_native/aes_gcm.c index 6589d411975..220788d4e97 100644 --- a/src/plugins/crypto_native/aes_gcm.c +++ b/src/plugins/crypto_native/aes_gcm.c @@ -118,40 +118,49 @@ aes_gcm_key_exp (vnet_crypto_key_t *key, aes_key_size_t ks) foreach_aes_gcm_handler_type; #undef _ -clib_error_t * +static int +probe () +{ #if defined(__VAES__) && defined(__AVX512F__) -crypto_native_aes_gcm_init_icl (vlib_main_t *vm) + if (clib_cpu_supports_vpclmulqdq () && clib_cpu_supports_vaes () && + clib_cpu_supports_avx512f ()) + return 50; #elif defined(__VAES__) -crypto_native_aes_gcm_init_adl (vlib_main_t *vm) -#elif __AVX512F__ -crypto_native_aes_gcm_init_skx (vlib_main_t *vm) -#elif __AVX2__ -crypto_native_aes_gcm_init_hsw (vlib_main_t *vm) + if (clib_cpu_supports_vpclmulqdq () && clib_cpu_supports_vaes ()) + return 40; +#elif defined(__AVX512F__) + if (clib_cpu_supports_pclmulqdq () && clib_cpu_supports_avx512f ()) + return 30; +#elif defined(__AVX2__) + if (clib_cpu_supports_pclmulqdq () && clib_cpu_supports_avx2 ()) + return 20; +#elif __AES__ + if (clib_cpu_supports_pclmulqdq () && clib_cpu_supports_aes ()) + return 10; #elif __aarch64__ -crypto_native_aes_gcm_init_neon (vlib_main_t *vm) -#else -crypto_native_aes_gcm_init_slm (vlib_main_t *vm) + if (clib_cpu_supports_aarch64_aes ()) + return 10; #endif -{ - crypto_native_main_t *cm = &crypto_native_main; - -#define _(x) \ - vnet_crypto_register_ops_handler (vm, cm->crypto_engine_index, \ - VNET_CRYPTO_OP_AES_##x##_GCM_ENC, \ - aes_ops_enc_aes_gcm_##x); \ - vnet_crypto_register_ops_handler (vm, cm->crypto_engine_index, \ - VNET_CRYPTO_OP_AES_##x##_GCM_DEC, \ - aes_ops_dec_aes_gcm_##x); \ - cm->key_fn[VNET_CRYPTO_ALG_AES_##x##_GCM] = aes_gcm_key_exp_##x; - foreach_aes_gcm_handler_type; -#undef _ - return 0; + return -1; } -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ +#define _(b) \ + CRYPTO_NATIVE_OP_HANDLER (aes_##b##_gcm_enc) = { \ + .op_id = VNET_CRYPTO_OP_AES_##b##_GCM_ENC, \ + .fn = aes_ops_enc_aes_gcm_##b, \ + .probe = probe, \ + }; \ + \ + CRYPTO_NATIVE_OP_HANDLER (aes_##b##_gcm_dec) = { \ + .op_id = VNET_CRYPTO_OP_AES_##b##_GCM_DEC, \ + .fn = aes_ops_dec_aes_gcm_##b, \ + .probe = probe, \ + }; \ + CRYPTO_NATIVE_KEY_HANDLER (aes_##b##_gcm) = { \ + .alg_id = VNET_CRYPTO_ALG_AES_##b##_GCM, \ + .key_fn = aes_gcm_key_exp_##b, \ + .probe = probe, \ + }; + +_ (128) _ (192) _ (256) +#undef _ diff --git a/src/plugins/crypto_native/crypto_native.h b/src/plugins/crypto_native/crypto_native.h index c15b8cbd1da..3d18e8cabd0 100644 --- a/src/plugins/crypto_native/crypto_native.h +++ b/src/plugins/crypto_native/crypto_native.h @@ -19,33 +19,66 @@ #define __crypto_native_h__ typedef void *(crypto_native_key_fn_t) (vnet_crypto_key_t * key); +typedef int (crypto_native_variant_probe_t) (); + +typedef struct crypto_native_op_handler +{ + struct crypto_native_op_handler *next; + vnet_crypto_op_id_t op_id; + vnet_crypto_ops_handler_t *fn; + vnet_crypto_chained_ops_handler_t *cfn; + crypto_native_variant_probe_t *probe; + int priority; +} crypto_native_op_handler_t; + +typedef struct crypto_native_key_handler +{ + struct crypto_native_key_handler *next; + vnet_crypto_alg_t alg_id; + crypto_native_key_fn_t *key_fn; + crypto_native_variant_probe_t *probe; + int priority; +} crypto_native_key_handler_t; typedef struct { u32 crypto_engine_index; crypto_native_key_fn_t *key_fn[VNET_CRYPTO_N_ALGS]; void **key_data; + crypto_native_op_handler_t *op_handlers; + crypto_native_key_handler_t *key_handlers; } crypto_native_main_t; extern crypto_native_main_t crypto_native_main; -#define foreach_crypto_native_march_variant \ - _ (slm) _ (hsw) _ (skx) _ (icl) _ (adl) _ (neon) - -#define _(v) \ - clib_error_t __clib_weak *crypto_native_aes_cbc_init_##v (vlib_main_t *vm); \ - clib_error_t __clib_weak *crypto_native_aes_ctr_init_##v (vlib_main_t *vm); \ - clib_error_t __clib_weak *crypto_native_aes_gcm_init_##v (vlib_main_t *vm); - -foreach_crypto_native_march_variant; -#undef _ +#define CRYPTO_NATIVE_OP_HANDLER(x) \ + static crypto_native_op_handler_t __crypto_native_op_handler_##x; \ + static void __clib_constructor __crypto_native_op_handler_cb_##x (void) \ + { \ + crypto_native_main_t *cm = &crypto_native_main; \ + int priority = __crypto_native_op_handler_##x.probe (); \ + if (priority >= 0) \ + { \ + __crypto_native_op_handler_##x.priority = priority; \ + __crypto_native_op_handler_##x.next = cm->op_handlers; \ + cm->op_handlers = &__crypto_native_op_handler_##x; \ + } \ + } \ + static crypto_native_op_handler_t __crypto_native_op_handler_##x +#define CRYPTO_NATIVE_KEY_HANDLER(x) \ + static crypto_native_key_handler_t __crypto_native_key_handler_##x; \ + static void __clib_constructor __crypto_native_key_handler_cb_##x (void) \ + { \ + crypto_native_main_t *cm = &crypto_native_main; \ + int priority = __crypto_native_key_handler_##x.probe (); \ + if (priority >= 0) \ + { \ + __crypto_native_key_handler_##x.priority = priority; \ + __crypto_native_key_handler_##x.next = cm->key_handlers; \ + cm->key_handlers = &__crypto_native_key_handler_##x; \ + } \ + } \ + static crypto_native_key_handler_t __crypto_native_key_handler_##x #endif /* __crypto_native_h__ */ -/* - * fd.io coding-style-patch-verification: ON - * - * Local Variables: - * eval: (c-set-style "gnu") - * End: - */ diff --git a/src/plugins/crypto_native/main.c b/src/plugins/crypto_native/main.c index 8a59be319b9..2bc0d98f196 100644 --- a/src/plugins/crypto_native/main.c +++ b/src/plugins/crypto_native/main.c @@ -63,95 +63,52 @@ clib_error_t * crypto_native_init (vlib_main_t * vm) { crypto_native_main_t *cm = &crypto_native_main; - clib_error_t *error = 0; - if (clib_cpu_supports_x86_aes () == 0 && - clib_cpu_supports_aarch64_aes () == 0) + if (cm->op_handlers == 0) return 0; cm->crypto_engine_index = vnet_crypto_register_engine (vm, "native", 100, "Native ISA Optimized Crypto"); - if (0); -#if __x86_64__ - else if (crypto_native_aes_cbc_init_icl && clib_cpu_supports_vaes () && - clib_cpu_supports_avx512f ()) - error = crypto_native_aes_cbc_init_icl (vm); - else if (crypto_native_aes_cbc_init_adl && clib_cpu_supports_vaes ()) - error = crypto_native_aes_cbc_init_adl (vm); - else if (crypto_native_aes_cbc_init_skx && clib_cpu_supports_avx512f ()) - error = crypto_native_aes_cbc_init_skx (vm); - else if (crypto_native_aes_cbc_init_hsw && clib_cpu_supports_avx2 ()) - error = crypto_native_aes_cbc_init_hsw (vm); - else if (crypto_native_aes_cbc_init_slm) - error = crypto_native_aes_cbc_init_slm (vm); -#endif -#if __aarch64__ - else if (crypto_native_aes_cbc_init_neon) - error = crypto_native_aes_cbc_init_neon (vm); -#endif - else - error = clib_error_return (0, "No AES CBC implemenation available"); - - if (error) - return error; - - if (0) - ; -#if __x86_64__ - else if (crypto_native_aes_ctr_init_icl && clib_cpu_supports_vaes () && - clib_cpu_supports_avx512f ()) - error = crypto_native_aes_ctr_init_icl (vm); - else if (crypto_native_aes_ctr_init_adl && clib_cpu_supports_vaes ()) - error = crypto_native_aes_ctr_init_adl (vm); - else if (crypto_native_aes_ctr_init_skx && clib_cpu_supports_avx512f ()) - error = crypto_native_aes_ctr_init_skx (vm); - else if (crypto_native_aes_ctr_init_hsw && clib_cpu_supports_avx2 ()) - error = crypto_native_aes_ctr_init_hsw (vm); - else if (crypto_native_aes_ctr_init_slm) - error = crypto_native_aes_ctr_init_slm (vm); -#endif -#if __aarch64__ - else if (crypto_native_aes_ctr_init_neon) - error = crypto_native_aes_ctr_init_neon (vm); -#endif - else - error = clib_error_return (0, "No AES CTR implemenation available"); - - if (error) - return error; - -#if __x86_64__ - if (clib_cpu_supports_pclmulqdq ()) + crypto_native_op_handler_t *oh = cm->op_handlers; + crypto_native_key_handler_t *kh = cm->key_handlers; + crypto_native_op_handler_t **best_by_op_id = 0; + crypto_native_key_handler_t **best_by_alg_id = 0; + + while (oh) { - if (crypto_native_aes_gcm_init_icl && clib_cpu_supports_vaes () && - clib_cpu_supports_avx512f ()) - error = crypto_native_aes_gcm_init_icl (vm); - else if (crypto_native_aes_gcm_init_adl && clib_cpu_supports_vaes ()) - error = crypto_native_aes_gcm_init_adl (vm); - else if (crypto_native_aes_gcm_init_skx && clib_cpu_supports_avx512f ()) - error = crypto_native_aes_gcm_init_skx (vm); - else if (crypto_native_aes_gcm_init_hsw && clib_cpu_supports_avx2 ()) - error = crypto_native_aes_gcm_init_hsw (vm); - else if (crypto_native_aes_gcm_init_slm) - error = crypto_native_aes_gcm_init_slm (vm); - else - error = clib_error_return (0, "No AES GCM implemenation available"); - - if (error) - return error; + vec_validate (best_by_op_id, oh->op_id); + + if (best_by_op_id[oh->op_id] == 0 || + best_by_op_id[oh->op_id]->priority < oh->priority) + best_by_op_id[oh->op_id] = oh; + + oh = oh->next; } -#endif -#if __aarch64__ - if (crypto_native_aes_gcm_init_neon) - error = crypto_native_aes_gcm_init_neon (vm); - else - error = clib_error_return (0, "No AES GCM implemenation available"); - - if (error) - return error; -#endif + + while (kh) + { + vec_validate (best_by_alg_id, kh->alg_id); + + if (best_by_alg_id[kh->alg_id] == 0 || + best_by_alg_id[kh->alg_id]->priority < kh->priority) + best_by_alg_id[kh->alg_id] = kh; + + kh = kh->next; + } + + vec_foreach_pointer (oh, best_by_op_id) + if (oh) + vnet_crypto_register_ops_handlers (vm, cm->crypto_engine_index, + oh->op_id, oh->fn, oh->cfn); + + vec_foreach_pointer (kh, best_by_alg_id) + if (kh) + cm->key_fn[kh->alg_id] = kh->key_fn; + + vec_free (best_by_op_id); + vec_free (best_by_alg_id); vnet_crypto_register_key_handler (vm, cm->crypto_engine_index, crypto_native_key_handler); diff --git a/src/plugins/crypto_native/sha2.c b/src/plugins/crypto_native/sha2.c new file mode 100644 index 00000000000..459ce6d8e79 --- /dev/null +++ b/src/plugins/crypto_native/sha2.c @@ -0,0 +1,186 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright(c) 2024 Cisco Systems, Inc. + */ + +#include <vlib/vlib.h> +#include <vnet/plugin/plugin.h> +#include <vnet/crypto/crypto.h> +#include <crypto_native/crypto_native.h> +#include <vppinfra/crypto/sha2.h> + +static_always_inline u32 +crypto_native_ops_hash_sha2 (vlib_main_t *vm, vnet_crypto_op_t *ops[], + u32 n_ops, vnet_crypto_op_chunk_t *chunks, + clib_sha2_type_t type, int maybe_chained) +{ + vnet_crypto_op_t *op = ops[0]; + clib_sha2_ctx_t ctx; + u32 n_left = n_ops; + +next: + if (op->flags & VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS) + { + vnet_crypto_op_chunk_t *chp = chunks + op->chunk_index; + clib_sha2_init (&ctx, type); + for (int j = 0; j < op->n_chunks; j++, chp++) + clib_sha2_update (&ctx, chp->src, chp->len); + clib_sha2_final (&ctx, op->digest); + } + else + clib_sha2 (type, op->src, op->len, op->digest); + + op->status = VNET_CRYPTO_OP_STATUS_COMPLETED; + + if (--n_left) + { + op += 1; + goto next; + } + + return n_ops; +} + +static_always_inline u32 +crypto_native_ops_hmac_sha2 (vlib_main_t *vm, vnet_crypto_op_t *ops[], + u32 n_ops, vnet_crypto_op_chunk_t *chunks, + clib_sha2_type_t type) +{ + crypto_native_main_t *cm = &crypto_native_main; + vnet_crypto_op_t *op = ops[0]; + u32 n_left = n_ops; + clib_sha2_hmac_ctx_t ctx; + u8 buffer[64]; + u32 sz, n_fail = 0; + + for (; n_left; n_left--, op++) + { + clib_sha2_hmac_init ( + &ctx, type, (clib_sha2_hmac_key_data_t *) cm->key_data[op->key_index]); + if (op->flags & VNET_CRYPTO_OP_FLAG_CHAINED_BUFFERS) + { + vnet_crypto_op_chunk_t *chp = chunks + op->chunk_index; + for (int j = 0; j < op->n_chunks; j++, chp++) + clib_sha2_hmac_update (&ctx, chp->src, chp->len); + } + else + clib_sha2_hmac_update (&ctx, op->src, op->len); + + clib_sha2_hmac_final (&ctx, buffer); + + if (op->digest_len) + { + sz = op->digest_len; + if (op->flags & VNET_CRYPTO_OP_FLAG_HMAC_CHECK) + { + if ((memcmp (op->digest, buffer, sz))) + { + n_fail++; + op->status = VNET_CRYPTO_OP_STATUS_FAIL_BAD_HMAC; + continue; + } + } + else + clib_memcpy_fast (op->digest, buffer, sz); + } + else + { + sz = clib_sha2_variants[type].digest_size; + if (op->flags & VNET_CRYPTO_OP_FLAG_HMAC_CHECK) + { + if ((memcmp (op->digest, buffer, sz))) + { + n_fail++; + op->status = VNET_CRYPTO_OP_STATUS_FAIL_BAD_HMAC; + continue; + } + } + else + clib_memcpy_fast (op->digest, buffer, sz); + } + + op->status = VNET_CRYPTO_OP_STATUS_COMPLETED; + } + + return n_ops - n_fail; +} + +static void * +sha2_key_add (vnet_crypto_key_t *key, clib_sha2_type_t type) +{ + clib_sha2_hmac_key_data_t *kd; + + kd = clib_mem_alloc_aligned (sizeof (*kd), CLIB_CACHE_LINE_BYTES); + clib_sha2_hmac_key_data (type, key->data, vec_len (key->data), kd); + + return kd; +} + +static int +probe () +{ +#if defined(__SHA__) && defined(__x86_64__) + if (clib_cpu_supports_sha ()) + return 50; +#elif defined(__ARM_FEATURE_SHA2) + if (clib_cpu_supports_sha2 ()) + return 10; +#endif + return -1; +} + +#define _(b) \ + static u32 crypto_native_ops_hash_sha##b ( \ + vlib_main_t *vm, vnet_crypto_op_t *ops[], u32 n_ops) \ + { \ + return crypto_native_ops_hash_sha2 (vm, ops, n_ops, 0, CLIB_SHA2_##b, 0); \ + } \ + \ + static u32 crypto_native_ops_chained_hash_sha##b ( \ + vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, \ + u32 n_ops) \ + { \ + return crypto_native_ops_hash_sha2 (vm, ops, n_ops, chunks, \ + CLIB_SHA2_##b, 1); \ + } \ + \ + static u32 crypto_native_ops_hmac_sha##b ( \ + vlib_main_t *vm, vnet_crypto_op_t *ops[], u32 n_ops) \ + { \ + return crypto_native_ops_hmac_sha2 (vm, ops, n_ops, 0, CLIB_SHA2_##b); \ + } \ + \ + static u32 crypto_native_ops_chained_hmac_sha##b ( \ + vlib_main_t *vm, vnet_crypto_op_t *ops[], vnet_crypto_op_chunk_t *chunks, \ + u32 n_ops) \ + { \ + return crypto_native_ops_hmac_sha2 (vm, ops, n_ops, chunks, \ + CLIB_SHA2_##b); \ + } \ + \ + static void *sha2_##b##_key_add (vnet_crypto_key_t *k) \ + { \ + return sha2_key_add (k, CLIB_SHA2_##b); \ + } \ + \ + CRYPTO_NATIVE_OP_HANDLER (crypto_native_hash_sha##b) = { \ + .op_id = VNET_CRYPTO_OP_SHA##b##_HASH, \ + .fn = crypto_native_ops_hash_sha##b, \ + .cfn = crypto_native_ops_chained_hash_sha##b, \ + .probe = probe, \ + }; \ + CRYPTO_NATIVE_OP_HANDLER (crypto_native_hmac_sha##b) = { \ + .op_id = VNET_CRYPTO_OP_SHA##b##_HMAC, \ + .fn = crypto_native_ops_hmac_sha##b, \ + .cfn = crypto_native_ops_chained_hmac_sha##b, \ + .probe = probe, \ + }; \ + CRYPTO_NATIVE_KEY_HANDLER (crypto_native_hmac_sha##b) = { \ + .alg_id = VNET_CRYPTO_ALG_HMAC_SHA##b, \ + .key_fn = sha2_##b##_key_add, \ + .probe = probe, \ + }; + +_ (224) +_ (256) + +#undef _ diff --git a/src/plugins/crypto_sw_scheduler/main.c b/src/plugins/crypto_sw_scheduler/main.c index b32c8ae0594..73a158e86b2 100644 --- a/src/plugins/crypto_sw_scheduler/main.c +++ b/src/plugins/crypto_sw_scheduler/main.c @@ -455,7 +455,9 @@ crypto_sw_scheduler_dequeue (vlib_main_t *vm, u32 *nb_elts_processed, crypto_sw_scheduler_queue_t *current_queue = 0; u32 tail, head; u8 found = 0; + u8 recheck_queues = 1; +run_next_queues: /* get a pending frame to process */ if (ptd->self_crypto_enabled) { @@ -565,6 +567,11 @@ crypto_sw_scheduler_dequeue (vlib_main_t *vm, u32 *nb_elts_processed, return f; } + if (!found && recheck_queues) + { + recheck_queues = 0; + goto run_next_queues; + } return 0; } diff --git a/src/plugins/dev_iavf/port.c b/src/plugins/dev_iavf/port.c index 982436d9b45..90e81e960c4 100644 --- a/src/plugins/dev_iavf/port.c +++ b/src/plugins/dev_iavf/port.c @@ -42,29 +42,35 @@ iavf_port_vlan_strip_disable (vlib_main_t *vm, vnet_dev_port_t *port) vnet_dev_t *dev = port->dev; iavf_port_t *ap = vnet_dev_get_port_data (port); virtchnl_vlan_caps_t vc; - vnet_dev_rv_t rv; + vnet_dev_rv_t rv = VNET_DEV_ERR_NOT_SUPPORTED; u32 outer, inner; const u32 mask = VIRTCHNL_VLAN_ETHERTYPE_8100; - if ((ap->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) == 0) - return iavf_vc_op_disable_vlan_stripping (vm, dev); + if (ap->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN_V2) + { + if ((rv = iavf_vc_op_get_offload_vlan_v2_caps (vm, dev, &vc))) + return rv; - if ((rv = iavf_vc_op_get_offload_vlan_v2_caps (vm, dev, &vc))) - return rv; + outer = vc.offloads.stripping_support.outer; + inner = vc.offloads.stripping_support.inner; - outer = vc.offloads.stripping_support.outer; - inner = vc.offloads.stripping_support.inner; + outer = outer & VIRTCHNL_VLAN_TOGGLE ? outer & mask : 0; + inner = inner & VIRTCHNL_VLAN_TOGGLE ? inner & mask : 0; - outer = outer & VIRTCHNL_VLAN_TOGGLE ? outer & mask : 0; - inner = inner & VIRTCHNL_VLAN_TOGGLE ? inner & mask : 0; + virtchnl_vlan_setting_t vs = { + .vport_id = ap->vsi_id, + .outer_ethertype_setting = outer, + .inner_ethertype_setting = inner, + }; - virtchnl_vlan_setting_t vs = { - .vport_id = ap->vsi_id, - .outer_ethertype_setting = outer, - .inner_ethertype_setting = inner, - }; + if ((rv = iavf_vc_op_disable_vlan_stripping_v2 (vm, dev, &vs))) + return rv; + } - return iavf_vc_op_disable_vlan_stripping_v2 (vm, dev, &vs); + if (ap->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_VLAN) + return iavf_vc_op_disable_vlan_stripping (vm, dev); + + return rv; } vnet_dev_rv_t @@ -275,7 +281,12 @@ iavf_port_init (vlib_main_t *vm, vnet_dev_port_t *port) u64_bit_set (&ap->intr_mode_per_rxq_bitmap, q->queue_id, 1); if ((rv = iavf_port_vlan_strip_disable (vm, port))) - return rv; + { + if (rv == VNET_DEV_ERR_NOT_SUPPORTED) + log_warn (port->dev, "device doesn't support vlan stripping"); + else + return rv; + } if ((rv = iavf_port_init_rss (vm, port))) return rv; diff --git a/src/plugins/dev_octeon/init.c b/src/plugins/dev_octeon/init.c index 47be8a8f9a4..97a11e0d0d7 100644 --- a/src/plugins/dev_octeon/init.c +++ b/src/plugins/dev_octeon/init.c @@ -51,7 +51,9 @@ static struct } _ (0xa063, RVU_PF, "Marvell Octeon Resource Virtualization Unit PF"), - _ (0xa0f8, RVU_VF, "Marvell Octeon Resource Virtualization Unit VF"), + _ (0xa064, RVU_VF, "Marvell Octeon Resource Virtualization Unit VF"), + _ (0xa0f8, LBK_VF, "Marvell Octeon Loopback Unit VF"), + _ (0xa0f7, SDP_VF, "Marvell Octeon System DPI Packet Interface Unit VF"), _ (0xa0f3, CPT_VF, "Marvell Octeon Cryptographic Accelerator Unit VF"), #undef _ }; @@ -113,7 +115,7 @@ oct_init_nix (vlib_main_t *vm, vnet_dev_t *dev) if ((rrv = roc_nix_dev_init (cd->nix))) return cnx_return_roc_err (dev, rrv, "roc_nix_dev_init"); - if (roc_nix_npc_mac_addr_get (cd->nix, mac_addr)) + if ((rrv = roc_nix_npc_mac_addr_get (cd->nix, mac_addr))) return cnx_return_roc_err (dev, rrv, "roc_nix_npc_mac_addr_get"); vnet_dev_port_add_args_t port_add_args = { @@ -239,12 +241,19 @@ oct_init (vlib_main_t *vm, vnet_dev_t *dev) strncpy ((char *) cd->plt_pci_dev.name, dev->device_id, sizeof (cd->plt_pci_dev.name) - 1); - if (cd->type == OCT_DEVICE_TYPE_RVU_PF || cd->type == OCT_DEVICE_TYPE_RVU_VF) - return oct_init_nix (vm, dev); - else if (cd->type == OCT_DEVICE_TYPE_CPT_VF) - return oct_init_cpt (vm, dev); - else - return VNET_DEV_ERR_UNSUPPORTED_DEVICE; + switch (cd->type) + { + case OCT_DEVICE_TYPE_RVU_PF: + case OCT_DEVICE_TYPE_RVU_VF: + case OCT_DEVICE_TYPE_SDP_VF: + return oct_init_nix (vm, dev); + + case OCT_DEVICE_TYPE_CPT_VF: + return oct_init_cpt (vm, dev); + + default: + return VNET_DEV_ERR_UNSUPPORTED_DEVICE; + } return 0; } diff --git a/src/plugins/dev_octeon/octeon.h b/src/plugins/dev_octeon/octeon.h index fd8a92c7b3d..e43cde0a35f 100644 --- a/src/plugins/dev_octeon/octeon.h +++ b/src/plugins/dev_octeon/octeon.h @@ -15,11 +15,15 @@ #include <base/roc_api.h> #include <dev_octeon/hw_defs.h> +#define OCT_BATCH_ALLOC_IOVA0_MASK 0xFFFFFFFFFFFFFF80 + typedef enum { OCT_DEVICE_TYPE_UNKNOWN = 0, OCT_DEVICE_TYPE_RVU_PF, OCT_DEVICE_TYPE_RVU_VF, + OCT_DEVICE_TYPE_LBK_VF, + OCT_DEVICE_TYPE_SDP_VF, OCT_DEVICE_TYPE_CPT_VF, } __clib_packed oct_device_type_t; @@ -72,13 +76,15 @@ typedef struct typedef struct { CLIB_ALIGN_MARK (cl, 128); - union - { - struct npa_batch_alloc_status_s status; - u64 iova[16]; - }; + u64 iova[16]; } oct_npa_batch_alloc_cl128_t; +typedef union +{ + struct npa_batch_alloc_status_s status; + u64 as_u64; +} oct_npa_batch_alloc_status_t; + STATIC_ASSERT_SIZEOF (oct_npa_batch_alloc_cl128_t, 128); typedef struct @@ -157,7 +163,8 @@ vnet_dev_rv_t oct_flow_query (vlib_main_t *, vnet_dev_port_t *, u32, uword, _ (AURA_BATCH_ALLOC_ISSUE_FAIL, aura_batch_alloc_issue_fail, ERROR, \ "aura batch alloc issue failed") \ _ (AURA_BATCH_ALLOC_NOT_READY, aura_batch_alloc_not_ready, ERROR, \ - "aura batch alloc not ready") + "aura batch alloc not ready") \ + _ (MTU_EXCEEDED, mtu_exceeded, ERROR, "mtu exceeded") typedef enum { diff --git a/src/plugins/dev_octeon/port.c b/src/plugins/dev_octeon/port.c index 00ad8b9c477..98a4c28b37d 100644 --- a/src/plugins/dev_octeon/port.c +++ b/src/plugins/dev_octeon/port.c @@ -284,8 +284,11 @@ oct_txq_stop (vlib_main_t *vm, vnet_dev_tx_queue_t *txq) for (n = ctq->ba_num_cl, cl = ctq->ba_buffer + ctq->ba_first_cl; n; cl++, n--) { - if (cl->status.ccode != 0) - for (u32 i = 0; i < cl->status.count; i++) + oct_npa_batch_alloc_status_t st; + + st.as_u64 = __atomic_load_n (cl->iova, __ATOMIC_ACQUIRE); + if (st.status.ccode != ALLOC_CCODE_INVAL) + for (u32 i = 0; i < st.status.count; i++) { vlib_buffer_t *b = (vlib_buffer_t *) (cl->iova[i] + off); vlib_buffer_free_one (vm, vlib_get_buffer_index (vm, b)); @@ -376,6 +379,82 @@ oct_port_stop (vlib_main_t *vm, vnet_dev_port_t *port) } vnet_dev_rv_t +oct_validate_config_promisc_mode (vnet_dev_port_t *port, int enable) +{ + vnet_dev_t *dev = port->dev; + oct_device_t *cd = vnet_dev_get_data (dev); + struct roc_nix *nix = cd->nix; + + if (roc_nix_is_vf_or_sdp (nix)) + return VNET_DEV_ERR_UNSUPPORTED_DEVICE; + + return VNET_DEV_OK; +} + +vnet_dev_rv_t +oct_op_config_promisc_mode (vlib_main_t *vm, vnet_dev_port_t *port, int enable) +{ + vnet_dev_t *dev = port->dev; + oct_device_t *cd = vnet_dev_get_data (dev); + struct roc_nix *nix = cd->nix; + int rv; + + rv = roc_nix_npc_promisc_ena_dis (nix, enable); + if (rv) + { + return oct_roc_err (dev, rv, "roc_nix_npc_promisc_ena_dis failed"); + } + + rv = roc_nix_mac_promisc_mode_enable (nix, enable); + if (rv) + { + return oct_roc_err (dev, rv, + "roc_nix_mac_promisc_mode_enable(%s) failed", + enable ? "true" : "false"); + } + + return VNET_DEV_OK; +} + +static vnet_dev_rv_t +oct_port_add_del_eth_addr (vlib_main_t *vm, vnet_dev_port_t *port, + vnet_dev_hw_addr_t *addr, int is_add, + int is_primary) +{ + vnet_dev_t *dev = port->dev; + oct_device_t *cd = vnet_dev_get_data (dev); + struct roc_nix *nix = cd->nix; + vnet_dev_rv_t rv = VNET_DEV_OK; + + i32 rrv; + + if (is_primary) + { + if (is_add) + { + /* Update mac address at NPC */ + rrv = roc_nix_npc_mac_addr_set (nix, (u8 *) addr); + if (rrv) + rv = oct_roc_err (dev, rrv, "roc_nix_npc_mac_addr_set() failed"); + + /* Update mac address at CGX for PFs only */ + if (!roc_nix_is_vf_or_sdp (nix)) + { + rrv = roc_nix_mac_addr_set (nix, (u8 *) addr); + if (rrv) + { + /* Rollback to previous mac address */ + roc_nix_npc_mac_addr_set (nix, + (u8 *) &port->primary_hw_addr); + rv = oct_roc_err (dev, rrv, "roc_nix_mac_addr_set() failed"); + } + } + } + } + return rv; +} + +vnet_dev_rv_t oct_port_cfg_change_validate (vlib_main_t *vm, vnet_dev_port_t *port, vnet_dev_port_cfg_change_req_t *req) { @@ -389,6 +468,8 @@ oct_port_cfg_change_validate (vlib_main_t *vm, vnet_dev_port_t *port, break; case VNET_DEV_PORT_CFG_PROMISC_MODE: + rv = oct_validate_config_promisc_mode (port, req->promisc); + break; case VNET_DEV_PORT_CFG_CHANGE_PRIMARY_HW_ADDR: case VNET_DEV_PORT_CFG_ADD_SECONDARY_HW_ADDR: case VNET_DEV_PORT_CFG_REMOVE_SECONDARY_HW_ADDR: @@ -418,9 +499,13 @@ oct_port_cfg_change (vlib_main_t *vm, vnet_dev_port_t *port, switch (req->type) { case VNET_DEV_PORT_CFG_PROMISC_MODE: + rv = oct_op_config_promisc_mode (vm, port, req->promisc); break; case VNET_DEV_PORT_CFG_CHANGE_PRIMARY_HW_ADDR: + rv = oct_port_add_del_eth_addr (vm, port, &req->addr, + /* is_add */ 1, + /* is_primary */ 1); break; case VNET_DEV_PORT_CFG_ADD_SECONDARY_HW_ADDR: diff --git a/src/plugins/dev_octeon/queue.c b/src/plugins/dev_octeon/queue.c index 9378fc3b7c7..d6ae794fb8d 100644 --- a/src/plugins/dev_octeon/queue.c +++ b/src/plugins/dev_octeon/queue.c @@ -57,12 +57,20 @@ oct_tx_queue_alloc (vlib_main_t *vm, vnet_dev_tx_queue_t *txq) oct_txq_t *ctq = vnet_dev_get_tx_queue_data (txq); vnet_dev_port_t *port = txq->port; vnet_dev_t *dev = port->dev; + u32 sz = sizeof (void *) * ROC_CN10K_NPA_BATCH_ALLOC_MAX_PTRS; + vnet_dev_rv_t rv; log_debug (dev, "tx_queue_alloc: queue %u alocated", txq->queue_id); - return vnet_dev_dma_mem_alloc ( - vm, dev, sizeof (void *) * ROC_CN10K_NPA_BATCH_ALLOC_MAX_PTRS, 128, - (void **) &ctq->ba_buffer); + rv = vnet_dev_dma_mem_alloc (vm, dev, sz, 128, (void **) &ctq->ba_buffer); + + if (rv != VNET_DEV_OK) + return rv; + + clib_memset_u64 (ctq->ba_buffer, OCT_BATCH_ALLOC_IOVA0_MASK, + ROC_CN10K_NPA_BATCH_ALLOC_MAX_PTRS); + + return rv; } void diff --git a/src/plugins/dev_octeon/rx_node.c b/src/plugins/dev_octeon/rx_node.c index 5f7e5a8469b..997f1356199 100644 --- a/src/plugins/dev_octeon/rx_node.c +++ b/src/plugins/dev_octeon/rx_node.c @@ -217,7 +217,8 @@ oct_rxq_refill (vlib_main_t *vm, vnet_dev_rx_queue_t *rxq, u16 n_refill) while (n_lines >= batch_max_lines) { - n_alloc = vlib_buffer_alloc (vm, buffer_indices, batch_max_bufs); + n_alloc = + vlib_buffer_alloc_from_pool (vm, buffer_indices, batch_max_bufs, bpi); if (PREDICT_FALSE (n_alloc < batch_max_bufs)) goto alloc_fail; oct_rxq_refill_batch (vm, lmt_id, addr, lines, buffer_indices, w0, @@ -313,7 +314,7 @@ oct_rx_node_inline (vlib_main_t *vm, vlib_node_runtime_t *node, n_desc = (status.tail - head) & cq_mask; if (n_desc == 0) - return 0; + goto refill; vlib_get_new_next_frame (vm, node, ctx->next_index, ctx->to_next, ctx->n_left_to_next); @@ -365,14 +366,15 @@ oct_rx_node_inline (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_put_next_frame (vm, node, ctx->next_index, ctx->n_left_to_next); - n_enq = crq->n_enq - ctx->n_segs; - n_enq += oct_rxq_refill (vm, rxq, rxq->size - n_enq); - crq->n_enq = n_enq; - vlib_increment_combined_counter ( vnm->interface_main.combined_sw_if_counters + VNET_INTERFACE_COUNTER_RX, thr_idx, ctx->hw_if_index, ctx->n_rx_pkts, ctx->n_rx_bytes); +refill: + n_enq = crq->n_enq - ctx->n_segs; + n_enq += oct_rxq_refill (vm, rxq, rxq->size - n_enq); + crq->n_enq = n_enq; + return ctx->n_rx_pkts; } diff --git a/src/plugins/dev_octeon/tx_node.c b/src/plugins/dev_octeon/tx_node.c index 5deaa82a0c1..a2e4b07de8a 100644 --- a/src/plugins/dev_octeon/tx_node.c +++ b/src/plugins/dev_octeon/tx_node.c @@ -22,8 +22,11 @@ typedef struct u32 n_tx_bytes; u32 n_drop; vlib_buffer_t *drop[VLIB_FRAME_SIZE]; + u32 n_exd_mtu; + vlib_buffer_t *exd_mtu[VLIB_FRAME_SIZE]; u32 batch_alloc_not_ready; u32 batch_alloc_issue_fail; + int max_pkt_len; u16 lmt_id; u64 lmt_ioaddr; lmt_line_t *lmt_lines; @@ -46,9 +49,12 @@ oct_batch_free (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq) for (cl = ctq->ba_buffer + ctq->ba_first_cl; num_cl > 0; num_cl--, cl++) { - u8 count; - if (cl->status.ccode == ALLOC_CCODE_INVAL) + oct_npa_batch_alloc_status_t st; + + if ((st.as_u64 = __atomic_load_n (cl->iova, __ATOMIC_RELAXED)) == + OCT_BATCH_ALLOC_IOVA0_MASK + ALLOC_CCODE_INVAL) { + cl_not_ready: ctx->batch_alloc_not_ready++; n_freed = bi - (u32 *) ctq->ba_buffer; if (n_freed > 0) @@ -63,11 +69,15 @@ oct_batch_free (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq) return 0; } - count = cl->status.count; + if (st.status.count > 8 && + __atomic_load_n (cl->iova + 8, __ATOMIC_RELAXED) == + OCT_BATCH_ALLOC_IOVA0_MASK) + goto cl_not_ready; + #if (CLIB_DEBUG > 0) - cl->status.count = cl->status.ccode = 0; + cl->iova[0] &= OCT_BATCH_ALLOC_IOVA0_MASK; #endif - if (PREDICT_TRUE (count == 16)) + if (PREDICT_TRUE (st.status.count == 16)) { /* optimize for likely case where cacheline is full */ vlib_get_buffer_indices_with_offset (vm, (void **) cl, bi, 16, @@ -76,9 +86,9 @@ oct_batch_free (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq) } else { - vlib_get_buffer_indices_with_offset (vm, (void **) cl, bi, count, - off); - bi += count; + vlib_get_buffer_indices_with_offset (vm, (void **) cl, bi, + st.status.count, off); + bi += st.status.count; } } @@ -89,7 +99,8 @@ oct_batch_free (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq) /* clear status bits in each cacheline */ n = cl - ctq->ba_buffer; for (u32 i = 0; i < n; i++) - ctq->ba_buffer[i].iova[0] = 0; + ctq->ba_buffer[i].iova[0] = ctq->ba_buffer[i].iova[8] = + OCT_BATCH_ALLOC_IOVA0_MASK; ctq->ba_num_cl = ctq->ba_first_cl = 0; } @@ -125,7 +136,8 @@ oct_batch_free (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq) static_always_inline u8 oct_tx_enq1 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vlib_buffer_t *b, - lmt_line_t *line, u32 flags, int simple, int trace) + lmt_line_t *line, u32 flags, int simple, int trace, u32 *n, + u8 *dpl) { u8 n_dwords = 2; u32 total_len = 0; @@ -140,6 +152,12 @@ oct_tx_enq1 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vlib_buffer_t *b, }, }; + if (PREDICT_FALSE (vlib_buffer_length_in_chain (vm, b) > ctx->max_pkt_len)) + { + ctx->exd_mtu[ctx->n_exd_mtu++] = b; + return 0; + } + if (!simple && flags & VLIB_BUFFER_NEXT_PRESENT) { u8 n_tail_segs = 0; @@ -151,7 +169,7 @@ oct_tx_enq1 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vlib_buffer_t *b, tail_segs[n_tail_segs++] = t; if (n_tail_segs > 5) { - ctx->drop[ctx->n_drop++] = t; + ctx->drop[ctx->n_drop++] = b; return 0; } } @@ -223,6 +241,9 @@ oct_tx_enq1 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vlib_buffer_t *b, for (u32 i = 0; i < n_dwords; i++) line->dwords[i] = d.as_u128[i]; + *dpl = n_dwords; + *n = *n + 1; + return n_dwords; } @@ -232,7 +253,7 @@ oct_tx_enq16 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq, { u8 dwords_per_line[16], *dpl = dwords_per_line; u64 lmt_arg, ioaddr, n_lines; - u32 n_left, or_flags_16 = 0; + u32 n_left, or_flags_16 = 0, n = 0; const u32 not_simple_flags = VLIB_BUFFER_NEXT_PRESENT | VNET_BUFFER_F_OFFLOAD; lmt_line_t *l = ctx->lmt_lines; @@ -240,7 +261,7 @@ oct_tx_enq16 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq, /* Data Store Memory Barrier - outer shareable domain */ asm volatile("dmb oshst" ::: "memory"); - for (n_left = n_pkts; n_left >= 8; n_left -= 8, b += 8, l += 8) + for (n_left = n_pkts; n_left >= 8; n_left -= 8, b += 8) { u32 f0, f1, f2, f3, f4, f5, f6, f7, or_f = 0; vlib_prefetch_buffer_header (b[8], LOAD); @@ -261,48 +282,54 @@ oct_tx_enq16 (vlib_main_t *vm, oct_tx_ctx_t *ctx, vnet_dev_tx_queue_t *txq, if ((or_f & not_simple_flags) == 0) { int simple = 1; - oct_tx_enq1 (vm, ctx, b[0], l, f0, simple, trace); - oct_tx_enq1 (vm, ctx, b[1], l + 1, f1, simple, trace); + oct_tx_enq1 (vm, ctx, b[0], l, f0, simple, trace, &n, &dpl[n]); + oct_tx_enq1 (vm, ctx, b[1], l + n, f1, simple, trace, &n, &dpl[n]); vlib_prefetch_buffer_header (b[13], LOAD); - oct_tx_enq1 (vm, ctx, b[2], l + 2, f2, simple, trace); - oct_tx_enq1 (vm, ctx, b[3], l + 3, f3, simple, trace); + oct_tx_enq1 (vm, ctx, b[2], l + n, f2, simple, trace, &n, &dpl[n]); + oct_tx_enq1 (vm, ctx, b[3], l + n, f3, simple, trace, &n, &dpl[n]); vlib_prefetch_buffer_header (b[14], LOAD); - oct_tx_enq1 (vm, ctx, b[4], l + 4, f4, simple, trace); - oct_tx_enq1 (vm, ctx, b[5], l + 5, f5, simple, trace); + oct_tx_enq1 (vm, ctx, b[4], l + n, f4, simple, trace, &n, &dpl[n]); + oct_tx_enq1 (vm, ctx, b[5], l + n, f5, simple, trace, &n, &dpl[n]); vlib_prefetch_buffer_header (b[15], LOAD); - oct_tx_enq1 (vm, ctx, b[6], l + 6, f6, simple, trace); - oct_tx_enq1 (vm, ctx, b[7], l + 7, f7, simple, trace); - dpl[0] = dpl[1] = dpl[2] = dpl[3] = 2; - dpl[4] = dpl[5] = dpl[6] = dpl[7] = 2; + oct_tx_enq1 (vm, ctx, b[6], l + n, f6, simple, trace, &n, &dpl[n]); + oct_tx_enq1 (vm, ctx, b[7], l + n, f7, simple, trace, &n, &dpl[n]); } else { int simple = 0; - dpl[0] = oct_tx_enq1 (vm, ctx, b[0], l, f0, simple, trace); - dpl[1] = oct_tx_enq1 (vm, ctx, b[1], l + 1, f1, simple, trace); + oct_tx_enq1 (vm, ctx, b[0], l, f0, simple, trace, &n, &dpl[n]); + oct_tx_enq1 (vm, ctx, b[1], l + n, f1, simple, trace, &n, &dpl[n]); vlib_prefetch_buffer_header (b[13], LOAD); - dpl[2] = oct_tx_enq1 (vm, ctx, b[2], l + 2, f2, simple, trace); - dpl[3] = oct_tx_enq1 (vm, ctx, b[3], l + 3, f3, simple, trace); + oct_tx_enq1 (vm, ctx, b[2], l + n, f2, simple, trace, &n, &dpl[n]); + oct_tx_enq1 (vm, ctx, b[3], l + n, f3, simple, trace, &n, &dpl[n]); vlib_prefetch_buffer_header (b[14], LOAD); - dpl[4] = oct_tx_enq1 (vm, ctx, b[4], l + 4, f4, simple, trace); - dpl[5] = oct_tx_enq1 (vm, ctx, b[5], l + 5, f5, simple, trace); + oct_tx_enq1 (vm, ctx, b[4], l + n, f4, simple, trace, &n, &dpl[n]); + oct_tx_enq1 (vm, ctx, b[5], l + n, f5, simple, trace, &n, &dpl[n]); vlib_prefetch_buffer_header (b[15], LOAD); - dpl[6] = oct_tx_enq1 (vm, ctx, b[6], l + 6, f6, simple, trace); - dpl[7] = oct_tx_enq1 (vm, ctx, b[7], l + 7, f7, simple, trace); + oct_tx_enq1 (vm, ctx, b[6], l + n, f6, simple, trace, &n, &dpl[n]); + oct_tx_enq1 (vm, ctx, b[7], l + n, f7, simple, trace, &n, &dpl[n]); } - dpl += 8; + dpl += n; + l += n; + n = 0; } - for (; n_left > 0; n_left -= 1, b += 1, l += 1) + for (; n_left > 0; n_left -= 1, b += 1) { u32 f0 = b[0]->flags; - dpl++[0] = oct_tx_enq1 (vm, ctx, b[0], l, f0, 0, trace); + oct_tx_enq1 (vm, ctx, b[0], l, f0, 0, trace, &n, &dpl[n]); or_flags_16 |= f0; + dpl += n; + l += n; + n = 0; } lmt_arg = ctx->lmt_id; ioaddr = ctx->lmt_ioaddr; - n_lines = n_pkts; + n_lines = dpl - dwords_per_line; + + if (PREDICT_FALSE (!n_lines)) + return n_pkts; if (PREDICT_FALSE (or_flags_16 & VLIB_BUFFER_NEXT_PRESENT)) { @@ -342,6 +369,8 @@ VNET_DEV_NODE_FN (oct_tx_node) vnet_dev_tx_node_runtime_t *rt = vnet_dev_get_tx_node_runtime (node); vnet_dev_tx_queue_t *txq = rt->tx_queue; oct_txq_t *ctq = vnet_dev_get_tx_queue_data (txq); + vnet_dev_t *dev = txq->port->dev; + oct_device_t *cd = vnet_dev_get_data (dev); u32 node_index = node->node_index; u32 *from = vlib_frame_vector_args (frame); u32 n, n_enq, n_left, n_pkts = frame->n_vectors; @@ -355,6 +384,7 @@ VNET_DEV_NODE_FN (oct_tx_node) .sq = ctq->sq.qid, .sizem1 = 1, }, + .max_pkt_len = roc_nix_max_pkt_len (cd->nix), .lmt_id = lmt_id, .lmt_ioaddr = ctq->io_addr, .lmt_lines = ctq->lmt_addr + (lmt_id << ROC_LMT_LINE_SIZE_LOG2), @@ -388,21 +418,25 @@ VNET_DEV_NODE_FN (oct_tx_node) n += oct_tx_enq16 (vm, &ctx, txq, b, n_left, /* trace */ 0); } - ctq->n_enq = n_enq + n; + ctq->n_enq = n_enq + n - ctx.n_drop - ctx.n_exd_mtu; if (n < n_pkts) { - n = n_pkts - n; - vlib_buffer_free (vm, from + n, n); + u32 n_free = n_pkts - n; + vlib_buffer_free (vm, from + n, n_free); vlib_error_count (vm, node->node_index, OCT_TX_NODE_CTR_NO_FREE_SLOTS, - n); - n_pkts -= ctx.n_drop; + n_free); + n_pkts -= n_free; } if (ctx.n_drop) vlib_error_count (vm, node->node_index, OCT_TX_NODE_CTR_CHAIN_TOO_LONG, ctx.n_drop); + if (PREDICT_FALSE (ctx.n_exd_mtu)) + vlib_error_count (vm, node->node_index, OCT_TX_NODE_CTR_MTU_EXCEEDED, + ctx.n_exd_mtu); + if (ctx.batch_alloc_not_ready) vlib_error_count (vm, node_index, OCT_TX_NODE_CTR_AURA_BATCH_ALLOC_NOT_READY, @@ -423,5 +457,13 @@ VNET_DEV_NODE_FN (oct_tx_node) n_pkts -= ctx.n_drop; } + if (PREDICT_FALSE (ctx.n_exd_mtu)) + { + u32 bi[VLIB_FRAME_SIZE]; + vlib_get_buffer_indices (vm, ctx.exd_mtu, bi, ctx.n_exd_mtu); + vlib_buffer_free (vm, bi, ctx.n_exd_mtu); + n_pkts -= ctx.n_exd_mtu; + } + return n_pkts; } diff --git a/src/plugins/dpdk/CMakeLists.txt b/src/plugins/dpdk/CMakeLists.txt index 48b1548f9c2..48c56f35282 100644 --- a/src/plugins/dpdk/CMakeLists.txt +++ b/src/plugins/dpdk/CMakeLists.txt @@ -90,8 +90,10 @@ else() ############################################################################## # libnuma ############################################################################## - vpp_plugin_find_library(dpdk NUMA_LIB "numa") - list(APPEND DPDK_LINK_LIBRARIES ${NUMA_LIB}) + if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") + vpp_plugin_find_library(dpdk NUMA_LIB "numa") + list(APPEND DPDK_LINK_LIBRARIES ${NUMA_LIB}) + endif() ############################################################################## # Mellanox libraries diff --git a/src/plugins/dpdk/device/cli.c b/src/plugins/dpdk/device/cli.c index c838800deb4..77f9a27f97b 100644 --- a/src/plugins/dpdk/device/cli.c +++ b/src/plugins/dpdk/device/cli.c @@ -89,12 +89,18 @@ show_dpdk_physmem (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { clib_error_t *err = 0; - u32 pipe_max_size; int fds[2]; u8 *s = 0; int n, n_try; FILE *f; + /* + * XXX: Pipes on FreeBSD grow dynamically up to 64KB (FreeBSD 15), don't + * manually tweak this value on FreeBSD at the moment. + */ +#ifdef __linux__ + u32 pipe_max_size; + err = clib_sysfs_read ("/proc/sys/fs/pipe-max-size", "%u", &pipe_max_size); if (err) @@ -112,6 +118,7 @@ show_dpdk_physmem (vlib_main_t * vm, unformat_input_t * input, err = clib_error_return_unix (0, "fcntl(F_SETPIPE_SZ)"); goto error; } +#endif /* __linux__ */ if (fcntl (fds[0], F_SETFL, O_NONBLOCK) == -1) { diff --git a/src/plugins/dpdk/device/common.c b/src/plugins/dpdk/device/common.c index dc6b0c1c952..7a49c5aaef2 100644 --- a/src/plugins/dpdk/device/common.c +++ b/src/plugins/dpdk/device/common.c @@ -491,6 +491,7 @@ dpdk_get_pci_device (const struct rte_eth_dev_info *info) return NULL; } +#ifdef __linux__ /* If this device is VMBUS return pointer to info, otherwise NULL */ struct rte_vmbus_device * dpdk_get_vmbus_device (const struct rte_eth_dev_info *info) @@ -507,6 +508,7 @@ dpdk_get_vmbus_device (const struct rte_eth_dev_info *info) else return NULL; } +#endif /* __linux__ */ /* * fd.io coding-style-patch-verification: ON diff --git a/src/plugins/dpdk/device/dpdk.h b/src/plugins/dpdk/device/dpdk.h index c22a67a07e7..88a4d9ff618 100644 --- a/src/plugins/dpdk/device/dpdk.h +++ b/src/plugins/dpdk/device/dpdk.h @@ -24,7 +24,9 @@ #include <rte_eal.h> #include <rte_bus_pci.h> +#ifdef __linux__ #include <rte_bus_vmbus.h> +#endif /* __linux__ */ #include <rte_ethdev.h> #include <rte_version.h> #include <rte_net.h> @@ -35,7 +37,9 @@ #include <bus_driver.h> #include <bus_pci_driver.h> +#ifdef __linux__ #include <bus_vmbus_driver.h> +#endif /* __linux__ */ #endif #include <vnet/devices/devices.h> diff --git a/src/plugins/dpdk/device/init.c b/src/plugins/dpdk/device/init.c index d15cfd7233a..421f662efa2 100644 --- a/src/plugins/dpdk/device/init.c +++ b/src/plugins/dpdk/device/init.c @@ -187,9 +187,11 @@ dpdk_find_startup_config (struct rte_eth_dev_info *di) { dpdk_main_t *dm = &dpdk_main; struct rte_pci_device *pci_dev; - struct rte_vmbus_device *vmbus_dev; vlib_pci_addr_t pci_addr; +#ifdef __linux__ + struct rte_vmbus_device *vmbus_dev; vlib_vmbus_addr_t vmbus_addr; +#endif /* __linux__ */ uword *p = 0; if ((pci_dev = dpdk_get_pci_device (di))) @@ -202,6 +204,7 @@ dpdk_find_startup_config (struct rte_eth_dev_info *di) hash_get (dm->conf->device_config_index_by_pci_addr, pci_addr.as_u32); } +#ifdef __linux__ if ((vmbus_dev = dpdk_get_vmbus_device (di))) { unformat_input_t input_vmbus; @@ -216,6 +219,7 @@ dpdk_find_startup_config (struct rte_eth_dev_info *di) &vmbus_addr); unformat_free (&input_vmbus); } +#endif /* __linux__ */ if (p) return pool_elt_at_index (dm->conf->dev_confs, p[0]); @@ -566,8 +570,18 @@ dpdk_bind_devices_to_uio (dpdk_config_main_t * conf) continue; } +#ifdef __FreeBSD__ + /* + * The defines for the PCI_CLASS_* types are platform specific and differ + * on FreeBSD. + */ + if (d->device_class != PCI_CLASS_NETWORK && + d->device_class != PCI_CLASS_PROCESSOR_CO) + continue; +#else if (d->device_class != PCI_CLASS_NETWORK_ETHERNET && d->device_class != PCI_CLASS_PROCESSOR_CO) continue; +#endif /* __FreeBSD__ */ if (num_whitelisted) { @@ -1045,15 +1059,11 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input) u8 no_vmbus = 0; u8 file_prefix = 0; u8 *socket_mem = 0; - u8 *huge_dir_path = 0; u32 vendor, device, domain, bus, func; void *fmt_func; void *fmt_addr; f64 poll_interval; - huge_dir_path = - format (0, "%s/hugepages%c", vlib_unix_get_runtime_dir (), 0); - conf->device_config_index_by_pci_addr = hash_create (0, sizeof (uword)); mhash_init (&conf->device_config_index_by_vmbus_addr, sizeof (uword), sizeof (vlib_vmbus_addr_t)); @@ -1270,6 +1280,7 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input) vec_add1 (conf->eal_init_args, (u8 *) "--no-telemetry"); } +#ifdef __linux__ if (!file_prefix) { tmp = format (0, "--file-prefix%c", 0); @@ -1277,6 +1288,7 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input) tmp = format (0, "vpp%c", 0); vec_add1 (conf->eal_init_args, tmp); } +#endif if (no_pci == 0 && geteuid () == 0) dpdk_bind_devices_to_uio (conf); @@ -1396,11 +1408,6 @@ dpdk_config (vlib_main_t * vm, unformat_input_t * input) RTE_VECT_SIMD_256 : RTE_VECT_SIMD_512); - /* lazy umount hugepages */ - umount2 ((char *) huge_dir_path, MNT_DETACH); - rmdir ((char *) huge_dir_path); - vec_free (huge_dir_path); - /* main thread 1st */ if ((error = dpdk_buffer_pools_create (vm))) return error; diff --git a/src/plugins/dpdk/main.c b/src/plugins/dpdk/main.c index 47007219482..9781d0ed7f0 100644 --- a/src/plugins/dpdk/main.c +++ b/src/plugins/dpdk/main.c @@ -13,13 +13,6 @@ * limitations under the License. */ -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <linux/vfio.h> -#include <sys/ioctl.h> - #include <vnet/vnet.h> #include <vnet/plugin/plugin.h> #include <dpdk/device/dpdk.h> diff --git a/src/plugins/fateshare/fateshare.c b/src/plugins/fateshare/fateshare.c index 33ee167bce3..971d32303db 100644 --- a/src/plugins/fateshare/fateshare.c +++ b/src/plugins/fateshare/fateshare.c @@ -17,6 +17,7 @@ #include <vnet/vnet.h> #include <vnet/plugin/plugin.h> +#include <vppinfra/unix.h> #include <fateshare/fateshare.h> #include <vlibapi/api.h> @@ -26,7 +27,11 @@ #include <sys/types.h> #include <sys/wait.h> +#ifdef __linux__ #include <sys/prctl.h> // prctl(), PR_SET_PDEATHSIG +#else +#include <sys/procctl.h> +#endif /* __linux__ */ #include <limits.h> fateshare_main_t fateshare_main; @@ -86,12 +91,23 @@ launch_monitor (fateshare_main_t *kmp) { dup2 (logfd, 1); dup2 (logfd, 2); +#ifdef __linux__ int r = prctl (PR_SET_PDEATHSIG, SIGTERM); if (r == -1) { perror (0); exit (1); } +#else + int r, s = SIGTERM; + + r = procctl (P_PID, 0, PROC_PDEATHSIG_CTL, &s); + if (r == -1) + { + perror (0); + exit (1); + } +#endif /* __linux__ */ pid_t current_ppid = getppid (); if (current_ppid != ppid_before_fork) { @@ -197,24 +213,30 @@ fateshare_config (vlib_main_t *vm, unformat_input_t *input) if (fmp->monitor_cmd == 0) { - char *p, path[PATH_MAX]; - int rv; + char *p; + u8 *path; /* find executable path */ - if ((rv = readlink ("/proc/self/exe", path, PATH_MAX - 1)) == -1) + path = os_get_exec_path (); + + if (path == 0) return clib_error_return ( - 0, "could not stat /proc/self/exe - set monitor manually"); + 0, "could not get exec path - set monitor manually"); - /* readlink doesn't provide null termination */ - path[rv] = 0; + /* add null termination */ + vec_add1 (path, 0); /* strip filename */ - if ((p = strrchr (path, '/')) == 0) - return clib_error_return ( - 0, "could not determine vpp directory - set monitor manually"); + if ((p = strrchr ((char *) path, '/')) == 0) + { + vec_free (path); + return clib_error_return ( + 0, "could not determine vpp directory - set monitor manually"); + } *p = 0; fmp->monitor_cmd = format (0, "%s/vpp_fateshare_monitor\0", path); + vec_free (path); } if (fmp->monitor_logfile == 0) { diff --git a/src/plugins/fateshare/vpp_fateshare_monitor.c b/src/plugins/fateshare/vpp_fateshare_monitor.c index 7b203884c4e..7af451ccffe 100644 --- a/src/plugins/fateshare/vpp_fateshare_monitor.c +++ b/src/plugins/fateshare/vpp_fateshare_monitor.c @@ -4,7 +4,12 @@ #include <sys/types.h> #include <sys/wait.h> +#ifdef __linux__ #include <sys/prctl.h> // prctl(), PR_SET_PDEATHSIG +#else +#include <signal.h> +#include <sys/procctl.h> +#endif /* __linux__ */ #include <sys/stat.h> #include <fcntl.h> @@ -82,6 +87,7 @@ launch_command (char *scmd, char *logname_base) } /* child */ +#ifdef __linux__ int r = prctl (PR_SET_PDEATHSIG, SIGTERM); if (r == -1) { @@ -89,6 +95,17 @@ launch_command (char *scmd, char *logname_base) sleep (5); exit (1); } +#else + int r, s = SIGTERM; + + r = procctl (P_PID, 0, PROC_PDEATHSIG_CTL, &s); + if (r == -1) + { + perror ("procctl"); + exit (1); + } +#endif /* __linux__ */ + if (getppid () != ppid_before_fork) { sleep (5); @@ -180,12 +197,23 @@ main (int argc, char **argv) exit (2); } +#ifdef __linux__ int r = prctl (PR_SET_PDEATHSIG, SIGTERM); if (r == -1) { perror (0); exit (1); } +#else + int r, s = SIGTERM; + + r = procctl (P_PID, 0, PROC_PDEATHSIG_CTL, &s); + if (r == -1) + { + perror ("procctl"); + exit (1); + } +#endif /* __linux__ */ /* Establish handler. */ struct sigaction sa; diff --git a/src/plugins/hs_apps/CMakeLists.txt b/src/plugins/hs_apps/CMakeLists.txt index bd43eb34afa..179c9c7a4c4 100644 --- a/src/plugins/hs_apps/CMakeLists.txt +++ b/src/plugins/hs_apps/CMakeLists.txt @@ -55,7 +55,7 @@ if(VPP_BUILD_VCL_TESTS) ) add_vpp_executable(${test} SOURCES "vcl/${test}.c" - LINK_LIBRARIES vppcom pthread + LINK_LIBRARIES vppcom pthread ${EPOLL_LIB} NO_INSTALL ) endforeach() @@ -68,7 +68,7 @@ if(VPP_BUILD_VCL_TESTS) SOURCES "vcl/${test}.c" vcl/vcl_test_protos.c - LINK_LIBRARIES vppcom pthread + LINK_LIBRARIES vppcom pthread ${EPOLL_LIB} NO_INSTALL ) endforeach() diff --git a/src/plugins/hs_apps/http_client_cli.c b/src/plugins/hs_apps/http_client_cli.c index f44d4e1bcd1..1a321bf44a8 100644 --- a/src/plugins/hs_apps/http_client_cli.c +++ b/src/plugins/hs_apps/http_client_cli.c @@ -13,11 +13,9 @@ * limitations under the License. */ -#include <vnet/session/application.h> #include <vnet/session/application_interface.h> #include <vnet/session/session.h> #include <http/http.h> -#include <hs_apps/http_cli.h> #define HCC_DEBUG 0 @@ -68,6 +66,7 @@ typedef struct typedef enum { HCC_REPLY_RECEIVED = 100, + HCC_TRANSPORT_CLOSED, } hcc_cli_signal_t; static hcc_main_t hcc_main; @@ -273,6 +272,17 @@ hcc_ts_cleanup_callback (session_t *s, session_cleanup_ntf_t ntf) hcc_session_free (s->thread_index, hs); } +static void +hcc_ts_transport_closed (session_t *s) +{ + hcc_main_t *hcm = &hcc_main; + + HCC_DBG ("transport closed"); + + vlib_process_signal_event_mt (hcm->vlib_main, hcm->cli_node_index, + HCC_TRANSPORT_CLOSED, 0); +} + static session_cb_vft_t hcc_session_cb_vft = { .session_accept_callback = hcc_ts_accept_callback, .session_disconnect_callback = hcc_ts_disconnect_callback, @@ -281,6 +291,7 @@ static session_cb_vft_t hcc_session_cb_vft = { .builtin_app_tx_callback = hcc_ts_tx_callback, .session_reset_callback = hcc_ts_reset_callback, .session_cleanup_callback = hcc_ts_cleanup_callback, + .session_transport_closed_callback = hcc_ts_transport_closed, }; static clib_error_t * @@ -370,7 +381,7 @@ hcc_connect () } static clib_error_t * -hcc_run (vlib_main_t *vm) +hcc_run (vlib_main_t *vm, int print_output) { vlib_thread_main_t *vtm = vlib_get_thread_main (); hcc_main_t *hcm = &hcc_main; @@ -407,11 +418,15 @@ hcc_run (vlib_main_t *vm) goto cleanup; case HCC_REPLY_RECEIVED: - vlib_cli_output (vm, "%v", hcm->http_response); + if (print_output) + vlib_cli_output (vm, "%v", hcm->http_response); vec_free (hcm->http_response); break; + case HCC_TRANSPORT_CLOSED: + err = clib_error_return (0, "error, transport closed"); + break; default: - clib_error_return (0, "unexpected event %d", event_type); + err = clib_error_return (0, "unexpected event %d", event_type); break; } @@ -448,7 +463,7 @@ hcc_command_fn (vlib_main_t *vm, unformat_input_t *input, u64 seg_size; u8 *appns_id = 0; clib_error_t *err = 0; - int rv; + int rv, print_output = 1; hcm->prealloc_fifos = 0; hcm->private_segment_size = 0; @@ -472,6 +487,8 @@ hcc_command_fn (vlib_main_t *vm, unformat_input_t *input, hcm->fifo_size <<= 10; else if (unformat (line_input, "uri %s", &hcm->uri)) ; + else if (unformat (line_input, "no-output")) + print_output = 0; else if (unformat (line_input, "appns %_%v%_", &appns_id)) ; else if (unformat (line_input, "secret %lu", &hcm->appns_secret)) @@ -506,7 +523,7 @@ hcc_command_fn (vlib_main_t *vm, unformat_input_t *input, vnet_session_enable_disable (vm, 1 /* turn on TCP, etc. */); vlib_worker_thread_barrier_release (vm); - err = hcc_run (vm); + err = hcc_run (vm, print_output); if (hcc_detach ()) { @@ -526,7 +543,7 @@ done: VLIB_CLI_COMMAND (hcc_command, static) = { .path = "http cli client", .short_help = "[appns <app-ns> secret <appns-secret>] uri http://<ip-addr> " - "query <query-string>", + "query <query-string> [no-output]", .function = hcc_command_fn, .is_mp_safe = 1, }; diff --git a/src/plugins/http/http.c b/src/plugins/http/http.c index 036e6929987..526e665903a 100644 --- a/src/plugins/http/http.c +++ b/src/plugins/http/http.c @@ -74,14 +74,14 @@ format_http_state (u8 *s, va_list *va) return format (s, "unknown"); } -static inline void -http_state_change (http_conn_t *hc, http_state_t state) -{ - HTTP_DBG (1, "changing http state %U -> %U", format_http_state, - hc->http_state, format_http_state, state); - ASSERT (hc->http_state != state); - hc->http_state = state; -} +#define http_state_change(_hc, _state) \ + do \ + { \ + HTTP_DBG (1, "changing http state %U -> %U", format_http_state, \ + (_hc)->http_state, format_http_state, _state); \ + (_hc)->http_state = _state; \ + } \ + while (0) static inline http_worker_t * http_worker_get (u32 thread_index) @@ -140,6 +140,7 @@ http_listener_free (http_conn_t *lhc) { http_main_t *hm = &http_main; + vec_free (lhc->app_name); if (CLIB_DEBUG) memset (lhc, 0xfc, sizeof (*lhc)); pool_put (hm->listener_pool, lhc); @@ -372,12 +373,12 @@ static const char *http_redirect_template = "HTTP/1.1 %s\r\n"; static const char *http_response_template = "HTTP/1.1 %s\r\n" "Date: %U GMT\r\n" "Expires: %U GMT\r\n" - "Server: VPP Static\r\n" + "Server: %s\r\n" "Content-Type: %s\r\n" "Content-Length: %lu\r\n\r\n"; static const char *http_request_template = "GET %s HTTP/1.1\r\n" - "User-Agent: VPP HTTP client\r\n" + "User-Agent: %s\r\n" "Accept: */*\r\n"; static u32 @@ -520,17 +521,19 @@ http_state_wait_server_reply (http_conn_t *hc, transport_send_params_t *sp) http_msg_t msg = {}; app_worker_t *app_wrk; session_t *as; - http_status_code_t ec; rv = http_read_message (hc); /* Nothing yet, wait for data or timer expire */ if (rv) - return HTTP_SM_STOP; + { + HTTP_DBG (1, "no data to deq"); + return HTTP_SM_STOP; + } if (vec_len (hc->rx_buf) < 8) { - ec = HTTP_STATUS_BAD_REQUEST; + clib_warning ("response buffer too short"); goto error; } @@ -546,9 +549,7 @@ http_state_wait_server_reply (http_conn_t *hc, transport_send_params_t *sp) if (rv) { clib_warning ("failed to parse http reply"); - session_transport_closing_notify (&hc->connection); - http_disconnect_transport (hc); - return -1; + goto error; } msg.data.len = content_length; u32 dlen = vec_len (hc->rx_buf) - hc->rx_buf_offset; @@ -577,7 +578,7 @@ http_state_wait_server_reply (http_conn_t *hc, transport_send_params_t *sp) { hc->rx_buf_offset = 0; vec_reset_length (hc->rx_buf); - http_state_change (hc, HTTP_STATE_WAIT_CLIENT_METHOD); + http_state_change (hc, HTTP_STATE_WAIT_APP_METHOD); } else { @@ -585,23 +586,20 @@ http_state_wait_server_reply (http_conn_t *hc, transport_send_params_t *sp) } app_wrk = app_worker_get_if_valid (as->app_wrk_index); - app_worker_rx_notify (app_wrk, as); + if (app_wrk) + app_worker_rx_notify (app_wrk, as); return HTTP_SM_STOP; } else { - HTTP_DBG (0, "Unknown http method %v", hc->rx_buf); - ec = HTTP_STATUS_METHOD_NOT_ALLOWED; + clib_warning ("Unknown http method %v", hc->rx_buf); goto error; } - return HTTP_SM_STOP; error: - - http_send_error (hc, ec); session_transport_closing_notify (&hc->connection); + session_transport_closed_notify (&hc->connection); http_disconnect_transport (hc); - return HTTP_SM_ERROR; } @@ -734,6 +732,7 @@ http_state_wait_app_reply (http_conn_t *hc, transport_send_params_t *sp) * Add headers. For now: * - current time * - expiration time + * - server name * - content type * - data length */ @@ -748,6 +747,8 @@ http_state_wait_app_reply (http_conn_t *hc, transport_send_params_t *sp) format_clib_timebase_time, now, /* Expires */ format_clib_timebase_time, now + 600.0, + /* Server */ + hc->app_name, /* Content type */ http_content_type_str[msg.content_type], /* Length */ @@ -791,7 +792,6 @@ error: static http_sm_result_t http_state_wait_app_method (http_conn_t *hc, transport_send_params_t *sp) { - http_status_code_t sc; http_msg_t msg; session_t *as; u8 *buf = 0, *request; @@ -806,29 +806,24 @@ http_state_wait_app_method (http_conn_t *hc, transport_send_params_t *sp) if (msg.data.type > HTTP_MSG_DATA_PTR) { clib_warning ("no data"); - sc = HTTP_STATUS_INTERNAL_ERROR; goto error; } if (msg.type != HTTP_MSG_REQUEST) { clib_warning ("unexpected message type %d", msg.type); - sc = HTTP_STATUS_INTERNAL_ERROR; goto error; } - sc = msg.code; - vec_validate (buf, msg.data.len - 1); rv = svm_fifo_dequeue (as->tx_fifo, msg.data.len, buf); ASSERT (rv == msg.data.len); - request = format (0, http_request_template, buf); + request = format (0, http_request_template, buf, hc->app_name); offset = http_send_data (hc, request, vec_len (request), 0); if (offset != vec_len (request)) { clib_warning ("sending request failed!"); - sc = HTTP_STATUS_INTERNAL_ERROR; goto error; } @@ -837,83 +832,85 @@ http_state_wait_app_method (http_conn_t *hc, transport_send_params_t *sp) vec_free (buf); vec_free (request); - return HTTP_SM_CONTINUE; + return HTTP_SM_STOP; error: - clib_warning ("unexpected msg type from app %u", msg.type); - http_send_error (hc, sc); + svm_fifo_dequeue_drop_all (as->tx_fifo); session_transport_closing_notify (&hc->connection); + session_transport_closed_notify (&hc->connection); http_disconnect_transport (hc); - return HTTP_SM_STOP; -} - -static void -http_app_enqueue (http_conn_t *hc, session_t *as) -{ - app_worker_t *app_wrk; - u32 dlen, max_enq, n_enq; - int rv; - - dlen = vec_len (hc->rx_buf) - hc->rx_buf_offset; - if (!dlen) - return; - - max_enq = svm_fifo_max_enqueue (as->rx_fifo); - n_enq = clib_min (max_enq, dlen); - rv = svm_fifo_enqueue (as->rx_fifo, n_enq, &hc->rx_buf[hc->rx_buf_offset]); - if (rv < 0) - return; - - hc->rx_buf_offset += rv; - if (hc->rx_buf_offset >= vec_len (hc->rx_buf)) - { - vec_reset_length (hc->rx_buf); - hc->rx_buf_offset = 0; - } - - app_wrk = app_worker_get_if_valid (as->app_wrk_index); - ASSERT (app_wrk); - app_worker_rx_notify (app_wrk, as); + return HTTP_SM_ERROR; } static http_sm_result_t http_state_client_io_more_data (http_conn_t *hc, transport_send_params_t *sp) { session_t *as, *ts; - u32 max_deq; - int n_read; + app_worker_t *app_wrk; + svm_fifo_seg_t _seg, *seg = &_seg; + u32 max_len, max_deq, max_enq, n_segs = 1; + int rv, len; as = session_get_from_handle (hc->h_pa_session_handle); ts = session_get_from_handle (hc->h_tc_session_handle); - http_app_enqueue (hc, as); + max_deq = svm_fifo_max_dequeue (ts->rx_fifo); + if (max_deq == 0) + { + HTTP_DBG (1, "no data to deq"); + return HTTP_SM_STOP; + } - if (hc->to_recv == 0) + max_enq = svm_fifo_max_enqueue (as->rx_fifo); + if (max_enq == 0) { - http_state_change (hc, HTTP_STATE_WAIT_CLIENT_METHOD); + HTTP_DBG (1, "app's rx fifo full"); + svm_fifo_add_want_deq_ntf (as->rx_fifo, SVM_FIFO_WANT_DEQ_NOTIF); return HTTP_SM_STOP; } - max_deq = svm_fifo_max_dequeue (ts->rx_fifo); - if (max_deq > 0) + max_len = clib_min (max_enq, max_deq); + len = svm_fifo_segments (ts->rx_fifo, 0, seg, &n_segs, max_len); + if (len < 0) { - vec_validate (hc->rx_buf, max_deq - 1); - n_read = svm_fifo_dequeue (ts->rx_fifo, max_deq, hc->rx_buf); - ASSERT (n_read == max_deq); + HTTP_DBG (1, "svm_fifo_segments() len %d", len); + return HTTP_SM_STOP; + } - if (svm_fifo_is_empty (ts->rx_fifo)) - svm_fifo_unset_event (ts->rx_fifo); + rv = svm_fifo_enqueue_segments (as->rx_fifo, seg, 1, 0 /* allow partial */); + if (rv < 0) + { + clib_warning ("data enqueue failed, rv: %d", rv); + return HTTP_SM_ERROR; + } - hc->to_recv -= n_read; - vec_set_len (hc->rx_buf, n_read); + svm_fifo_dequeue_drop (ts->rx_fifo, rv); + if (rv > hc->to_recv) + { + clib_warning ("http protocol error: received more data than expected"); + session_transport_closing_notify (&hc->connection); + http_disconnect_transport (hc); + http_state_change (hc, HTTP_STATE_WAIT_APP_METHOD); + return HTTP_SM_ERROR; } + hc->to_recv -= rv; + HTTP_DBG (1, "drained %d from ts; remains %d", rv, hc->to_recv); - if (hc->rx_buf_offset < vec_len (hc->rx_buf) || - svm_fifo_max_dequeue_cons (ts->rx_fifo)) + if (hc->to_recv == 0) { - session_enqueue_notify (ts); + hc->rx_buf_offset = 0; + vec_reset_length (hc->rx_buf); + http_state_change (hc, HTTP_STATE_WAIT_APP_METHOD); } - return HTTP_SM_CONTINUE; + + app_wrk = app_worker_get_if_valid (as->app_wrk_index); + if (app_wrk) + app_worker_rx_notify (app_wrk, as); + + if (svm_fifo_max_dequeue_cons (ts->rx_fifo)) + session_enqueue_notify (ts); + + return HTTP_SM_STOP; } static http_sm_result_t @@ -983,6 +980,7 @@ static void http_req_run_state_machine (http_conn_t *hc, transport_send_params_t *sp) { http_sm_result_t res; + do { res = state_funcs[hc->http_state](hc, sp); @@ -1010,6 +1008,12 @@ http_ts_rx_callback (session_t *ts) return -1; } + if (hc->state == HTTP_CONN_STATE_CLOSED) + { + svm_fifo_dequeue_drop_all (ts->tx_fifo); + return 0; + } + http_req_run_state_machine (hc, 0); if (hc->state == HTTP_CONN_STATE_TRANSPORT_CLOSED) @@ -1153,6 +1157,11 @@ http_transport_connect (transport_endpoint_cfg_t *tep) hc->state = HTTP_CONN_STATE_CONNECTING; cargs->api_context = hc_index; + if (vec_len (app->name)) + hc->app_name = vec_dup (app->name); + else + hc->app_name = format (0, "VPP HTTP client"); + HTTP_DBG (1, "hc ho_index %x", hc_index); if ((error = vnet_connect (cargs))) @@ -1205,6 +1214,11 @@ http_start_listen (u32 app_listener_index, transport_endpoint_cfg_t *tep) lhc->c_s_index = app_listener_index; lhc->c_flags |= TRANSPORT_CONNECTION_F_NO_LOOKUP; + if (vec_len (app->name)) + lhc->app_name = vec_dup (app->name); + else + lhc->app_name = format (0, "VPP server app"); + return lhc_index; } @@ -1245,7 +1259,11 @@ http_transport_close (u32 hc_index, u32 thread_index) http_disconnect_transport (hc); return; } - + else if (hc->state == HTTP_CONN_STATE_CLOSED) + { + HTTP_DBG (1, "nothing to do, already closed"); + return; + } as = session_get_from_handle (hc->h_pa_session_handle); /* Nothing more to send, confirm close */ diff --git a/src/plugins/http/http.h b/src/plugins/http/http.h index dbae5ac4611..c9912dd6db8 100644 --- a/src/plugins/http/http.h +++ b/src/plugins/http/http.h @@ -227,6 +227,7 @@ typedef struct http_tc_ http_conn_state_t state; u32 timer_handle; + u8 *app_name; /* * Current request diff --git a/src/plugins/ikev2/ikev2.api b/src/plugins/ikev2/ikev2.api index 58b7fc05d9e..de276e7f3ea 100644 --- a/src/plugins/ikev2/ikev2.api +++ b/src/plugins/ikev2/ikev2.api @@ -72,8 +72,6 @@ define ikev2_sa_dump { u32 client_index; u32 context; - - option status = "in_progress"; }; /** \brief Dump all SAs @@ -86,6 +84,17 @@ define ikev2_sa_v2_dump u32 context; }; +/** \brief Dump all SAs + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request +*/ +define ikev2_sa_v3_dump +{ + u32 client_index; + u32 context; + option status = "in_progress"; +}; + /** \brief Details about IKE SA @param context - sender context, to match reply w/ request @param retval - return code @@ -97,7 +106,6 @@ define ikev2_sa_details i32 retval; vl_api_ikev2_sa_t sa; - option status = "in_progress"; }; /** \brief Details about IKE SA @@ -113,6 +121,20 @@ define ikev2_sa_v2_details vl_api_ikev2_sa_v2_t sa; }; +/** \brief Details about IKE SA + @param context - sender context, to match reply w/ request + @param retval - return code + @param sa - SA data +*/ +define ikev2_sa_v3_details +{ + u32 context; + i32 retval; + + vl_api_ikev2_sa_v3_t sa; + option status = "in_progress"; +}; + /** \brief Dump child SA of specific SA @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request @@ -125,7 +147,6 @@ define ikev2_child_sa_dump u32 sa_index; option vat_help = "sa_index <index>"; - option status = "in_progress"; }; /** \brief Child SA details @@ -139,6 +160,34 @@ define ikev2_child_sa_details i32 retval; vl_api_ikev2_child_sa_t child_sa; +}; + +/** \brief Dump child SA of specific SA + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param sa_index - index of specific sa +*/ +define ikev2_child_sa_v2_dump +{ + u32 client_index; + u32 context; + + u32 sa_index; + option vat_help = "sa_index <index>"; + option status = "in_progress"; +}; + +/** \brief Child SA details + @param context - sender context, to match reply w/ request + @param retval - return code + @param child_sa - child SA data +*/ +define ikev2_child_sa_v2_details +{ + u32 context; + i32 retval; + + vl_api_ikev2_child_sa_v2_t child_sa; option status = "in_progress"; }; diff --git a/src/plugins/ikev2/ikev2.c b/src/plugins/ikev2/ikev2.c index d559565487e..9bea2c96d12 100644 --- a/src/plugins/ikev2/ikev2.c +++ b/src/plugins/ikev2/ikev2.c @@ -1888,7 +1888,7 @@ ikev2_sa_match_ts (ikev2_sa_t * sa) } static ikev2_profile_t * -ikev2_select_profile (ikev2_main_t *km, ikev2_sa_t *sa, +ikev2_select_profile (vlib_main_t *vm, ikev2_main_t *km, ikev2_sa_t *sa, ikev2_sa_transform_t *tr_prf, u8 *key_pad) { ikev2_profile_t *ret = 0, *p; @@ -1928,6 +1928,7 @@ ikev2_select_profile (ikev2_main_t *km, ikev2_sa_t *sa, if (!clib_memcmp (auth, sa_auth->data, vec_len (sa_auth->data))) { ikev2_set_state (sa, IKEV2_STATE_AUTHENTICATED); + sa->auth_timestamp = vlib_time_now (vm); vec_free (auth); ret = p; break; @@ -1946,6 +1947,7 @@ ikev2_select_profile (ikev2_main_t *km, ikev2_sa_t *sa, if (ikev2_verify_sign (p->auth.key, sa_auth->data, authmsg) == 1) { ikev2_set_state (sa, IKEV2_STATE_AUTHENTICATED); + sa->auth_timestamp = vlib_time_now (vm); ret = p; break; } @@ -1961,7 +1963,7 @@ ikev2_select_profile (ikev2_main_t *km, ikev2_sa_t *sa, } static void -ikev2_sa_auth (ikev2_sa_t *sa) +ikev2_sa_auth (ikev2_sa_t *sa, vlib_main_t *vm) { ikev2_main_t *km = &ikev2_main; ikev2_profile_t *sel_p = 0; @@ -1982,7 +1984,7 @@ ikev2_sa_auth (ikev2_sa_t *sa) } key_pad = format (0, "%s", IKEV2_KEY_PAD); - sel_p = ikev2_select_profile (km, sa, tr_prf, key_pad); + sel_p = ikev2_select_profile (vm, km, sa, tr_prf, key_pad); if (sel_p) { @@ -2230,6 +2232,8 @@ ikev2_create_tunnel_interface (vlib_main_t *vm, ikev2_sa_t *sa, clib_memset (&a, 0, sizeof (a)); + child->timestamp = vlib_time_now (vm); + if (!child->r_proposals) { ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN); @@ -3424,7 +3428,7 @@ ikev2_node_internal (vlib_main_t *vm, vlib_node_runtime_t *node, sa0->dst_port = clib_net_to_host_u16 (udp0->src_port); res = ikev2_process_auth_req (vm, sa0, ike0, rlen); if (res) - ikev2_sa_auth (sa0); + ikev2_sa_auth (sa0, vm); else vlib_node_increment_counter (vm, node->node_index, IKEV2_ERROR_MALFORMED_PACKET, 1); diff --git a/src/plugins/ikev2/ikev2_api.c b/src/plugins/ikev2/ikev2_api.c index bb44e9f364f..c9608aa660b 100644 --- a/src/plugins/ikev2/ikev2_api.c +++ b/src/plugins/ikev2/ikev2_api.c @@ -173,7 +173,7 @@ send_profile (ikev2_profile_t * profile, vl_api_registration_t * reg, rmp->profile.lifetime_jitter = profile->lifetime_jitter; rmp->profile.handover = profile->handover; - vl_api_ikev2_profile_t_endian (&rmp->profile); + vl_api_ikev2_profile_t_endian (&rmp->profile, 1 /* to network */); vl_api_send_msg (reg, (u8 *) rmp); } @@ -291,7 +291,7 @@ send_sa (ikev2_sa_t * sa, vl_api_ikev2_sa_dump_t * mp, u32 api_sa_index) ikev2_copy_stats (&rsa->stats, &sa->stats); - vl_api_ikev2_sa_t_endian(rsa); + vl_api_ikev2_sa_t_endian (rsa, 1 /* to network */); }); } @@ -382,7 +382,7 @@ send_sa_v2 (ikev2_sa_t *sa, vl_api_ikev2_sa_v2_dump_t *mp, u32 api_sa_index) ikev2_copy_stats (&rsa->stats, &sa->stats); - vl_api_ikev2_sa_v2_t_endian (rsa); + vl_api_ikev2_sa_v2_t_endian (rsa, 1 /* to network */); }); } @@ -405,6 +405,100 @@ vl_api_ikev2_sa_v2_dump_t_handler (vl_api_ikev2_sa_v2_dump_t *mp) } static void +send_sa_v3 (ikev2_sa_t *sa, vl_api_ikev2_sa_v3_dump_t *mp, u32 api_sa_index) +{ + ikev2_main_t *km = &ikev2_main; + vl_api_ikev2_sa_v3_details_t *rmp = 0; + int rv = 0; + ikev2_sa_transform_t *tr; + ikev2_profile_t *p; + p = pool_elt_at_index (km->profiles, sa->profile_index); + vlib_main_t *vm = vlib_get_main (); + + REPLY_MACRO2_ZERO (VL_API_IKEV2_SA_V3_DETAILS, { + vl_api_ikev2_sa_v3_t *rsa = &rmp->sa; + vl_api_ikev2_keys_t *k = &rsa->keys; + + int size_data = sizeof (rsa->profile_name) - 1; + if (vec_len (p->name) < size_data) + size_data = vec_len (p->name); + clib_memcpy (rsa->profile_name, p->name, size_data); + + rsa->state = ikev2_state_encode (sa->state); + + rsa->uptime = vlib_time_now (vm) - sa->auth_timestamp; + + rsa->sa_index = api_sa_index; + ip_address_encode2 (&sa->iaddr, &rsa->iaddr); + ip_address_encode2 (&sa->raddr, &rsa->raddr); + rsa->ispi = sa->ispi; + rsa->rspi = sa->rspi; + cp_id (&rsa->i_id, &sa->i_id); + cp_id (&rsa->r_id, &sa->r_id); + + tr = ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR); + if (tr) + cp_sa_transform (&rsa->encryption, tr); + + tr = ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_PRF); + if (tr) + cp_sa_transform (&rsa->prf, tr); + + tr = + ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_INTEG); + if (tr) + cp_sa_transform (&rsa->integrity, tr); + + tr = ikev2_sa_get_td_for_type (sa->r_proposals, IKEV2_TRANSFORM_TYPE_DH); + if (tr) + cp_sa_transform (&rsa->dh, tr); + + k->sk_d_len = vec_len (sa->sk_d); + clib_memcpy (&k->sk_d, sa->sk_d, k->sk_d_len); + + k->sk_ai_len = vec_len (sa->sk_ai); + clib_memcpy (&k->sk_ai, sa->sk_ai, k->sk_ai_len); + + k->sk_ar_len = vec_len (sa->sk_ar); + clib_memcpy (&k->sk_ar, sa->sk_ar, k->sk_ar_len); + + k->sk_ei_len = vec_len (sa->sk_ei); + clib_memcpy (&k->sk_ei, sa->sk_ei, k->sk_ei_len); + + k->sk_er_len = vec_len (sa->sk_er); + clib_memcpy (&k->sk_er, sa->sk_er, k->sk_er_len); + + k->sk_pi_len = vec_len (sa->sk_pi); + clib_memcpy (&k->sk_pi, sa->sk_pi, k->sk_pi_len); + + k->sk_pr_len = vec_len (sa->sk_pr); + clib_memcpy (&k->sk_pr, sa->sk_pr, k->sk_pr_len); + + ikev2_copy_stats (&rsa->stats, &sa->stats); + + vl_api_ikev2_sa_v3_t_endian (rsa, 1 /* to network */); + }); +} + +static void +vl_api_ikev2_sa_v3_dump_t_handler (vl_api_ikev2_sa_v3_dump_t *mp) +{ + ikev2_main_t *km = &ikev2_main; + ikev2_main_per_thread_data_t *tkm; + ikev2_sa_t *sa; + + vec_foreach (tkm, km->per_thread_data) + { + pool_foreach (sa, tkm->sas) + { + u32 api_sa_index = + ikev2_encode_sa_index (sa - tkm->sas, tkm - km->per_thread_data); + send_sa_v3 (sa, mp, api_sa_index); + } + } +} + +static void send_child_sa (ikev2_child_sa_t * child, vl_api_ikev2_child_sa_dump_t * mp, u32 child_sa_index, u32 sa_index) @@ -455,7 +549,7 @@ send_child_sa (ikev2_child_sa_t * child, k->sk_ar_len); } - vl_api_ikev2_child_sa_t_endian (&rmp->child_sa); + vl_api_ikev2_child_sa_t_endian (&rmp->child_sa, 1 /* to network */); }); } @@ -488,6 +582,85 @@ vl_api_ikev2_child_sa_dump_t_handler (vl_api_ikev2_child_sa_dump_t * mp) } static void +send_child_sa_v2 (ikev2_child_sa_t *child, vl_api_ikev2_child_sa_v2_dump_t *mp, + u32 child_sa_index, u32 sa_index) +{ + vl_api_ikev2_child_sa_v2_details_t *rmp = 0; + int rv = 0; + ikev2_sa_transform_t *tr; + vlib_main_t *vm = vlib_get_main (); + + REPLY_MACRO2_ZERO (VL_API_IKEV2_CHILD_SA_V2_DETAILS, { + vl_api_ikev2_keys_t *k = &rmp->child_sa.keys; + rmp->child_sa.child_sa_index = child_sa_index; + rmp->child_sa.uptime = vlib_time_now (vm) - child->timestamp; + rmp->child_sa.sa_index = sa_index; + rmp->child_sa.i_spi = child->i_proposals ? child->i_proposals[0].spi : 0; + rmp->child_sa.r_spi = child->r_proposals ? child->r_proposals[0].spi : 0; + + tr = + ikev2_sa_get_td_for_type (child->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR); + if (tr) + cp_sa_transform (&rmp->child_sa.encryption, tr); + + tr = ikev2_sa_get_td_for_type (child->r_proposals, + IKEV2_TRANSFORM_TYPE_INTEG); + if (tr) + cp_sa_transform (&rmp->child_sa.integrity, tr); + + tr = + ikev2_sa_get_td_for_type (child->r_proposals, IKEV2_TRANSFORM_TYPE_ESN); + if (tr) + cp_sa_transform (&rmp->child_sa.esn, tr); + + k->sk_ei_len = vec_len (child->sk_ei); + clib_memcpy (&k->sk_ei, child->sk_ei, k->sk_ei_len); + + k->sk_er_len = vec_len (child->sk_er); + clib_memcpy (&k->sk_er, child->sk_er, k->sk_er_len); + + if (vec_len (child->sk_ai)) + { + k->sk_ai_len = vec_len (child->sk_ai); + clib_memcpy (&k->sk_ai, child->sk_ai, k->sk_ai_len); + + k->sk_ar_len = vec_len (child->sk_ar); + clib_memcpy (&k->sk_ar, child->sk_ar, k->sk_ar_len); + } + + vl_api_ikev2_child_sa_v2_t_endian (&rmp->child_sa, 1 /* to network */); + }); +} + +static void +vl_api_ikev2_child_sa_v2_dump_t_handler (vl_api_ikev2_child_sa_v2_dump_t *mp) +{ + ikev2_main_t *im = &ikev2_main; + ikev2_main_per_thread_data_t *tkm; + ikev2_sa_t *sa; + ikev2_child_sa_t *child; + u32 sai = ~0, ti = ~0; + + ikev2_decode_sa_index (clib_net_to_host_u32 (mp->sa_index), &sai, &ti); + + if (vec_len (im->per_thread_data) <= ti) + return; + + tkm = vec_elt_at_index (im->per_thread_data, ti); + + if (pool_len (tkm->sas) <= sai || pool_is_free_index (tkm->sas, sai)) + return; + + sa = pool_elt_at_index (tkm->sas, sai); + + vec_foreach (child, sa->childs) + { + u32 child_sa_index = child - sa->childs; + send_child_sa_v2 (child, mp, child_sa_index, sai); + } +} + +static void vl_api_ikev2_traffic_selector_dump_t_handler (vl_api_ikev2_traffic_selector_dump_t * mp) { @@ -527,7 +700,7 @@ static void rmp->ts.sa_index = api_sa_index; rmp->ts.child_sa_index = child_sa_index; cp_ts (&rmp->ts, ts, mp->is_initiator); - vl_api_ikev2_ts_t_endian (&rmp->ts); + vl_api_ikev2_ts_t_endian (&rmp->ts, 1 /* to network */); }); } } diff --git a/src/plugins/ikev2/ikev2_cli.c b/src/plugins/ikev2/ikev2_cli.c index 733ae478b83..975774c48d5 100644 --- a/src/plugins/ikev2/ikev2_cli.c +++ b/src/plugins/ikev2/ikev2_cli.c @@ -74,12 +74,16 @@ format_ikev2_child_sa (u8 * s, va_list * va) ikev2_ts_t *ts; ikev2_sa_transform_t *tr; u8 *c = 0; + vlib_main_t *vm = vlib_get_main (); u32 indent = format_get_indent (s); indent += 1; s = format (s, "child sa %u:", index); + s = format (s, "\n uptime: %f (s)\n ", + vlib_time_now (vm) - child->timestamp); + tr = ikev2_sa_get_td_for_type (child->r_proposals, IKEV2_TRANSFORM_TYPE_ENCR); c = format (c, "%U ", format_ikev2_sa_transform, tr); @@ -135,6 +139,7 @@ format_ikev2_sa (u8 * s, va_list * va) ikev2_sa_transform_t *tr; ikev2_child_sa_t *child; u32 indent = 1; + vlib_main_t *vm = vlib_get_main (); ikev2_main_t *km = &ikev2_main; ikev2_profile_t *p; @@ -168,6 +173,9 @@ format_ikev2_sa (u8 * s, va_list * va) s = format (s, "\n state: %s", stateNames[sa->state]); } + s = + format (s, "\n uptime: %f (s)\n", vlib_time_now (vm) - sa->auth_timestamp); + s = format (s, "\n%U", format_white_space, indent); s = format (s, "nonce i:%U\n%Ur:%U\n", diff --git a/src/plugins/ikev2/ikev2_priv.h b/src/plugins/ikev2/ikev2_priv.h index a11538f92c7..0639809e9b1 100644 --- a/src/plugins/ikev2/ikev2_priv.h +++ b/src/plugins/ikev2/ikev2_priv.h @@ -307,6 +307,8 @@ typedef struct f64 time_to_expiration; u8 is_expired; i8 rekey_retries; + + f64 timestamp; } ikev2_child_sa_t; typedef struct @@ -488,6 +490,8 @@ typedef struct u8 keys_generated; ikev2_stats_t stats; + + f64 auth_timestamp; } ikev2_sa_t; diff --git a/src/plugins/ikev2/ikev2_test.c b/src/plugins/ikev2/ikev2_test.c index 18d01dc6ffb..93683a5b5dc 100644 --- a/src/plugins/ikev2/ikev2_test.c +++ b/src/plugins/ikev2/ikev2_test.c @@ -391,7 +391,7 @@ vl_api_ikev2_sa_details_t_handler (vl_api_ikev2_sa_details_t * mp) ip_address_t iaddr; ip_address_t raddr; vl_api_ikev2_keys_t *k = &sa->keys; - vl_api_ikev2_sa_t_endian (sa); + vl_api_ikev2_sa_t_endian (sa, 0 /* from network */); ip_address_decode2 (&sa->iaddr, &iaddr); ip_address_decode2 (&sa->raddr, &raddr); @@ -461,7 +461,7 @@ vl_api_ikev2_sa_v2_details_t_handler (vl_api_ikev2_sa_v2_details_t *mp) ip_address_t iaddr; ip_address_t raddr; vl_api_ikev2_keys_t *k = &sa->keys; - vl_api_ikev2_sa_v2_t_endian (sa); + vl_api_ikev2_sa_v2_t_endian (sa, 0 /* from network */); ip_address_decode2 (&sa->iaddr, &iaddr); ip_address_decode2 (&sa->raddr, &raddr); @@ -497,6 +497,76 @@ vl_api_ikev2_sa_v2_details_t_handler (vl_api_ikev2_sa_v2_details_t *mp) } static int +api_ikev2_sa_v3_dump (vat_main_t *vam) +{ + ikev2_test_main_t *im = &ikev2_test_main; + vl_api_ikev2_sa_v3_dump_t *mp; + vl_api_control_ping_t *mp_ping; + int ret; + + /* Construct the API message */ + M (IKEV2_SA_V3_DUMP, mp); + + /* send it... */ + S (mp); + + /* Use a control ping for synchronization */ + if (!im->ping_id) + im->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC)); + mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping)); + mp_ping->_vl_msg_id = htons (im->ping_id); + mp_ping->client_index = vam->my_client_index; + vam->result_ready = 0; + + S (mp_ping); + + /* Wait for a reply... */ + W (ret); + return ret; +} + +static void +vl_api_ikev2_sa_v3_details_t_handler (vl_api_ikev2_sa_v3_details_t *mp) +{ + vat_main_t *vam = ikev2_test_main.vat_main; + vl_api_ikev2_sa_v3_t *sa = &mp->sa; + ip_address_t iaddr; + ip_address_t raddr; + vl_api_ikev2_keys_t *k = &sa->keys; + vl_api_ikev2_sa_v3_t_endian (sa, 0 /* from network */); + + ip_address_decode2 (&sa->iaddr, &iaddr); + ip_address_decode2 (&sa->raddr, &raddr); + + fformat (vam->ofp, "profile name %s sa index: %d\n", mp->sa.profile_name, + mp->sa.sa_index); + fformat (vam->ofp, " iip %U ispi %lx rip %U rspi %lx\n", format_ip_address, + &iaddr, sa->ispi, format_ip_address, &raddr, sa->rspi); + fformat (vam->ofp, " %U ", format_ikev2_sa_transform, &sa->encryption); + fformat (vam->ofp, "%U ", format_ikev2_sa_transform, &sa->prf); + fformat (vam->ofp, "%U ", format_ikev2_sa_transform, &sa->integrity); + fformat (vam->ofp, "%U \n", format_ikev2_sa_transform, &sa->dh); + + fformat (vam->ofp, " SK_d %U\n", format_hex_bytes, k->sk_d, k->sk_d_len); + + fformat (vam->ofp, " SK_a i:%U\n r:%U\n", format_hex_bytes, + k->sk_ai, k->sk_ai_len, format_hex_bytes, k->sk_ar, k->sk_ar_len); + + fformat (vam->ofp, " SK_e i:%U\n r:%U\n", format_hex_bytes, + k->sk_ei, k->sk_ei_len, format_hex_bytes, k->sk_er, k->sk_er_len); + + fformat (vam->ofp, " SK_p i:%U\n r:%U\n", format_hex_bytes, + k->sk_pi, k->sk_pi_len, format_hex_bytes, k->sk_pr, k->sk_pr_len); + + fformat (vam->ofp, " identifier (i) %U\n", format_ikev2_id_type_and_data, + &sa->i_id); + fformat (vam->ofp, " identifier (r) %U\n", format_ikev2_id_type_and_data, + &sa->r_id); + + vam->result_ready = 1; +} + +static int api_ikev2_child_sa_dump (vat_main_t * vam) { unformat_input_t *i = vam->input; @@ -549,7 +619,84 @@ vl_api_ikev2_child_sa_details_t_handler (vl_api_ikev2_child_sa_details_t * mp) vat_main_t *vam = ikev2_test_main.vat_main; vl_api_ikev2_child_sa_t *child_sa = &mp->child_sa; vl_api_ikev2_keys_t *k = &child_sa->keys; - vl_api_ikev2_child_sa_t_endian (child_sa); + vl_api_ikev2_child_sa_t_endian (child_sa, 0 /* from network */); + + fformat (vam->ofp, " child sa %u:\n", child_sa->child_sa_index); + + fformat (vam->ofp, " %U ", format_ikev2_sa_transform, + &child_sa->encryption); + fformat (vam->ofp, "%U ", format_ikev2_sa_transform, &child_sa->integrity); + fformat (vam->ofp, "%U \n", format_ikev2_sa_transform, &child_sa->esn); + + fformat (vam->ofp, " spi(i) %lx spi(r) %lx\n", child_sa->i_spi, + child_sa->r_spi); + + fformat (vam->ofp, " SK_e i:%U\n r:%U\n", format_hex_bytes, + k->sk_ei, k->sk_ei_len, format_hex_bytes, k->sk_er, k->sk_er_len); + if (k->sk_ai_len) + { + fformat (vam->ofp, " SK_a i:%U\n r:%U\n", format_hex_bytes, + k->sk_ai, k->sk_ai_len, format_hex_bytes, k->sk_ar, + k->sk_ar_len); + } + vam->result_ready = 1; +} + +static int +api_ikev2_child_sa_v2_dump (vat_main_t *vam) +{ + unformat_input_t *i = vam->input; + ikev2_test_main_t *im = &ikev2_test_main; + vl_api_ikev2_child_sa_dump_t *mp; + vl_api_control_ping_t *mp_ping; + int ret; + u32 sa_index = ~0; + + while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT) + { + if (unformat (i, "sa_index %d", &sa_index)) + ; + else + { + errmsg ("parse error '%U'", format_unformat_error, i); + return -99; + } + } + + if (sa_index == ~0) + return -99; + + /* Construct the API message */ + M (IKEV2_CHILD_SA_DUMP, mp); + + mp->sa_index = clib_net_to_host_u32 (sa_index); + + /* send it... */ + S (mp); + + /* Use a control ping for synchronization */ + if (!im->ping_id) + im->ping_id = vl_msg_api_get_msg_index ((u8 *) (VL_API_CONTROL_PING_CRC)); + mp_ping = vl_msg_api_alloc_as_if_client (sizeof (*mp_ping)); + mp_ping->_vl_msg_id = htons (im->ping_id); + mp_ping->client_index = vam->my_client_index; + vam->result_ready = 0; + + S (mp_ping); + + /* Wait for a reply... */ + W (ret); + return ret; +} + +static void +vl_api_ikev2_child_sa_v2_details_t_handler ( + vl_api_ikev2_child_sa_details_t *mp) +{ + vat_main_t *vam = ikev2_test_main.vat_main; + vl_api_ikev2_child_sa_t *child_sa = &mp->child_sa; + vl_api_ikev2_keys_t *k = &child_sa->keys; + vl_api_ikev2_child_sa_t_endian (child_sa, 0 /* from network */); fformat (vam->ofp, " child sa %u:\n", child_sa->child_sa_index); @@ -637,7 +784,7 @@ static void vat_main_t *vam = ikev2_test_main.vat_main; vl_api_ikev2_ts_t *ts = &mp->ts; ip_address_t start_addr, end_addr; - vl_api_ikev2_ts_t_endian (ts); + vl_api_ikev2_ts_t_endian (ts, 0 /* from network */); ip_address_decode2 (&ts->start_addr, &start_addr); ip_address_decode2 (&ts->end_addr, &end_addr); diff --git a/src/plugins/ikev2/ikev2_types.api b/src/plugins/ikev2/ikev2_types.api index f0e50165501..2492611703d 100644 --- a/src/plugins/ikev2/ikev2_types.api +++ b/src/plugins/ikev2/ikev2_types.api @@ -128,6 +128,19 @@ typedef ikev2_child_sa vl_api_ikev2_sa_transform_t esn; }; +typedef ikev2_child_sa_v2 +{ + u32 sa_index; + u32 child_sa_index; + u32 i_spi; + u32 r_spi; + vl_api_ikev2_keys_t keys; + vl_api_ikev2_sa_transform_t encryption; + vl_api_ikev2_sa_transform_t integrity; + vl_api_ikev2_sa_transform_t esn; + f64 uptime; +}; + typedef ikev2_sa_stats { u16 n_keepalives; @@ -197,4 +210,30 @@ typedef ikev2_sa_v2 vl_api_ikev2_sa_transform_t dh; vl_api_ikev2_sa_stats_t stats; +}; + +typedef ikev2_sa_v3 +{ + u32 sa_index; + string profile_name[64]; + vl_api_ikev2_state_t state; + + u64 ispi; + u64 rspi; + vl_api_address_t iaddr; + vl_api_address_t raddr; + + vl_api_ikev2_keys_t keys; + + /* ID */ + vl_api_ikev2_id_t i_id; + vl_api_ikev2_id_t r_id; + + vl_api_ikev2_sa_transform_t encryption; + vl_api_ikev2_sa_transform_t integrity; + vl_api_ikev2_sa_transform_t prf; + vl_api_ikev2_sa_transform_t dh; + + vl_api_ikev2_sa_stats_t stats; + f64 uptime; };
\ No newline at end of file diff --git a/src/plugins/lb/lb.c b/src/plugins/lb/lb.c index f8d5fe8d833..7ae1884ff31 100644 --- a/src/plugins/lb/lb.c +++ b/src/plugins/lb/lb.c @@ -373,9 +373,9 @@ void lb_garbage_collection() } vec_foreach(i, to_be_removed_vips) { - vip = &lbm->vips[*i]; - pool_put(lbm->vips, vip); - pool_free(vip->as_indexes); + vip = &lbm->vips[*i]; + pool_free (vip->as_indexes); + pool_put (lbm->vips, vip); } vec_free(to_be_removed_vips); diff --git a/src/plugins/linux-cp/lcp.c b/src/plugins/linux-cp/lcp.c index 561ebb152ae..34e8550a13f 100644 --- a/src/plugins/linux-cp/lcp.c +++ b/src/plugins/linux-cp/lcp.c @@ -161,6 +161,28 @@ lcp_get_netlink_processing_active (void) return lcpm->netlink_processing_active; } +void +lcp_set_default_num_queues (u16 num_queues, u8 is_tx) +{ + lcp_main_t *lcpm = &lcp_main; + + if (is_tx) + lcpm->num_tx_queues = num_queues; + else + lcpm->num_rx_queues = num_queues; +} + +u16 +lcp_get_default_num_queues (u8 is_tx) +{ + lcp_main_t *lcpm = &lcp_main; + + if (is_tx) + return lcpm->num_tx_queues; + + return lcpm->num_rx_queues ?: vlib_num_workers (); +} + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/plugins/linux-cp/lcp.h b/src/plugins/linux-cp/lcp.h index 3b6b4ec00d4..e89b149f67d 100644 --- a/src/plugins/linux-cp/lcp.h +++ b/src/plugins/linux-cp/lcp.h @@ -28,6 +28,8 @@ typedef struct lcp_main_s u8 lcp_sync; /* Automatically sync VPP changes to LCP */ u8 del_static_on_link_down; /* Delete static routes when link goes down */ u8 del_dynamic_on_link_down; /* Delete dynamic routes when link goes down */ + u16 num_rx_queues; + u16 num_tx_queues; u8 test_mode; /* Set when Unit testing */ u8 netlink_processing_active; /* Set while a batch of Netlink messages are being processed */ @@ -61,6 +63,12 @@ u8 lcp_get_del_dynamic_on_link_down (void); void lcp_set_netlink_processing_active (u8 is_processing); u8 lcp_get_netlink_processing_active (void); +/** + * Get/Set the default queue number for LCP host taps. + */ +void lcp_set_default_num_queues (u16 num_queues, u8 is_tx); +u16 lcp_get_default_num_queues (u8 is_tx); + #endif /* diff --git a/src/plugins/linux-cp/lcp_api.c b/src/plugins/linux-cp/lcp_api.c index 991516a3ecd..74421230e9d 100644 --- a/src/plugins/linux-cp/lcp_api.c +++ b/src/plugins/linux-cp/lcp_api.c @@ -214,9 +214,16 @@ vl_api_lcp_itf_pair_get_v2_t_handler (vl_api_lcp_itf_pair_get_v2_t *mp) else { VALIDATE_SW_IF_INDEX_END (mp); + + u32 pair_index = lcp_itf_pair_find_by_phy (mp->sw_if_index); + if (pair_index == INDEX_INVALID) + { + rv = VNET_API_ERROR_INVALID_SW_IF_INDEX; + goto bad_sw_if_index; + } send_lcp_itf_pair_details ( - lcp_itf_pair_find_by_phy (mp->sw_if_index), - vl_api_client_index_to_registration (mp->client_index), mp->context); + pair_index, vl_api_client_index_to_registration (mp->client_index), + mp->context); BAD_SW_IF_INDEX_LABEL; REPLY_MACRO2_END (VL_API_LCP_ITF_PAIR_GET_V2_REPLY, diff --git a/src/plugins/linux-cp/lcp_interface.c b/src/plugins/linux-cp/lcp_interface.c index 921dccf5519..e1f4a6a1d69 100644 --- a/src/plugins/linux-cp/lcp_interface.c +++ b/src/plugins/linux-cp/lcp_interface.c @@ -555,6 +555,7 @@ static clib_error_t * lcp_itf_pair_config (vlib_main_t *vm, unformat_input_t *input) { u8 *default_ns; + u32 tmp; default_ns = NULL; @@ -579,6 +580,10 @@ lcp_itf_pair_config (vlib_main_t *vm, unformat_input_t *input) lcp_set_del_static_on_link_down (1 /* is_del */); else if (unformat (input, "del-dynamic-on-link-down")) lcp_set_del_dynamic_on_link_down (1 /* is_del */); + else if (unformat (input, "num-rx-queues %d", &tmp)) + lcp_set_default_num_queues (tmp, 0 /* is_tx */); + else if (unformat (input, "num-tx-queues %d", &tmp)) + lcp_set_default_num_queues (tmp, 1 /* is_tx */); else return clib_error_return (0, "interfaces not found"); } @@ -988,8 +993,10 @@ lcp_itf_pair_create (u32 phy_sw_if_index, u8 *host_if_name, else { tap_create_if_args_t args = { - .num_rx_queues = clib_max (1, vlib_num_workers ()), - .num_tx_queues = 1, + .num_rx_queues = + clib_max (1, lcp_get_default_num_queues (0 /* is_tx */)), + .num_tx_queues = + clib_max (1, lcp_get_default_num_queues (1 /* is_tx */)), .id = hw->hw_if_index, .sw_if_index = ~0, .rx_ring_sz = 256, diff --git a/src/plugins/lisp/lisp-cp/lisp_types.h b/src/plugins/lisp/lisp-cp/lisp_types.h index 21bd72178d7..e92f8f80c70 100644 --- a/src/plugins/lisp/lisp-cp/lisp_types.h +++ b/src/plugins/lisp/lisp-cp/lisp_types.h @@ -198,7 +198,8 @@ u8 gid_address_len (gid_address_t * a); void *gid_address_cast (gid_address_t * gid, gid_address_type_t type); void gid_address_copy (gid_address_t * dst, gid_address_t * src); u32 gid_address_parse (u8 * offset, gid_address_t * a); -void gid_address_ip_set (gid_address_t * dst, void *src, u8 version); +void gid_address_ip_set (gid_address_t *dst, void *src, + ip_address_family_t version); #define gid_address_type(_a) (_a)->type #define gid_address_ippref(_a) (_a)->ippref diff --git a/src/plugins/map/ip6_map_t.c b/src/plugins/map/ip6_map_t.c index 6bfc8e0f952..51853d619e6 100644 --- a/src/plugins/map/ip6_map_t.c +++ b/src/plugins/map/ip6_map_t.c @@ -529,7 +529,10 @@ ip6_map_t (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) ip60 = vlib_buffer_get_current (p0); d0 = - ip6_map_get_domain (&ip60->dst_address, + /* Originally using the IPv6 dest for rule lookup, now source + * [dgeist] ip6_map_get_domain (&ip60->dst_address, + */ + ip6_map_get_domain (&ip60->src_address, &vnet_buffer (p0)->map_t.map_domain_index, &error0); if (!d0) diff --git a/src/plugins/map/lpm.c b/src/plugins/map/lpm.c index c0e5bad1417..a2fc3337167 100644 --- a/src/plugins/map/lpm.c +++ b/src/plugins/map/lpm.c @@ -28,7 +28,13 @@ masked_address32 (uint32_t addr, uint8_t len) static uint64_t masked_address64 (uint64_t addr, uint8_t len) { - return len == 64 ? addr : addr & ~(~0ull >> len); + /* This was originally causing non-64-bit masks to not match due to LSB vs + * MSB masking (0s at the head of the value) Probably needs some corner case + * checking in case my masking logic was off [dgeist] + * + * return len == 64 ? addr : addr & ~(~0ull >> len); + */ + return len == 64 ? addr : addr & ((1ull << (len)) - 1); } static void @@ -126,13 +132,25 @@ lpm_128_add (lpm_t *lpm, void *addr_v, u8 pfxlen, u32 value) BVT(clib_bihash_kv) kv; ip6_address_t *addr = addr_v; - kv.key[0] = masked_address64(addr->as_u64[0], pfxlen > 64 ? 64 : pfxlen); + /* This is a quick hack. It works for pfxlen < 64 but needs validation for + * other [dgeist] + * + * kv.key[0] = masked_address64(addr->as_u64[0], pfxlen > 64 ? 64 : pfxlen); + */ + kv.key[0] = masked_address64 (addr->as_u64[0], pfxlen > 64 ? 64 : 64); kv.key[1] = masked_address64(addr->as_u64[1], pfxlen > 64 ? pfxlen - 64 : 0); kv.key[2] = pfxlen; kv.value = value; BV(clib_bihash_add_del)(&lpm->bihash, &kv, 1); lpm->prefix_length_refcount[pfxlen]++; - lpm->prefix_lengths_bitmap = clib_bitmap_set (lpm->prefix_lengths_bitmap, 128 - pfxlen, 1); + /* Populating the lengths bitmap table with prefix of 48 instead of 80 + * (128 - 48) [dgeist] + * + * lpm->prefix_lengths_bitmap = clib_bitmap_set ( + * lpm->prefix_lengths_bitmap, 128 - pfxlen, 1); + */ + lpm->prefix_lengths_bitmap = clib_bitmap_set ( + lpm->prefix_lengths_bitmap, pfxlen > 64 ? 128 - pfxlen : pfxlen, 1); } static void @@ -148,8 +166,8 @@ lpm_128_delete (lpm_t *lpm, void *addr_v, u8 pfxlen) /* refcount accounting */ ASSERT (lpm->prefix_length_refcount[pfxlen] > 0); if (--lpm->prefix_length_refcount[pfxlen] == 0) { - lpm->prefix_lengths_bitmap = clib_bitmap_set (lpm->prefix_lengths_bitmap, - 128 - pfxlen, 0); + lpm->prefix_lengths_bitmap = + clib_bitmap_set (lpm->prefix_lengths_bitmap, 128 - pfxlen, 0); } } diff --git a/src/plugins/map/map.c b/src/plugins/map/map.c index 6c9668dde51..3cffadd39e8 100644 --- a/src/plugins/map/map.c +++ b/src/plugins/map/map.c @@ -176,6 +176,10 @@ map_create_domain (ip4_address_t * ip4_prefix, mm->ip6_src_prefix_tbl->add (mm->ip6_src_prefix_tbl, &d->ip6_src, d->ip6_src_len, *map_domain_index); + /* Let's build a table with the MAP rule ip6 prefixes as well [dgeist] */ + mm->ip6_prefix_tbl->add (mm->ip6_prefix_tbl, &d->ip6_prefix, + d->ip6_prefix_len, *map_domain_index); + /* Validate packet/byte counters */ map_domain_counter_lock (mm); int i; @@ -218,6 +222,9 @@ map_delete_domain (u32 map_domain_index) d->ip4_prefix_len); mm->ip6_src_prefix_tbl->delete (mm->ip6_src_prefix_tbl, &d->ip6_src, d->ip6_src_len); + /* Addition to remove the new table [dgeist] */ + mm->ip6_prefix_tbl->delete (mm->ip6_prefix_tbl, &d->ip6_prefix, + d->ip6_prefix_len); /* Release user-assigned MAP domain name. */ map_free_extras (map_domain_index); diff --git a/src/plugins/map/map.h b/src/plugins/map/map.h index d874aa47b3a..86b8ec22df4 100644 --- a/src/plugins/map/map.h +++ b/src/plugins/map/map.h @@ -335,7 +335,11 @@ ip6_map_get_domain (ip6_address_t * addr, u32 * map_domain_index, u8 * error) { map_main_t *mm = &map_main; u32 mdi = - mm->ip6_src_prefix_tbl->lookup (mm->ip6_src_prefix_tbl, addr, 128); + /* This is the old src (ip6 destination) hash lookup [dgeist] + * + * mm->ip6_src_prefix_tbl->lookup (mm->ip6_src_prefix_tbl, addr, 128); + */ + mm->ip6_prefix_tbl->lookup (mm->ip6_prefix_tbl, addr, 128); if (mdi == ~0) { *error = MAP_ERROR_NO_DOMAIN; diff --git a/src/plugins/nat/nat44-ed/nat44_ed_api.c b/src/plugins/nat/nat44-ed/nat44_ed_api.c index 1f01410afce..b6c9d51d777 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed_api.c +++ b/src/plugins/nat/nat44-ed/nat44_ed_api.c @@ -442,7 +442,8 @@ send_nat44_ed_output_interface_details (u32 index, vl_api_registration_t *rp, /* Endian hack until apigen registers _details * endian functions */ - vl_api_nat44_ed_output_interface_details_t_endian (rmp); + vl_api_nat44_ed_output_interface_details_t_endian (rmp, + 1 /* to network */); rmp->_vl_msg_id = htons (rmp->_vl_msg_id); rmp->context = htonl (rmp->context); })); diff --git a/src/plugins/nat/nat44-ed/nat44_ed_in2out.c b/src/plugins/nat/nat44-ed/nat44_ed_in2out.c index 4ba51bcaea6..9b4dac3b356 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed_in2out.c +++ b/src/plugins/nat/nat44-ed/nat44_ed_in2out.c @@ -523,6 +523,7 @@ slow_path_ed (vlib_main_t *vm, snat_main_t *sm, vlib_buffer_t *b, nat_6t_flow_dport_rewrite_set (&s->o2i, l_port); } nat_6t_flow_txfib_rewrite_set (&s->o2i, rx_fib_index); + nat_6t_flow_saddr_rewrite_set (&s->o2i, r_addr.as_u32); if (nat_ed_alloc_addr_and_port ( sm, rx_fib_index, tx_sw_if_index, proto, thread_index, l_addr, @@ -567,6 +568,7 @@ slow_path_ed (vlib_main_t *vm, snat_main_t *sm, vlib_buffer_t *b, } nat_6t_flow_daddr_rewrite_set (&s->o2i, l_addr.as_u32); nat_6t_flow_txfib_rewrite_set (&s->o2i, rx_fib_index); + nat_6t_flow_saddr_rewrite_set (&s->o2i, r_addr.as_u32); if (nat_ed_ses_o2i_flow_hash_add_del (sm, thread_index, s, 2)) { nat_elog_notice (sm, "out2in key add failed"); diff --git a/src/plugins/nat/nat44-ei/nat44_ei_api.c b/src/plugins/nat/nat44-ei/nat44_ei_api.c index 8671a556929..454a5032c6a 100644 --- a/src/plugins/nat/nat44-ei/nat44_ei_api.c +++ b/src/plugins/nat/nat44-ei/nat44_ei_api.c @@ -751,7 +751,8 @@ send_nat44_ei_output_interface_details (u32 index, vl_api_registration_t *rp, /* Endian hack until apigen registers _details * endian functions */ - vl_api_nat44_ei_output_interface_details_t_endian (rmp); + vl_api_nat44_ei_output_interface_details_t_endian (rmp, + 1 /* to network */); rmp->_vl_msg_id = htons (rmp->_vl_msg_id); rmp->context = htonl (rmp->context); })); diff --git a/src/plugins/nat/nat44-ei/nat44_ei_in2out.c b/src/plugins/nat/nat44-ei/nat44_ei_in2out.c index 01b333a5234..3b981d69986 100644 --- a/src/plugins/nat/nat44-ei/nat44_ei_in2out.c +++ b/src/plugins/nat/nat44-ei/nat44_ei_in2out.c @@ -859,7 +859,7 @@ nat44_ei_icmp_in2out (vlib_buffer_t *b0, ip4_header_t *ip0, nat44_ei_main_t *nm = &nat44_ei_main; vlib_main_t *vm = vlib_get_main (); ip4_address_t addr; - u16 port; + u16 port = 0; u32 fib_index; nat_protocol_t proto; icmp_echo_header_t *echo0, *inner_echo0 = 0; diff --git a/src/plugins/nat/pnat/pnat_api.c b/src/plugins/nat/pnat/pnat_api.c index 02e61219d1e..a4e7ff192bf 100644 --- a/src/plugins/nat/pnat/pnat_api.c +++ b/src/plugins/nat/pnat/pnat_api.c @@ -116,7 +116,8 @@ static void send_bindings_details(u32 index, vl_api_registration_t *rp, /* Endian hack until apigen registers _details * endian functions */ - vl_api_pnat_bindings_details_t_endian(rmp); + vl_api_pnat_bindings_details_t_endian( + rmp, 1 /* to network */); rmp->_vl_msg_id = htons(rmp->_vl_msg_id); rmp->context = htonl(rmp->context); })); @@ -158,7 +159,7 @@ static void send_interfaces_details(u32 index, vl_api_registration_t *rp, /* Endian hack until apigen registers _details * endian functions */ - vl_api_pnat_interfaces_details_t_endian(rmp); + vl_api_pnat_interfaces_details_t_endian(rmp, 1 /* to network */); rmp->_vl_msg_id = htons(rmp->_vl_msg_id); rmp->context = htonl(rmp->context); })); diff --git a/src/plugins/stn/stn.c b/src/plugins/stn/stn.c index 6e789feca5d..c0ac0d0b3a6 100644 --- a/src/plugins/stn/stn.c +++ b/src/plugins/stn/stn.c @@ -49,7 +49,7 @@ format_stn_rule (u8 * s, va_list * args) s = format (s, "%Uiface: %U (%d)\n", format_white_space, indent, format_vnet_sw_if_index_name, vnet_get_main(), r->sw_if_index, r->sw_if_index); - s = format (s, "%Unext_node: %s (%d)", format_white_space, indent, + s = format (s, "%Unext_node: %v (%d)", format_white_space, indent, next_node->name, next_node->index); return s; } diff --git a/src/plugins/tlsopenssl/tls_openssl.c b/src/plugins/tlsopenssl/tls_openssl.c index a21e3bb54c1..5d172a0adcf 100644 --- a/src/plugins/tlsopenssl/tls_openssl.c +++ b/src/plugins/tlsopenssl/tls_openssl.c @@ -455,8 +455,11 @@ check_tls_fifo: sp->flags |= TRANSPORT_SND_F_DESCHED; } else - /* Request tx reschedule of the app session */ - app_session->flags |= SESSION_F_CUSTOM_TX; + { + /* Request tx reschedule of the app session */ + if (wrote) + app_session->flags |= SESSION_F_CUSTOM_TX; + } return wrote; } @@ -1176,18 +1179,13 @@ int tls_openssl_set_ciphers (char *ciphers) { openssl_main_t *om = &openssl_main; - int i; if (!ciphers) { return -1; } - vec_validate (om->ciphers, strlen (ciphers)); - for (i = 0; i < vec_len (om->ciphers) - 1; i++) - { - om->ciphers[i] = toupper (ciphers[i]); - } + vec_validate_init_c_string (om->ciphers, ciphers, strlen (ciphers)); return 0; diff --git a/src/plugins/unittest/gso_test.c b/src/plugins/unittest/gso_test.c index 54eb7422c87..43c614341d2 100644 --- a/src/plugins/unittest/gso_test.c +++ b/src/plugins/unittest/gso_test.c @@ -96,12 +96,94 @@ GSO_TEST_REGISTER_DATA (gso_ipv6_tcp, static) = { .is_ip6 = 1, }; +/* + * this does not support tunnel packets + */ +static void +set_hdr_offsets (vlib_buffer_t *b0, u8 is_l2) +{ + u16 ethertype = 0, l2hdr_sz = 0; + vnet_buffer_oflags_t oflags = 0; + u8 l4_proto = 0; + + if (!is_l2) + { + switch (b0->data[0] & 0xf0) + { + case 0x40: + ethertype = ETHERNET_TYPE_IP4; + break; + case 0x60: + ethertype = ETHERNET_TYPE_IP6; + break; + } + } + else + { + ethernet_header_t *eh = (ethernet_header_t *) b0->data; + ethertype = clib_net_to_host_u16 (eh->type); + l2hdr_sz = sizeof (ethernet_header_t); + + if (ethernet_frame_is_tagged (ethertype)) + { + ethernet_vlan_header_t *vlan = (ethernet_vlan_header_t *) (eh + 1); + + ethertype = clib_net_to_host_u16 (vlan->type); + l2hdr_sz += sizeof (*vlan); + if (ethertype == ETHERNET_TYPE_VLAN) + { + vlan++; + ethertype = clib_net_to_host_u16 (vlan->type); + l2hdr_sz += sizeof (*vlan); + } + } + } + + vnet_buffer (b0)->l2_hdr_offset = 0; + vnet_buffer (b0)->l3_hdr_offset = l2hdr_sz; + + if (PREDICT_TRUE (ethertype == ETHERNET_TYPE_IP4)) + { + ip4_header_t *ip4 = (ip4_header_t *) (b0->data + l2hdr_sz); + vnet_buffer (b0)->l4_hdr_offset = l2hdr_sz + ip4_header_bytes (ip4); + l4_proto = ip4->protocol; + oflags |= VNET_BUFFER_OFFLOAD_F_IP_CKSUM; + b0->flags |= (VNET_BUFFER_F_IS_IP4 | VNET_BUFFER_F_L2_HDR_OFFSET_VALID | + VNET_BUFFER_F_L3_HDR_OFFSET_VALID | + VNET_BUFFER_F_L4_HDR_OFFSET_VALID); + } + else if (PREDICT_TRUE (ethertype == ETHERNET_TYPE_IP6)) + { + ip6_header_t *ip6 = (ip6_header_t *) (b0->data + l2hdr_sz); + vnet_buffer (b0)->l4_hdr_offset = l2hdr_sz + sizeof (ip6_header_t); + /* FIXME IPv6 EH traversal */ + l4_proto = ip6->protocol; + b0->flags |= (VNET_BUFFER_F_IS_IP6 | VNET_BUFFER_F_L2_HDR_OFFSET_VALID | + VNET_BUFFER_F_L3_HDR_OFFSET_VALID | + VNET_BUFFER_F_L4_HDR_OFFSET_VALID); + } + if (l4_proto == IP_PROTOCOL_TCP) + { + oflags |= VNET_BUFFER_OFFLOAD_F_TCP_CKSUM; + } + else if (l4_proto == IP_PROTOCOL_UDP) + { + oflags |= VNET_BUFFER_OFFLOAD_F_UDP_CKSUM; + } + if (oflags) + vnet_buffer_offload_flags_set (b0, oflags); +} + static u32 -fill_buffers (vlib_main_t *vm, u32 *buffer_indices, u8 *data, u32 data_size, - u32 n_buffers, u32 buffer_size, u32 packet_size, u32 gso_size, - u32 l4_hdr_len) +fill_buffers (vlib_main_t *vm, u32 *buffer_indices, + gso_test_data_t *gso_test_data, u32 n_buffers, u32 buffer_size, + u32 packet_size, u32 gso_size) { u32 i; + u8 *data = gso_test_data->data; + u32 data_size = gso_test_data->data_size; + u32 l4_hdr_len = gso_test_data->l4_hdr_len; + u8 is_l2 = gso_test_data->is_l2; for (i = 0; i < n_buffers; i++) { @@ -153,6 +235,8 @@ fill_buffers (vlib_main_t *vm, u32 *buffer_indices, u8 *data, u32 data_size, len += fill_data_size; } while (k < n_bufs); + + set_hdr_offsets (b, is_l2); b->flags |= VNET_BUFFER_F_GSO; vnet_buffer2 (b)->gso_size = gso_size; vnet_buffer2 (b)->gso_l4_hdr_sz = l4_hdr_len; @@ -165,17 +249,14 @@ fill_buffers (vlib_main_t *vm, u32 *buffer_indices, u8 *data, u32 data_size, static_always_inline u32 gso_segment_buffer_test (vlib_main_t *vm, u32 bi, - vnet_interface_per_thread_data_t *ptd, u8 is_l2, - u8 is_ip6) + vnet_interface_per_thread_data_t *ptd, u8 is_l2) { vlib_buffer_t *b = vlib_get_buffer (vm, bi); - generic_header_offset_t gho = { 0 }; u32 n_tx_bytes = 0; if (PREDICT_TRUE (b->flags & VNET_BUFFER_F_GSO)) { - vnet_generic_header_offset_parser (b, &gho, is_l2, !is_ip6, is_ip6); - n_tx_bytes = gso_segment_buffer_inline (vm, ptd, b, &gho, is_l2, is_ip6); + n_tx_bytes = gso_segment_buffer_inline (vm, ptd, b, is_l2); } return n_tx_bytes; @@ -237,19 +318,16 @@ test_gso_perf (vlib_main_t *vm, gso_test_main_t *gtm) vlib_buffer_free (vm, buffer_indices, n_alloc); goto done; } - n_filled = - fill_buffers (vm, buffer_indices, gso_test_data->data, - gso_test_data->data_size, n_buffers, buffer_size, - packet_size, gso_size, gso_test_data->l4_hdr_len); + n_filled = fill_buffers (vm, buffer_indices, gso_test_data, n_buffers, + buffer_size, packet_size, gso_size); u8 is_l2 = gso_test_data->is_l2; - u8 is_ip6 = gso_test_data->is_ip6; for (k = 0; k < warmup_rounds; k++) { for (j = 0; j < n_filled; j++) - gso_segment_buffer_test (vm, buffer_indices[j], &ptd[j], is_l2, - is_ip6); + gso_segment_buffer_test (vm, buffer_indices[j], &ptd[j], is_l2); + for (j = 0; j < n_filled; j++) { vlib_buffer_free (vm, ptd[j].split_buffers, @@ -264,8 +342,9 @@ test_gso_perf (vlib_main_t *vm, gso_test_main_t *gtm) { t0 = clib_cpu_time_now (); for (j = 0; j < n_filled; j++) - gso_segment_buffer_test (vm, buffer_indices[j], &ptd[j], is_l2, - is_ip6); + gso_segment_buffer_test (vm, buffer_indices[j], &ptd[j], + is_l2); + t1 = clib_cpu_time_now (); t2[i] += (t1 - t0); for (j = 0; j < n_filled; j++) diff --git a/src/plugins/unittest/policer_test.c b/src/plugins/unittest/policer_test.c index 2b14bf687bf..41f769960a3 100644 --- a/src/plugins/unittest/policer_test.c +++ b/src/plugins/unittest/policer_test.c @@ -21,7 +21,7 @@ policer_test (vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd_arg) { int policer_index, i; - uint rate_kbps, burst, num_pkts; + unsigned int rate_kbps, burst, num_pkts; double total_bytes, cpu_ticks_per_pkt, time = 0; double cpu_speed, cpu_ticks_per_byte; policer_result_e result, input_colour = POLICE_CONFORM; diff --git a/src/plugins/vhost/CMakeLists.txt b/src/plugins/vhost/CMakeLists.txt index f72d9f20346..6b86c8c98d1 100644 --- a/src/plugins/vhost/CMakeLists.txt +++ b/src/plugins/vhost/CMakeLists.txt @@ -29,4 +29,6 @@ add_vpp_plugin(vhost API_FILES vhost_user.api + + SUPPORTED_OS_LIST Linux ) diff --git a/src/plugins/wireguard/wireguard_chachapoly.c b/src/plugins/wireguard/wireguard_chachapoly.c index 0dd7908d2e2..ad644ff6cb8 100644 --- a/src/plugins/wireguard/wireguard_chachapoly.c +++ b/src/plugins/wireguard/wireguard_chachapoly.c @@ -72,11 +72,11 @@ wg_xchacha20poly1305_encrypt (vlib_main_t *vm, u8 *src, u32 src_len, u8 *dst, u64 h_nonce; clib_memcpy (&h_nonce, nonce + 16, sizeof (h_nonce)); - h_nonce = le64toh (h_nonce); + h_nonce = clib_little_to_host_u64 (h_nonce); hchacha20 (derived_key, nonce, key); for (i = 0; i < (sizeof (derived_key) / sizeof (derived_key[0])); i++) - (derived_key[i]) = htole32 ((derived_key[i])); + (derived_key[i]) = clib_host_to_little_u32 ((derived_key[i])); uint32_t key_idx; @@ -102,11 +102,11 @@ wg_xchacha20poly1305_decrypt (vlib_main_t *vm, u8 *src, u32 src_len, u8 *dst, u64 h_nonce; clib_memcpy (&h_nonce, nonce + 16, sizeof (h_nonce)); - h_nonce = le64toh (h_nonce); + h_nonce = clib_little_to_host_u64 (h_nonce); hchacha20 (derived_key, nonce, key); for (i = 0; i < (sizeof (derived_key) / sizeof (derived_key[0])); i++) - (derived_key[i]) = htole32 ((derived_key[i])); + (derived_key[i]) = clib_host_to_little_u32 ((derived_key[i])); uint32_t key_idx; diff --git a/src/plugins/wireguard/wireguard_noise.c b/src/plugins/wireguard/wireguard_noise.c index 5fe2e44b03b..c3f28f442f5 100644 --- a/src/plugins/wireguard/wireguard_noise.c +++ b/src/plugins/wireguard/wireguard_noise.c @@ -751,8 +751,8 @@ noise_tai64n_now (uint8_t output[NOISE_TIMESTAMP_LEN]) unix_nanosec &= REJECT_INTERVAL_MASK; /* https://cr.yp.to/libtai/tai64.html */ - sec = htobe64 (0x400000000000000aULL + unix_sec); - nsec = htobe32 (unix_nanosec); + sec = clib_host_to_big_u64 (0x400000000000000aULL + unix_sec); + nsec = clib_host_to_big_u32 (unix_nanosec); /* memcpy to output buffer, assuming output could be unaligned. */ clib_memcpy (output, &sec, sizeof (sec)); |