[dpdk-dev] [PATCH v3 5/5] app/test-pmd: add CLI for TM packet classification
Jasvinder Singh
jasvinder.singh at intel.com
Wed Sep 20 11:56:53 CEST 2017
Add following CLIs in testpmd application;
- command to set the packet field mask and offset value for
classification.
- command to set traffic class translation table entry
Signed-off-by: Jasvinder Singh <jasvinder.singh at intel.com>
---
app/test-pmd/cmdline.c | 11 ++
app/test-pmd/cmdline_tm.c | 305 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 316 insertions(+)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 70a376a..480fe4b 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -702,6 +702,13 @@ static void cmd_help_long_parsed(void *parsed_result,
"port tm hierarchy commit (port_id) (clean_on_fail)\n"
" Commit tm hierarchy.\n\n"
+ "set port tm pktfield (subport|pipe|tc) (port_id) offset"
+ " (offset) mask (mask)\n"
+ " Set port tm packet field.\n\n"
+
+ "set port tm tc table (port_id) index (tb_index) tc (tc_id)"
+ " queue (queue id)\n"
+ " Set port tm traffic class table entry.\n\n"
#endif
, list_pkt_forwarding_modes()
);
@@ -14275,6 +14282,8 @@ extern cmdline_parse_inst_t cmd_del_port_tm_node;
extern cmdline_parse_inst_t cmd_set_port_tm_node_parent;
#endif
extern cmdline_parse_inst_t cmd_port_tm_hierarchy_commit;
+extern cmdline_parse_inst_t cmd_set_port_tm_pktfield;
+extern cmdline_parse_inst_t cmd_set_port_tm_tc_table;
#endif
/* *********************************************************************** */
@@ -14488,6 +14497,8 @@ cmdline_parse_ctx_t main_ctx[] = {
(cmdline_parse_inst_t *)&cmd_set_port_tm_node_parent,
#endif
(cmdline_parse_inst_t *)&cmd_port_tm_hierarchy_commit,
+ (cmdline_parse_inst_t *)&cmd_set_port_tm_pktfield,
+ (cmdline_parse_inst_t *)&cmd_set_port_tm_tc_table,
#endif
NULL,
};
diff --git a/app/test-pmd/cmdline_tm.c b/app/test-pmd/cmdline_tm.c
index b36326d..829442f 100644
--- a/app/test-pmd/cmdline_tm.c
+++ b/app/test-pmd/cmdline_tm.c
@@ -2197,3 +2197,308 @@ cmdline_parse_inst_t cmd_port_tm_hierarchy_commit = {
NULL,
},
};
+
+static int
+port_tm_pktfield_validate_mask(uint64_t mask, uint64_t n)
+{
+ int count = __builtin_popcountll(mask);
+ int pos_lead = sizeof(uint64_t) * 8 - __builtin_clzll(mask);
+ int pos_trail = __builtin_ctzll(mask);
+ int count_expected = __builtin_popcount(n - 1);
+
+ /* Handle the exceptions */
+ if (n == 0)
+ return -1; /* Error */
+
+ if ((mask == 0) && (n == 1))
+ return 0; /* OK */
+
+ if (((mask == 0) && (n != 1)) || ((mask != 0) && (n == 1)))
+ return -2; /* Error */
+
+ /* Check that mask is contiguous */
+ if ((pos_lead - pos_trail) != count)
+ return -3; /* Error */
+
+ /* Check that mask contains the expected number of bits set */
+ if (count != count_expected)
+ return -4; /* Error */
+
+ return 0; /* OK */
+ }
+
+/* *** Set Port TM Packet Fields *** */
+struct cmd_set_port_tm_pktfield_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t tm;
+ cmdline_fixed_string_t pktfield;
+ cmdline_fixed_string_t type;
+ uint8_t port_id;
+ cmdline_fixed_string_t offset_string;
+ uint32_t offset;
+ cmdline_fixed_string_t mask_string;
+ uint64_t mask;
+};
+
+cmdline_parse_token_string_t cmd_set_port_tm_pktfield_set =
+ TOKEN_STRING_INITIALIZER(
+ struct cmd_set_port_tm_pktfield_result, set, "set");
+cmdline_parse_token_string_t cmd_set_port_tm_pktfield_port =
+ TOKEN_STRING_INITIALIZER(
+ struct cmd_set_port_tm_pktfield_result, port, "port");
+cmdline_parse_token_string_t cmd_set_port_tm_pktfield_tm =
+ TOKEN_STRING_INITIALIZER(
+ struct cmd_set_port_tm_pktfield_result, tm, "tm");
+cmdline_parse_token_string_t cmd_set_port_tm_pktfield_pktfield =
+ TOKEN_STRING_INITIALIZER(
+ struct cmd_set_port_tm_pktfield_result,
+ pktfield, "pktfield");
+cmdline_parse_token_string_t cmd_set_port_tm_pktfield_type =
+ TOKEN_STRING_INITIALIZER(
+ struct cmd_set_port_tm_pktfield_result,
+ type, "subport#pipe#tc");
+cmdline_parse_token_num_t cmd_set_port_tm_pktfield_port_id =
+ TOKEN_NUM_INITIALIZER(
+ struct cmd_set_port_tm_pktfield_result,
+ port_id, UINT8);
+cmdline_parse_token_string_t cmd_set_port_tm_pktfield_offset_string =
+ TOKEN_STRING_INITIALIZER(
+ struct cmd_set_port_tm_pktfield_result,
+ offset_string, "offset");
+cmdline_parse_token_num_t cmd_set_port_tm_pktfield_offset =
+ TOKEN_NUM_INITIALIZER(
+ struct cmd_set_port_tm_pktfield_result,
+ offset, UINT32);
+cmdline_parse_token_string_t cmd_set_port_tm_pktfield_mask_string =
+ TOKEN_STRING_INITIALIZER(
+ struct cmd_set_port_tm_pktfield_result,
+ mask_string, "mask");
+cmdline_parse_token_num_t cmd_set_port_tm_pktfield_mask =
+ TOKEN_NUM_INITIALIZER(
+ struct cmd_set_port_tm_pktfield_result,
+ mask, UINT64);
+
+static void cmd_set_port_tm_pktfield_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_port_tm_pktfield_result *res = parsed_result;
+ struct rte_port *p;
+ uint32_t offset = res->offset;
+ uint64_t mask = res->mask;
+ uint8_t port_id = res->port_id;
+ int ret;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN))
+ return;
+
+ p = &ports[port_id];
+
+ /* Port tm flag */
+ if (p->softport.tm_flag == 0) {
+ printf(" tm not enabled on port %u (error)\n", port_id);
+ return;
+ }
+
+ /* Forward mode: tm */
+ if (strcmp(cur_fwd_config.fwd_eng->fwd_mode_name, "tm")) {
+ printf(" tm mode not enabled(error)\n");
+ return;
+ }
+
+ /* Subport */
+ if (strcmp(res->type, "subport") == 0) {
+ uint32_t n = p->softport.tm.n_subports_per_port;
+
+ ret = port_tm_pktfield_validate_mask(mask, n);
+ if (ret) {
+ printf(" invalid subport mask(error %d)", ret);
+ return;
+ }
+ /* Set packet field */
+ p->softport.tm.tm_pktfield0_slabpos = offset;
+ p->softport.tm.tm_pktfield0_slabmask = mask;
+ p->softport.tm.tm_pktfield0_slabshr = __builtin_ctzll(mask);
+ return;
+ }
+
+ /* Pipe */
+ if (strcmp(res->type, "pipe") == 0) {
+ uint32_t n = p->softport.tm.n_pipes_per_subport;
+
+ ret = port_tm_pktfield_validate_mask(mask, n);
+ if (ret) {
+ printf(" invalid pipe mask(error %d)", ret);
+ return;
+ }
+ /* Set packet field */
+ p->softport.tm.tm_pktfield1_slabpos = offset;
+ p->softport.tm.tm_pktfield1_slabmask = mask;
+ p->softport.tm.tm_pktfield1_slabshr = __builtin_ctzll(mask);
+ return;
+ }
+
+ /* Traffic class */
+ if (strcmp(res->type, "tc") == 0) {
+ uint32_t n = RTE_DIM(p->softport.tm.tm_tc_table);
+
+ ret = port_tm_pktfield_validate_mask(mask, n);
+ if (ret) {
+ printf(" invalid tc mask(error %d)", ret);
+ return;
+ }
+ /* Set packet field */
+ p->softport.tm.tm_pktfield1_slabpos = offset;
+ p->softport.tm.tm_pktfield1_slabmask = mask;
+ p->softport.tm.tm_pktfield1_slabshr = __builtin_ctzll(mask);
+ return;
+ }
+}
+
+cmdline_parse_inst_t cmd_set_port_tm_pktfield = {
+ .f = cmd_set_port_tm_pktfield_parsed,
+ .data = NULL,
+ .help_str = "Set port tm pktfield",
+ .tokens = {
+ (void *)&cmd_set_port_tm_pktfield_set,
+ (void *)&cmd_set_port_tm_pktfield_port,
+ (void *)&cmd_set_port_tm_pktfield_tm,
+ (void *)&cmd_set_port_tm_pktfield_pktfield,
+ (void *)&cmd_set_port_tm_pktfield_type,
+ (void *)&cmd_set_port_tm_pktfield_port_id,
+ (void *)&cmd_set_port_tm_pktfield_offset_string,
+ (void *)&cmd_set_port_tm_pktfield_offset,
+ (void *)&cmd_set_port_tm_pktfield_mask_string,
+ (void *)&cmd_set_port_tm_pktfield_mask,
+ NULL,
+ },
+};
+
+/* *** Set Port TM Traffic Class Table Entry *** */
+struct cmd_set_port_tm_tc_table_result {
+ cmdline_fixed_string_t set;
+ cmdline_fixed_string_t port;
+ cmdline_fixed_string_t tm;
+ cmdline_fixed_string_t tc_table;
+ uint8_t port_id;
+ cmdline_fixed_string_t index_string;
+ uint32_t index;
+ cmdline_fixed_string_t tc_string;
+ uint32_t tc;
+ cmdline_fixed_string_t queue_string;
+ uint32_t queue;
+};
+
+cmdline_parse_token_string_t cmd_set_port_tm_tc_table_set =
+ TOKEN_STRING_INITIALIZER(
+ struct cmd_set_port_tm_tc_table_result, set, "set");
+cmdline_parse_token_string_t cmd_set_port_tm_tc_table_port =
+ TOKEN_STRING_INITIALIZER(
+ struct cmd_set_port_tm_tc_table_result, port, "port");
+cmdline_parse_token_string_t cmd_set_port_tm_tc_table_tm =
+ TOKEN_STRING_INITIALIZER(
+ struct cmd_set_port_tm_tc_table_result, tm, "tm");
+cmdline_parse_token_string_t cmd_set_port_tm_tc_table_tc_table =
+ TOKEN_STRING_INITIALIZER(
+ struct cmd_set_port_tm_tc_table_result,
+ tc_table, "tc table");
+cmdline_parse_token_num_t cmd_set_port_tm_tc_table_port_id =
+ TOKEN_NUM_INITIALIZER(
+ struct cmd_set_port_tm_tc_table_result,
+ port_id, UINT8);
+cmdline_parse_token_string_t cmd_set_port_tm_tc_table_index_string =
+ TOKEN_STRING_INITIALIZER(
+ struct cmd_set_port_tm_tc_table_result,
+ index_string, "index");
+cmdline_parse_token_num_t cmd_set_port_tm_tc_table_index =
+ TOKEN_NUM_INITIALIZER(
+ struct cmd_set_port_tm_tc_table_result,
+ index, UINT32);
+cmdline_parse_token_string_t cmd_set_port_tm_tc_table_tc_string =
+ TOKEN_STRING_INITIALIZER(
+ struct cmd_set_port_tm_tc_table_result,
+ tc_string, "tc");
+cmdline_parse_token_num_t cmd_set_port_tm_tc_table_tc =
+ TOKEN_NUM_INITIALIZER(
+ struct cmd_set_port_tm_tc_table_result,
+ tc, UINT32);
+cmdline_parse_token_string_t cmd_set_port_tm_tc_table_queue_string =
+ TOKEN_STRING_INITIALIZER(
+ struct cmd_set_port_tm_tc_table_result,
+ queue_string, "queue");
+cmdline_parse_token_num_t cmd_set_port_tm_tc_table_queue =
+ TOKEN_NUM_INITIALIZER(
+ struct cmd_set_port_tm_tc_table_result,
+ queue, UINT32);
+
+static void cmd_set_port_tm_tc_table_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_set_port_tm_tc_table_result *res = parsed_result;
+ struct rte_port *p;
+ uint32_t tc = res->tc;
+ uint32_t index = res->index;
+ uint32_t queue = res->queue;
+ uint32_t val;
+ uint8_t port_id = res->port_id;
+
+ if (port_id_is_invalid(port_id, ENABLED_WARN))
+ return;
+
+ p = &ports[port_id];
+
+ /* Port tm flag */
+ if (p->softport.tm_flag == 0) {
+ printf(" tm not enabled on port %u (error)\n", port_id);
+ return;
+ }
+
+ /* Forward mode: tm */
+ if (strcmp(cur_fwd_config.fwd_eng->fwd_mode_name, "tm")) {
+ printf(" tm mode not enabled(error)\n");
+ return;
+ }
+
+ /* Traffic class table index */
+ if (tc >= RTE_DIM(p->softport.tm.tm_tc_table)) {
+ printf(" invalid traffic class table index(error)\n");
+ return;
+ }
+
+ /* Traffic class id */
+ if (tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE) {
+ printf(" invalid traffic class id(error)\n");
+ return;
+ }
+
+ /* Traffic class queue */
+ if (queue >= RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) {
+ printf(" invalid traffic class queue(error)\n");
+ return;
+ }
+
+ val = tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue;
+ p->softport.tm.tm_tc_table[index] = val;
+}
+
+cmdline_parse_inst_t cmd_set_port_tm_tc_table = {
+ .f = cmd_set_port_tm_tc_table_parsed,
+ .data = NULL,
+ .help_str = "Set port tm TC table entry",
+ .tokens = {
+ (void *)&cmd_set_port_tm_tc_table_set,
+ (void *)&cmd_set_port_tm_tc_table_port,
+ (void *)&cmd_set_port_tm_tc_table_tm,
+ (void *)&cmd_set_port_tm_tc_table_tc_table,
+ (void *)&cmd_set_port_tm_tc_table_port_id,
+ (void *)&cmd_set_port_tm_tc_table_index_string,
+ (void *)&cmd_set_port_tm_tc_table_index,
+ (void *)&cmd_set_port_tm_tc_table_tc_string,
+ (void *)&cmd_set_port_tm_tc_table_tc,
+ (void *)&cmd_set_port_tm_tc_table_queue_string,
+ (void *)&cmd_set_port_tm_tc_table_queue,
+ NULL,
+ },
+};
--
2.9.3
More information about the dev
mailing list