[dpdk-dev] [PATCH v4 5/5] app/test-pmd: add CLI for TM packet classification

Jasvinder Singh jasvinder.singh at intel.com
Fri Sep 22 18:35:06 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         |  13 ++
 app/test-pmd/cmdline_tm.c      | 309 +++++++++++++++++++++++++++++++++++++++++
 app/test-pmd/testpmd_cmdline.h |   4 +
 3 files changed, 326 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index de7f487..cc0a505 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -700,6 +700,15 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"port tm hierarchy commit (port_id) (clean_on_fail)\n"
 			"	Commit tm hierarchy.\n\n"
 
+#if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED
+			"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()
 		);
 	}
@@ -14460,6 +14469,10 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_del_port_tm_node,
 	(cmdline_parse_inst_t *)&cmd_set_port_tm_node_parent,
 	(cmdline_parse_inst_t *)&cmd_port_tm_hierarchy_commit,
+#if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED
+	(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 5fc946d..ddeb45b 100644
--- a/app/test-pmd/cmdline_tm.c
+++ b/app/test-pmd/cmdline_tm.c
@@ -1890,3 +1890,312 @@ cmdline_parse_inst_t cmd_port_tm_hierarchy_commit = {
 		NULL,
 	},
 };
+
+#if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED
+
+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,
+	},
+};
+
+#endif
diff --git a/app/test-pmd/testpmd_cmdline.h b/app/test-pmd/testpmd_cmdline.h
index 4fa7cc4..b6ca8c4 100755
--- a/app/test-pmd/testpmd_cmdline.h
+++ b/app/test-pmd/testpmd_cmdline.h
@@ -52,5 +52,9 @@ extern cmdline_parse_inst_t cmd_add_port_tm_leaf_node;
 extern cmdline_parse_inst_t cmd_del_port_tm_node;
 extern cmdline_parse_inst_t cmd_set_port_tm_node_parent;
 extern cmdline_parse_inst_t cmd_port_tm_hierarchy_commit;
+#if defined RTE_LIBRTE_PMD_SOFTNIC && defined RTE_LIBRTE_SCHED
+extern cmdline_parse_inst_t cmd_set_port_tm_pktfield;
+extern cmdline_parse_inst_t cmd_set_port_tm_tc_table;
+#endif
 
 #endif /* _TESTPMD_CMDLINE_H_ */
-- 
2.9.3



More information about the dev mailing list