From c18feafa193c0d816eae3a4861b1f9016cf236d7 Mon Sep 17 00:00:00 2001 From: Dekel Peled Date: Sun, 21 Oct 2018 17:22:48 +0300 Subject: [PATCH] app/testpmd: support metadata as flow rule item As described in [1], this series adds option to set metadata value as match pattern when creating a new flow rule. This patch introduces additional options in testpmd commands: - New item type "meta" "data" - New per-port offload flag "match_metadata". It also adds commands to configure the tx_metadata value to use: - New 'config' command takes a 32 bit value and stores it per port: port config tx_metadata testpmd will add to any Tx packet sent from this port the metadata value, and set ol_flags accordingly. - A matching 'show' command is added to read the configured value: port config tx_metadata [1] "ethdev: support metadata as flow rule criteria" Signed-off-by: Dekel Peled Reviewed-by: Ferruh Yigit --- app/test-pmd/cmdline.c | 111 +++++++++++++++++++- app/test-pmd/cmdline_flow.c | 28 +++++ app/test-pmd/testpmd.c | 5 + app/test-pmd/testpmd.h | 2 + app/test-pmd/txonly.c | 9 ++ doc/guides/testpmd_app_ug/testpmd_funcs.rst | 21 +++- 6 files changed, 172 insertions(+), 4 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 3b469ac64f..fc74b95176 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -17499,7 +17499,8 @@ cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_offload = "sctp_cksum#tcp_tso#udp_tso#outer_ipv4_cksum#" "qinq_insert#vxlan_tnl_tso#gre_tnl_tso#" "ipip_tnl_tso#geneve_tnl_tso#macsec_insert#" - "mt_lockfree#multi_segs#mbuf_fast_free#security"); + "mt_lockfree#multi_segs#mbuf_fast_free#security#" + "match_metadata"); cmdline_parse_token_string_t cmd_config_per_port_tx_offload_result_on_off = TOKEN_STRING_INITIALIZER (struct cmd_config_per_port_tx_offload_result, @@ -17580,8 +17581,8 @@ cmdline_parse_inst_t cmd_config_per_port_tx_offload = { "sctp_cksum|tcp_tso|udp_tso|outer_ipv4_cksum|" "qinq_insert|vxlan_tnl_tso|gre_tnl_tso|" "ipip_tnl_tso|geneve_tnl_tso|macsec_insert|" - "mt_lockfree|multi_segs|mbuf_fast_free|security " - "on|off", + "mt_lockfree|multi_segs|mbuf_fast_free|security|" + "match_metadata on|off", .tokens = { (void *)&cmd_config_per_port_tx_offload_result_port, (void *)&cmd_config_per_port_tx_offload_result_config, @@ -17698,6 +17699,108 @@ cmdline_parse_inst_t cmd_config_per_queue_tx_offload = { } }; +/* *** configure tx_metadata for specific port *** */ +struct cmd_config_tx_metadata_specific_result { + cmdline_fixed_string_t port; + cmdline_fixed_string_t keyword; + uint16_t port_id; + cmdline_fixed_string_t item; + uint32_t value; +}; + +static void +cmd_config_tx_metadata_specific_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_config_tx_metadata_specific_result *res = parsed_result; + + if (port_id_is_invalid(res->port_id, ENABLED_WARN)) + return; + ports[res->port_id].tx_metadata = rte_cpu_to_be_32(res->value); +} + +cmdline_parse_token_string_t cmd_config_tx_metadata_specific_port = + TOKEN_STRING_INITIALIZER(struct cmd_config_tx_metadata_specific_result, + port, "port"); +cmdline_parse_token_string_t cmd_config_tx_metadata_specific_keyword = + TOKEN_STRING_INITIALIZER(struct cmd_config_tx_metadata_specific_result, + keyword, "config"); +cmdline_parse_token_num_t cmd_config_tx_metadata_specific_id = + TOKEN_NUM_INITIALIZER(struct cmd_config_tx_metadata_specific_result, + port_id, UINT16); +cmdline_parse_token_string_t cmd_config_tx_metadata_specific_item = + TOKEN_STRING_INITIALIZER(struct cmd_config_tx_metadata_specific_result, + item, "tx_metadata"); +cmdline_parse_token_num_t cmd_config_tx_metadata_specific_value = + TOKEN_NUM_INITIALIZER(struct cmd_config_tx_metadata_specific_result, + value, UINT32); + +cmdline_parse_inst_t cmd_config_tx_metadata_specific = { + .f = cmd_config_tx_metadata_specific_parsed, + .data = NULL, + .help_str = "port config tx_metadata ", + .tokens = { + (void *)&cmd_config_tx_metadata_specific_port, + (void *)&cmd_config_tx_metadata_specific_keyword, + (void *)&cmd_config_tx_metadata_specific_id, + (void *)&cmd_config_tx_metadata_specific_item, + (void *)&cmd_config_tx_metadata_specific_value, + NULL, + }, +}; + +/* *** display tx_metadata per port configuration *** */ +struct cmd_show_tx_metadata_result { + cmdline_fixed_string_t cmd_show; + cmdline_fixed_string_t cmd_port; + cmdline_fixed_string_t cmd_keyword; + portid_t cmd_pid; +}; + +static void +cmd_show_tx_metadata_parsed(void *parsed_result, + __attribute__((unused)) struct cmdline *cl, + __attribute__((unused)) void *data) +{ + struct cmd_show_tx_metadata_result *res = parsed_result; + + if (!rte_eth_dev_is_valid_port(res->cmd_pid)) { + printf("invalid port id %u\n", res->cmd_pid); + return; + } + if (!strcmp(res->cmd_keyword, "tx_metadata")) { + printf("Port %u tx_metadata: %u\n", res->cmd_pid, + ports[res->cmd_pid].tx_metadata); + } +} + +cmdline_parse_token_string_t cmd_show_tx_metadata_show = + TOKEN_STRING_INITIALIZER(struct cmd_show_tx_metadata_result, + cmd_show, "show"); +cmdline_parse_token_string_t cmd_show_tx_metadata_port = + TOKEN_STRING_INITIALIZER(struct cmd_show_tx_metadata_result, + cmd_port, "port"); +cmdline_parse_token_num_t cmd_show_tx_metadata_pid = + TOKEN_NUM_INITIALIZER(struct cmd_show_tx_metadata_result, + cmd_pid, UINT16); +cmdline_parse_token_string_t cmd_show_tx_metadata_keyword = + TOKEN_STRING_INITIALIZER(struct cmd_show_tx_metadata_result, + cmd_keyword, "tx_metadata"); + +cmdline_parse_inst_t cmd_show_tx_metadata = { + .f = cmd_show_tx_metadata_parsed, + .data = NULL, + .help_str = "show port tx_metadata", + .tokens = { + (void *)&cmd_show_tx_metadata_show, + (void *)&cmd_show_tx_metadata_port, + (void *)&cmd_show_tx_metadata_pid, + (void *)&cmd_show_tx_metadata_keyword, + NULL, + }, +}; + /* ******************************************************************************** */ /* list of instructions */ @@ -17967,6 +18070,8 @@ cmdline_parse_ctx_t main_ctx[] = { (cmdline_parse_inst_t *)&cmd_operate_bpf_ld_parse, (cmdline_parse_inst_t *)&cmd_operate_bpf_unld_parse, #endif + (cmdline_parse_inst_t *)&cmd_config_tx_metadata_specific, + (cmdline_parse_inst_t *)&cmd_show_tx_metadata, NULL, }; diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index a527b6bb49..7932b54c03 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -178,6 +178,8 @@ enum index { ITEM_ICMP6_ND_OPT_SLA_ETH_SLA, ITEM_ICMP6_ND_OPT_TLA_ETH, ITEM_ICMP6_ND_OPT_TLA_ETH_TLA, + ITEM_META, + ITEM_META_DATA, /* Validate/create actions. */ ACTIONS, @@ -546,6 +548,11 @@ static const enum index item_param[] = { ZERO, }; +static const enum index item_param_is[] = { + ITEM_PARAM_IS, + ZERO, +}; + static const enum index next_item[] = { ITEM_END, ITEM_VOID, @@ -584,6 +591,7 @@ static const enum index next_item[] = { ITEM_ICMP6_ND_OPT, ITEM_ICMP6_ND_OPT_SLA_ETH, ITEM_ICMP6_ND_OPT_TLA_ETH, + ITEM_META, ZERO, }; @@ -804,6 +812,12 @@ static const enum index item_icmp6_nd_opt_tla_eth[] = { ZERO, }; +static const enum index item_meta[] = { + ITEM_META_DATA, + ITEM_NEXT, + ZERO, +}; + static const enum index next_action[] = { ACTION_END, ACTION_VOID, @@ -2070,6 +2084,20 @@ static const struct token token_list[] = { .args = ARGS(ARGS_ENTRY_HTON (struct rte_flow_item_icmp6_nd_opt_tla_eth, tla)), }, + [ITEM_META] = { + .name = "meta", + .help = "match metadata header", + .priv = PRIV_ITEM(META, sizeof(struct rte_flow_item_meta)), + .next = NEXT(item_meta), + .call = parse_vc, + }, + [ITEM_META_DATA] = { + .name = "data", + .help = "metadata value", + .next = NEXT(item_meta, NEXT_ENTRY(UNSIGNED), item_param_is), + .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_meta, + data, "\xff\xff\xff\xff")), + }, /* Validate/create actions. */ [ACTIONS] = { diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c index eea6df0fae..6296f498f3 100644 --- a/app/test-pmd/testpmd.c +++ b/app/test-pmd/testpmd.c @@ -1063,6 +1063,10 @@ init_config(void) DEV_TX_OFFLOAD_MBUF_FAST_FREE)) port->dev_conf.txmode.offloads &= ~DEV_TX_OFFLOAD_MBUF_FAST_FREE; + if (!(port->dev_info.tx_offload_capa & + DEV_TX_OFFLOAD_MATCH_METADATA)) + port->dev_conf.txmode.offloads &= + ~DEV_TX_OFFLOAD_MATCH_METADATA; if (numa_support) { if (port_numa[pid] != NUMA_NO_CONFIG) port_per_socket[port_numa[pid]]++; @@ -1091,6 +1095,7 @@ init_config(void) /* set flag to initialize port/queue */ port->need_reconfig = 1; port->need_reconfig_queues = 1; + port->tx_metadata = 0; } /* diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 3da728cad9..c07548e170 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -196,6 +196,8 @@ struct rte_port { #ifdef SOFTNIC struct softnic_port softport; /**< softnic params */ #endif + /**< metadata value to insert in Tx packets. */ + rte_be32_t tx_metadata; }; /** diff --git a/app/test-pmd/txonly.c b/app/test-pmd/txonly.c index 1f08b6ed37..fae84cac2b 100644 --- a/app/test-pmd/txonly.c +++ b/app/test-pmd/txonly.c @@ -253,6 +253,15 @@ pkt_burst_transmit(struct fwd_stream *fs) pkt->l2_len = sizeof(struct ether_hdr); pkt->l3_len = sizeof(struct ipv4_hdr); pkts_burst[nb_pkt] = pkt; + + /* + * If user configured metadata value add it to packet + * and set ol_flags accordingly + */ + if (ports[fs->tx_port].tx_metadata) { + pkt->tx_metadata = ports[fs->tx_port].tx_metadata; + pkt->ol_flags |= PKT_TX_METADATA; + } } nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_pkt); /* diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index d712bb6571..3854271483 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -423,6 +423,12 @@ List port level and all queue level Tx offloading configuration:: testpmd> show port (port_id) tx_offload configuration +show tx metadata setting +~~~~~~~~~~~~~~~~~~~~~~~~ + +Show Tx metadata value set for a specific port:: + + testpmd> show port (port_id) tx_metadata Configuration Functions ----------------------- @@ -1532,7 +1538,8 @@ Enable or disable a per port Tx offloading on all Tx queues of a port:: sctp_cksum, tcp_tso, udp_tso, outer_ipv4_cksum, qinq_insert, vxlan_tnl_tso, gre_tnl_tso, ipip_tnl_tso, geneve_tnl_tso, macsec_insert, - mt_lockfree, multi_segs, mbuf_fast_free, security + mt_lockfree, multi_segs, mbuf_fast_free, security, + match_metadata This command should be run when the port is stopped, or else it will fail. @@ -2028,6 +2035,14 @@ port config udp_tunnel_port Add/remove UDP tunnel port for VXLAN/GENEVE tunneling protocols:: testpmd> port config (port_id) udp_tunnel_port add|rm vxlan|geneve (udp_port) +port config tx_metadata +~~~~~~~~~~~~~~~~~~~~~~~ + +Set Tx metadata value per port. +testpmd will add this value to any Tx packet sent from this port:: + + testpmd> port config (port_id) tx_metadata (value) + Link Bonding Functions ---------------------- @@ -3595,6 +3610,10 @@ This section lists supported pattern items and their attributes, if any. - ``tla {MAC-48}``: target Ethernet LLA. +- ``meta``: match application specific metadata. + + - ``data {unsigned}``: metadata value. + Actions list ^^^^^^^^^^^^