From: Jie Liu <[email protected]> Introduce private testpmd commands and implementation files to enable debugging and testing of sxe2-specific hardware features (such as packet scheduling reset, UDP tunnel configuration, and IPsec ingress/ egress offloads) directly within the testpmd application.
Signed-off-by: Jie Liu <[email protected]> --- drivers/net/sxe2/meson.build | 5 +- drivers/net/sxe2/sxe2_ethdev.c | 26 + drivers/net/sxe2/sxe2_ethdev.h | 2 + drivers/net/sxe2/sxe2_testpmd.c | 733 +++++++++++++++++++++ drivers/net/sxe2/sxe2_testpmd_lib.c | 969 ++++++++++++++++++++++++++++ drivers/net/sxe2/sxe2_testpmd_lib.h | 142 ++++ drivers/net/sxe2/sxe2_tm.c | 18 + drivers/net/sxe2/sxe2_tm.h | 2 + 8 files changed, 1895 insertions(+), 2 deletions(-) create mode 100644 drivers/net/sxe2/sxe2_testpmd.c create mode 100644 drivers/net/sxe2/sxe2_testpmd_lib.c create mode 100644 drivers/net/sxe2/sxe2_testpmd_lib.h diff --git a/drivers/net/sxe2/meson.build b/drivers/net/sxe2/meson.build index 5a02b1c3d3..00a331c208 100644 --- a/drivers/net/sxe2/meson.build +++ b/drivers/net/sxe2/meson.build @@ -9,9 +9,10 @@ endif cflags += ['-g'] -deps += ['common_sxe2', 'hash','cryptodev','security'] +deps += ['common_sxe2', 'hash', 'cryptodev', 'security', 'cmdline'] includes += include_directories('../../common/sxe2') +testpmd_sources = files('sxe2_testpmd.c') if arch_subdir == 'x86' sources += files('sxe2_txrx_vec_sse.c') @@ -79,7 +80,7 @@ sources += files( 'sxe2_flow_parse_engine.c', 'sxe2_dump.c', 'sxe2_txrx_check_mbuf.c', - + 'sxe2_testpmd_lib.c', ) allow_internal_get_api = true diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c index 73a92d99f8..0b19e17c2e 100644 --- a/drivers/net/sxe2/sxe2_ethdev.c +++ b/drivers/net/sxe2/sxe2_ethdev.c @@ -1661,6 +1661,32 @@ static int32_t sxe2_sched_uinit(struct rte_eth_dev *dev) return ret; } +int32_t sxe2_sched_reset(struct rte_eth_dev *dev) +{ + int32_t ret = 0; + + if (dev->data->dev_started) { + PMD_LOG_ERR(DRV, "Device failed to Stop."); + ret = -EPERM; + goto l_end; + } + + ret = sxe2_tm_conf_reset(dev); + if (ret) + goto l_end; + + ret = sxe2_sched_uinit(dev); + if (ret) + goto l_end; + + ret = sxe2_sched_init(dev); + if (ret) + goto l_end; + +l_end: + return ret; +} + static int32_t sxe2_dev_init(struct rte_eth_dev *dev, struct sxe2_dev_kvargs_info *kvargs __rte_unused) { diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h index e7a8ee0dd5..56b3b3cfe4 100644 --- a/drivers/net/sxe2/sxe2_ethdev.h +++ b/drivers/net/sxe2/sxe2_ethdev.h @@ -361,6 +361,8 @@ bool sxe2_ethdev_check(struct rte_eth_dev *dev); uint32_t sxe2_sched_mode_get(struct sxe2_adapter *adapter); +int32_t sxe2_sched_reset(struct rte_eth_dev *dev); + struct sxe2_pci_map_bar_info *sxe2_dev_get_bar_info(struct sxe2_adapter *adapter, enum sxe2_pci_map_resource res_type); diff --git a/drivers/net/sxe2/sxe2_testpmd.c b/drivers/net/sxe2/sxe2_testpmd.c new file mode 100644 index 0000000000..5792058212 --- /dev/null +++ b/drivers/net/sxe2/sxe2_testpmd.c @@ -0,0 +1,733 @@ + +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd. + */ + +#ifndef SXE2_TEST +#include <cmdline_parse_num.h> +#include <cmdline_parse_string.h> +#include <stdlib.h> +#include <testpmd.h> + +#include "sxe2_common_log.h" +#include "sxe2_testpmd_lib.h" + +#define SXE2_SWITCH_BUFF_SIZE (4 * 1024 * 1024) + +struct cmd_stats_info_show_result { + cmdline_fixed_string_t sxe2; + cmdline_fixed_string_t show; + cmdline_fixed_string_t stats; + portid_t port_id; +}; +cmdline_parse_token_string_t cmd_stats_info_sxe2 = + TOKEN_STRING_INITIALIZER(struct cmd_stats_info_show_result, sxe2, "sxe2"); +cmdline_parse_token_string_t cmd_stats_info_show = + TOKEN_STRING_INITIALIZER(struct cmd_stats_info_show_result, show, "show"); +cmdline_parse_token_string_t cmd_stats_info_stats = + TOKEN_STRING_INITIALIZER(struct cmd_stats_info_show_result, stats, "stats"); +cmdline_parse_token_num_t cmd_stats_info_port_id = + TOKEN_NUM_INITIALIZER(struct cmd_stats_info_show_result, port_id, RTE_UINT16); + +struct cmd_flow_rule_result { + cmdline_fixed_string_t sxe2; + cmdline_fixed_string_t flow; + cmdline_fixed_string_t rule; + cmdline_fixed_string_t dump; + portid_t port_id; +}; +cmdline_parse_token_string_t cmd_flow_rule_sxe2 = + TOKEN_STRING_INITIALIZER(struct cmd_flow_rule_result, sxe2, "sxe2"); +cmdline_parse_token_string_t cmd_flow_rule_flow = + TOKEN_STRING_INITIALIZER(struct cmd_flow_rule_result, flow, "flow"); +cmdline_parse_token_string_t cmd_flow_rule_rule = + TOKEN_STRING_INITIALIZER(struct cmd_flow_rule_result, rule, "rule"); +cmdline_parse_token_string_t cmd_flow_rule_dmp = + TOKEN_STRING_INITIALIZER(struct cmd_flow_rule_result, dump, "dump"); +cmdline_parse_token_num_t cmd_flow_rule_port_id = + TOKEN_NUM_INITIALIZER(struct cmd_flow_rule_result, port_id, RTE_UINT16); + +struct cmd_udp_tunnel { + cmdline_fixed_string_t sxe2; + cmdline_fixed_string_t tunnel_type; + cmdline_fixed_string_t action; + cmdline_fixed_string_t udp_tunnel_port; + uint16_t udp_port; + portid_t port_id; +}; + +cmdline_parse_token_string_t cmd_udp_tunnel_sxe2 = + TOKEN_STRING_INITIALIZER(struct cmd_udp_tunnel, sxe2, "sxe2"); +cmdline_parse_token_string_t cmd_udp_tunnel_action = + TOKEN_STRING_INITIALIZER(struct cmd_udp_tunnel, action, "add#rm#show"); +cmdline_parse_token_string_t cmd_udp_tunnel_udp_tunnel_port = + TOKEN_STRING_INITIALIZER(struct cmd_udp_tunnel, udp_tunnel_port, "udp_tunnel_port"); +cmdline_parse_token_string_t cmd_udp_tunnel_tunnel_type = + TOKEN_STRING_INITIALIZER(struct cmd_udp_tunnel, + tunnel_type, "vxlan#vxlan-gpe#geneve#gtp-c#gtp-u#pfcp#ecpri#mpls#nvgre#l2tp#teredo"); +cmdline_parse_token_num_t cmd_udp_tunnel_udp_port = + TOKEN_NUM_INITIALIZER(struct cmd_udp_tunnel, udp_port, RTE_UINT16); +cmdline_parse_token_num_t cmd_udp_tunnel_port_id = + TOKEN_NUM_INITIALIZER(struct cmd_udp_tunnel, port_id, RTE_UINT16); + +struct cmd_sched_result { + cmdline_fixed_string_t sxe2; + cmdline_fixed_string_t sched; + cmdline_fixed_string_t reset; + portid_t port_id; +}; + +cmdline_parse_token_string_t cmd_sched_sxe2 = + TOKEN_STRING_INITIALIZER(struct cmd_sched_result, sxe2, "sxe2"); +cmdline_parse_token_string_t cmd_sched_sched = + TOKEN_STRING_INITIALIZER(struct cmd_sched_result, sched, "sched"); +cmdline_parse_token_string_t cmd_sched_reset = + TOKEN_STRING_INITIALIZER(struct cmd_sched_result, reset, "reset"); +cmdline_parse_token_num_t cmd_sched_port_id = + TOKEN_NUM_INITIALIZER(struct cmd_sched_result, port_id, RTE_UINT16); + +struct cmd_ipsec_result { + cmdline_fixed_string_t sxe2; + cmdline_fixed_string_t engin; + cmdline_fixed_string_t dir; + cmdline_fixed_string_t op; + portid_t port_id; + uint16_t session_id; + cmdline_fixed_string_t encrypt_algo; + cmdline_fixed_string_t encrypt_key; + cmdline_fixed_string_t auth_algo; + cmdline_fixed_string_t auth_key; + cmdline_fixed_string_t dst_ip; + uint16_t sport; + uint16_t dport; + uint32_t spi; +}; +cmdline_parse_token_string_t cmd_ipsec_mgt_sxe2 = + TOKEN_STRING_INITIALIZER(struct cmd_ipsec_result, sxe2, "sxe2"); +cmdline_parse_token_string_t cmd_ipsec_mgt_module = + TOKEN_STRING_INITIALIZER(struct cmd_ipsec_result, engin, "ipsec"); +cmdline_parse_token_string_t cmd_ipsec_mgt_dir = + TOKEN_STRING_INITIALIZER(struct cmd_ipsec_result, dir, "egress#ingress"); +cmdline_parse_token_string_t cmd_ipsec_mgt_op = + TOKEN_STRING_INITIALIZER(struct cmd_ipsec_result, op, "add#rm#show"); +cmdline_parse_token_num_t cmd_ipsec_mgt_port_id = + TOKEN_NUM_INITIALIZER(struct cmd_ipsec_result, port_id, RTE_UINT16); +cmdline_parse_token_num_t cmd_ipsec_mgt_session_id = + TOKEN_NUM_INITIALIZER(struct cmd_ipsec_result, session_id, RTE_UINT16); +cmdline_parse_token_string_t cmd_ipsec_mgt_encrypt_algo = + TOKEN_STRING_INITIALIZER(struct cmd_ipsec_result, encrypt_algo, "aes-cbc#sm4-cbc#null"); +cmdline_parse_token_string_t cmd_ipsec_mgt_encrypt_key = + TOKEN_STRING_INITIALIZER(struct cmd_ipsec_result, encrypt_key, NULL); +cmdline_parse_token_string_t cmd_ipsec_mgt_auth_algo = + TOKEN_STRING_INITIALIZER(struct cmd_ipsec_result, auth_algo, "sha-hmac#sm3-hmac#null"); +cmdline_parse_token_string_t cmd_ipsec_mgt_auth_key = + TOKEN_STRING_INITIALIZER(struct cmd_ipsec_result, auth_key, NULL); +cmdline_parse_token_string_t cmd_ipsec_mgt_dst_ip = + TOKEN_STRING_INITIALIZER(struct cmd_ipsec_result, dst_ip, NULL); +cmdline_parse_token_num_t cmd_ipsec_mgt_sport = + TOKEN_NUM_INITIALIZER(struct cmd_ipsec_result, sport, RTE_UINT16); +cmdline_parse_token_num_t cmd_ipsec_mgt_dport = + TOKEN_NUM_INITIALIZER(struct cmd_ipsec_result, dport, RTE_UINT16); +cmdline_parse_token_num_t cmd_ipsec_mgt_spi = + TOKEN_NUM_INITIALIZER(struct cmd_ipsec_result, spi, RTE_UINT32); + +struct cmd_ipsec_set_result { + cmdline_fixed_string_t sxe2; + cmdline_fixed_string_t engin; + cmdline_fixed_string_t op; + cmdline_fixed_string_t type; + portid_t port_id; + uint16_t conf_value; +}; +cmdline_parse_token_string_t cmd_ipsec_set_sxe2 = + TOKEN_STRING_INITIALIZER(struct cmd_ipsec_set_result, sxe2, "sxe2"); +cmdline_parse_token_string_t cmd_ipsec_set_module = + TOKEN_STRING_INITIALIZER(struct cmd_ipsec_set_result, engin, "ipsec"); +cmdline_parse_token_string_t cmd_ipsec_set_op = + TOKEN_STRING_INITIALIZER(struct cmd_ipsec_set_result, op, "set#get"); +cmdline_parse_token_string_t cmd_ipsec_set_type = + TOKEN_STRING_INITIALIZER(struct cmd_ipsec_set_result, type, "session-id#esp-hdr-offset"); +cmdline_parse_token_num_t cmd_ipsec_set_port_id = + TOKEN_NUM_INITIALIZER(struct cmd_ipsec_set_result, port_id, RTE_UINT16); +cmdline_parse_token_num_t cmd_ipsec_set_value = + TOKEN_NUM_INITIALIZER(struct cmd_ipsec_set_result, conf_value, RTE_UINT16); + +struct cmd_ipsec_flush_result { + cmdline_fixed_string_t sxe2; + cmdline_fixed_string_t engin; + cmdline_fixed_string_t op; + portid_t port_id; +}; +cmdline_parse_token_string_t cmd_ipsec_flush_sxe2 = + TOKEN_STRING_INITIALIZER(struct cmd_ipsec_flush_result, sxe2, "sxe2"); +cmdline_parse_token_string_t cmd_ipsec_flush_module = + TOKEN_STRING_INITIALIZER(struct cmd_ipsec_flush_result, engin, "ipsec"); +cmdline_parse_token_string_t cmd_ipsec_flush_op = + TOKEN_STRING_INITIALIZER(struct cmd_ipsec_flush_result, op, "flush"); +cmdline_parse_token_num_t cmd_ipsec_flush_port_id = + TOKEN_NUM_INITIALIZER(struct cmd_ipsec_flush_result, port_id, RTE_UINT16); + +struct cmd_inject_irq { + cmdline_fixed_string_t sxe2; + cmdline_fixed_string_t inject; + cmdline_fixed_string_t irq; + portid_t port_id; + cmdline_fixed_string_t type; +}; +cmdline_parse_token_string_t cmd_inject_irq_sxe2 = + TOKEN_STRING_INITIALIZER(struct cmd_inject_irq, sxe2, "sxe2"); +cmdline_parse_token_string_t cmd_inject_irq_inject = + TOKEN_STRING_INITIALIZER(struct cmd_inject_irq, inject, "inject"); +cmdline_parse_token_string_t cmd_inject_irq_irq = + TOKEN_STRING_INITIALIZER(struct cmd_inject_irq, irq, "irq"); +cmdline_parse_token_num_t cmd_inject_irq_port_id = + TOKEN_NUM_INITIALIZER(struct cmd_inject_irq, port_id, RTE_UINT16); +cmdline_parse_token_string_t cmd_inject_irq_type = + TOKEN_STRING_INITIALIZER(struct cmd_inject_irq, type, "reset#lsc"); + +static void cmd_dump_flow_rule_parsed(void *parsed_result, + struct cmdline *cl, + __rte_unused void *data) +{ + struct cmd_flow_rule_result *res = parsed_result; + int ret = -1; + + ret = sxe2_flow_rule_dump(res->port_id, cl); + switch (ret) { + case 0: + break; + case -EINVAL: + cmdline_printf(cl, "Invalid parameters.\n"); + break; + case -ENODEV: + cmdline_printf(cl, "Device doesn't support\n"); + break; + default: + cmdline_printf(cl, + "Failed to switch rule dump," + " error: (%s)\n", + strerror(-ret)); + } +} + +static void cmd_udp_tunnel_set_parsed(void *parsed_result, + struct cmdline *cl, + __rte_unused void *data) +{ + struct cmd_udp_tunnel *res = parsed_result; + int32_t ret = -1; + uint8_t action; + const char *action_str[SXE2_TESTPMD_CMD_UDP_TUNNEL_MAX] = { + [SXE2_TESTPMD_CMD_UDP_TUNNEL_ADD] = "add", + [SXE2_TESTPMD_CMD_UDP_TUNNEL_DEL] = "rm", + [SXE2_TESTPMD_CMD_UDP_TUNNEL_GET] = "show"}; + + for (action = 0; action < SXE2_TESTPMD_CMD_UDP_TUNNEL_MAX; action++) + if (!strcmp(res->action, action_str[action])) + break; + + if (action >= SXE2_TESTPMD_CMD_UDP_TUNNEL_MAX) { + cmdline_printf(cl, "Invalid action!\n"); + return; + } + + ret = sxe2_udp_tunnel_operations(res->port_id, cl, action, + res->udp_port, + res->tunnel_type); + if (ret) + cmdline_printf(cl, "%s udp tunnel port failed, ret = %d\n", + action_str[action], ret); +} + +static void cmd_dump_stats_info_parsed(void *parsed_result, + struct cmdline *cl, + __rte_unused void *data) +{ + struct cmd_stats_info_show_result *res = parsed_result; + int ret = -1; + + ret = sxe2_stats_info_show(res->port_id); + switch (ret) { + case 0: + break; + case -EINVAL: + cmdline_printf(cl, "Invalid parameters.\n"); + break; + case -ENODEV: + cmdline_printf(cl, "Device doesn't support\n"); + break; + default: + cmdline_printf(cl, + "Failed to show stats info," + " error: (%s)\n", strerror(-ret)); + } +} + +static uint8_t cmd_ipsec_op_get(char *op) +{ + uint8_t i; + const char *op_type[SXE2_TESTPMD_CMD_IPSEC_OP_MAX] = { + [SXE2_TESTPMD_CMD_IPSEC_OP_ADD] = "add", + [SXE2_TESTPMD_CMD_IPSEC_OP_RM] = "rm", + [SXE2_TESTPMD_CMD_IPSEC_OP_SHOW] = "show", + }; + + for (i = 0; i < SXE2_TESTPMD_CMD_IPSEC_OP_MAX; i++) { + if (!strcmp(op, op_type[i])) + break; + } + + return i; +} + +static uint8_t cmd_ipsec_dir_get(char *dir) +{ + uint8_t i; + const char *dir_type[SXE2_TESTPMD_CMD_IPSEC_DIR_MAX] = { + [SXE2_TESTPMD_CMD_IPSEC_DIR_EGRESS] = "egress", + [SXE2_TESTPMD_CMD_IPSEC_DIR_INGRESS] = "ingress" + }; + + for (i = 0; i < SXE2_TESTPMD_CMD_IPSEC_DIR_MAX; i++) { + if (!strcmp(dir, dir_type[i])) + break; + } + + return i; +} + +static int sxe2_hex_to_val(char c) +{ + int val = 0; + + if (c >= '0' && c <= '9') + val = c - '0'; + if (c >= 'A' && c <= 'F') + val = 10 + c - 'A'; + if (c >= 'a' && c <= 'f') + val = 10 + c - 'a'; + return val; +} + +static void sxe2_hex_to_bytes(uint8_t *enc_key, char *hex_str, uint8_t len) +{ + uint8_t i; + int high = 0; + int low = 0; + + for (i = 0; i < len; i++) { + high = sxe2_hex_to_val(hex_str[2 * i]); + low = sxe2_hex_to_val(hex_str[2 * i + 1]); + enc_key[i] = (high << 4) | low; + } +} + +static int32_t cmd_ipsec_add_param_fill(struct sxe2_ipsec_conf_param *param, + struct cmdline *cl, + struct cmd_ipsec_result *res) +{ + uint8_t i; + uint8_t j; + int32_t ret = -1; + const char *encrypt_algo[SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_MAX] = { + [SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_AES_CBC] = "aes-cbc", + [SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_SM4_CBC] = "sm4-cbc", + [SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_NULL] = "null" + }; + + const char *auth_algo[SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_MAX] = { + [SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_SHA_HMAC] = "sha-hmac", + [SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_SM3_HMAC] = "sm3-hmac", + [SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_NULL] = "null" + }; + + for (i = 0; i < SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_MAX; i++) + if (!strcmp(res->encrypt_algo, encrypt_algo[i])) + break; + + if (i >= SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_MAX) { + cmdline_printf(cl, "Invalid ipsec encrypt algo: %s!\n", res->encrypt_algo); + ret = -EINVAL; + goto l_end; + } + + for (j = 0; j < SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_MAX; j++) { + if (!strcmp(res->auth_algo, auth_algo[j])) + break; + } + + + if (j >= SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_MAX) { + cmdline_printf(cl, "Invalid ipsec auth algo: %s!\n", res->auth_algo); + ret = -EINVAL; + goto l_end; + } + + param->encrypt_algo = i; + param->auth_algo = j; + if (param->encrypt_algo == SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_SM4_CBC) + param->enc_len = 16; + else + param->enc_len = 32; + + sxe2_hex_to_bytes(param->enc_key, res->encrypt_key, param->enc_len); + if (param->auth_algo != SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_NULL) { + param->auth_len = 32; + sxe2_hex_to_bytes(param->auth_key, res->auth_key, param->auth_len); + } + + ret = 0; + +l_end: + return ret; +} + +static int32_t cmd_ipsec_egress_op_parsed(struct sxe2_ipsec_conf_param *param, + struct cmdline *cl, + struct cmd_ipsec_result *res) +{ + int32_t ret = -1; + + switch (param->op) { + case SXE2_TESTPMD_CMD_IPSEC_OP_ADD: + ret = cmd_ipsec_add_param_fill(param, cl, res); + if (ret) + goto l_end; + ret = sxe2_ipsec_egress_create(param, cl); + break; + case SXE2_TESTPMD_CMD_IPSEC_OP_RM: + param->session_id = res->session_id; + ret = sxe2_ipsec_egress_destroy(param, cl); + break; + case SXE2_TESTPMD_CMD_IPSEC_OP_SHOW: + ret = sxe2_ipsec_egress_show(param, cl); + break; + default: + ret = -EINVAL; + break; + } + +l_end: + return ret; +} + +static int32_t cmd_ipsec_ip_addr_parsed(struct sxe2_ipsec_conf_param *param, + struct cmdline *cl, + struct cmd_ipsec_result *res) +{ + int32_t ret = -1; + struct in_addr addr4; + struct in6_addr addr6; + + if (inet_pton(AF_INET, res->dst_ip, &addr4) == 1) { + param->ip_addr.type = RTE_SECURITY_IPSEC_TUNNEL_IPV4; + param->ip_addr.dst_ipv4 = addr4.s_addr; + ret = 0; + } else if (inet_pton(AF_INET6, res->dst_ip, &addr6) == 1) { + param->ip_addr.type = RTE_SECURITY_IPSEC_TUNNEL_IPV6; + memcpy(¶m->ip_addr.dst_ipv6, &addr6, sizeof(param->ip_addr.dst_ipv6)); + ret = 0; + } else { + cmdline_printf(cl, "Invalid ip address: %s!\n", res->dst_ip); + ret = -EINVAL; + goto l_end; + } + +l_end: + return ret; +} + +static int32_t cmd_ipsec_ingress_op_parsed(struct sxe2_ipsec_conf_param *param, + struct cmdline *cl, + struct cmd_ipsec_result *res) +{ + int32_t ret = -1; + + switch (param->op) { + case SXE2_TESTPMD_CMD_IPSEC_OP_ADD: + ret = cmd_ipsec_add_param_fill(param, cl, res); + if (ret) + goto l_end; + param->sport = htons(res->sport); + param->dport = htons(res->dport); + param->spi = htonl(res->spi); + ret = cmd_ipsec_ip_addr_parsed(param, cl, res); + if (ret) + goto l_end; + ret = sxe2_ipsec_ingress_create(param, cl); + break; + case SXE2_TESTPMD_CMD_IPSEC_OP_RM: + param->session_id = res->session_id; + ret = sxe2_ipsec_ingress_destroy(param, cl); + break; + case SXE2_TESTPMD_CMD_IPSEC_OP_SHOW: + ret = sxe2_ipsec_ingress_show(param, cl); + break; + default: + ret = -EINVAL; + break; + } + +l_end: + return ret; +} + +static int32_t cmd_ipsec_dir_parsed(struct sxe2_ipsec_conf_param *param, + struct cmdline *cl, + struct cmd_ipsec_result *res) +{ + int32_t ret = -1; + + switch (param->dir) { + case SXE2_TESTPMD_CMD_IPSEC_DIR_EGRESS: + ret = cmd_ipsec_egress_op_parsed(param, cl, res); + break; + case SXE2_TESTPMD_CMD_IPSEC_DIR_INGRESS: + ret = cmd_ipsec_ingress_op_parsed(param, cl, res); + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static void cmd_ipsec_mgt_parsed(void *parsed_result, + struct cmdline *cl, + __rte_unused void *data) +{ + struct cmd_ipsec_result *res = parsed_result; + struct sxe2_ipsec_conf_param param; + int32_t ret = -1; + uint8_t dir = 0; + uint8_t op = 0; + + dir = cmd_ipsec_dir_get(res->dir); + if (dir >= SXE2_TESTPMD_CMD_IPSEC_DIR_MAX) { + cmdline_printf(cl, "Invalid ipsec direction: %s!\n", res->dir); + ret = -EINVAL; + goto l_end; + } + + op = cmd_ipsec_op_get(res->op); + if (op >= SXE2_TESTPMD_CMD_IPSEC_OP_MAX) { + cmdline_printf(cl, "Invalid ipsec operation: %s!\n", res->op); + ret = -EINVAL; + goto l_end; + } + + memset(¶m, 0, sizeof(struct sxe2_ipsec_conf_param)); + param.dir = dir; + param.op = op; + param.port_id = res->port_id; + ret = cmd_ipsec_dir_parsed(¶m, cl, res); + + if (ret) + cmdline_printf(cl, "Command execute failed, ret = %d\n", ret); + +l_end: + return; +} + +static void cmd_ipsec_set_parsed(void *parsed_result, + struct cmdline *cl, + __rte_unused void *data) +{ + struct cmd_ipsec_set_result *res = parsed_result; + int32_t ret = -1; + + if (!strcmp(res->op, "set")) + ret = sxe2_ipsec_conf_set(res->port_id, cl, res->type, res->conf_value); + else if (!strcmp(res->op, "get")) + ret = sxe2_ipsec_conf_get(res->port_id, cl, res->type); + else + cmdline_printf(cl, "Invalid op: %s\n", res->op); + + if (ret) + cmdline_printf(cl, "Command execute failed, ret = %d\n", ret); +} + +static void cmd_ipsec_flush_parsed(void *parsed_result, + struct cmdline *cl, + __rte_unused void *data) +{ + struct cmd_ipsec_flush_result *res = parsed_result; + int32_t ret = -1; + + ret = sxe2_ipsec_flush(res->port_id, cl); + + if (ret) + cmdline_printf(cl, "Command execute failed, ret = %d\n", ret); +} + +cmdline_parse_inst_t cmd_flow_rule_dump = { + .f = cmd_dump_flow_rule_parsed, + .data = NULL, + .help_str = "sxe2 flow rule dump <port_id>", + .tokens = { + (void *)&cmd_flow_rule_sxe2, + (void *)&cmd_flow_rule_flow, + (void *)&cmd_flow_rule_rule, + (void *)&cmd_flow_rule_dmp, + (void *)&cmd_flow_rule_port_id, + NULL, + }, +}; + +cmdline_parse_inst_t cmd_udp_tunnel_set = { + .f = cmd_udp_tunnel_set_parsed, + .data = NULL, + .help_str = "sxe2 <port_id> udp_tunnel_port add|rm|show " + "vxlan|vxlan-gpe|geneve|gtp-c|gtp-u|pfcp|ecpri|mpls|nvgre|l2tp|teredo <udp_port>", + .tokens = { + (void *)&cmd_udp_tunnel_sxe2, + (void *)&cmd_udp_tunnel_port_id, + (void *)&cmd_udp_tunnel_udp_tunnel_port, + (void *)&cmd_udp_tunnel_action, + (void *)&cmd_udp_tunnel_tunnel_type, + (void *)&cmd_udp_tunnel_udp_port, + NULL, + }, +}; + +cmdline_parse_inst_t cmd_stats_mgt = { + .f = cmd_dump_stats_info_parsed, + .data = NULL, + .help_str = "sxe2 show stats <port_id>", + .tokens = { + (void *)&cmd_stats_info_sxe2, + (void *)&cmd_stats_info_show, + (void *)&cmd_stats_info_stats, + (void *)&cmd_stats_info_port_id, + NULL, + }, +}; + +static void cmd_sched_reset_cfg(void *parsed_result, + struct cmdline *cl, + __rte_unused void *data) +{ + struct cmd_sched_result *res = parsed_result; + int32_t ret = -1; + + ret = sxe2_testpmd_sched_reset(res->port_id); + switch (ret) { + case 0: + break; + case -EINVAL: + cmdline_printf(cl, "invalid sched ops\n"); + break; + case -ENOTSUP: + cmdline_printf(cl, "function not implemented\n"); + break; + default: + cmdline_printf(cl, "programming error: (%s)\n", + strerror(-ret)); + } +} + +cmdline_parse_inst_t cmd_sched_reset_cmd = { + .f = cmd_sched_reset_cfg, + .data = NULL, + .help_str = "sxe2 sched reset <port_id>", + .tokens = { + (void *)&cmd_sched_sxe2, + (void *)&cmd_sched_sched, + (void *)&cmd_sched_reset, + (void *)&cmd_sched_port_id, + NULL, + }, +}; + +cmdline_parse_inst_t cmd_ipsec_mgt = { + .f = cmd_ipsec_mgt_parsed, + .data = NULL, + .help_str = "sxe2 ipsec egress|ingress add|rm|show " + "<port_id> <session_id> aes-cbc|sm4-cbc|null <encrypt_key> sha-hmac|sm3-hmac|null " + "<auth_key> <dst_ip> <sport> <dport> <spi>", + .tokens = { + (void *)&cmd_ipsec_mgt_sxe2, + (void *)&cmd_ipsec_mgt_module, + (void *)&cmd_ipsec_mgt_dir, + (void *)&cmd_ipsec_mgt_op, + (void *)&cmd_ipsec_mgt_port_id, + (void *)&cmd_ipsec_mgt_session_id, + (void *)&cmd_ipsec_mgt_encrypt_algo, + (void *)&cmd_ipsec_mgt_encrypt_key, + (void *)&cmd_ipsec_mgt_auth_algo, + (void *)&cmd_ipsec_mgt_auth_key, + (void *)&cmd_ipsec_mgt_dst_ip, + (void *)&cmd_ipsec_mgt_sport, + (void *)&cmd_ipsec_mgt_dport, + (void *)&cmd_ipsec_mgt_spi, + NULL, + }, +}; + +cmdline_parse_inst_t cmd_ipsec_set = { + .f = cmd_ipsec_set_parsed, + .data = NULL, + .help_str = "sxe2 ipsec set|get esp-hdr-offset|session-id <port_id> <value>", + .tokens = { + (void *)&cmd_ipsec_set_sxe2, + (void *)&cmd_ipsec_set_module, + (void *)&cmd_ipsec_set_op, + (void *)&cmd_ipsec_set_type, + (void *)&cmd_ipsec_set_port_id, + (void *)&cmd_ipsec_set_value, + NULL, + }, +}; + +cmdline_parse_inst_t cmd_ipsec_flush = { + .f = cmd_ipsec_flush_parsed, + .data = NULL, + .help_str = "sxe2 ipsec flush <port_id>.\n", + .tokens = { + (void *)&cmd_ipsec_flush_sxe2, + (void *)&cmd_ipsec_flush_module, + (void *)&cmd_ipsec_flush_op, + (void *)&cmd_ipsec_flush_port_id, + NULL, + }, +}; + +static struct testpmd_driver_commands sxe2_cmds = { + .commands = { + { + &cmd_udp_tunnel_set, + "sxe2 udp tunnel port set.\n" + "Add or remove a customed udp port for specific tunnel protocol\n\n", + }, + { + &cmd_sched_reset_cmd, + "sxe2 sched reset <port_id>.\n" + "Reset sched node on the port\n\n", + }, + { + &cmd_stats_mgt, + "sxe2 show stats.\n" + "Dump a runtime sxe2 dev stats on a port\n\n", + }, + { + &cmd_ipsec_mgt, + "sxe2 ipsec <dir> <op> <port_id> <session_id> <encrypt_algo> <encrypt_key>" + "<encrypt_len> <auth_algo> <auth_key> <auth_len> <dst_ip> <sport> <dport> <spi>.\n" + "Create/query/remove ipsec security session\n\n", + }, + { + &cmd_ipsec_set, + "sxe2 ipsec set <port_id> <session_id> <esp_hdr_offset>.\n" + "Set enabled tx session id or esp offset.\n\n", + }, + { + &cmd_ipsec_flush, + "sxe2 ipsec flush <port_id>.\n" + "Flush ipsec all configurations\n\n", + }, + { NULL, NULL}, + }, +}; +TESTPMD_ADD_DRIVER_COMMANDS(sxe2_cmds) +#endif diff --git a/drivers/net/sxe2/sxe2_testpmd_lib.c b/drivers/net/sxe2/sxe2_testpmd_lib.c new file mode 100644 index 0000000000..ab2530ffe6 --- /dev/null +++ b/drivers/net/sxe2/sxe2_testpmd_lib.c @@ -0,0 +1,969 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd. + */ + +#include <rte_bus.h> +#include <eal_export.h> + +#include "sxe2_common_log.h" +#include "sxe2_ethdev.h" +#include "sxe2_stats.h" +#include "sxe2_testpmd_lib.h" + +struct rte_mempool *g_sess_pool; + +bool g_sxe2_ipsec_mgt_init; +struct sxe2_ipsec_session_mgt g_tx_session[SXE2_IPSEC_PORT_MAX][SXE2_IPSEC_SESSION_MAX]; +struct sxe2_ipsec_session_mgt g_rx_session[SXE2_IPSEC_PORT_MAX][SXE2_IPSEC_SESSION_MAX]; +uint16_t g_tx_sess_id[SXE2_IPSEC_PORT_MAX] = {0}; +uint16_t g_esp_header_offset[SXE2_IPSEC_PORT_MAX] = {0}; + +static bool sxe2_is_supported(struct rte_eth_dev *dev) +{ + return sxe2_ethdev_check(dev); +} + +RTE_EXPORT_EXPERIMENTAL_SYMBOL(sxe2_testpmd_sched_reset, 26.07) +int32_t +sxe2_testpmd_sched_reset(uint16_t port_id) +{ + struct rte_eth_dev *dev = NULL; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + + dev = &rte_eth_devices[port_id]; + if (!sxe2_is_supported(dev)) { + PMD_LOG_ERR(DRV, "Invalid dev."); + return -ENODEV; + } + + return sxe2_sched_reset(dev); +} + +extern const char *sxe2_flow_type_name[SXE2_FLOW_TYPE_MAX]; + +RTE_EXPORT_EXPERIMENTAL_SYMBOL(sxe2_flow_rule_dump, 26.07) +int32_t +sxe2_flow_rule_dump(uint16_t port_id, struct cmdline *cl) +{ + struct rte_eth_dev *dev = NULL; + struct sxe2_adapter *adapter = NULL; + int32_t ret = -1; + struct rte_flow_list_t *flow_list = NULL; + struct rte_flow *flow = NULL; + uint32_t index = 0; + struct sxe2_flow *hw_flow = NULL; + uint8_t i = 0; + + const char *sxe2_flow_engine_name[SXE2_FLOW_ENGINE_MAX] = { + [SXE2_FLOW_ENGINE_ACL] = "acl", + [SXE2_FLOW_ENGINE_RSS] = "rss", + [SXE2_FLOW_ENGINE_SWITCH] = "switch", + [SXE2_FLOW_ENGINE_FNAV] = "fnav", + }; + const char *sxe2_flow_action_name[SXE2_FLOW_ACTION_MAX] = { + [SXE2_FLOW_ACTION_DROP] = "drop", + [SXE2_FLOW_ACTION_TC_REDIRECT] = "tc_redirect", + [SXE2_FLOW_ACTION_TO_VSI] = "to_vsi", + [SXE2_FLOW_ACTION_TO_VSI_LIST] = "to_vsi_list", + [SXE2_FLOW_ACTION_PASSTHRU] = "passthru", + [SXE2_FLOW_ACTION_QUEUE] = "queue", + [SXE2_FLOW_ACTION_Q_REGION] = "q_region", + [SXE2_FLOW_ACTION_MARK] = "mark", + [SXE2_FLOW_ACTION_COUNT] = "count", + [SXE2_FLOW_ACTION_RSS] = "rss", + }; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + dev = &rte_eth_devices[port_id]; + if (!sxe2_is_supported(dev)) { + PMD_LOG_ERR(DRV, "Invalid dev"); + ret = -ENODEV; + goto l_end; + } + adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev); + flow_list = &adapter->flow_ctxt.rte_flow_list; + cmdline_printf(cl, "Dump sxe2 flow rule:\n"); + TAILQ_FOREACH(flow, flow_list, next) { + cmdline_printf(cl, "rule index: %d\n", index++); + TAILQ_FOREACH(hw_flow, &flow->sxe2_flow_list, next) { + cmdline_printf(cl, "\thw flow id: %d\n", hw_flow->flow_id); + cmdline_printf(cl, "\t\ttype: %s\n", + sxe2_flow_type_name[hw_flow->meta.flow_type]); + cmdline_printf(cl, "\t\tprio: %d\n", hw_flow->meta.flow_prio); + cmdline_printf(cl, "\t\tsrc vsi: %d,rule vsi: %d\n", + hw_flow->meta.flow_src_vsi, hw_flow->meta.flow_rule_vsi); + cmdline_printf(cl, "\t\tengine type: %s\n", + sxe2_flow_engine_name[hw_flow->engine_type]); + cmdline_printf(cl, "\t\taction:"); + for (i = 0; i < SXE2_FLOW_ACTION_MAX; i++) { + if (sxe2_test_bit(i, hw_flow->action.act_types)) + cmdline_printf(cl, "%s ", sxe2_flow_action_name[i]); + } + cmdline_printf(cl, "\n"); + } + } + cmdline_printf(cl, "Dump sxe2 flow rule end.\n"); + ret = 0; +l_end: + return ret; +} + +static const char *tunnel_type_list[SXE2_UDP_TUNNEL_MAX] = { + [SXE2_UDP_TUNNEL_PROTOCOL_VXLAN] = "vxlan", + [SXE2_UDP_TUNNEL_PROTOCOL_VXLAN_GPE] = "vxlan-gpe", + [SXE2_UDP_TUNNEL_PROTOCOL_GENEVE] = "geneve", + [SXE2_UDP_TUNNEL_PROTOCOL_GTP_C] = "gtp-c", + [SXE2_UDP_TUNNEL_PROTOCOL_GTP_U] = "gtp-u", + [SXE2_UDP_TUNNEL_PROTOCOL_PFCP] = "pfcp", + [SXE2_UDP_TUNNEL_PROTOCOL_ECPRI] = "ecpri", + [SXE2_UDP_TUNNEL_PROTOCOL_MPLS] = "mpls", + [SXE2_UDP_TUNNEL_PROTOCOL_NVGRE] = "nvgre", + [SXE2_UDP_TUNNEL_PROTOCOL_L2TP] = "l2tp", + [SXE2_UDP_TUNNEL_PROTOCOL_TEREDO] = "teredo" +}; + +static enum sxe2_udp_tunnel_protocol sxe2_udp_tunnel_type_str2proto(const char *tunnel_type) +{ + enum sxe2_udp_tunnel_protocol proto; + + for (proto = 0; proto < SXE2_UDP_TUNNEL_MAX; proto++) { + if (tunnel_type_list[proto] != NULL && + strcmp(tunnel_type_list[proto], tunnel_type) == 0) { + break; + } + } + + return proto; +} + +RTE_EXPORT_EXPERIMENTAL_SYMBOL(sxe2_udp_tunnel_operations, 26.07) +int32_t +sxe2_udp_tunnel_operations(uint16_t port_id, struct cmdline *cl, uint8_t action, + uint16_t udp_port, const char *tunnel_type) +{ + enum sxe2_udp_tunnel_protocol proto = sxe2_udp_tunnel_type_str2proto(tunnel_type); + struct rte_eth_dev *dev = NULL; + struct sxe2_adapter *adapter = NULL; + struct sxe2_udp_tunnel_cfg tunnel_config = { 0 }; + int32_t ret = -1; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + dev = &rte_eth_devices[port_id]; + if (!sxe2_is_supported(dev)) { + PMD_LOG_ERR(DRV, "Invalid dev."); + ret = -ENODEV; + goto l_end; + } + + if (proto >= SXE2_UDP_TUNNEL_MAX) { + cmdline_printf(cl, "Invalid tunnel type!\n"); + goto l_end; + } + adapter = dev->data->dev_private; + switch (action) { + case SXE2_TESTPMD_CMD_UDP_TUNNEL_ADD: + ret = sxe2_udp_tunnel_port_add_common(adapter, proto, udp_port); + break; + case SXE2_TESTPMD_CMD_UDP_TUNNEL_DEL: + ret = sxe2_udp_tunnel_port_del_common(adapter, proto, udp_port); + break; + case SXE2_TESTPMD_CMD_UDP_TUNNEL_GET: + tunnel_config.protocol = proto; + ret = sxe2_udp_tunnel_port_get_common(adapter, &tunnel_config); + if (!ret) { + cmdline_printf(cl, "Dump firmware udp tunnel config: [proto:%s, port:%d," + "enable:%d, src/dst:%d/%d, used:%d]\n", + tunnel_type_list[proto], tunnel_config.fw_port, + tunnel_config.fw_status, tunnel_config.fw_src_en, + tunnel_config.fw_dst_en, tunnel_config.fw_used); + } + break; + default: + break; + } + +l_end: + return ret; +} + +RTE_EXPORT_EXPERIMENTAL_SYMBOL(sxe2_stats_info_show, 26.07) +int32_t +sxe2_stats_info_show(uint16_t port_id) +{ + struct rte_eth_dev *dev = NULL; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + + dev = &rte_eth_devices[port_id]; + if (!sxe2_is_supported(dev)) { + PMD_LOG_ERR(DRV, "Invalid dev."); + return -ENODEV; + } + + return 0; +} + +static int32_t sxe2_ipsec_init_mempools(void *sec_ctx) +{ + uint16_t nb_sess = 8192; + uint32_t sess_sz; + char s[64]; + int32_t ret = -1; + + sess_sz = rte_security_session_get_size(sec_ctx); + if (g_sess_pool == NULL) { + snprintf(s, sizeof(s), "sess_pool"); + g_sess_pool = rte_mempool_create(s, nb_sess, sess_sz, + MEMPOOL_CACHE_SIZE, 0, + NULL, NULL, NULL, NULL, + SOCKET_ID_ANY, 0); + if (g_sess_pool == NULL) { + ret = -ENOMEM; + PMD_LOG_ERR(DRV, "Failed to malloc session pool memory."); + goto l_end; + } + } + ret = 0; + +l_end: + return ret; +} + +static void sxe2_ipsec_init_session_mgt(void) +{ + uint16_t i; + uint8_t port_id; + + if (g_sxe2_ipsec_mgt_init) + return; + + for (port_id = 0; port_id < SXE2_IPSEC_PORT_MAX; port_id++) { + for (i = 0; i < SXE2_IPSEC_SESSION_MAX; i++) { + g_tx_session[port_id][i].session = NULL; + g_tx_session[port_id][i].encrypt_algo = SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_NULL; + g_tx_session[port_id][i].auth_algo = SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_NULL; + g_tx_session[port_id][i].session_id = i; + g_tx_session[port_id][i].status = 0; + } + } + + for (port_id = 0; port_id < SXE2_IPSEC_PORT_MAX; port_id++) { + for (i = 0; i < SXE2_IPSEC_SESSION_MAX; i++) { + g_rx_session[port_id][i].session = NULL; + g_rx_session[port_id][i].encrypt_algo = SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_NULL; + g_rx_session[port_id][i].auth_algo = SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_NULL; + g_rx_session[port_id][i].session_id = i; + g_rx_session[port_id][i].status = 0; + } + } + + g_sxe2_ipsec_mgt_init = true; +} + +static uint16_t sxe2_ipsec_session_mgt_alloc(enum sxe2_testpmd_ipsec_dir dir, uint16_t port_id) +{ + uint16_t i; + uint16_t index = 0XFFFF; + struct sxe2_ipsec_session_mgt *mgt = NULL; + + if (dir == SXE2_TESTPMD_CMD_IPSEC_DIR_EGRESS) + mgt = g_tx_session[port_id]; + else + mgt = g_rx_session[port_id]; + + for (i = 0; i < SXE2_IPSEC_SESSION_MAX; i++) { + if (mgt[i].status == 0) { + index = i; + mgt[i].status = 1; + break; + } + } + + return index; +} + +static void sxe2_ipsec_session_mgt_free(enum sxe2_testpmd_ipsec_dir dir, + uint16_t index, uint16_t port_id) +{ + struct sxe2_ipsec_session_mgt *mgt = NULL; + + if (dir == SXE2_TESTPMD_CMD_IPSEC_DIR_EGRESS) + mgt = g_tx_session[port_id]; + else + mgt = g_rx_session[port_id]; + + mgt[index].session = NULL; + mgt[index].status = 0; +} + +static int32_t sxe2_ipsec_egress_construct(struct cmdline *cl, + struct rte_crypto_sym_xform **xform, + struct sxe2_ipsec_conf_param *param) +{ + struct rte_crypto_sym_xform *cur_xform = NULL; + struct rte_crypto_sym_xform *next_xform = NULL; + int32_t ret = -1; + + cur_xform = rte_zmalloc("current xform", + sizeof(struct rte_crypto_sym_xform), 0); + if (cur_xform == NULL) { + ret = -ENOMEM; + cmdline_printf(cl, "Failed to malloc memory!\n"); + goto l_end; + } + cur_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cur_xform->cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT; + if (param->encrypt_algo == SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_AES_CBC) + cur_xform->cipher.algo = SXE2_RTE_CRYPTO_CIPHER_AES_CBC; + else + cur_xform->cipher.algo = SXE2_RTE_RTE_CRYPTO_CIPHER_SM4_CBC; + cur_xform->cipher.key.length = param->enc_len; + cur_xform->cipher.key.data = param->enc_key; + + if (param->auth_algo == SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_NULL) { + ret = 0; + goto l_end; + } + + next_xform = rte_zmalloc("next xform", + sizeof(struct rte_crypto_sym_xform), 0); + if (next_xform == NULL) { + rte_free(cur_xform); + ret = -ENOMEM; + cmdline_printf(cl, "Failed to malloc memory!\n"); + goto l_end; + } + next_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; + next_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE; + if (param->auth_algo == SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_SHA_HMAC) + next_xform->auth.algo = SXE2_RTE_CRYPTO_AUTH_SHA256_HMAC; + else + next_xform->auth.algo = SXE2_RTE_CRYPTO_AUTH_SM3_HMAC; + next_xform->auth.key.length = param->auth_len; + next_xform->auth.key.data = param->auth_key; + cur_xform->next = next_xform; + ret = 0; + +l_end: + *xform = cur_xform; + return ret; +} + +static int32_t sxe2_ipsec_ingress_construct(struct cmdline *cl, + struct rte_crypto_sym_xform **xform, + struct sxe2_ipsec_conf_param *param) +{ + struct rte_crypto_sym_xform *cur_xform = NULL; + struct rte_crypto_sym_xform *next_xform = NULL; + int32_t ret = -1; + + cur_xform = rte_zmalloc("current xform", + sizeof(struct rte_crypto_sym_xform), 0); + if (cur_xform == NULL) { + ret = -ENOMEM; + cmdline_printf(cl, "Failed to malloc memory!\n"); + goto l_end; + } + + if (param->auth_algo == SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_NULL) { + cur_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; + cur_xform->cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; + if (param->encrypt_algo == SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_AES_CBC) + cur_xform->cipher.algo = SXE2_RTE_CRYPTO_CIPHER_AES_CBC; + else + cur_xform->cipher.algo = SXE2_RTE_RTE_CRYPTO_CIPHER_SM4_CBC; + cur_xform->cipher.key.length = param->enc_len; + cur_xform->cipher.key.data = param->enc_key; + ret = 0; + goto l_end; + } + + cur_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH; + cur_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY; + if (param->auth_algo == SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_SHA_HMAC) + cur_xform->auth.algo = SXE2_RTE_CRYPTO_AUTH_SHA256_HMAC; + else + cur_xform->auth.algo = SXE2_RTE_CRYPTO_AUTH_SM3_HMAC; + + cur_xform->auth.key.length = param->auth_len; + cur_xform->auth.key.data = param->auth_key; + + next_xform = rte_zmalloc("next xform", + sizeof(struct rte_crypto_sym_xform), 0); + if (next_xform == NULL) { + rte_free(cur_xform); + ret = -ENOMEM; + cmdline_printf(cl, "Failed to malloc memory!\n"); + goto l_end; + } + + next_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER; + next_xform->cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT; + if (param->encrypt_algo == SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_AES_CBC) + next_xform->cipher.algo = SXE2_RTE_CRYPTO_CIPHER_AES_CBC; + else + next_xform->cipher.algo = SXE2_RTE_RTE_CRYPTO_CIPHER_SM4_CBC; + next_xform->cipher.key.length = param->enc_len; + next_xform->cipher.key.data = param->enc_key; + cur_xform->next = next_xform; + ret = 0; + +l_end: + *xform = cur_xform; + return ret; +} + +RTE_EXPORT_EXPERIMENTAL_SYMBOL(sxe2_ipsec_ingress_create, 26.07) +int32_t +sxe2_ipsec_ingress_create(struct sxe2_ipsec_conf_param *param, struct cmdline *cl) +{ + struct rte_eth_dev *dev = NULL; + struct rte_security_session_conf conf; + struct rte_crypto_sym_xform *encrypt_xform = NULL; + void *session = NULL; + struct rte_security_ctx *p_ctx = NULL; + int32_t ret = -1; + uint16_t index; + uint8_t i; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(param->port_id, -ENODEV); + + dev = &rte_eth_devices[param->port_id]; + if (!sxe2_is_supported(dev)) { + PMD_LOG_ERR(DRV, "Invalid dev."); + ret = -ENODEV; + goto l_end; + } + + if (dev->data->dev_started != 0) { + cmdline_printf(cl, "port %d must be stopped.\n", dev->data->port_id); + ret = 0; + goto l_end; + } + + p_ctx = rte_eth_dev_get_sec_ctx(param->port_id); + + if (g_sess_pool == NULL) { + ret = sxe2_ipsec_init_mempools(p_ctx); + if (ret) + goto l_end; + } + + sxe2_ipsec_init_session_mgt(); + + memset(&conf, 0, sizeof(conf)); + conf.protocol = RTE_SECURITY_PROTOCOL_IPSEC; + conf.action_type = RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO; + conf.ipsec.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; + conf.ipsec.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; + conf.ipsec.direction = RTE_SECURITY_IPSEC_SA_DIR_INGRESS; + conf.ipsec.spi = param->spi; + conf.ipsec.udp.sport = param->sport; + conf.ipsec.udp.dport = param->dport; + conf.ipsec.tunnel.type = param->ip_addr.type; + if (param->sport || param->dport) + conf.ipsec.options.udp_encap = true; + if (param->ip_addr.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) + conf.ipsec.tunnel.ipv4.dst_ip.s_addr = param->ip_addr.dst_ipv4; + else + memcpy(&conf.ipsec.tunnel.ipv6.dst_addr, + ¶m->ip_addr.dst_ipv6, + sizeof(param->ip_addr.dst_ipv6)); + + ret = sxe2_ipsec_ingress_construct(cl, &encrypt_xform, param); + if (ret) + goto l_end; + conf.crypto_xform = encrypt_xform; + + session = rte_security_session_create(p_ctx, &conf, g_sess_pool); + if (session == NULL) { + ret = -1; + goto l_free; + } + + index = sxe2_ipsec_session_mgt_alloc(param->dir, param->port_id); + if (index == 0XFFFF) { + ret = -1; + goto l_free; + } + + g_rx_session[param->port_id][index].session = session; + g_rx_session[param->port_id][index].encrypt_algo = param->encrypt_algo; + g_rx_session[param->port_id][index].auth_algo = param->auth_algo; + for (i = 0; i < 32; i++) { + g_rx_session[param->port_id][index].enc_key[i] = param->enc_key[i]; + g_rx_session[param->port_id][index].auth_key[i] = param->auth_key[i]; + } + g_rx_session[param->port_id][index].sport = ntohs(param->sport); + g_rx_session[param->port_id][index].dport = ntohs(param->dport); + g_rx_session[param->port_id][index].spi = ntohl(param->spi); + memcpy(&g_rx_session[param->port_id][index].ip_addr, + ¶m->ip_addr, + sizeof(struct sxe2_ipsec_ip_param)); + + ret = 0; + +l_free: + if (encrypt_xform->next) + rte_free(encrypt_xform->next); + if (encrypt_xform) + rte_free(encrypt_xform); + +l_end: + return ret; +} + +RTE_EXPORT_EXPERIMENTAL_SYMBOL(sxe2_ipsec_ingress_destroy, 26.07) +int32_t +sxe2_ipsec_ingress_destroy(struct sxe2_ipsec_conf_param *param, struct cmdline *cl) +{ + struct rte_eth_dev *dev = NULL; + struct rte_security_ctx *p_ctx = NULL; + struct rte_security_session *session = NULL; + int32_t ret = -1; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(param->port_id, -ENODEV); + + dev = &rte_eth_devices[param->port_id]; + if (!sxe2_is_supported(dev)) { + cmdline_printf(cl, "Invalid dev.\n"); + ret = -ENODEV; + goto l_end; + } + + if (dev->data->dev_started != 0) { + cmdline_printf(cl, "port %d must be stopped.\n", dev->data->port_id); + ret = 0; + goto l_end; + } + + if (param->session_id >= SXE2_IPSEC_SESSION_MAX) { + PMD_LOG_ERR(DRV, "Invalid session id."); + ret = -EINVAL; + goto l_end; + } + + if (!g_rx_session[param->port_id][param->session_id].status) { + PMD_LOG_ERR(DRV, "Invalid session status."); + ret = -EINVAL; + goto l_end; + } + + if (g_rx_session[param->port_id][param->session_id].session == NULL) { + PMD_LOG_ERR(DRV, "Invalid session data."); + ret = -EINVAL; + goto l_end; + } + + p_ctx = rte_eth_dev_get_sec_ctx(param->port_id); + + session = g_rx_session[param->port_id][param->session_id].session; + ret = rte_security_session_destroy(p_ctx, session); + if (ret) + goto l_end; + sxe2_ipsec_session_mgt_free(param->dir, param->session_id, param->port_id); + + ret = 0; +l_end: + return ret; +} + +RTE_EXPORT_EXPERIMENTAL_SYMBOL(sxe2_ipsec_ingress_show, 26.07) +int32_t +sxe2_ipsec_ingress_show(struct sxe2_ipsec_conf_param *param, struct cmdline *cl) +{ + struct rte_eth_dev *dev = NULL; + int32_t ret = -1; + uint16_t i; + uint8_t j; + char encrypt_key[65]; + char auth_key[65]; + const char *encrypt_algo[SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_MAX] = { + [SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_AES_CBC] = "aes-cbc", + [SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_SM4_CBC] = "sm4-cbc", + [SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_NULL] = "null" + }; + + const char *auth_algo[SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_MAX] = { + [SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_SHA_HMAC] = "sha-hmac", + [SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_SM3_HMAC] = "sm3-hmac", + [SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_NULL] = "null" + }; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(param->port_id, -ENODEV); + + dev = &rte_eth_devices[param->port_id]; + if (!sxe2_is_supported(dev)) { + PMD_LOG_ERR(DRV, "Invalid dev."); + ret = -ENODEV; + goto l_end; + } + + for (i = 0; i < SXE2_IPSEC_SESSION_MAX; i++) { + if (g_rx_session[param->port_id][i].status && + g_rx_session[param->port_id][i].session) { + memset(encrypt_key, '\0', sizeof(encrypt_key)); + memset(auth_key, '\0', sizeof(auth_key)); + for (j = 0; j < 32; j++) { + sprintf(encrypt_key + 2 * j, "%02x", + g_rx_session[param->port_id][i].enc_key[j]); + } + + if (g_rx_session[param->port_id][i].auth_algo != + SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_NULL) { + for (j = 0; j < 32; j++) { + sprintf(auth_key + 2 * j, "%02x", + g_rx_session[param->port_id][i].auth_key[j]); + } + } + + cmdline_printf(cl, "session_id:%u, direction:rx ," + "encrypt_algo:%s, encrypt_key:0x%s," + "auth_algo:%s, auth_key:0x%s, sport:%u, dport:%u, spi:%u\n", + i, + encrypt_algo[g_rx_session[param->port_id][i].encrypt_algo], + encrypt_key, + auth_algo[g_rx_session[param->port_id][i].auth_algo], + auth_key, + g_rx_session[param->port_id][i].sport, + g_rx_session[param->port_id][i].dport, + g_rx_session[param->port_id][i].spi); + } + } + + ret = 0; + +l_end: + return ret; +} + +RTE_EXPORT_EXPERIMENTAL_SYMBOL(sxe2_ipsec_egress_create, 26.07) +int32_t +sxe2_ipsec_egress_create(struct sxe2_ipsec_conf_param *param, struct cmdline *cl) +{ + struct rte_eth_dev *dev = NULL; + struct rte_security_session_conf conf; + struct rte_crypto_sym_xform *encrypt_xform = NULL; + void *session = NULL; + struct rte_security_ctx *p_ctx = NULL; + int32_t ret = -1; + uint16_t index; + uint8_t i; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(param->port_id, -ENODEV); + + dev = &rte_eth_devices[param->port_id]; + if (!sxe2_is_supported(dev)) { + PMD_LOG_ERR(DRV, "Invalid dev."); + ret = -ENODEV; + goto l_end; + } + + if (dev->data->dev_started != 0) { + cmdline_printf(cl, "port %d must be stopped.\n", dev->data->port_id); + ret = 0; + goto l_end; + } + + p_ctx = rte_eth_dev_get_sec_ctx(param->port_id); + + if (g_sess_pool == NULL) { + ret = sxe2_ipsec_init_mempools(p_ctx); + if (ret) + goto l_end; + } + + sxe2_ipsec_init_session_mgt(); + + memset(&conf, 0, sizeof(conf)); + conf.protocol = RTE_SECURITY_PROTOCOL_IPSEC; + conf.action_type = RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO; + conf.ipsec.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL; + conf.ipsec.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP; + conf.ipsec.direction = RTE_SECURITY_IPSEC_SA_DIR_EGRESS; + + ret = sxe2_ipsec_egress_construct(cl, &encrypt_xform, param); + if (ret) + goto l_end; + conf.crypto_xform = encrypt_xform; + + session = rte_security_session_create(p_ctx, &conf, g_sess_pool); + if (session == NULL) { + ret = -1; + goto l_free; + } + + index = sxe2_ipsec_session_mgt_alloc(param->dir, param->port_id); + if (index == 0XFFFF) { + ret = -1; + goto l_free; + } + + g_tx_session[param->port_id][index].session = session; + g_tx_session[param->port_id][index].encrypt_algo = param->encrypt_algo; + g_tx_session[param->port_id][index].auth_algo = param->auth_algo; + for (i = 0; i < 32; i++) { + g_tx_session[param->port_id][index].enc_key[i] = param->enc_key[i]; + g_tx_session[param->port_id][index].auth_key[i] = param->auth_key[i]; + } + ret = 0; + +l_free: + if (encrypt_xform->next) + rte_free(encrypt_xform->next); + if (encrypt_xform) + rte_free(encrypt_xform); + +l_end: + return ret; +} + +RTE_EXPORT_EXPERIMENTAL_SYMBOL(sxe2_ipsec_egress_destroy, 26.07) +int32_t +sxe2_ipsec_egress_destroy(struct sxe2_ipsec_conf_param *param, struct cmdline *cl) +{ + struct rte_eth_dev *dev = NULL; + struct rte_security_ctx *p_ctx = NULL; + struct rte_security_session *session = NULL; + int32_t ret = -1; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(param->port_id, -ENODEV); + + dev = &rte_eth_devices[param->port_id]; + if (!sxe2_is_supported(dev)) { + PMD_LOG_ERR(DRV, "Invalid dev."); + ret = -ENODEV; + goto l_end; + } + + if (dev->data->dev_started != 0) { + cmdline_printf(cl, "port %d must be stopped.\n", dev->data->port_id); + ret = 0; + goto l_end; + } + + if (param->session_id >= SXE2_IPSEC_SESSION_MAX) { + PMD_LOG_ERR(DRV, "Invalid session id."); + ret = -EINVAL; + goto l_end; + } + + if (!g_tx_session[param->port_id][param->session_id].status) { + PMD_LOG_ERR(DRV, "Invalid session status."); + ret = -EINVAL; + goto l_end; + } + + if (g_tx_session[param->port_id][param->session_id].session == NULL) { + PMD_LOG_ERR(DRV, "Invalid session data."); + ret = -EINVAL; + goto l_end; + } + + p_ctx = rte_eth_dev_get_sec_ctx(param->port_id); + + session = g_tx_session[param->port_id][param->session_id].session; + ret = rte_security_session_destroy(p_ctx, session); + if (ret) + goto l_end; + sxe2_ipsec_session_mgt_free(param->dir, param->session_id, param->port_id); + + ret = 0; + +l_end: + return ret; +} + +RTE_EXPORT_EXPERIMENTAL_SYMBOL(sxe2_ipsec_egress_show, 26.07) +int32_t +sxe2_ipsec_egress_show(struct sxe2_ipsec_conf_param *param, struct cmdline *cl) +{ + struct rte_eth_dev *dev = NULL; + int32_t ret = -1; + uint16_t i; + uint8_t j; + char encrypt_key[65]; + char auth_key[65]; + const char *encrypt_algo[SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_MAX] = { + [SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_AES_CBC] = "aes-cbc", + [SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_SM4_CBC] = "sm4-cbc", + [SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_NULL] = "null" + }; + + const char *auth_algo[SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_MAX] = { + [SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_SHA_HMAC] = "sha-hmac", + [SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_SM3_HMAC] = "sm3-hmac", + [SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_NULL] = "null" + }; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(param->port_id, -ENODEV); + + dev = &rte_eth_devices[param->port_id]; + if (!sxe2_is_supported(dev)) { + PMD_LOG_ERR(DRV, "Invalid dev."); + ret = -ENODEV; + goto l_end; + } + + for (i = 0; i < SXE2_IPSEC_SESSION_MAX; i++) { + if (g_tx_session[param->port_id][i].status && + g_tx_session[param->port_id][i].session) { + memset(encrypt_key, '\0', sizeof(encrypt_key)); + memset(auth_key, '\0', sizeof(auth_key)); + for (j = 0; j < 32; j++) + sprintf(encrypt_key + 2 * j, "%02x", + g_tx_session[param->port_id][i].enc_key[j]); + if (g_tx_session[param->port_id][i].auth_algo != + SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_NULL) + for (j = 0; j < 32; j++) + sprintf(auth_key + 2 * j, "%02x", + g_tx_session[param->port_id][i].auth_key[j]); + + cmdline_printf(cl, "id:%u, tx , encrypt_algo:%s," + "encrypt_key:0x%s, auth_algo:%s, auth_key:0x%s.\n", + i, + encrypt_algo[g_tx_session[param->port_id][i].encrypt_algo], + encrypt_key, + auth_algo[g_tx_session[param->port_id][i].auth_algo], + auth_key); + } + } + + ret = 0; + +l_end: + return ret; +} + +RTE_EXPORT_EXPERIMENTAL_SYMBOL(sxe2_ipsec_conf_get, 26.07) +int32_t +sxe2_ipsec_conf_get(uint16_t port_id, struct cmdline *cl, char type[]) +{ + struct rte_eth_dev *dev = NULL; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + + dev = &rte_eth_devices[port_id]; + if (!sxe2_is_supported(dev)) { + PMD_LOG_ERR(DRV, "Invalid dev."); + return -ENODEV; + } + if (!strcmp(type, "session-id")) + cmdline_printf(cl, "session-id: %u\n", + g_tx_sess_id[port_id]); + else if (!strcmp(type, "esp-hdr-offset")) + cmdline_printf(cl, "esp-hdr-offset: %u\n", + g_esp_header_offset[port_id]); + else + cmdline_printf(cl, "Invalid type: %s\n", type); + + return 0; +} + +RTE_EXPORT_EXPERIMENTAL_SYMBOL(sxe2_ipsec_conf_set, 26.07) +int32_t +sxe2_ipsec_conf_set(uint16_t port_id, struct cmdline *cl, char type[], uint16_t value) +{ + struct rte_eth_dev *dev = NULL; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + + dev = &rte_eth_devices[port_id]; + if (!sxe2_is_supported(dev)) { + PMD_LOG_ERR(DRV, "Invalid dev."); + return -ENODEV; + } + if (!strcmp(type, "session-id")) { + if (value >= 4096 || !g_tx_session[port_id][value].status) { + cmdline_printf(cl, "Invalid session-id: %u," + "0 <= value <= 4095 or the session is inactive.\n", value); + return -EINVAL; + } + g_tx_sess_id[port_id] = value; + cmdline_printf(cl, "session-id: %u\n", g_tx_sess_id[port_id]); + } else if (!strcmp(type, "esp-hdr-offset")) { + if (value < 34 || value > 512) { + cmdline_printf(cl, "Invalid esp-hdr-offset: %u," + "34 <= value <= 512.\n", value); + return -EINVAL; + } + g_esp_header_offset[port_id] = value; + cmdline_printf(cl, "esp-hdr-offset: %u\n", + g_esp_header_offset[port_id]); + } else { + cmdline_printf(cl, "Invalid type: %s\n", type); + } + + return 0; +} + +RTE_EXPORT_EXPERIMENTAL_SYMBOL(sxe2_ipsec_stats_show, 26.07) +int32_t +sxe2_ipsec_stats_show(uint16_t port_id) +{ + (void)port_id; + return 0; +} + + +RTE_EXPORT_EXPERIMENTAL_SYMBOL(sxe2_ipsec_flush, 26.07) +int32_t +sxe2_ipsec_flush(uint16_t port_id, struct cmdline *cl) +{ + struct rte_eth_dev *dev = NULL; + struct rte_security_ctx *p_ctx = NULL; + struct rte_security_session *session = NULL; + int32_t ret = -1; + uint16_t i; + + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); + + dev = &rte_eth_devices[port_id]; + if (!sxe2_is_supported(dev)) { + cmdline_printf(cl, "Invalid dev.\n"); + ret = -ENODEV; + goto l_end; + } + + if (dev->data->dev_started != 0) { + cmdline_printf(cl, "port %d must be stopped.\n", dev->data->port_id); + ret = 0; + goto l_end; + } + + p_ctx = rte_eth_dev_get_sec_ctx(port_id); + + g_esp_header_offset[port_id] = 0; + g_tx_sess_id[port_id] = 0; + + for (i = 0; i < SXE2_IPSEC_SESSION_MAX; i++) { + session = g_tx_session[port_id][i].session; + if (g_tx_session[port_id][i].status && session) { + ret = rte_security_session_destroy(p_ctx, session); + if (ret) + cmdline_printf(cl, "failed to destroy tx session: %d.\n", i); + else + sxe2_ipsec_session_mgt_free(SXE2_TESTPMD_CMD_IPSEC_DIR_EGRESS, + i, port_id); + } + } + + for (i = 0; i < SXE2_IPSEC_SESSION_MAX; i++) { + session = g_rx_session[port_id][i].session; + if (g_rx_session[port_id][i].status && session) { + ret = rte_security_session_destroy(p_ctx, session); + if (ret) + cmdline_printf(cl, "failed to destroy rx session: %d.\n", i); + else + sxe2_ipsec_session_mgt_free(SXE2_TESTPMD_CMD_IPSEC_DIR_INGRESS, + i, port_id); + } + } + + g_sxe2_ipsec_mgt_init = false; + ret = 0; + +l_end: + return ret; +} diff --git a/drivers/net/sxe2/sxe2_testpmd_lib.h b/drivers/net/sxe2/sxe2_testpmd_lib.h new file mode 100644 index 0000000000..3d2659ef00 --- /dev/null +++ b/drivers/net/sxe2/sxe2_testpmd_lib.h @@ -0,0 +1,142 @@ + +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd. + */ + +#ifndef __SXE2_TESTPMD_LIB_H__ +#define __SXE2_TESTPMD_LIB_H__ +#include <cmdline.h> +#include "sxe2_ipsec.h" + +#define SXE2_IPSEC_SESSION_MAX (4096) +#define SXE2_IPSEC_PORT_MAX RTE_MAX_ETHPORTS +#define MEMPOOL_CACHE_SIZE (512 / 2) + +enum { + SXE2_TESTPMD_CMD_UDP_TUNNEL_ADD = 0, + SXE2_TESTPMD_CMD_UDP_TUNNEL_DEL = 1, + SXE2_TESTPMD_CMD_UDP_TUNNEL_GET = 2, + SXE2_TESTPMD_CMD_UDP_TUNNEL_MAX, +}; + +enum sxe2_testpmd_ipsec_op { + SXE2_TESTPMD_CMD_IPSEC_OP_ADD = 0, + SXE2_TESTPMD_CMD_IPSEC_OP_RM = 1, + SXE2_TESTPMD_CMD_IPSEC_OP_SHOW = 2, + SXE2_TESTPMD_CMD_IPSEC_OP_MAX, +}; + +enum sxe2_testpmd_ipsec_dir { + SXE2_TESTPMD_CMD_IPSEC_DIR_EGRESS = 0, + SXE2_TESTPMD_CMD_IPSEC_DIR_INGRESS = 1, + SXE2_TESTPMD_CMD_IPSEC_DIR_MAX, +}; + +enum sxe2_testpmd_ipsec_encrypt_algo { + SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_AES_CBC = 0, + SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_SM4_CBC = 1, + SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_NULL = 2, + SXE2_TESTPMD_CMD_IPSEC_EN_ALGO_MAX, +}; + +enum sxe2_testpmd_ipsec_auth_algo { + SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_SHA_HMAC = 0, + SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_SM3_HMAC = 1, + SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_NULL = 2, + SXE2_TESTPMD_CMD_IPSEC_AUTH_ALGO_MAX, +}; + +struct sxe2_ipsec_conf_param { + enum sxe2_testpmd_ipsec_dir dir; + enum sxe2_testpmd_ipsec_op op; + enum sxe2_testpmd_ipsec_encrypt_algo encrypt_algo; + enum sxe2_testpmd_ipsec_auth_algo auth_algo; + struct sxe2_ipsec_ip_param ip_addr; + uint32_t spi; + uint16_t port_id; + uint16_t session_id; + uint16_t sport; + uint16_t dport; + uint8_t enc_key[32]; + uint8_t enc_len; + uint8_t auth_key[32]; + uint8_t auth_len; +}; + +struct sxe2_ipsec_session_mgt { + void *session; + enum sxe2_testpmd_ipsec_encrypt_algo encrypt_algo; + enum sxe2_testpmd_ipsec_auth_algo auth_algo; + struct sxe2_ipsec_ip_param ip_addr; + uint32_t spi; + uint16_t session_id; + uint16_t sport; + uint16_t dport; + uint8_t enc_key[32]; + uint8_t auth_key[32]; + uint8_t status; +}; + +__rte_experimental +int32_t +sxe2_testpmd_sched_reset(uint16_t port_id); + +__rte_experimental +int32_t +sxe2_flow_rule_dump(uint16_t port_id, struct cmdline *cl); + +__rte_experimental +int32_t +sxe2_udp_tunnel_operations(uint16_t port_id, struct cmdline *cl, uint8_t action, + uint16_t udp_port, const char *tunnel_type); + +__rte_experimental +int32_t +sxe2_stats_info_show(uint16_t port_id); + +__rte_experimental +int32_t +sxe2_ipsec_ingress_create(struct sxe2_ipsec_conf_param *param, struct cmdline *cl); + +__rte_experimental +int32_t +sxe2_ipsec_ingress_destroy(struct sxe2_ipsec_conf_param *param, struct cmdline *cl); + +__rte_experimental +int32_t +sxe2_ipsec_ingress_show(struct sxe2_ipsec_conf_param *param, struct cmdline *cl); + +__rte_experimental +int32_t +sxe2_ipsec_egress_create(struct sxe2_ipsec_conf_param *param, struct cmdline *cl); + +__rte_experimental +int32_t +sxe2_ipsec_egress_destroy(struct sxe2_ipsec_conf_param *param, struct cmdline *cl); + +__rte_experimental +int32_t +sxe2_ipsec_egress_show(struct sxe2_ipsec_conf_param *param, struct cmdline *cl); + +__rte_experimental +int32_t +sxe2_ipsec_conf_get(uint16_t port_id, struct cmdline *cl, char type[]); + +__rte_experimental +int32_t +sxe2_ipsec_conf_set(uint16_t port_id, struct cmdline *cl, char type[], uint16_t value); + +__rte_experimental +int32_t +sxe2_ipsec_stats_show(uint16_t port_id); + +__rte_experimental +int32_t +sxe2_ipsec_flush(uint16_t port_id, struct cmdline *cl); + +extern struct sxe2_ipsec_session_mgt g_tx_session[SXE2_IPSEC_PORT_MAX][SXE2_IPSEC_SESSION_MAX]; +extern uint16_t g_tx_sess_id[SXE2_IPSEC_PORT_MAX]; +extern uint16_t g_esp_header_offset[SXE2_IPSEC_PORT_MAX]; +extern struct rte_mempool *g_sess_pool; + +#endif /* __SXE2_TESTPMD_LIB_H__ */ diff --git a/drivers/net/sxe2/sxe2_tm.c b/drivers/net/sxe2/sxe2_tm.c index 4c4f793cd5..5de9b5d3b7 100644 --- a/drivers/net/sxe2/sxe2_tm.c +++ b/drivers/net/sxe2/sxe2_tm.c @@ -982,6 +982,24 @@ int32_t sxe2_tm_init(struct rte_eth_dev *dev) return ret; } +int32_t sxe2_tm_conf_reset(struct rte_eth_dev *dev) +{ + int32_t ret; + + ret = sxe2_tm_uninit(dev); + if (ret) + goto l_end; + + ret = sxe2_tm_init(dev); + if (ret) + goto l_end; + + PMD_LOG_DEBUG(DRV, "Tm config reset succeed."); + +l_end: + return ret; +} + static int32_t sxe2_tm_chk_all_leaf(struct rte_eth_dev *dev) { int32_t ret = 0; diff --git a/drivers/net/sxe2/sxe2_tm.h b/drivers/net/sxe2/sxe2_tm.h index c4f8da6a8e..b0bfc2091d 100644 --- a/drivers/net/sxe2/sxe2_tm.h +++ b/drivers/net/sxe2/sxe2_tm.h @@ -73,4 +73,6 @@ int32_t sxe2_tm_init(struct rte_eth_dev *dev); int32_t sxe2_tm_uninit(struct rte_eth_dev *dev); +int32_t sxe2_tm_conf_reset(struct rte_eth_dev *dev); + #endif /* __SXE2_TM_H__ */ -- 2.47.3

