[dpdk-dev] [PATCH] app/flow-perf: support meter policy API

Subsystems: the rest · Maintainer: Linus Torvalds

STALE1806d

55 messages, 4 authors, 2021-11-16 · open the first message on its own page

[dpdk-dev] [PATCH] app/flow-perf: support meter policy API

From: Haifei Luo <hidden>
Date: 2021-04-06 06:50:57

Add option "policy-mtr" to indicate if meter creation will include policy
or not. Meter creation will keep same without it.

With "policy-mtr", policy is introduced. API create_meter_policy
is to create a policy. API create_meter_rule will use it to create
meter.

Depends-on: series=16037 ("Support meter policy API ")
https://patchwork.dpdk.org/project/dpdk/list/?series=16037

Signed-off-by: Haifei Luo <redacted>
---
 app/test-flow-perf/actions_gen.c |  6 ++-
 app/test-flow-perf/actions_gen.h |  3 +-
 app/test-flow-perf/config.h      |  6 +--
 app/test-flow-perf/flow_gen.c    |  2 +-
 app/test-flow-perf/main.c        | 93 ++++++++++++++++++++++++++++++++++++++--
 doc/guides/tools/flow-perf.rst   |  3 ++
 6 files changed, 102 insertions(+), 11 deletions(-)
diff --git a/app/test-flow-perf/actions_gen.c b/app/test-flow-perf/actions_gen.c
index 1f5c64f..248e19a 100644
--- a/app/test-flow-perf/actions_gen.c
+++ b/app/test-flow-perf/actions_gen.c
@@ -19,7 +19,6 @@
 #include "flow_gen.h"
 #include "config.h"
 
-
 /* Storage for additional parameters for actions */
 struct additional_para {
 	uint16_t queue;
@@ -30,6 +29,7 @@ struct additional_para {
 	uint64_t encap_data;
 	uint64_t decap_data;
 	uint8_t core_idx;
+	uint16_t port_id;
 };
 
 /* Storage for struct rte_flow_action_raw_encap including external data. */
@@ -907,7 +907,8 @@ struct action_rss_data {
 void
 fill_actions(struct rte_flow_action *actions, uint64_t *flow_actions,
 	uint32_t counter, uint16_t next_table, uint16_t hairpinq,
-	uint64_t encap_data, uint64_t decap_data, uint8_t core_idx)
+	uint64_t encap_data, uint64_t decap_data, uint8_t core_idx,
+	uint16_t port_id)
 {
 	struct additional_para additional_para_data;
 	uint8_t actions_counter = 0;
@@ -930,6 +931,7 @@ struct action_rss_data {
 		.encap_data = encap_data,
 		.decap_data = decap_data,
 		.core_idx = core_idx,
+		.port_id = port_id,
 	};
 
 	if (hairpinq != 0) {
diff --git a/app/test-flow-perf/actions_gen.h b/app/test-flow-perf/actions_gen.h
index 77353cf..f846734 100644
--- a/app/test-flow-perf/actions_gen.h
+++ b/app/test-flow-perf/actions_gen.h
@@ -19,6 +19,7 @@
 
 void fill_actions(struct rte_flow_action *actions, uint64_t *flow_actions,
 	uint32_t counter, uint16_t next_table, uint16_t hairpinq,
-	uint64_t encap_data, uint64_t decap_data, uint8_t core_idx);
+	uint64_t encap_data, uint64_t decap_data, uint8_t core_idx,
+	uint16_t port_id);
 
 #endif /* FLOW_PERF_ACTION_GEN */
diff --git a/app/test-flow-perf/config.h b/app/test-flow-perf/config.h
index 3d4696d..50dbf90 100644
--- a/app/test-flow-perf/config.h
+++ b/app/test-flow-perf/config.h
@@ -8,15 +8,15 @@
 #define GET_RSS_HF() (ETH_RSS_IP | ETH_RSS_TCP)
 
 /* Configuration */
-#define RXQ_NUM 4
-#define TXQ_NUM 4
+#define RXQ_NUM 10
+#define TXQ_NUM 10
 #define TOTAL_MBUF_NUM 32000
 #define MBUF_SIZE 2048
 #define MBUF_CACHE_SIZE 512
 #define NR_RXD  256
 #define NR_TXD  256
 #define MAX_PORTS 64
-#define METER_CIR 1250000
+#define METER_CIR 1250000000
 #define DEFAULT_METER_PROF_ID 100
 
 /* This is used for encap/decap & header modify actions.
diff --git a/app/test-flow-perf/flow_gen.c b/app/test-flow-perf/flow_gen.c
index df4af16..62e4cf5 100644
--- a/app/test-flow-perf/flow_gen.c
+++ b/app/test-flow-perf/flow_gen.c
@@ -61,7 +61,7 @@ struct rte_flow *
 
 	fill_actions(actions, flow_actions,
 		outer_ip_src, next_table, hairpinq,
-		encap_data, decap_data, core_idx);
+		encap_data, decap_data, core_idx, port_id);
 
 	fill_items(items, flow_items, outer_ip_src, core_idx);
 
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 66ec776..9a0d758 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -53,6 +53,8 @@
 static uint64_t flow_items[MAX_ITEMS_NUM];
 static uint64_t flow_actions[MAX_ACTIONS_NUM];
 static uint64_t flow_attrs[MAX_ATTRS_NUM];
+uint32_t g_policy_id[MAX_PORTS];
+
 static uint8_t items_idx, actions_idx, attrs_idx;
 
 static uint64_t ports_mask;
@@ -61,6 +63,7 @@
 static bool delete_flag;
 static bool dump_socket_mem_flag;
 static bool enable_fwd;
+static bool policy_mtr;
 
 static struct rte_mempool *mbuf_mp;
 static uint32_t nb_lcores;
@@ -114,6 +117,13 @@ struct multi_cores_pool {
 	.cores_count = 1,
 };
 
+/* Storage for struct rte_flow_action_rss including external data. */
+struct action_rss_data {
+	struct rte_flow_action_rss conf;
+	uint8_t key[40];
+	uint16_t queue[128];
+};
+
 static void
 usage(char *progname)
 {
@@ -131,6 +141,7 @@ struct multi_cores_pool {
 	printf("  --enable-fwd: To enable packets forwarding"
 		" after insertion\n");
 	printf("  --portmask=N: hexadecimal bitmask of ports used\n");
+	printf("  --policy-mtr: To create meter with policy\n");
 
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
@@ -569,6 +580,7 @@ struct multi_cores_pool {
 		{ "enable-fwd",                 0, 0, 0 },
 		{ "portmask",                   1, 0, 0 },
 		{ "cores",                      1, 0, 0 },
+		{ "policy-mtr",                 0, 0, 0 },
 		/* Attributes */
 		{ "ingress",                    0, 0, 0 },
 		{ "egress",                     0, 0, 0 },
@@ -798,6 +810,10 @@ struct multi_cores_pool {
 					rte_exit(EXIT_FAILURE, " ");
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name,
+					"policy-mtr") == 0) {
+				policy_mtr = true;
+			}
 			break;
 		default:
 			fprintf(stderr, "Invalid option: %s\n", argv[optind]);
@@ -909,6 +925,60 @@ struct multi_cores_pool {
 }
 
 static void
+create_meter_policy(void)
+{
+	struct rte_mtr_error error;
+	uint32_t policy_id;
+	int ret, i, port_id;
+	const struct rte_flow_action *acts[RTE_COLORS];
+	struct action_rss_data rss_data;
+	struct rte_flow_action g_actions[2], r_actions[2];
+	uint16_t nr_ports;
+
+	memset(&rss_data, 0, sizeof(rss_data));
+	rss_data.conf.func = RTE_ETH_HASH_FUNCTION_DEFAULT;
+	rss_data.conf.level = 0;
+	rss_data.conf.types = GET_RSS_HF();
+	rss_data.conf.key_len = 0;
+	rss_data.conf.key = NULL;
+	rss_data.conf.queue_num  = RXQ_NUM;
+	uint16_t q_data[RXQ_NUM];
+	rss_data.conf.queue = q_data;
+
+	for (i = 0; i < RXQ_NUM; i++)
+		q_data[i] = i;
+
+	for (i = 0; i < RXQ_NUM; i++)
+		rss_data.queue[i] = i;
+
+	g_actions[0].type = RTE_FLOW_ACTION_TYPE_RSS;
+	g_actions[0].conf = &(rss_data.conf);
+	g_actions[1].type = RTE_FLOW_ACTION_TYPE_END;
+	g_actions[1].conf = NULL;
+
+	r_actions[0].type = RTE_FLOW_ACTION_TYPE_DROP;
+	r_actions[0].conf = NULL;
+	r_actions[1].type = RTE_FLOW_ACTION_TYPE_END;
+	r_actions[1].conf = NULL;
+
+	acts[0] = &g_actions[0];
+	acts[1] = NULL;
+	acts[2] = &r_actions[0];
+
+	nr_ports = rte_eth_dev_count_avail();
+	for (port_id = 0; port_id < nr_ports; port_id++) {
+		policy_id = port_id + 10;
+		ret = rte_mtr_meter_policy_create(port_id,
+				policy_id,
+				acts, &error);
+		if (ret)
+			printf("meter add failed port_id  %d\n",
+				port_id);
+		g_policy_id[port_id] = policy_id;
+	}
+}
+
+static void
 create_meter_rule(int port_id, uint32_t counter)
 {
 	int ret;
@@ -924,7 +994,14 @@ struct multi_cores_pool {
 
 	/*create meter*/
 	params.meter_profile_id = default_prof_id;
-	ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+
+	if (!policy_mtr)
+		ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+	else {
+		params.meter_policy_id = g_policy_id[port_id];
+		ret = rte_mtr_create(port_id, counter, &params, 0, &error);
+	}
+
 	if (ret != 0) {
 		printf("Port %u create meter idx(%d) error(%d) message: %s\n",
 			port_id, counter, error.type,
@@ -938,11 +1015,16 @@ struct multi_cores_pool {
 {
 	struct rte_mtr_error error;
 
-	if (rte_mtr_destroy(port_id, counter, &error)) {
-		printf("Port %u destroy meter(%d) error(%d) message: %s\n",
+	if (policy_mtr) {
+		if (rte_mtr_meter_policy_delete(port_id, counter+1, &error))
+			printf("erro delete policy %d\n", counter+1);
+	} else {
+		if (rte_mtr_destroy(port_id, counter, &error)) {
+			printf("Port %u destroy meter(%d) error(%d) message: %s\n",
 			port_id, counter, error.type,
 			error.message ? error.message : "(no stated reason)");
-		rte_exit(EXIT_FAILURE, "Error in deleting meter rule");
+			rte_exit(EXIT_FAILURE, "Error in deleting meter rule");
+		}
 	}
 }
 
@@ -1876,6 +1958,9 @@ struct multi_cores_pool {
 
 	if (has_meter())
 		create_meter_profile();
+	if (policy_mtr)
+		create_meter_policy();
+
 	rte_eal_mp_remote_launch(run_rte_flow_handler_cores, NULL, CALL_MAIN);
 
 	if (enable_fwd) {
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 017e200..50fe683 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -349,3 +349,6 @@ Actions:
 *       ``--meter``
         Add meter action to all flows actions.
         Currently, 1 meter profile -> N meter rules -> N rte flows.
+
+*       ``--policy-mtr``
+        Add policy-mtr to create meter with policy.
-- 
1.8.3.1

Re: [dpdk-dev] [PATCH] app/flow-perf: support meter policy API

From: Wisam Monther <hidden>
Date: 2021-05-09 10:47:44

Hi,
quoted hunk
-----Original Message-----
From: Haifei Luo <redacted>
Sent: Tuesday, April 6, 2021 9:51 AM
To: <redacted>; Ori Kam <redacted>; Slava Ovsiienko
[off-list ref]; Matan Azrad [off-list ref]; Shahaf
Shuler [off-list ref]; Wisam Monther [off-list ref]
Cc: <redacted>; NBU-Contact-Thomas Monjalon
[off-list ref]; Raslan Darawsheh [off-list ref]; Roni
Bar Yanai [off-list ref]
Subject: [PATCH] app/flow-perf: support meter policy API

Add option "policy-mtr" to indicate if meter creation will include policy or not.
Meter creation will keep same without it.

With "policy-mtr", policy is introduced. API create_meter_policy is to create a
policy. API create_meter_rule will use it to create meter.

Depends-on: series=16037 ("Support meter policy API ")
https://patchwork.dpdk.org/project/dpdk/list/?series=16037

Signed-off-by: Haifei Luo <redacted>
---
 app/test-flow-perf/actions_gen.c |  6 ++-  app/test-flow-perf/actions_gen.h
|  3 +-
 app/test-flow-perf/config.h      |  6 +--
 app/test-flow-perf/flow_gen.c    |  2 +-
 app/test-flow-perf/main.c        | 93
++++++++++++++++++++++++++++++++++++++--
 doc/guides/tools/flow-perf.rst   |  3 ++
 6 files changed, 102 insertions(+), 11 deletions(-)
diff --git a/app/test-flow-perf/actions_gen.c b/app/test-flow-
perf/actions_gen.c
index 1f5c64f..248e19a 100644
--- a/app/test-flow-perf/actions_gen.c
+++ b/app/test-flow-perf/actions_gen.c
@@ -19,7 +19,6 @@
 #include "flow_gen.h"
 #include "config.h"

54 more quoted lines

This is irrelevant change
quoted hunk
 #define TOTAL_MBUF_NUM 32000
 #define MBUF_SIZE 2048
 #define MBUF_CACHE_SIZE 512
 #define NR_RXD  256
 #define NR_TXD  256
 #define MAX_PORTS 64
-#define METER_CIR 1250000
+#define METER_CIR 1250000000
Why to change the default?
quoted hunk
 #define DEFAULT_METER_PROF_ID 100

 /* This is used for encap/decap & header modify actions.
diff --git a/app/test-flow-perf/flow_gen.c b/app/test-flow-perf/flow_gen.c
index df4af16..62e4cf5 100644
--- a/app/test-flow-perf/flow_gen.c
+++ b/app/test-flow-perf/flow_gen.c
@@ -61,7 +61,7 @@ struct rte_flow *

 	fill_actions(actions, flow_actions,
 		outer_ip_src, next_table, hairpinq,
-		encap_data, decap_data, core_idx);
+		encap_data, decap_data, core_idx, port_id);

 	fill_items(items, flow_items, outer_ip_src, core_idx);
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c index
66ec776..9a0d758 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -53,6 +53,8 @@
 static uint64_t flow_items[MAX_ITEMS_NUM];  static uint64_t
flow_actions[MAX_ACTIONS_NUM];  static uint64_t
flow_attrs[MAX_ATTRS_NUM];
+uint32_t g_policy_id[MAX_PORTS];
+
 static uint8_t items_idx, actions_idx, attrs_idx;

 static uint64_t ports_mask;
@@ -61,6 +63,7 @@
 static bool delete_flag;
 static bool dump_socket_mem_flag;
 static bool enable_fwd;
+static bool policy_mtr;

 static struct rte_mempool *mbuf_mp;
 static uint32_t nb_lcores;
@@ -114,6 +117,13 @@ struct multi_cores_pool {
 	.cores_count = 1,
 };

8 more quoted lines

Why you create this struct?
quoted hunk
 static void
 usage(char *progname)
 {
@@ -131,6 +141,7 @@ struct multi_cores_pool {
 	printf("  --enable-fwd: To enable packets forwarding"
 		" after insertion\n");
 	printf("  --portmask=N: hexadecimal bitmask of ports used\n");
+	printf("  --policy-mtr: To create meter with policy\n");
It's worthy to mention the current supported policies here, and also what is the default.
quoted hunk

 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n"); @@ -569,6
+580,7 @@ struct multi_cores_pool {
 		{ "enable-fwd",                 0, 0, 0 },
 		{ "portmask",                   1, 0, 0 },
 		{ "cores",                      1, 0, 0 },
+		{ "policy-mtr",                 0, 0, 0 },
 		/* Attributes */
 		{ "ingress",                    0, 0, 0 },
 		{ "egress",                     0, 0, 0 },
@@ -798,6 +810,10 @@ struct multi_cores_pool {
 					rte_exit(EXIT_FAILURE, " ");
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name,
+					"policy-mtr") == 0) {
+				policy_mtr = true;
+			}
 			break;
 		default:
 			fprintf(stderr, "Invalid option: %s\n", argv[optind]);
@@ -909,6 +925,60 @@ struct multi_cores_pool {  }

 static void
+create_meter_policy(void)
+{
+	struct rte_mtr_error error;
+	uint32_t policy_id;
+	int ret, i, port_id;
+	const struct rte_flow_action *acts[RTE_COLORS];
+	struct action_rss_data rss_data;
+	struct rte_flow_action g_actions[2], r_actions[2];
+	uint16_t nr_ports;
+
+	memset(&rss_data, 0, sizeof(rss_data));
+	rss_data.conf.func = RTE_ETH_HASH_FUNCTION_DEFAULT;
+	rss_data.conf.level = 0;
+	rss_data.conf.types = GET_RSS_HF();
+	rss_data.conf.key_len = 0;

16 more quoted lines

This is some fixed behavior, it's not that right to use something like this,
Example of other solution to have option like:
--meter-w-policy=G:<GREEN_ACTIONS>, Y:<YELLOW_ACTIONS>, R:<RED_ACTIONS>
This way it will be easier to use, and more dynamic, it's never right to set fixed actions
For such application.
quoted hunk
+	r_actions[0].type = RTE_FLOW_ACTION_TYPE_DROP;
+	r_actions[0].conf = NULL;
+	r_actions[1].type = RTE_FLOW_ACTION_TYPE_END;
+	r_actions[1].conf = NULL;
+
+	acts[0] = &g_actions[0];
+	acts[1] = NULL;
+	acts[2] = &r_actions[0];
+
+	nr_ports = rte_eth_dev_count_avail();
+	for (port_id = 0; port_id < nr_ports; port_id++) {
+		policy_id = port_id + 10;
+		ret = rte_mtr_meter_policy_create(port_id,
+				policy_id,
+				acts, &error);
+		if (ret)
+			printf("meter add failed port_id  %d\n",
+				port_id);
+		g_policy_id[port_id] = policy_id;
+	}
+}
+
+static void
 create_meter_rule(int port_id, uint32_t counter)  {
 	int ret;
@@ -924,7 +994,14 @@ struct multi_cores_pool {

 	/*create meter*/
 	params.meter_profile_id = default_prof_id;
-	ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+
+	if (!policy_mtr)
+		ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+	else {
+		params.meter_policy_id = g_policy_id[port_id];
+		ret = rte_mtr_create(port_id, counter, &params, 0, &error);
+	}
+
 	if (ret != 0) {
 		printf("Port %u create meter idx(%d) error(%d) message:

50 more quoted lines

[dpdk-dev] [PATCH v2 0/3] support new format meter

From: Rongwei Liu <hidden>
Date: 2021-07-21 07:05:58

Add option "policy-mtr" and "policy-g_actions" for meter with policy
Add option "meter-cir" to specify meter CIR value
Add option "packet-mode" to identify pps or bps based profile

Rongwei Liu (3):
  app/flow-perf: support meter policy API
  app/flow-perf: add new meter CIR Configuration
  app/flow-perf: add the supports for meter PPS

 app/test-flow-perf/main.c      | 133 +++++++++++++++++++++++++++++++--
 doc/guides/tools/flow-perf.rst |  12 +++
 2 files changed, 137 insertions(+), 8 deletions(-)

-- 
2.27.0

[dpdk-dev] [PATCH v2 1/3] app/flow-perf: support meter policy API

From: Rongwei Liu <hidden>
Date: 2021-07-21 07:06:03

Add option "policy-mtr" to indicate if meter creation will include policy
or not. Meter creation will keep same without it.

With "policy-mtr", policy is introduced. API create_meter_policy
is to create a policy. API create_meter_rule will use it to create
meter.

Add option "policy-g_actions" to specify meter policy green color actions.
W/o this, policy creation will fail since there is no default one.

Signed-off-by: Haifei Luo <redacted>
Signed-off-by: Jiawei Wang <redacted>
Signed-off-by: Rongwei Liu <redacted>
---
 app/test-flow-perf/main.c      | 121 ++++++++++++++++++++++++++++++---
 doc/guides/tools/flow-perf.rst |   6 ++
 2 files changed, 119 insertions(+), 8 deletions(-)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 9be8edc31d..e0d94f943a 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -37,6 +37,7 @@
 #include <rte_mtr.h>
 
 #include "config.h"
+#include "actions_gen.h"
 #include "flow_gen.h"
 
 #define MAX_BATCHES_COUNT          100
@@ -49,10 +50,12 @@ static uint8_t flow_group;
 
 static uint64_t encap_data;
 static uint64_t decap_data;
+static uint64_t g_actions;
 
 static uint64_t flow_items[MAX_ITEMS_NUM];
 static uint64_t flow_actions[MAX_ACTIONS_NUM];
 static uint64_t flow_attrs[MAX_ATTRS_NUM];
+static uint32_t g_policy_id[MAX_PORTS];
 static uint8_t items_idx, actions_idx, attrs_idx;
 
 static uint64_t ports_mask;
@@ -62,6 +65,7 @@ static bool delete_flag;
 static bool dump_socket_mem_flag;
 static bool enable_fwd;
 static bool unique_data;
+static bool policy_mtr;
 
 static struct rte_mempool *mbuf_mp;
 static uint32_t nb_lcores;
@@ -69,6 +73,7 @@ static uint32_t rules_count;
 static uint32_t rules_batch;
 static uint32_t hairpin_queues_num; /* total hairpin q number - default: 0 */
 static uint32_t nb_lcores;
+static uint64_t meter_cir;
 
 #define MAX_PKT_BURST    32
 #define LCORE_MODE_PKT    1
@@ -134,6 +139,8 @@ usage(char *progname)
 	printf("  --portmask=N: hexadecimal bitmask of ports used\n");
 	printf("  --unique-data: flag to set using unique data for all"
 		" actions that support data, such as header modify and encap actions\n");
+	printf("  --policy-mtr: To create meter with policy\n");
+	printf("  --policy-g_actions: To set meter policy green color actions\n");
 
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
@@ -573,6 +580,9 @@ args_parse(int argc, char **argv)
 		{ "unique-data",                0, 0, 0 },
 		{ "portmask",                   1, 0, 0 },
 		{ "cores",                      1, 0, 0 },
+		{ "policy-mtr",                 0, 0, 0 },
+		{ "policy-g_actions",           1, 0, 0 },
+		{ "meter-profile-alg",          1, 0, 0 },
 		/* Attributes */
 		{ "ingress",                    0, 0, 0 },
 		{ "egress",                     0, 0, 0 },
@@ -802,6 +812,32 @@ args_parse(int argc, char **argv)
 						RTE_MAX_LCORE);
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
+				policy_mtr = true;
+			if (strcmp(lgopts[opt_idx].name,
+					"policy-g_actions") == 0) {
+				token = strtok(optarg, ",");
+				while (token != NULL) {
+					for (i = 0;
+					     i < RTE_DIM(flow_options); i++) {
+						if (strcmp(optarg,
+						    flow_options[i].str) == 0) {
+							g_actions |=
+							flow_options[i].mask;
+							break;
+						}
+					}
+					/* Reached last item with no match */
+					if (i == (RTE_DIM(flow_options) - 1)) {
+						fprintf(stderr,
+							"Invalid g_actions "
+							"item: %s\n", token);
+						usage(argv[0]);
+						rte_exit(EXIT_SUCCESS, "Invalid g_actions item\n");
+					}
+					token = strtok(NULL, ",");
+				}
+			}
 			break;
 		default:
 			usage(argv[0]);
@@ -912,6 +948,62 @@ has_meter(void)
 	return 0;
 }
 
+static void
+create_meter_policy(void)
+{
+	struct rte_mtr_error error;
+	uint32_t policy_id;
+	int ret, i, port_id;
+	struct rte_mtr_meter_policy_params policy;
+	struct rte_flow_action r_actions[2];
+	uint16_t nr_ports;
+	struct rte_flow_action actions[MAX_ACTIONS_NUM];
+	uint64_t flow_actions[MAX_ACTIONS_NUM];
+	int lcore_counter = 0;
+	int lcore_id = rte_lcore_id();
+
+	memset(actions, 0, sizeof(actions));
+	memset(flow_actions, 0, sizeof(flow_actions));
+	memset(&policy, 0, sizeof(policy));
+	RTE_LCORE_FOREACH(i) {
+		/*  If core not needed return. */
+		if (lcore_id == i) {
+			if (lcore_counter >= (int) mc_pool.cores_count)
+				return;
+			break;
+		}
+		lcore_counter++;
+	}
+	lcore_id = lcore_counter;
+
+	if (lcore_id >= (int) mc_pool.cores_count)
+		return;
+
+	flow_actions[0] = g_actions;
+	fill_actions(actions, flow_actions, 0, 0, 0,
+		     0, 0, lcore_id, unique_data);
+
+	r_actions[0].type = RTE_FLOW_ACTION_TYPE_DROP;
+	r_actions[0].conf = NULL;
+	r_actions[1].type = RTE_FLOW_ACTION_TYPE_END;
+	r_actions[1].conf = NULL;
+
+	policy.actions[RTE_COLOR_GREEN] = &actions[0];
+	policy.actions[RTE_COLOR_YELLOW] = NULL;
+	policy.actions[RTE_COLOR_RED] = &r_actions[0];
+
+	nr_ports = rte_eth_dev_count_avail();
+	for (port_id = 0; port_id < nr_ports; port_id++) {
+		policy_id = port_id + 10;
+		ret = rte_mtr_meter_policy_add(port_id, policy_id,
+					       &policy, &error);
+		if (ret)
+			printf("meter policy add failed "
+			       "port_id %d\n", port_id);
+		g_policy_id[port_id] = policy_id;
+	}
+}
+
 static void
 create_meter_rule(int port_id, uint32_t counter)
 {
@@ -928,7 +1020,14 @@ create_meter_rule(int port_id, uint32_t counter)
 
 	/*create meter*/
 	params.meter_profile_id = default_prof_id;
-	ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+
+	if (!policy_mtr) {
+		ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+	} else {
+		params.meter_policy_id = g_policy_id[port_id];
+		ret = rte_mtr_create(port_id, counter, &params, 0, &error);
+	}
+
 	if (ret != 0) {
 		printf("Port %u create meter idx(%d) error(%d) message: %s\n",
 			port_id, counter, error.type,
@@ -942,11 +1041,16 @@ destroy_meter_rule(int port_id, uint32_t counter)
 {
 	struct rte_mtr_error error;
 
-	if (rte_mtr_destroy(port_id, counter, &error)) {
-		printf("Port %u destroy meter(%d) error(%d) message: %s\n",
+	if (policy_mtr) {
+		if (rte_mtr_meter_policy_delete(port_id, counter+1, &error))
+			printf("error delete policy %d\n", counter+1);
+	} else {
+		if (rte_mtr_destroy(port_id, counter, &error)) {
+			printf("Port %u destroy meter(%d) error(%d) message: %s\n",
 			port_id, counter, error.type,
 			error.message ? error.message : "(no stated reason)");
-		rte_exit(EXIT_FAILURE, "Error in deleting meter rule\n");
+			rte_exit(EXIT_FAILURE, "Error in deleting meter rule");
+		}
 	}
 }
 
@@ -1051,12 +1155,10 @@ create_meter_profile(void)
 		/* If port outside portmask */
 		if (!((ports_mask >> port_id) & 0x1))
 			continue;
-
 		mp.alg = RTE_MTR_SRTCM_RFC2697;
-		mp.srtcm_rfc2697.cir = METER_CIR;
-		mp.srtcm_rfc2697.cbs = METER_CIR / 8;
+		mp.srtcm_rfc2697.cir = meter_cir;
+		mp.srtcm_rfc2697.cbs = meter_cir / 8;
 		mp.srtcm_rfc2697.ebs = 0;
-
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
@@ -1875,6 +1977,7 @@ main(int argc, char **argv)
 	dump_socket_mem_flag = false;
 	flow_group = DEFAULT_GROUP;
 	unique_data = false;
+	meter_cir = METER_CIR;
 
 	signal(SIGINT, signal_handler);
 	signal(SIGTERM, signal_handler);
@@ -1894,6 +1997,8 @@ main(int argc, char **argv)
 
 	if (has_meter())
 		create_meter_profile();
+	if (policy_mtr)
+		create_meter_policy();
 	rte_eal_mp_remote_launch(run_rte_flow_handler_cores, NULL, CALL_MAIN);
 
 	if (enable_fwd) {
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 280bf7e0e0..90b6934537 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -354,3 +354,9 @@ Actions:
 *       ``--meter``
         Add meter action to all flows actions.
         Currently, 1 meter profile -> N meter rules -> N rte flows.
+
+*       ``--policy-mtr``
+        Add policy-mtr to create meter with policy.
+
+*       ``--policy-g_actions``
+        Add policy-g_actions to specify policy green color actions.
-- 
2.27.0

[dpdk-dev] [PATCH v2 2/3] app/flow-perf: add new meter CIR Configuration

From: Rongwei Liu <hidden>
Date: 2021-07-21 07:06:11

Add the new meter CIR configuration parameter, user can set the
different value for committed information rate(CIR) parameter.

The usage as below:
--meter-cir=N, default count is 1250000.

Signed-off-by: Jiawei Wang <redacted>
Signed-off-by: Rongwei Liu <redacted>
---
 app/test-flow-perf/main.c      | 8 +++++++-
 doc/guides/tools/flow-perf.rst | 3 +++
 2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index e0d94f943a..dd0aac8b06 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -141,6 +141,8 @@ usage(char *progname)
 		" actions that support data, such as header modify and encap actions\n");
 	printf("  --policy-mtr: To create meter with policy\n");
 	printf("  --policy-g_actions: To set meter policy green color actions\n");
+	printf("  --meter-cir=N: to set committed information rate(CIR)"
+		" parameter in meter profile, default is %d\n", METER_CIR);
 
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
@@ -582,7 +584,7 @@ args_parse(int argc, char **argv)
 		{ "cores",                      1, 0, 0 },
 		{ "policy-mtr",                 0, 0, 0 },
 		{ "policy-g_actions",           1, 0, 0 },
-		{ "meter-profile-alg",          1, 0, 0 },
+		{ "meter-cir",                  1, 0, 0 },
 		/* Attributes */
 		{ "ingress",                    0, 0, 0 },
 		{ "egress",                     0, 0, 0 },
@@ -814,6 +816,10 @@ args_parse(int argc, char **argv)
 			}
 			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
 				policy_mtr = true;
+			if (strcmp(lgopts[opt_idx].name, "meter-cir") == 0) {
+				n = atoi(optarg);
+				meter_cir = (uint64_t) n;
+			}
 			if (strcmp(lgopts[opt_idx].name,
 					"policy-g_actions") == 0) {
 				token = strtok(optarg, ",");
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 90b6934537..113e078eb5 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -105,6 +105,9 @@ The command line options are:
         Such as header modify and encap actions. Default is using fixed
         data for any action that support data for all flows.
 
+*	``--meter-cir=N``
+	Set the committed information rate(CIR) parameter, default count is 1250000.
+
 Attributes:
 
 *	``--ingress``
-- 
2.27.0

[dpdk-dev] [PATCH v2 3/3] app/flow-perf: add the supports for meter PPS

From: Rongwei Liu <hidden>
Date: 2021-07-21 07:06:17

The flow perf application used the srtcm_rfc2697 as meter profile
while do the meter testing.

This patch adds the support new configuration parameter
'--packet-mode' to generate the meter flows with the packet mode.

Signed-off-by: Jiawei Wang <redacted>
Signed-off-by: Rongwei Liu <redacted>
---
 app/test-flow-perf/main.c      | 6 ++++++
 doc/guides/tools/flow-perf.rst | 3 +++
 2 files changed, 9 insertions(+)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index dd0aac8b06..d2003108cc 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -66,6 +66,7 @@ static bool dump_socket_mem_flag;
 static bool enable_fwd;
 static bool unique_data;
 static bool policy_mtr;
+static bool packet_mode;
 
 static struct rte_mempool *mbuf_mp;
 static uint32_t nb_lcores;
@@ -143,6 +144,7 @@ usage(char *progname)
 	printf("  --policy-g_actions: To set meter policy green color actions\n");
 	printf("  --meter-cir=N: to set committed information rate(CIR)"
 		" parameter in meter profile, default is %d\n", METER_CIR);
+	printf("  --packet-mode: To enable packet mode for meter profile\n");
 
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
@@ -585,6 +587,7 @@ args_parse(int argc, char **argv)
 		{ "policy-mtr",                 0, 0, 0 },
 		{ "policy-g_actions",           1, 0, 0 },
 		{ "meter-cir",                  1, 0, 0 },
+		{ "packet-mode",                0, 0, 0 },
 		/* Attributes */
 		{ "ingress",                    0, 0, 0 },
 		{ "egress",                     0, 0, 0 },
@@ -820,6 +823,8 @@ args_parse(int argc, char **argv)
 				n = atoi(optarg);
 				meter_cir = (uint64_t) n;
 			}
+			if (strcmp(lgopts[opt_idx].name, "packet-mode") == 0)
+				packet_mode = true;
 			if (strcmp(lgopts[opt_idx].name,
 					"policy-g_actions") == 0) {
 				token = strtok(optarg, ",");
@@ -1165,6 +1170,7 @@ create_meter_profile(void)
 		mp.srtcm_rfc2697.cir = meter_cir;
 		mp.srtcm_rfc2697.cbs = meter_cir / 8;
 		mp.srtcm_rfc2697.ebs = 0;
+		mp.packet_mode = packet_mode;
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 113e078eb5..1ec0d5d408 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -108,6 +108,9 @@ The command line options are:
 *	``--meter-cir=N``
 	Set the committed information rate(CIR) parameter, default count is 1250000.
 
+*	``--packet-mode``
+	Enable packets mode for meter profile.
+
 Attributes:
 
 *	``--ingress``
-- 
2.27.0

Re: [dpdk-dev] [PATCH v2 1/3] app/flow-perf: support meter policy API

From: Wisam Monther <hidden>
Date: 2021-09-26 09:45:11

Hi,
quoted hunk
-----Original Message-----
From: Rongwei Liu <redacted>
Sent: Wednesday, July 21, 2021 10:06 AM
To: Matan Azrad <redacted>; Slava Ovsiienko
[off-list ref]; Ori Kam [off-list ref]; NBU-Contact-
Thomas Monjalon [off-list ref]; Wisam Monther
[off-list ref]
Cc: <redacted>; Raslan Darawsheh <redacted>; Haifei Luo
[off-list ref]; Jiawei(Jonny) Wang [off-list ref]
Subject: [PATCH v2 1/3] app/flow-perf: support meter policy API

Add option "policy-mtr" to indicate if meter creation will include policy or not.
Meter creation will keep same without it.

With "policy-mtr", policy is introduced. API create_meter_policy is to create a
policy. API create_meter_rule will use it to create meter.

Add option "policy-g_actions" to specify meter policy green color actions.
W/o this, policy creation will fail since there is no default one.

Signed-off-by: Haifei Luo <redacted>
Signed-off-by: Jiawei Wang <redacted>
Signed-off-by: Rongwei Liu <redacted>
---
 app/test-flow-perf/main.c      | 121 ++++++++++++++++++++++++++++++--
-
 doc/guides/tools/flow-perf.rst |   6 ++
 2 files changed, 119 insertions(+), 8 deletions(-)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c index
9be8edc31d..e0d94f943a 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -37,6 +37,7 @@
 #include <rte_mtr.h>

 #include "config.h"
+#include "actions_gen.h"
 #include "flow_gen.h"

24 more quoted lines

i see it's defined but not really used, i think all the meter_cir should be squashed w/ next commit
quoted hunk
 #define MAX_PKT_BURST    32
 #define LCORE_MODE_PKT    1
@@ -134,6 +139,8 @@ usage(char *progname)
 	printf("  --portmask=N: hexadecimal bitmask of ports used\n");
 	printf("  --unique-data: flag to set using unique data for all"
 		" actions that support data, such as header modify and encap
actions\n");
+	printf("  --policy-mtr: To create meter with policy\n");
+	printf("  --policy-g_actions: To set meter policy green color
+actions\n");

 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n"); @@ -573,6
+580,9 @@ args_parse(int argc, char **argv)
 		{ "unique-data",                0, 0, 0 },
 		{ "portmask",                   1, 0, 0 },
 		{ "cores",                      1, 0, 0 },
+		{ "policy-mtr",                 0, 0, 0 },
+		{ "policy-g_actions",           1, 0, 0 },
i prefer to have those in the end with the actions

+		{ "meter-profile-alg",          1, 0, 0 },
i don't see any use or parse for meter-profile-alg
quoted hunk
 		/* Attributes */
 		{ "ingress",                    0, 0, 0 },
 		{ "egress",                     0, 0, 0 },
@@ -802,6 +812,32 @@ args_parse(int argc, char **argv)
 						RTE_MAX_LCORE);
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
do we really need this parameter,
for std meter user can use --meter
for the new one, something like: --policy-meter=[G_ACTIONS]

I'm trying to reduce the dependencies for any new parameters
quoted hunk
+				policy_mtr = true;
+			if (strcmp(lgopts[opt_idx].name,
+					"policy-g_actions") == 0) {
+				token = strtok(optarg, ",");
+				while (token != NULL) {
+					for (i = 0;
+					     i < RTE_DIM(flow_options); i++) {
+						if (strcmp(optarg,
+						    flow_options[i].str) == 0) {
+							g_actions |=
+							flow_options[i].mask;
+							break;
+						}
+					}
+					/* Reached last item with no match
*/
+					if (i == (RTE_DIM(flow_options) - 1)) {
+						fprintf(stderr,
+							"Invalid g_actions "
+							"item: %s\n", token);
+						usage(argv[0]);
+						rte_exit(EXIT_SUCCESS,
"Invalid g_actions item\n");
+					}
+					token = strtok(NULL, ",");
+				}
+			}
 			break;
 		default:
 			usage(argv[0]);
@@ -912,6 +948,62 @@ has_meter(void)
 	return 0;
 }

+static void
+create_meter_policy(void)
+{
+	struct rte_mtr_error error;
+	uint32_t policy_id;
+	int ret, i, port_id;

7 more quoted lines

not sure that you are using the correct mapping of multiple cores.

In short the user can pass: cores=90,91,92,93,94,95

The app usually map all cores to new internal ids from 0 - N.
While this solution will break the user freedom of choosing any core
+
+	memset(actions, 0, sizeof(actions));
struct rte_flow_action actions[MAX_ACTIONS_NUM] = {0, 0};
+	memset(flow_actions, 0, sizeof(flow_actions));
uint64_t flow_actions[MAX_ACTIONS_NUM] = { 0 };
+	memset(&policy, 0, sizeof(policy));
in rte_mtr_meter_policy_params it have const struct rte_flow_action,
and since it's const i really don't like the idea of setting it to 0 by memset.
it's one time init and that's it
quoted hunk
+	RTE_LCORE_FOREACH(i) {
+		/*  If core not needed return. */
+		if (lcore_id == i) {
+			if (lcore_counter >= (int) mc_pool.cores_count)
+				return;
+			break;
+		}
+		lcore_counter++;
+	}
+	lcore_id = lcore_counter;
+
+	if (lcore_id >= (int) mc_pool.cores_count)
+		return;
no need for such logic, just take the core id as parameter, all this logic already done
quoted hunk
+
+	flow_actions[0] = g_actions;
+	fill_actions(actions, flow_actions, 0, 0, 0,
+		     0, 0, lcore_id, unique_data);
Will this create one meter for all flows or you are doing new meter for each flow?
can you please elaborate?
What is the exact goal here?
+
+	r_actions[0].type = RTE_FLOW_ACTION_TYPE_DROP;
+	r_actions[0].conf = NULL;
+	r_actions[1].type = RTE_FLOW_ACTION_TYPE_END;
+	r_actions[1].conf = NULL;
+
+	policy.actions[RTE_COLOR_GREEN] = &actions[0];
+	policy.actions[RTE_COLOR_YELLOW] = NULL;
+	policy.actions[RTE_COLOR_RED] = &r_actions[0];
+
+	nr_ports = rte_eth_dev_count_avail();
+	for (port_id = 0; port_id < nr_ports; port_id++) {
+		policy_id = port_id + 10;
+		ret = rte_mtr_meter_policy_add(port_id, policy_id,
+					       &policy, &error);
+		if (ret)
+			printf("meter policy add failed "
+			       "port_id %d\n", port_id);
+		g_policy_id[port_id] = policy_id;
+	}
+}
+
 static void
 create_meter_rule(int port_id, uint32_t counter)  { @@ -928,7 +1020,14 @@
create_meter_rule(int port_id, uint32_t counter)

 	/*create meter*/
 	params.meter_profile_id = default_prof_id;
-	ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+
+	if (!policy_mtr) {
+		ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+	} else {
+		params.meter_policy_id = g_policy_id[port_id];
+		ret = rte_mtr_create(port_id, counter, &params, 0, &error);
+	}
+
 	if (ret != 0) {
 		printf("Port %u create meter idx(%d) error(%d) message:
%s\n",

75 more quoted lines

Re: [dpdk-dev] [PATCH v2 2/3] app/flow-perf: add new meter CIR Configuration

From: Wisam Monther <hidden>
Date: 2021-09-26 09:46:06

quoted hunk
-----Original Message-----
From: Rongwei Liu <redacted>
Sent: Wednesday, July 21, 2021 10:06 AM
To: Matan Azrad <redacted>; Slava Ovsiienko
[off-list ref]; Ori Kam [off-list ref]; NBU-Contact-
Thomas Monjalon [off-list ref]; Wisam Monther
[off-list ref]
Cc: <redacted>; Raslan Darawsheh <redacted>; Jiawei(Jonny)
Wang [off-list ref]
Subject: [PATCH v2 2/3] app/flow-perf: add new meter CIR Configuration

Add the new meter CIR configuration parameter, user can set the different
value for committed information rate(CIR) parameter.

The usage as below:
--meter-cir=N, default count is 1250000.

Signed-off-by: Jiawei Wang <redacted>
Signed-off-by: Rongwei Liu <redacted>
---
 app/test-flow-perf/main.c      | 8 +++++++-
 doc/guides/tools/flow-perf.rst | 3 +++
 2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c index
e0d94f943a..dd0aac8b06 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -141,6 +141,8 @@ usage(char *progname)
 		" actions that support data, such as header modify and encap
actions\n");
 	printf("  --policy-mtr: To create meter with policy\n");
 	printf("  --policy-g_actions: To set meter policy green color
actions\n");
+	printf("  --meter-cir=N: to set committed information rate(CIR)"
+		" parameter in meter profile, default is %d\n", METER_CIR);

 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n"); @@ -582,7
+584,7 @@ args_parse(int argc, char **argv)

5 more quoted lines

The old one is irrelevant meter-profile-alg.
Moreover, i agree that meter-cir is control
quoted hunk
 		/* Attributes */
 		{ "ingress",                    0, 0, 0 },
 		{ "egress",                     0, 0, 0 },
@@ -814,6 +816,10 @@ args_parse(int argc, char **argv)
 			}
 			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
 				policy_mtr = true;
+			if (strcmp(lgopts[opt_idx].name, "meter-cir") == 0) {
+				n = atoi(optarg);
+				meter_cir = (uint64_t) n;
+			}
 			if (strcmp(lgopts[opt_idx].name,
 					"policy-g_actions") == 0) {
 				token = strtok(optarg, ",");
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 90b6934537..113e078eb5 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -105,6 +105,9 @@ The command line options are:
         Such as header modify and encap actions. Default is using fixed
         data for any action that support data for all flows.

+*	``--meter-cir=N``
+	Set the committed information rate(CIR) parameter, default count is
1250000.
count -> value?
+
 Attributes:

 *	``--ingress``
--
2.27.0

Re: [dpdk-dev] [PATCH v2 3/3] app/flow-perf: add the supports for meter PPS

From: Wisam Monther <hidden>
Date: 2021-09-26 09:47:58

Hi,
-----Original Message-----
From: Rongwei Liu <redacted>
Sent: Wednesday, July 21, 2021 10:06 AM
To: Matan Azrad <redacted>; Slava Ovsiienko
[off-list ref]; Ori Kam [off-list ref]; NBU-Contact-
Thomas Monjalon [off-list ref]; Wisam Monther
[off-list ref]
Cc: <redacted>; Raslan Darawsheh <redacted>; Jiawei(Jonny)
Wang [off-list ref]
Subject: [PATCH v2 3/3] app/flow-perf: add the supports for meter PPS

The flow perf application used the srtcm_rfc2697 as meter profile while do
the meter testing.

This patch adds the support new configuration parameter '--packet-mode' to
generate the meter flows with the packet mode.

Signed-off-by: Jiawei Wang <redacted>
Signed-off-by: Rongwei Liu <redacted>
Reviewed-by: Wisam Jaddo <redacted>

Please send new versions to fix the first two patches, and you can add my ack to the third patch for this version.

BRs,
Wisam Jaddo

[dpdk-dev] [PATCH v3 0/3] add meter policy support in flow-perf

From: Rongwei Liu <hidden>
Date: 2021-10-28 03:26:22

Add meter policy support and provide options to specify green/yellow/
red corlor actions and cir/cbs/ebs values.

v2: add option to specify green color actions.
v3: support yellow color action and ebs options.
Rongwei Liu (3):
  app/flow-perf: support meter policy API
  app/flow-perf: add meter-profile to support cir cbs and ebs
  app/flow-perf: add packet mode metering mode

 app/test-flow-perf/main.c      | 176 ++++++++++++++++++++++++++++++---
 doc/guides/tools/flow-perf.rst |   9 +-
 2 files changed, 169 insertions(+), 16 deletions(-)

-- 
2.27.0

[dpdk-dev] [PATCH v3 1/3] app/flow-perf: support meter policy API

From: Rongwei Liu <hidden>
Date: 2021-10-28 03:26:27

Add option "policy-mtr" to indicate if meter creation will include policy
or not. Meter creation will keep the same without it.

With "policy-mtr", the policy is introduced. API create_meter_policy
is to create a policy. API create_meter_rule will use it to create
a meter. The value of it is used to specify meter policy green color
actions.

Signed-off-by: Haifei Luo <redacted>
Signed-off-by: Jiawei Wang <redacted>
Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
 app/test-flow-perf/main.c      | 147 ++++++++++++++++++++++++++++++---
 doc/guides/tools/flow-perf.rst |   3 +
 2 files changed, 137 insertions(+), 13 deletions(-)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 3ebc025fb2..40e15d5f9a 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -37,6 +37,7 @@
 #include <rte_mtr.h>
 
 #include "config.h"
+#include "actions_gen.h"
 #include "flow_gen.h"
 
 #define MAX_BATCHES_COUNT          100
@@ -49,10 +50,13 @@ static uint8_t flow_group;
 
 static uint64_t encap_data;
 static uint64_t decap_data;
+static uint64_t all_actions[RTE_COLORS][MAX_ACTIONS_NUM];
+static char *actions_str[RTE_COLORS];
 
 static uint64_t flow_items[MAX_ITEMS_NUM];
 static uint64_t flow_actions[MAX_ACTIONS_NUM];
 static uint64_t flow_attrs[MAX_ATTRS_NUM];
+static uint32_t policy_id[MAX_PORTS];
 static uint8_t items_idx, actions_idx, attrs_idx;
 
 static uint64_t ports_mask;
@@ -62,6 +66,7 @@ static bool delete_flag;
 static bool dump_socket_mem_flag;
 static bool enable_fwd;
 static bool unique_data;
+static bool policy_mtr;
 
 static uint8_t rx_queues_count;
 static uint8_t tx_queues_count;
@@ -142,7 +147,8 @@ usage(char *progname)
 	printf("  --portmask=N: hexadecimal bitmask of ports used\n");
 	printf("  --unique-data: flag to set using unique data for all"
 		" actions that support data, such as header modify and encap actions\n");
-
+	printf("  --policy-mtr=\"g1,g2:y1:r1\": To create meter with specified "
+		"color actions\n");
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
 	printf("  --egress: set egress attribute in flows\n");
@@ -242,9 +248,10 @@ args_parse(int argc, char **argv)
 	char **argvopt;
 	char *token;
 	char *end;
+	char *arg;
 	int n, opt;
 	int opt_idx;
-	size_t i;
+	size_t i, j, k;
 
 	static const struct option_dict {
 		const char *str;
@@ -652,6 +659,7 @@ args_parse(int argc, char **argv)
 		{ "raw-decap",                  1, 0, 0 },
 		{ "vxlan-encap",                0, 0, 0 },
 		{ "vxlan-decap",                0, 0, 0 },
+		{ "policy-mtr",                 1, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -854,6 +862,46 @@ args_parse(int argc, char **argv)
 						RTE_MAX_LCORE);
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0) {
+				j = 0;
+				k = 0;
+				arg = optarg;
+				policy_mtr = true;
+				token = strsep(&arg, ":\0");
+				while (token != NULL && j < RTE_COLORS) {
+					actions_str[j++] = token;
+					token = strsep(&arg, ":\0");
+				}
+				j = 0;
+				token = strtok(actions_str[0], ",\0");
+				while (token == NULL && j < RTE_COLORS - 1)
+					token = strtok(actions_str[++j], ",\0");
+				while (j < RTE_COLORS && token != NULL) {
+					for (i = 0;
+					     i < RTE_DIM(flow_options); i++) {
+						if (!strcmp(token,
+						    flow_options[i].str)) {
+							all_actions[j][k++] =
+							flow_options[i].mask;
+							break;
+						}
+					}
+					/* Reached last item with no match */
+					if (i >= RTE_DIM(flow_options)) {
+						fprintf(stderr,
+							"Invalid actions "
+							"item: %s\n", token);
+						usage(argv[0]);
+						rte_exit(EXIT_SUCCESS, "Invalid actions item\n");
+					}
+					token = strtok(NULL, ",\0");
+					while (!token && j < RTE_COLORS - 1) {
+						token = strtok(actions_str[++j],
+								",\0");
+						k = 0;
+					}
+				}
+			}
 			break;
 		default:
 			usage(argv[0]);
@@ -964,12 +1012,68 @@ has_meter(void)
 	return 0;
 }
 
+static void
+create_meter_policy(void)
+{
+	struct rte_mtr_error error;
+	int ret, port_id;
+	struct rte_mtr_meter_policy_params policy;
+	uint16_t nr_ports;
+	struct rte_flow_action actions[RTE_COLORS][MAX_ACTIONS_NUM];
+	int i;
+
+	memset(actions, 0, sizeof(actions));
+	memset(&policy, 0, sizeof(policy));
+	for (i = 0; i < RTE_COLORS; i++)
+		fill_actions(actions[i], all_actions[i], 0, 0, 0,
+			     0, 0, 0, unique_data, rx_queues_count);
+
+	policy.actions[RTE_COLOR_GREEN] = actions[RTE_COLOR_GREEN];
+	policy.actions[RTE_COLOR_YELLOW] = actions[RTE_COLOR_YELLOW];
+	policy.actions[RTE_COLOR_RED] = actions[RTE_COLOR_RED];
+
+	nr_ports = rte_eth_dev_count_avail();
+	for (port_id = 0; port_id < nr_ports; port_id++) {
+		policy_id[port_id] = port_id + 10;
+		ret = rte_mtr_meter_policy_add(port_id, policy_id[port_id],
+					       &policy, &error);
+		if (ret) {
+			fprintf(stderr, "meter policy add failed port_id %d\n",
+				port_id);
+			policy_id[port_id] = UINT32_MAX;
+		}
+	}
+}
+
+
+static void
+destroy_meter_policy(void)
+{
+	struct rte_mtr_error error;
+	uint16_t nr_ports;
+	int port_id;
+
+	nr_ports = rte_eth_dev_count_avail();
+	for (port_id = 0; port_id < nr_ports; port_id++) {
+		/* If port outside portmask */
+		if (!((ports_mask >> port_id) & 0x1))
+			continue;
+
+		if (rte_mtr_meter_policy_delete
+			(port_id, policy_id[port_id], &error)) {
+			fprintf(stderr, "Port %u del policy error(%d) message: %s\n",
+				port_id, error.type,
+				error.message ? error.message : "(no stated reason)");
+			rte_exit(EXIT_FAILURE, "Error: Destroy meter policy Failed!\n");
+		}
+	}
+}
+
 static void
 create_meter_rule(int port_id, uint32_t counter)
 {
 	int ret;
 	struct rte_mtr_params params;
-	uint32_t default_prof_id = 100;
 	struct rte_mtr_error error;
 
 	memset(&params, 0, sizeof(struct rte_mtr_params));
@@ -979,8 +1083,15 @@ create_meter_rule(int port_id, uint32_t counter)
 	params.dscp_table = NULL;
 
 	/*create meter*/
-	params.meter_profile_id = default_prof_id;
-	ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+	params.meter_profile_id = DEFAULT_METER_PROF_ID;
+
+	if (!policy_mtr) {
+		ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+	} else {
+		params.meter_policy_id = policy_id[port_id];
+		ret = rte_mtr_create(port_id, counter, &params, 0, &error);
+	}
+
 	if (ret != 0) {
 		printf("Port %u create meter idx(%d) error(%d) message: %s\n",
 			port_id, counter, error.type,
@@ -994,11 +1105,17 @@ destroy_meter_rule(int port_id, uint32_t counter)
 {
 	struct rte_mtr_error error;
 
+	if (policy_mtr && policy_id[port_id] != UINT32_MAX) {
+		if (rte_mtr_meter_policy_delete(port_id, policy_id[port_id],
+					&error))
+			fprintf(stderr, "error delete policy %d\n", counter+1);
+		policy_id[port_id] = UINT32_MAX;
+	}
 	if (rte_mtr_destroy(port_id, counter, &error)) {
-		printf("Port %u destroy meter(%d) error(%d) message: %s\n",
-			port_id, counter, error.type,
-			error.message ? error.message : "(no stated reason)");
-		rte_exit(EXIT_FAILURE, "Error in deleting meter rule\n");
+		fprintf(stderr, "Port %u destroy meter(%d) error(%d) message: %s\n",
+		port_id, counter, error.type,
+		error.message ? error.message : "(no stated reason)");
+		rte_exit(EXIT_FAILURE, "Error in deleting meter rule");
 	}
 }
 
@@ -1103,12 +1220,10 @@ create_meter_profile(void)
 		/* If port outside portmask */
 		if (!((ports_mask >> port_id) & 0x1))
 			continue;
-
 		mp.alg = RTE_MTR_SRTCM_RFC2697;
 		mp.srtcm_rfc2697.cir = METER_CIR;
 		mp.srtcm_rfc2697.cbs = METER_CIR / 8;
 		mp.srtcm_rfc2697.ebs = 0;
-
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
@@ -1975,16 +2090,22 @@ main(int argc, char **argv)
 
 	printf(":: Flows Count per port: %d\n\n", rules_count);
 
-	if (has_meter())
+	if (has_meter()) {
 		create_meter_profile();
+		if (policy_mtr)
+			create_meter_policy();
+	}
 	rte_eal_mp_remote_launch(run_rte_flow_handler_cores, NULL, CALL_MAIN);
 
 	if (enable_fwd) {
 		init_lcore_info();
 		rte_eal_mp_remote_launch(start_forwarding, NULL, CALL_MAIN);
 	}
-	if (has_meter() && delete_flag)
+	if (has_meter() && delete_flag) {
 		destroy_meter_profile();
+		if (policy_mtr)
+			destroy_meter_policy();
+	}
 
 	RTE_ETH_FOREACH_DEV(port) {
 		rte_flow_flush(port, &error);
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 0855f88689..bf70682379 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -379,3 +379,6 @@ Actions:
 *       ``--meter``
         Add meter action to all flows actions.
         Currently, 1 meter profile -> N meter rules -> N rte flows.
+
+*       ``--policy-mtr=<str>``
+        Add policy-mtr to create meter with policy and specify policy actions.
-- 
2.27.0

[dpdk-dev] [PATCH v3 2/3] app/flow-perf: add meter-profile to support cir cbs and ebs

From: Rongwei Liu <hidden>
Date: 2021-10-28 03:26:34

Change meter-cir option to meter-profile to cover CIR/CBS/EBS all.

The usage is as below:
--meter-profile=N1,N2,N3 default value is 1250000 156250 0.

Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
 app/test-flow-perf/main.c      | 25 ++++++++++++++++++++++---
 doc/guides/tools/flow-perf.rst |  3 ++-
 2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 40e15d5f9a..8b8fc0fea3 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -82,6 +82,7 @@ static uint32_t rules_count;
 static uint32_t rules_batch;
 static uint32_t hairpin_queues_num; /* total hairpin q number - default: 0 */
 static uint32_t nb_lcores;
+static uint64_t meter_profile_values[3]; /* CIR CBS EBS values. */
 
 #define MAX_PKT_BURST    32
 #define LCORE_MODE_PKT    1
@@ -149,6 +150,9 @@ usage(char *progname)
 		" actions that support data, such as header modify and encap actions\n");
 	printf("  --policy-mtr=\"g1,g2:y1:r1\": To create meter with specified "
 		"color actions\n");
+	printf("  --meter-profile=cir,cbs,ebs: set CIR CBS EBS parameters in meter"
+		" profile, default is %d,%d,%d\n", METER_CIR, METER_CIR / 8, 0);
+
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
 	printf("  --egress: set egress attribute in flows\n");
@@ -660,6 +664,7 @@ args_parse(int argc, char **argv)
 		{ "vxlan-encap",                0, 0, 0 },
 		{ "vxlan-decap",                0, 0, 0 },
 		{ "policy-mtr",                 1, 0, 0 },
+		{ "meter-profile",              1, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -862,6 +867,18 @@ args_parse(int argc, char **argv)
 						RTE_MAX_LCORE);
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name,
+						"meter-profile") == 0) {
+				arg = optarg;
+				j = 0;
+				token = strsep(&arg, ",\0");
+				while (token != NULL && j < sizeof(
+						meter_profile_values) /
+						sizeof(uint64_t)) {
+					meter_profile_values[j++] = atol(token);
+					token = strsep(&arg, ",\0");
+				}
+			}
 			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0) {
 				j = 0;
 				k = 0;
@@ -1221,9 +1238,11 @@ create_meter_profile(void)
 		if (!((ports_mask >> port_id) & 0x1))
 			continue;
 		mp.alg = RTE_MTR_SRTCM_RFC2697;
-		mp.srtcm_rfc2697.cir = METER_CIR;
-		mp.srtcm_rfc2697.cbs = METER_CIR / 8;
-		mp.srtcm_rfc2697.ebs = 0;
+		mp.srtcm_rfc2697.cir = meter_profile_values[0] ?
+			meter_profile_values[0] : METER_CIR;
+		mp.srtcm_rfc2697.cbs = meter_profile_values[1] ?
+			meter_profile_values[1] : METER_CIR / 8;
+		mp.srtcm_rfc2697.ebs = meter_profile_values[2];
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index bf70682379..a38dda2fb7 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -130,7 +130,8 @@ The command line options are:
 *	``--total-mbuf-count=N``
 	Set the count of total mbuf number, default count is 32000.
 
-Attributes:
+*	``--meter-profile=N1,N2,N3``
+	Set the CIR, CBS and EBS parameter, default value is 1250000, 156250 and 0.
 
 *	``--ingress``
 	Set Ingress attribute to all flows attributes.
-- 
2.27.0

[dpdk-dev] [PATCH v3 3/3] app/flow-perf: add packet mode metering mode

From: Rongwei Liu <hidden>
Date: 2021-10-28 03:26:41

The flow perf application used the srtcm_rfc2697 as meter profile
while doing the meter testing.

This patch adds the support new configuration parameter
'--packet-mode' to generate the meter flows with the packet mode.

Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
 app/test-flow-perf/main.c      | 6 ++++++
 doc/guides/tools/flow-perf.rst | 3 +++
 2 files changed, 9 insertions(+)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 8b8fc0fea3..d63328ef11 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -67,6 +67,7 @@ static bool dump_socket_mem_flag;
 static bool enable_fwd;
 static bool unique_data;
 static bool policy_mtr;
+static bool packet_mode;
 
 static uint8_t rx_queues_count;
 static uint8_t tx_queues_count;
@@ -152,6 +153,7 @@ usage(char *progname)
 		"color actions\n");
 	printf("  --meter-profile=cir,cbs,ebs: set CIR CBS EBS parameters in meter"
 		" profile, default is %d,%d,%d\n", METER_CIR, METER_CIR / 8, 0);
+	printf("  --packet-mode: To enable packet mode for meter profile\n");
 
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
@@ -665,6 +667,7 @@ args_parse(int argc, char **argv)
 		{ "vxlan-decap",                0, 0, 0 },
 		{ "policy-mtr",                 1, 0, 0 },
 		{ "meter-profile",              1, 0, 0 },
+		{ "packet-mode",                0, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -879,6 +882,8 @@ args_parse(int argc, char **argv)
 					token = strsep(&arg, ",\0");
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name, "packet-mode") == 0)
+				packet_mode = true;
 			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0) {
 				j = 0;
 				k = 0;
@@ -1243,6 +1248,7 @@ create_meter_profile(void)
 		mp.srtcm_rfc2697.cbs = meter_profile_values[1] ?
 			meter_profile_values[1] : METER_CIR / 8;
 		mp.srtcm_rfc2697.ebs = meter_profile_values[2];
+		mp.packet_mode = packet_mode;
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index a38dda2fb7..e942a4400b 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -133,6 +133,9 @@ The command line options are:
 *	``--meter-profile=N1,N2,N3``
 	Set the CIR, CBS and EBS parameter, default value is 1250000, 156250 and 0.
 
+*	``--packet-mode``
+	Enable packets mode for meter profile.
+
 *	``--ingress``
 	Set Ingress attribute to all flows attributes.
 
-- 
2.27.0

Re: [dpdk-dev] [PATCH v3 1/3] app/flow-perf: support meter policy API

From: Thomas Monjalon <hidden>
Date: 2021-11-05 09:58:03

28/10/2021 05:25, Rongwei Liu:
quoted hunk
@@ -854,6 +862,46 @@ args_parse(int argc, char **argv)
 						RTE_MAX_LCORE);
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0) {
+				j = 0;
+				k = 0;
+				arg = optarg;
+				policy_mtr = true;
+				token = strsep(&arg, ":\0");
+				while (token != NULL && j < RTE_COLORS) {
+					actions_str[j++] = token;
+					token = strsep(&arg, ":\0");
+				}
+				j = 0;
+				token = strtok(actions_str[0], ",\0");
+				while (token == NULL && j < RTE_COLORS - 1)
+					token = strtok(actions_str[++j], ",\0");
+				while (j < RTE_COLORS && token != NULL) {
+					for (i = 0;
+					     i < RTE_DIM(flow_options); i++) {
+						if (!strcmp(token,
+						    flow_options[i].str)) {
+							all_actions[j][k++] =
+							flow_options[i].mask;
+							break;
+						}
+					}
+					/* Reached last item with no match */
+					if (i >= RTE_DIM(flow_options)) {
+						fprintf(stderr,
+							"Invalid actions "
+							"item: %s\n", token);
+						usage(argv[0]);
+						rte_exit(EXIT_SUCCESS, "Invalid actions item\n");
+					}
+					token = strtok(NULL, ",\0");
+					while (!token && j < RTE_COLORS - 1) {
+						token = strtok(actions_str[++j],
+								",\0");

4 more quoted lines

Could we avoid having so many indents?
Checkpatch suggest considering a refactoring.

[...]
+		fill_actions(actions[i], all_actions[i], 0, 0, 0,
+			     0, 0, 0, unique_data, rx_queues_count);
error: too few arguments to function ‘fill_actions’

That's a rebase issue because I merged first the patch
"app/flow-perf: add destination ports parameter"


Re: [dpdk-dev] [PATCH v3 1/3] app/flow-perf: support meter policy API

From: Rongwei Liu <hidden>
Date: 2021-11-05 10:24:37

HI Tomas:
	Flow-perf application run-time options are growing quickly and some of them are a little complex.
	Under current architecture, I don't find a valid way to reduce the indention level unless maintainer agree to simply the logic.

	For the fill_actions() function, I will rebase it once our github branch updated.
	It should be something like:
quoted
+             fill_actions(actions[i], all_actions[i], 0, 0, 0,
+                          0, 0, 0, unique_data, rx_queues_count, dst_port);
BR
Rongwei
-----Original Message-----
From: Thomas Monjalon <redacted>
Sent: Friday, November 5, 2021 5:58 PM
To: Wisam Monther <redacted>; Rongwei Liu
[off-list ref]
Cc: Matan Azrad <redacted>; Slava Ovsiienko
[off-list ref]; Ori Kam [off-list ref]; dev@dpdk.org;
Raslan Darawsheh [off-list ref]; Haifei Luo [off-list ref];
Jiawei(Jonny) Wang [off-list ref]
Subject: Re: [dpdk-dev] [PATCH v3 1/3] app/flow-perf: support meter policy
API

External email: Use caution opening links or attachments


28/10/2021 05:25, Rongwei Liu:
quoted
@@ -854,6 +862,46 @@ args_parse(int argc, char **argv)
                                              RTE_MAX_LCORE);
                              }
                      }
+                     if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0) {
+                             j = 0;
+                             k = 0;
+                             arg = optarg;
+                             policy_mtr = true;
+                             token = strsep(&arg, ":\0");
+                             while (token != NULL && j < RTE_COLORS) {
+                                     actions_str[j++] = token;
+                                     token = strsep(&arg, ":\0");
+                             }
+                             j = 0;
+                             token = strtok(actions_str[0], ",\0");
+                             while (token == NULL && j < RTE_COLORS - 1)
+                                     token = strtok(actions_str[++j], ",\0");
+                             while (j < RTE_COLORS && token != NULL) {
+                                     for (i = 0;
+                                          i < RTE_DIM(flow_options); i++) {
+                                             if (!strcmp(token,
+                                                 flow_options[i].str)) {
+                                                     all_actions[j][k++] =

34 more quoted lines

Re: [dpdk-dev] [PATCH v3 1/3] app/flow-perf: support meter policy API

From: Thomas Monjalon <hidden>
Date: 2021-11-05 10:34:23

05/11/2021 11:24, Rongwei Liu:
HI Tomas:
	Flow-perf application run-time options are growing quickly and some of them are a little complex.
	Under current architecture, I don't find a valid way to reduce the indention level unless maintainer agree to simply the logic.
Trust checkpatch, it is possible.
One basic solution is to have sub-functions.

Please do not top-post.
	For the fill_actions() function, I will rebase it once our github branch updated.
	It should be something like:
quoted
quoted
+             fill_actions(actions[i], all_actions[i], 0, 0, 0,
+                          0, 0, 0, unique_data, rx_queues_count, dst_port);
BR
Rongwei
quoted
-----Original Message-----
From: Thomas Monjalon <redacted>
Sent: Friday, November 5, 2021 5:58 PM
To: Wisam Monther <redacted>; Rongwei Liu
[off-list ref]
Cc: Matan Azrad <redacted>; Slava Ovsiienko
[off-list ref]; Ori Kam [off-list ref]; dev@dpdk.org;
Raslan Darawsheh [off-list ref]; Haifei Luo [off-list ref];
Jiawei(Jonny) Wang [off-list ref]
Subject: Re: [dpdk-dev] [PATCH v3 1/3] app/flow-perf: support meter policy
API

External email: Use caution opening links or attachments


28/10/2021 05:25, Rongwei Liu:
quoted
@@ -854,6 +862,46 @@ args_parse(int argc, char **argv)
                                              RTE_MAX_LCORE);
                              }
                      }
+                     if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0) {
+                             j = 0;
+                             k = 0;
+                             arg = optarg;
+                             policy_mtr = true;
+                             token = strsep(&arg, ":\0");
+                             while (token != NULL && j < RTE_COLORS) {
+                                     actions_str[j++] = token;
+                                     token = strsep(&arg, ":\0");
+                             }
+                             j = 0;

45 more quoted lines




[dpdk-dev] [PATCH v4 0/3] add meter policy support in flow-perf

From: Rongwei Liu <hidden>
Date: 2021-11-08 08:54:11

Add meter policy support and provide options to specify
green/yellow/red corlor actions and cir/cbs/ebs values.

v2: add option to specify green color actions.
v3: support yellow color action and ebs options.
v4: rebase on top of master-net-mlx

Rongwei Liu (3):
  app/flow-perf: support meter policy API
  app/flow-perf: add meter-profile to support cir cbs and ebs
  app/flow-perf: add packet mode metering mode

 app/test-flow-perf/main.c      | 838 +++++++++++++++++++--------------
 doc/guides/tools/flow-perf.rst |   9 +-
 2 files changed, 500 insertions(+), 347 deletions(-)

-- 
2.27.0

[dpdk-dev] [PATCH v4 2/3] app/flow-perf: add meter-profile to support cir cbs and ebs

From: Rongwei Liu <hidden>
Date: 2021-11-08 08:54:16

Change meter-cir option to meter-profile to cover CIR/CBS/EBS all.

The usage is as below:
--meter-profile=N1,N2,N3 default value is 1250000 156250 0.

Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
 app/test-flow-perf/main.c      | 27 +++++++++++++++++++++++----
 doc/guides/tools/flow-perf.rst |  3 ++-
 2 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 966ca9fc63..23ee5d2431 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -83,6 +83,7 @@ static uint32_t rules_count;
 static uint32_t rules_batch;
 static uint32_t hairpin_queues_num; /* total hairpin q number - default: 0 */
 static uint32_t nb_lcores;
+static uint64_t meter_profile_values[3]; /* CIR CBS EBS values. */
 
 #define MAX_PKT_BURST    32
 #define LCORE_MODE_PKT    1
@@ -481,6 +482,9 @@ usage(char *progname)
 		" actions that support data, such as header modify and encap actions\n");
 	printf("  --policy-mtr=\"g1,g2:y1:r1\": To create meter with specified "
 		"color actions\n");
+	printf("  --meter-profile=cir,cbs,ebs: set CIR CBS EBS parameters in meter"
+		" profile, default is %d,%d,%d\n", METER_CIR, METER_CIR / 8, 0);
+
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
 	printf("  --egress: set egress attribute in flows\n");
@@ -621,7 +625,7 @@ args_parse(int argc, char **argv)
 	char *arg;
 	int n, opt;
 	int opt_idx;
-	size_t i;
+	size_t i, j;
 
 	static const struct option lgopts[] = {
 		/* Control */
@@ -699,6 +703,7 @@ args_parse(int argc, char **argv)
 		{ "vxlan-encap",                0, 0, 0 },
 		{ "vxlan-decap",                0, 0, 0 },
 		{ "policy-mtr",                 1, 0, 0 },
+		{ "meter-profile",              1, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -915,6 +920,18 @@ args_parse(int argc, char **argv)
 						RTE_MAX_LCORE);
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name,
+						"meter-profile") == 0) {
+				arg = optarg;
+				j = 0;
+				token = strsep(&arg, ",\0");
+				while (token != NULL && j < sizeof(
+						meter_profile_values) /
+						sizeof(uint64_t)) {
+					meter_profile_values[j++] = atol(token);
+					token = strsep(&arg, ",\0");
+				}
+			}
 			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
 				handle_meter_policy(argv[0], optarg);
 			break;
@@ -1236,9 +1253,11 @@ create_meter_profile(void)
 		if (!((ports_mask >> port_id) & 0x1))
 			continue;
 		mp.alg = RTE_MTR_SRTCM_RFC2697;
-		mp.srtcm_rfc2697.cir = METER_CIR;
-		mp.srtcm_rfc2697.cbs = METER_CIR / 8;
-		mp.srtcm_rfc2697.ebs = 0;
+		mp.srtcm_rfc2697.cir = meter_profile_values[0] ?
+			meter_profile_values[0] : METER_CIR;
+		mp.srtcm_rfc2697.cbs = meter_profile_values[1] ?
+			meter_profile_values[1] : METER_CIR / 8;
+		mp.srtcm_rfc2697.ebs = meter_profile_values[2];
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index a23b94bb55..641600aaf9 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -130,7 +130,8 @@ The command line options are:
 *	``--total-mbuf-count=N``
 	Set the count of total mbuf number, default count is 32000.
 
-Attributes:
+*	``--meter-profile=N1,N2,N3``
+	Set the CIR, CBS and EBS parameter, default value is 1250000, 156250 and 0.
 
 *	``--ingress``
 	Set Ingress attribute to all flows attributes.
-- 
2.27.0

[dpdk-dev] [PATCH v4 1/3] app/flow-perf: support meter policy API

From: Rongwei Liu <hidden>
Date: 2021-11-08 08:54:23

Add option "policy-mtr" to indicate if meter creation will include policy
or not. Meter creation will keep the same without it.

With "policy-mtr", the policy is introduced. API create_meter_policy
is to create a policy. API create_meter_rule will use it to create
a meter. The value of it is used to specify meter policy green color
actions.

Signed-off-by: Haifei Luo <redacted>
Signed-off-by: Jiawei Wang <redacted>
Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
 app/test-flow-perf/main.c      | 807 +++++++++++++++++++--------------
 doc/guides/tools/flow-perf.rst |   3 +
 2 files changed, 467 insertions(+), 343 deletions(-)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index c1ad9bb0a3..966ca9fc63 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -37,6 +37,7 @@
 #include <rte_mtr.h>
 
 #include "config.h"
+#include "actions_gen.h"
 #include "flow_gen.h"
 
 #define MAX_BATCHES_COUNT          100
@@ -49,10 +50,13 @@ static uint8_t flow_group;
 
 static uint64_t encap_data;
 static uint64_t decap_data;
+static uint64_t all_actions[RTE_COLORS][MAX_ACTIONS_NUM];
+static char *actions_str[RTE_COLORS];
 
 static uint64_t flow_items[MAX_ITEMS_NUM];
 static uint64_t flow_actions[MAX_ACTIONS_NUM];
 static uint64_t flow_attrs[MAX_ATTRS_NUM];
+static uint32_t policy_id[MAX_PORTS];
 static uint8_t items_idx, actions_idx, attrs_idx;
 
 static uint64_t ports_mask;
@@ -63,6 +67,7 @@ static bool delete_flag;
 static bool dump_socket_mem_flag;
 static bool enable_fwd;
 static bool unique_data;
+static bool policy_mtr;
 
 static uint8_t rx_queues_count;
 static uint8_t tx_queues_count;
@@ -124,6 +129,337 @@ static struct multi_cores_pool mc_pool = {
 	.cores_count = 1,
 };
 
+static const struct option_dict {
+	const char *str;
+	const uint64_t mask;
+	uint64_t *map;
+	uint8_t *map_idx;
+
+} flow_options[] = {
+	{
+		.str = "ether",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ETH),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "ipv4",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "ipv6",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV6),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "vlan",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VLAN),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "tcp",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TCP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "udp",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "vxlan",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "vxlan-gpe",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN_GPE),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "gre",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GRE),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "geneve",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GENEVE),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "gtp",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GTP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "meta",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_META),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "tag",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TAG),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "icmpv4",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "icmpv6",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP6),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "ingress",
+		.mask = INGRESS,
+		.map = &flow_attrs[0],
+		.map_idx = &attrs_idx
+	},
+	{
+		.str = "egress",
+		.mask = EGRESS,
+		.map = &flow_attrs[0],
+		.map_idx = &attrs_idx
+	},
+	{
+		.str = "transfer",
+		.mask = TRANSFER,
+		.map = &flow_attrs[0],
+		.map_idx = &attrs_idx
+	},
+	{
+		.str = "port-id",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_ID),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "rss",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_RSS),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "queue",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_QUEUE),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "jump",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_JUMP),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "mark",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_MARK),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "count",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_COUNT),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-meta",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_META),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-tag",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_TAG),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "drop",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_DROP),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-mac",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_MAC_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-mac",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_MAC_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-ipv4",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-ipv4",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-ipv6",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-ipv6",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-tp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_TP_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-tp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_TP_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "inc-tcp-ack",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_INC_TCP_ACK
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "dec-tcp-ack",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "inc-tcp-seq",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "dec-tcp-seq",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-ttl",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_TTL
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "dec-ttl",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_DEC_TTL
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-ipv4-dscp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-ipv6-dscp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "flag",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_FLAG
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "meter",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_METER
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "vxlan-encap",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "vxlan-decap",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_VXLAN_DECAP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+};
+
 static void
 usage(char *progname)
 {
@@ -143,7 +479,8 @@ usage(char *progname)
 	printf("  --portmask=N: hexadecimal bitmask of ports used\n");
 	printf("  --unique-data: flag to set using unique data for all"
 		" actions that support data, such as header modify and encap actions\n");
-
+	printf("  --policy-mtr=\"g1,g2:y1:r1\": To create meter with specified "
+		"color actions\n");
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
 	printf("  --egress: set egress attribute in flows\n");
@@ -236,6 +573,44 @@ usage(char *progname)
 	printf("  --vxlan-decap: add vxlan_decap action to flow actions\n");
 }
 
+static void
+handle_meter_policy(char *prog, char *arg)
+{
+	char *token;
+	size_t i, j, k;
+	j = 0;
+	k = 0;
+	policy_mtr = true;
+	token = strsep(&arg, ":\0");
+	while (token != NULL && j < RTE_COLORS) {
+		actions_str[j++] = token;
+		token = strsep(&arg, ":\0");
+	}
+	j = 0;
+	token = strtok(actions_str[0], ",\0");
+	while (token == NULL && j < RTE_COLORS - 1)
+		token = strtok(actions_str[++j], ",\0");
+	while (j < RTE_COLORS && token != NULL) {
+		for (i = 0; i < RTE_DIM(flow_options); i++) {
+			if (!strcmp(token, flow_options[i].str)) {
+				all_actions[j][k++] = flow_options[i].mask;
+				break;
+			}
+		}
+		/* Reached last item with no match */
+		if (i >= RTE_DIM(flow_options)) {
+			fprintf(stderr, "Invalid actions item: %s\n", token);
+			usage(prog);
+			rte_exit(EXIT_SUCCESS, "Invalid actions item\n");
+		}
+		token = strtok(NULL, ",\0");
+		while (!token && j < RTE_COLORS - 1) {
+			token = strtok(actions_str[++j], ",\0");
+			k = 0;
+		}
+	}
+}
+
 static void
 args_parse(int argc, char **argv)
 {
@@ -243,341 +618,11 @@ args_parse(int argc, char **argv)
 	char **argvopt;
 	char *token;
 	char *end;
+	char *arg;
 	int n, opt;
 	int opt_idx;
 	size_t i;
 
-	static const struct option_dict {
-		const char *str;
-		const uint64_t mask;
-		uint64_t *map;
-		uint8_t *map_idx;
-
-	} flow_options[] = {
-		{
-			.str = "ether",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ETH),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "ipv4",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "ipv6",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV6),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "vlan",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VLAN),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "tcp",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TCP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "udp",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "vxlan",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "vxlan-gpe",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN_GPE),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "gre",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GRE),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "geneve",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GENEVE),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "gtp",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GTP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "meta",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_META),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "tag",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TAG),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "icmpv4",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "icmpv6",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP6),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "ingress",
-			.mask = INGRESS,
-			.map = &flow_attrs[0],
-			.map_idx = &attrs_idx
-		},
-		{
-			.str = "egress",
-			.mask = EGRESS,
-			.map = &flow_attrs[0],
-			.map_idx = &attrs_idx
-		},
-		{
-			.str = "transfer",
-			.mask = TRANSFER,
-			.map = &flow_attrs[0],
-			.map_idx = &attrs_idx
-		},
-		{
-			.str = "port-id",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_ID),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "rss",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_RSS),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "queue",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_QUEUE),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "jump",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_JUMP),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "mark",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_MARK),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "count",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_COUNT),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-meta",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_META),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-tag",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_TAG),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "drop",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_DROP),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-mac",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_MAC_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-mac",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_MAC_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-ipv4",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-ipv4",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-ipv6",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-ipv6",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-tp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_TP_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-tp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_TP_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "inc-tcp-ack",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_INC_TCP_ACK
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "dec-tcp-ack",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "inc-tcp-seq",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "dec-tcp-seq",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-ttl",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_TTL
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "dec-ttl",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_DEC_TTL
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-ipv4-dscp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-ipv6-dscp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "flag",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_FLAG
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "meter",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_METER
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "vxlan-encap",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "vxlan-decap",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_VXLAN_DECAP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-	};
-
 	static const struct option lgopts[] = {
 		/* Control */
 		{ "help",                       0, 0, 0 },
@@ -653,6 +698,7 @@ args_parse(int argc, char **argv)
 		{ "raw-decap",                  1, 0, 0 },
 		{ "vxlan-encap",                0, 0, 0 },
 		{ "vxlan-decap",                0, 0, 0 },
+		{ "policy-mtr",                 1, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -869,6 +915,8 @@ args_parse(int argc, char **argv)
 						RTE_MAX_LCORE);
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
+				handle_meter_policy(argv[0], optarg);
 			break;
 		default:
 			usage(argv[0]);
@@ -979,12 +1027,68 @@ has_meter(void)
 	return 0;
 }
 
+static void
+create_meter_policy(void)
+{
+	struct rte_mtr_error error;
+	int ret, port_id;
+	struct rte_mtr_meter_policy_params policy;
+	uint16_t nr_ports;
+	struct rte_flow_action actions[RTE_COLORS][MAX_ACTIONS_NUM];
+	int i;
+
+	memset(actions, 0, sizeof(actions));
+	memset(&policy, 0, sizeof(policy));
+	nr_ports = rte_eth_dev_count_avail();
+	for (port_id = 0; port_id < nr_ports; port_id++) {
+		for (i = 0; i < RTE_COLORS; i++)
+			fill_actions(actions[i], all_actions[i], 0, 0, 0,
+				     0, 0, 0, unique_data, rx_queues_count,
+				     dst_ports[port_id]);
+		policy.actions[RTE_COLOR_GREEN] = actions[RTE_COLOR_GREEN];
+		policy.actions[RTE_COLOR_YELLOW] = actions[RTE_COLOR_YELLOW];
+		policy.actions[RTE_COLOR_RED] = actions[RTE_COLOR_RED];
+		policy_id[port_id] = port_id + 10;
+		ret = rte_mtr_meter_policy_add(port_id, policy_id[port_id],
+					       &policy, &error);
+		if (ret) {
+			fprintf(stderr, "meter policy add failed port_id %d\n",
+				port_id);
+			policy_id[port_id] = UINT32_MAX;
+		}
+		memset(actions, 0, sizeof(actions));
+	}
+}
+
+
+static void
+destroy_meter_policy(void)
+{
+	struct rte_mtr_error error;
+	uint16_t nr_ports;
+	int port_id;
+
+	nr_ports = rte_eth_dev_count_avail();
+	for (port_id = 0; port_id < nr_ports; port_id++) {
+		/* If port outside portmask */
+		if (!((ports_mask >> port_id) & 0x1))
+			continue;
+
+		if (rte_mtr_meter_policy_delete
+			(port_id, policy_id[port_id], &error)) {
+			fprintf(stderr, "Port %u del policy error(%d) message: %s\n",
+				port_id, error.type,
+				error.message ? error.message : "(no stated reason)");
+			rte_exit(EXIT_FAILURE, "Error: Destroy meter policy Failed!\n");
+		}
+	}
+}
+
 static void
 create_meter_rule(int port_id, uint32_t counter)
 {
 	int ret;
 	struct rte_mtr_params params;
-	uint32_t default_prof_id = 100;
 	struct rte_mtr_error error;
 
 	memset(&params, 0, sizeof(struct rte_mtr_params));
@@ -994,8 +1098,15 @@ create_meter_rule(int port_id, uint32_t counter)
 	params.dscp_table = NULL;
 
 	/*create meter*/
-	params.meter_profile_id = default_prof_id;
-	ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+	params.meter_profile_id = DEFAULT_METER_PROF_ID;
+
+	if (!policy_mtr) {
+		ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+	} else {
+		params.meter_policy_id = policy_id[port_id];
+		ret = rte_mtr_create(port_id, counter, &params, 0, &error);
+	}
+
 	if (ret != 0) {
 		printf("Port %u create meter idx(%d) error(%d) message: %s\n",
 			port_id, counter, error.type,
@@ -1009,11 +1120,17 @@ destroy_meter_rule(int port_id, uint32_t counter)
 {
 	struct rte_mtr_error error;
 
+	if (policy_mtr && policy_id[port_id] != UINT32_MAX) {
+		if (rte_mtr_meter_policy_delete(port_id, policy_id[port_id],
+					&error))
+			fprintf(stderr, "error delete policy %d\n", counter+1);
+		policy_id[port_id] = UINT32_MAX;
+	}
 	if (rte_mtr_destroy(port_id, counter, &error)) {
-		printf("Port %u destroy meter(%d) error(%d) message: %s\n",
-			port_id, counter, error.type,
-			error.message ? error.message : "(no stated reason)");
-		rte_exit(EXIT_FAILURE, "Error in deleting meter rule\n");
+		fprintf(stderr, "Port %u destroy meter(%d) error(%d) message: %s\n",
+		port_id, counter, error.type,
+		error.message ? error.message : "(no stated reason)");
+		rte_exit(EXIT_FAILURE, "Error in deleting meter rule");
 	}
 }
 
@@ -1118,12 +1235,10 @@ create_meter_profile(void)
 		/* If port outside portmask */
 		if (!((ports_mask >> port_id) & 0x1))
 			continue;
-
 		mp.alg = RTE_MTR_SRTCM_RFC2697;
 		mp.srtcm_rfc2697.cir = METER_CIR;
 		mp.srtcm_rfc2697.cbs = METER_CIR / 8;
 		mp.srtcm_rfc2697.ebs = 0;
-
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
@@ -1992,16 +2107,22 @@ main(int argc, char **argv)
 
 	printf(":: Flows Count per port: %d\n\n", rules_count);
 
-	if (has_meter())
+	if (has_meter()) {
 		create_meter_profile();
+		if (policy_mtr)
+			create_meter_policy();
+	}
 	rte_eal_mp_remote_launch(run_rte_flow_handler_cores, NULL, CALL_MAIN);
 
 	if (enable_fwd) {
 		init_lcore_info();
 		rte_eal_mp_remote_launch(start_forwarding, NULL, CALL_MAIN);
 	}
-	if (has_meter() && delete_flag)
+	if (has_meter() && delete_flag) {
 		destroy_meter_profile();
+		if (policy_mtr)
+			destroy_meter_policy();
+	}
 
 	RTE_ETH_FOREACH_DEV(port) {
 		rte_flow_flush(port, &error);
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index e608a44c24..a23b94bb55 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -383,3 +383,6 @@ Actions:
 *       ``--meter``
         Add meter action to all flows actions.
         Currently, 1 meter profile -> N meter rules -> N rte flows.
+
+*       ``--policy-mtr=<str>``
+        Add policy-mtr to create meter with policy and specify policy actions.
-- 
2.27.0

[dpdk-dev] [PATCH v4 3/3] app/flow-perf: add packet mode metering mode

From: Rongwei Liu <hidden>
Date: 2021-11-08 08:54:32

The flow perf application used the srtcm_rfc2697 as meter profile
while doing the meter testing.

This patch adds the support new configuration parameter
'--packet-mode' to generate the meter flows with the packet mode.

Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
 app/test-flow-perf/main.c      | 6 ++++++
 doc/guides/tools/flow-perf.rst | 3 +++
 2 files changed, 9 insertions(+)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 23ee5d2431..374eeba3e3 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -68,6 +68,7 @@ static bool dump_socket_mem_flag;
 static bool enable_fwd;
 static bool unique_data;
 static bool policy_mtr;
+static bool packet_mode;
 
 static uint8_t rx_queues_count;
 static uint8_t tx_queues_count;
@@ -484,6 +485,7 @@ usage(char *progname)
 		"color actions\n");
 	printf("  --meter-profile=cir,cbs,ebs: set CIR CBS EBS parameters in meter"
 		" profile, default is %d,%d,%d\n", METER_CIR, METER_CIR / 8, 0);
+	printf("  --packet-mode: To enable packet mode for meter profile\n");
 
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
@@ -704,6 +706,7 @@ args_parse(int argc, char **argv)
 		{ "vxlan-decap",                0, 0, 0 },
 		{ "policy-mtr",                 1, 0, 0 },
 		{ "meter-profile",              1, 0, 0 },
+		{ "packet-mode",                0, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -932,6 +935,8 @@ args_parse(int argc, char **argv)
 					token = strsep(&arg, ",\0");
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name, "packet-mode") == 0)
+				packet_mode = true;
 			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
 				handle_meter_policy(argv[0], optarg);
 			break;
@@ -1258,6 +1263,7 @@ create_meter_profile(void)
 		mp.srtcm_rfc2697.cbs = meter_profile_values[1] ?
 			meter_profile_values[1] : METER_CIR / 8;
 		mp.srtcm_rfc2697.ebs = meter_profile_values[2];
+		mp.packet_mode = packet_mode;
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 641600aaf9..d77046433c 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -133,6 +133,9 @@ The command line options are:
 *	``--meter-profile=N1,N2,N3``
 	Set the CIR, CBS and EBS parameter, default value is 1250000, 156250 and 0.
 
+*	``--packet-mode``
+	Enable packets mode for meter profile.
+
 *	``--ingress``
 	Set Ingress attribute to all flows attributes.
 
-- 
2.27.0

Re: [dpdk-dev] [PATCH v4 1/3] app/flow-perf: support meter policy API

From: Thomas Monjalon <hidden>
Date: 2021-11-08 09:05:29

08/11/2021 09:53, Rongwei Liu:
Add option "policy-mtr" to indicate if meter creation will include policy
or not. Meter creation will keep the same without it.

With "policy-mtr", the policy is introduced. API create_meter_policy
is to create a policy. API create_meter_rule will use it to create
a meter. The value of it is used to specify meter policy green color
actions.

Signed-off-by: Haifei Luo <redacted>
Signed-off-by: Jiawei Wang <redacted>
Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
 app/test-flow-perf/main.c      | 807 +++++++++++++++++++--------------
 doc/guides/tools/flow-perf.rst |   3 +
 2 files changed, 467 insertions(+), 343 deletions(-)
This patch does not compile:
app/test-flow-perf/main.c:621:15: error: unused variable ‘arg’


[dpdk-dev] [PATCH v5 0/3] add meter policy support in flow-perf

From: Rongwei Liu <hidden>
Date: 2021-11-08 09:23:40

Add meter policy support and provide options to specify
green/yellow/red corlor actions and cir/cbs/ebs values.

v2: add option to specify green color actions.
v3: support yellow color action and ebs options.
v4: rebase on top of master-net-mlx.
v5: fix intermediate werror.

Rongwei Liu (3):
  app/flow-perf: support meter policy API
  app/flow-perf: add meter-profile to support cir cbs and ebs
  app/flow-perf: add packet mode metering mode

 app/test-flow-perf/main.c      | 838 +++++++++++++++++++--------------
 doc/guides/tools/flow-perf.rst |   9 +-
 2 files changed, 500 insertions(+), 347 deletions(-)

-- 
2.27.0

[dpdk-dev] [PATCH v5 2/3] app/flow-perf: add meter-profile to support cir cbs and ebs

From: Rongwei Liu <hidden>
Date: 2021-11-08 09:23:44

Change meter-cir option to meter-profile to cover CIR/CBS/EBS all.

The usage is as below:
--meter-profile=N1,N2,N3 default value is 1250000 156250 0.

Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
 app/test-flow-perf/main.c      | 28 ++++++++++++++++++++++++----
 doc/guides/tools/flow-perf.rst |  3 ++-
 2 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index a960e5b245..23ee5d2431 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -83,6 +83,7 @@ static uint32_t rules_count;
 static uint32_t rules_batch;
 static uint32_t hairpin_queues_num; /* total hairpin q number - default: 0 */
 static uint32_t nb_lcores;
+static uint64_t meter_profile_values[3]; /* CIR CBS EBS values. */
 
 #define MAX_PKT_BURST    32
 #define LCORE_MODE_PKT    1
@@ -481,6 +482,9 @@ usage(char *progname)
 		" actions that support data, such as header modify and encap actions\n");
 	printf("  --policy-mtr=\"g1,g2:y1:r1\": To create meter with specified "
 		"color actions\n");
+	printf("  --meter-profile=cir,cbs,ebs: set CIR CBS EBS parameters in meter"
+		" profile, default is %d,%d,%d\n", METER_CIR, METER_CIR / 8, 0);
+
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
 	printf("  --egress: set egress attribute in flows\n");
@@ -618,9 +622,10 @@ args_parse(int argc, char **argv)
 	char **argvopt;
 	char *token;
 	char *end;
+	char *arg;
 	int n, opt;
 	int opt_idx;
-	size_t i;
+	size_t i, j;
 
 	static const struct option lgopts[] = {
 		/* Control */
@@ -698,6 +703,7 @@ args_parse(int argc, char **argv)
 		{ "vxlan-encap",                0, 0, 0 },
 		{ "vxlan-decap",                0, 0, 0 },
 		{ "policy-mtr",                 1, 0, 0 },
+		{ "meter-profile",              1, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -914,6 +920,18 @@ args_parse(int argc, char **argv)
 						RTE_MAX_LCORE);
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name,
+						"meter-profile") == 0) {
+				arg = optarg;
+				j = 0;
+				token = strsep(&arg, ",\0");
+				while (token != NULL && j < sizeof(
+						meter_profile_values) /
+						sizeof(uint64_t)) {
+					meter_profile_values[j++] = atol(token);
+					token = strsep(&arg, ",\0");
+				}
+			}
 			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
 				handle_meter_policy(argv[0], optarg);
 			break;
@@ -1235,9 +1253,11 @@ create_meter_profile(void)
 		if (!((ports_mask >> port_id) & 0x1))
 			continue;
 		mp.alg = RTE_MTR_SRTCM_RFC2697;
-		mp.srtcm_rfc2697.cir = METER_CIR;
-		mp.srtcm_rfc2697.cbs = METER_CIR / 8;
-		mp.srtcm_rfc2697.ebs = 0;
+		mp.srtcm_rfc2697.cir = meter_profile_values[0] ?
+			meter_profile_values[0] : METER_CIR;
+		mp.srtcm_rfc2697.cbs = meter_profile_values[1] ?
+			meter_profile_values[1] : METER_CIR / 8;
+		mp.srtcm_rfc2697.ebs = meter_profile_values[2];
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index a23b94bb55..641600aaf9 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -130,7 +130,8 @@ The command line options are:
 *	``--total-mbuf-count=N``
 	Set the count of total mbuf number, default count is 32000.
 
-Attributes:
+*	``--meter-profile=N1,N2,N3``
+	Set the CIR, CBS and EBS parameter, default value is 1250000, 156250 and 0.
 
 *	``--ingress``
 	Set Ingress attribute to all flows attributes.
-- 
2.27.0

[dpdk-dev] [PATCH v5 1/3] app/flow-perf: support meter policy API

From: Rongwei Liu <hidden>
Date: 2021-11-08 09:23:50

Add option "policy-mtr" to indicate if meter creation will include policy
or not. Meter creation will keep the same without it.

With "policy-mtr", the policy is introduced. API create_meter_policy
is to create a policy. API create_meter_rule will use it to create
a meter. The value of it is used to specify meter policy green color
actions.

Signed-off-by: Haifei Luo <redacted>
Signed-off-by: Jiawei Wang <redacted>
Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
 app/test-flow-perf/main.c      | 806 +++++++++++++++++++--------------
 doc/guides/tools/flow-perf.rst |   3 +
 2 files changed, 466 insertions(+), 343 deletions(-)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index c1ad9bb0a3..a960e5b245 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -37,6 +37,7 @@
 #include <rte_mtr.h>
 
 #include "config.h"
+#include "actions_gen.h"
 #include "flow_gen.h"
 
 #define MAX_BATCHES_COUNT          100
@@ -49,10 +50,13 @@ static uint8_t flow_group;
 
 static uint64_t encap_data;
 static uint64_t decap_data;
+static uint64_t all_actions[RTE_COLORS][MAX_ACTIONS_NUM];
+static char *actions_str[RTE_COLORS];
 
 static uint64_t flow_items[MAX_ITEMS_NUM];
 static uint64_t flow_actions[MAX_ACTIONS_NUM];
 static uint64_t flow_attrs[MAX_ATTRS_NUM];
+static uint32_t policy_id[MAX_PORTS];
 static uint8_t items_idx, actions_idx, attrs_idx;
 
 static uint64_t ports_mask;
@@ -63,6 +67,7 @@ static bool delete_flag;
 static bool dump_socket_mem_flag;
 static bool enable_fwd;
 static bool unique_data;
+static bool policy_mtr;
 
 static uint8_t rx_queues_count;
 static uint8_t tx_queues_count;
@@ -124,6 +129,337 @@ static struct multi_cores_pool mc_pool = {
 	.cores_count = 1,
 };
 
+static const struct option_dict {
+	const char *str;
+	const uint64_t mask;
+	uint64_t *map;
+	uint8_t *map_idx;
+
+} flow_options[] = {
+	{
+		.str = "ether",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ETH),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "ipv4",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "ipv6",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV6),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "vlan",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VLAN),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "tcp",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TCP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "udp",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "vxlan",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "vxlan-gpe",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN_GPE),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "gre",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GRE),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "geneve",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GENEVE),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "gtp",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GTP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "meta",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_META),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "tag",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TAG),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "icmpv4",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "icmpv6",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP6),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "ingress",
+		.mask = INGRESS,
+		.map = &flow_attrs[0],
+		.map_idx = &attrs_idx
+	},
+	{
+		.str = "egress",
+		.mask = EGRESS,
+		.map = &flow_attrs[0],
+		.map_idx = &attrs_idx
+	},
+	{
+		.str = "transfer",
+		.mask = TRANSFER,
+		.map = &flow_attrs[0],
+		.map_idx = &attrs_idx
+	},
+	{
+		.str = "port-id",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_ID),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "rss",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_RSS),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "queue",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_QUEUE),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "jump",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_JUMP),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "mark",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_MARK),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "count",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_COUNT),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-meta",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_META),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-tag",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_TAG),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "drop",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_DROP),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-mac",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_MAC_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-mac",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_MAC_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-ipv4",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-ipv4",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-ipv6",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-ipv6",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-tp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_TP_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-tp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_TP_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "inc-tcp-ack",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_INC_TCP_ACK
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "dec-tcp-ack",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "inc-tcp-seq",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "dec-tcp-seq",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-ttl",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_TTL
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "dec-ttl",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_DEC_TTL
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-ipv4-dscp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-ipv6-dscp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "flag",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_FLAG
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "meter",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_METER
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "vxlan-encap",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "vxlan-decap",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_VXLAN_DECAP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+};
+
 static void
 usage(char *progname)
 {
@@ -143,7 +479,8 @@ usage(char *progname)
 	printf("  --portmask=N: hexadecimal bitmask of ports used\n");
 	printf("  --unique-data: flag to set using unique data for all"
 		" actions that support data, such as header modify and encap actions\n");
-
+	printf("  --policy-mtr=\"g1,g2:y1:r1\": To create meter with specified "
+		"color actions\n");
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
 	printf("  --egress: set egress attribute in flows\n");
@@ -236,6 +573,44 @@ usage(char *progname)
 	printf("  --vxlan-decap: add vxlan_decap action to flow actions\n");
 }
 
+static void
+handle_meter_policy(char *prog, char *arg)
+{
+	char *token;
+	size_t i, j, k;
+	j = 0;
+	k = 0;
+	policy_mtr = true;
+	token = strsep(&arg, ":\0");
+	while (token != NULL && j < RTE_COLORS) {
+		actions_str[j++] = token;
+		token = strsep(&arg, ":\0");
+	}
+	j = 0;
+	token = strtok(actions_str[0], ",\0");
+	while (token == NULL && j < RTE_COLORS - 1)
+		token = strtok(actions_str[++j], ",\0");
+	while (j < RTE_COLORS && token != NULL) {
+		for (i = 0; i < RTE_DIM(flow_options); i++) {
+			if (!strcmp(token, flow_options[i].str)) {
+				all_actions[j][k++] = flow_options[i].mask;
+				break;
+			}
+		}
+		/* Reached last item with no match */
+		if (i >= RTE_DIM(flow_options)) {
+			fprintf(stderr, "Invalid actions item: %s\n", token);
+			usage(prog);
+			rte_exit(EXIT_SUCCESS, "Invalid actions item\n");
+		}
+		token = strtok(NULL, ",\0");
+		while (!token && j < RTE_COLORS - 1) {
+			token = strtok(actions_str[++j], ",\0");
+			k = 0;
+		}
+	}
+}
+
 static void
 args_parse(int argc, char **argv)
 {
@@ -247,337 +622,6 @@ args_parse(int argc, char **argv)
 	int opt_idx;
 	size_t i;
 
-	static const struct option_dict {
-		const char *str;
-		const uint64_t mask;
-		uint64_t *map;
-		uint8_t *map_idx;
-
-	} flow_options[] = {
-		{
-			.str = "ether",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ETH),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "ipv4",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "ipv6",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV6),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "vlan",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VLAN),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "tcp",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TCP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "udp",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "vxlan",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "vxlan-gpe",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN_GPE),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "gre",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GRE),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "geneve",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GENEVE),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "gtp",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GTP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "meta",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_META),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "tag",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TAG),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "icmpv4",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "icmpv6",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP6),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "ingress",
-			.mask = INGRESS,
-			.map = &flow_attrs[0],
-			.map_idx = &attrs_idx
-		},
-		{
-			.str = "egress",
-			.mask = EGRESS,
-			.map = &flow_attrs[0],
-			.map_idx = &attrs_idx
-		},
-		{
-			.str = "transfer",
-			.mask = TRANSFER,
-			.map = &flow_attrs[0],
-			.map_idx = &attrs_idx
-		},
-		{
-			.str = "port-id",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_ID),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "rss",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_RSS),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "queue",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_QUEUE),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "jump",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_JUMP),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "mark",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_MARK),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "count",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_COUNT),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-meta",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_META),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-tag",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_TAG),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "drop",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_DROP),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-mac",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_MAC_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-mac",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_MAC_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-ipv4",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-ipv4",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-ipv6",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-ipv6",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-tp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_TP_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-tp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_TP_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "inc-tcp-ack",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_INC_TCP_ACK
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "dec-tcp-ack",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "inc-tcp-seq",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "dec-tcp-seq",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-ttl",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_TTL
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "dec-ttl",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_DEC_TTL
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-ipv4-dscp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-ipv6-dscp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "flag",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_FLAG
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "meter",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_METER
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "vxlan-encap",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "vxlan-decap",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_VXLAN_DECAP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-	};
-
 	static const struct option lgopts[] = {
 		/* Control */
 		{ "help",                       0, 0, 0 },
@@ -653,6 +697,7 @@ args_parse(int argc, char **argv)
 		{ "raw-decap",                  1, 0, 0 },
 		{ "vxlan-encap",                0, 0, 0 },
 		{ "vxlan-decap",                0, 0, 0 },
+		{ "policy-mtr",                 1, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -869,6 +914,8 @@ args_parse(int argc, char **argv)
 						RTE_MAX_LCORE);
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
+				handle_meter_policy(argv[0], optarg);
 			break;
 		default:
 			usage(argv[0]);
@@ -979,12 +1026,68 @@ has_meter(void)
 	return 0;
 }
 
+static void
+create_meter_policy(void)
+{
+	struct rte_mtr_error error;
+	int ret, port_id;
+	struct rte_mtr_meter_policy_params policy;
+	uint16_t nr_ports;
+	struct rte_flow_action actions[RTE_COLORS][MAX_ACTIONS_NUM];
+	int i;
+
+	memset(actions, 0, sizeof(actions));
+	memset(&policy, 0, sizeof(policy));
+	nr_ports = rte_eth_dev_count_avail();
+	for (port_id = 0; port_id < nr_ports; port_id++) {
+		for (i = 0; i < RTE_COLORS; i++)
+			fill_actions(actions[i], all_actions[i], 0, 0, 0,
+				     0, 0, 0, unique_data, rx_queues_count,
+				     dst_ports[port_id]);
+		policy.actions[RTE_COLOR_GREEN] = actions[RTE_COLOR_GREEN];
+		policy.actions[RTE_COLOR_YELLOW] = actions[RTE_COLOR_YELLOW];
+		policy.actions[RTE_COLOR_RED] = actions[RTE_COLOR_RED];
+		policy_id[port_id] = port_id + 10;
+		ret = rte_mtr_meter_policy_add(port_id, policy_id[port_id],
+					       &policy, &error);
+		if (ret) {
+			fprintf(stderr, "meter policy add failed port_id %d\n",
+				port_id);
+			policy_id[port_id] = UINT32_MAX;
+		}
+		memset(actions, 0, sizeof(actions));
+	}
+}
+
+
+static void
+destroy_meter_policy(void)
+{
+	struct rte_mtr_error error;
+	uint16_t nr_ports;
+	int port_id;
+
+	nr_ports = rte_eth_dev_count_avail();
+	for (port_id = 0; port_id < nr_ports; port_id++) {
+		/* If port outside portmask */
+		if (!((ports_mask >> port_id) & 0x1))
+			continue;
+
+		if (rte_mtr_meter_policy_delete
+			(port_id, policy_id[port_id], &error)) {
+			fprintf(stderr, "Port %u del policy error(%d) message: %s\n",
+				port_id, error.type,
+				error.message ? error.message : "(no stated reason)");
+			rte_exit(EXIT_FAILURE, "Error: Destroy meter policy Failed!\n");
+		}
+	}
+}
+
 static void
 create_meter_rule(int port_id, uint32_t counter)
 {
 	int ret;
 	struct rte_mtr_params params;
-	uint32_t default_prof_id = 100;
 	struct rte_mtr_error error;
 
 	memset(&params, 0, sizeof(struct rte_mtr_params));
@@ -994,8 +1097,15 @@ create_meter_rule(int port_id, uint32_t counter)
 	params.dscp_table = NULL;
 
 	/*create meter*/
-	params.meter_profile_id = default_prof_id;
-	ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+	params.meter_profile_id = DEFAULT_METER_PROF_ID;
+
+	if (!policy_mtr) {
+		ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+	} else {
+		params.meter_policy_id = policy_id[port_id];
+		ret = rte_mtr_create(port_id, counter, &params, 0, &error);
+	}
+
 	if (ret != 0) {
 		printf("Port %u create meter idx(%d) error(%d) message: %s\n",
 			port_id, counter, error.type,
@@ -1009,11 +1119,17 @@ destroy_meter_rule(int port_id, uint32_t counter)
 {
 	struct rte_mtr_error error;
 
+	if (policy_mtr && policy_id[port_id] != UINT32_MAX) {
+		if (rte_mtr_meter_policy_delete(port_id, policy_id[port_id],
+					&error))
+			fprintf(stderr, "error delete policy %d\n", counter+1);
+		policy_id[port_id] = UINT32_MAX;
+	}
 	if (rte_mtr_destroy(port_id, counter, &error)) {
-		printf("Port %u destroy meter(%d) error(%d) message: %s\n",
-			port_id, counter, error.type,
-			error.message ? error.message : "(no stated reason)");
-		rte_exit(EXIT_FAILURE, "Error in deleting meter rule\n");
+		fprintf(stderr, "Port %u destroy meter(%d) error(%d) message: %s\n",
+		port_id, counter, error.type,
+		error.message ? error.message : "(no stated reason)");
+		rte_exit(EXIT_FAILURE, "Error in deleting meter rule");
 	}
 }
 
@@ -1118,12 +1234,10 @@ create_meter_profile(void)
 		/* If port outside portmask */
 		if (!((ports_mask >> port_id) & 0x1))
 			continue;
-
 		mp.alg = RTE_MTR_SRTCM_RFC2697;
 		mp.srtcm_rfc2697.cir = METER_CIR;
 		mp.srtcm_rfc2697.cbs = METER_CIR / 8;
 		mp.srtcm_rfc2697.ebs = 0;
-
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
@@ -1992,16 +2106,22 @@ main(int argc, char **argv)
 
 	printf(":: Flows Count per port: %d\n\n", rules_count);
 
-	if (has_meter())
+	if (has_meter()) {
 		create_meter_profile();
+		if (policy_mtr)
+			create_meter_policy();
+	}
 	rte_eal_mp_remote_launch(run_rte_flow_handler_cores, NULL, CALL_MAIN);
 
 	if (enable_fwd) {
 		init_lcore_info();
 		rte_eal_mp_remote_launch(start_forwarding, NULL, CALL_MAIN);
 	}
-	if (has_meter() && delete_flag)
+	if (has_meter() && delete_flag) {
 		destroy_meter_profile();
+		if (policy_mtr)
+			destroy_meter_policy();
+	}
 
 	RTE_ETH_FOREACH_DEV(port) {
 		rte_flow_flush(port, &error);
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index e608a44c24..a23b94bb55 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -383,3 +383,6 @@ Actions:
 *       ``--meter``
         Add meter action to all flows actions.
         Currently, 1 meter profile -> N meter rules -> N rte flows.
+
+*       ``--policy-mtr=<str>``
+        Add policy-mtr to create meter with policy and specify policy actions.
-- 
2.27.0

[dpdk-dev] [PATCH v5 3/3] app/flow-perf: add packet mode metering mode

From: Rongwei Liu <hidden>
Date: 2021-11-08 09:23:58

The flow perf application used the srtcm_rfc2697 as meter profile
while doing the meter testing.

This patch adds the support new configuration parameter
'--packet-mode' to generate the meter flows with the packet mode.

Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
 app/test-flow-perf/main.c      | 6 ++++++
 doc/guides/tools/flow-perf.rst | 3 +++
 2 files changed, 9 insertions(+)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 23ee5d2431..374eeba3e3 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -68,6 +68,7 @@ static bool dump_socket_mem_flag;
 static bool enable_fwd;
 static bool unique_data;
 static bool policy_mtr;
+static bool packet_mode;
 
 static uint8_t rx_queues_count;
 static uint8_t tx_queues_count;
@@ -484,6 +485,7 @@ usage(char *progname)
 		"color actions\n");
 	printf("  --meter-profile=cir,cbs,ebs: set CIR CBS EBS parameters in meter"
 		" profile, default is %d,%d,%d\n", METER_CIR, METER_CIR / 8, 0);
+	printf("  --packet-mode: To enable packet mode for meter profile\n");
 
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
@@ -704,6 +706,7 @@ args_parse(int argc, char **argv)
 		{ "vxlan-decap",                0, 0, 0 },
 		{ "policy-mtr",                 1, 0, 0 },
 		{ "meter-profile",              1, 0, 0 },
+		{ "packet-mode",                0, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -932,6 +935,8 @@ args_parse(int argc, char **argv)
 					token = strsep(&arg, ",\0");
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name, "packet-mode") == 0)
+				packet_mode = true;
 			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
 				handle_meter_policy(argv[0], optarg);
 			break;
@@ -1258,6 +1263,7 @@ create_meter_profile(void)
 		mp.srtcm_rfc2697.cbs = meter_profile_values[1] ?
 			meter_profile_values[1] : METER_CIR / 8;
 		mp.srtcm_rfc2697.ebs = meter_profile_values[2];
+		mp.packet_mode = packet_mode;
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 641600aaf9..d77046433c 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -133,6 +133,9 @@ The command line options are:
 *	``--meter-profile=N1,N2,N3``
 	Set the CIR, CBS and EBS parameter, default value is 1250000, 156250 and 0.
 
+*	``--packet-mode``
+	Enable packets mode for meter profile.
+
 *	``--ingress``
 	Set Ingress attribute to all flows attributes.
 
-- 
2.27.0

Re: [dpdk-dev] [PATCH v5 0/3] add meter policy support in flow-perf

From: Thomas Monjalon <hidden>
Date: 2021-11-08 09:35:43

08/11/2021 10:23, Rongwei Liu:
Add meter policy support and provide options to specify
green/yellow/red corlor actions and cir/cbs/ebs values.

v2: add option to specify green color actions.
v3: support yellow color action and ebs options.
v4: rebase on top of master-net-mlx.
v5: fix intermediate werror.
Did you try to rebase on a recent main?
I see a lot of conflicts.

Re: [dpdk-dev] [PATCH v5 0/3] add meter policy support in flow-perf

From: Rongwei Liu <hidden>
Date: 2021-11-08 09:39:42

08/11/2021 10:23, Rongwei Liu:
quoted
Add meter policy support and provide options to specify
green/yellow/red corlor actions and cir/cbs/ebs values.

v2: add option to specify green color actions.
v3: support yellow color action and ebs options.
v4: rebase on top of master-net-mlx.
v5: fix intermediate werror.
Did you try to rebase on a recent main?
I see a lot of conflicts.
Rebase on top of master-net-mlx. See a lot of conflicts regarding PMD drivers when rebasing. 
If we see conflicts with existed flow-perf codes, I can try to setup a totally clean branch to generate patches.

Re: [dpdk-dev] [PATCH v5 0/3] add meter policy support in flow-perf

From: Thomas Monjalon <hidden>
Date: 2021-11-08 09:40:55

08/11/2021 10:39, Rongwei Liu:
quoted
08/11/2021 10:23, Rongwei Liu:
quoted
Add meter policy support and provide options to specify
green/yellow/red corlor actions and cir/cbs/ebs values.

v2: add option to specify green color actions.
v3: support yellow color action and ebs options.
v4: rebase on top of master-net-mlx.
v5: fix intermediate werror.
Did you try to rebase on a recent main?
I see a lot of conflicts.
Rebase on top of master-net-mlx. See a lot of conflicts regarding PMD drivers when rebasing. 
If we see conflicts with existed flow-perf codes, I can try to setup a totally clean branch to generate patches.
This series is targetting the main branch.
Please rebase on the upstream main of today.

[dpdk-dev] [PATCH v6 0/3] add meter policy support in flow-perf

From: Rongwei Liu <hidden>
Date: 2021-11-08 09:58:37

Add meter policy support and provide options to specify
green/yellow/red corlor actions and cir/cbs/ebs values.

v2: add option to specify green color actions.
v3: support yellow color action and ebs options.
v4: rebase on top of master-net-mlx.
v5: fix intermediate werror.
v6: rebase on top of main.

Rongwei Liu (3):
  app/flow-perf: support meter policy API
  app/flow-perf: add meter-profile to support cir cbs and ebs
  app/flow-perf: add packet mode metering mode

 app/test-flow-perf/main.c      | 838 +++++++++++++++++++--------------
 doc/guides/tools/flow-perf.rst |   9 +-
 2 files changed, 500 insertions(+), 347 deletions(-)

-- 
2.27.0

[dpdk-dev] [PATCH v6 1/3] app/flow-perf: support meter policy API

From: Rongwei Liu <hidden>
Date: 2021-11-08 09:58:44

Add option "policy-mtr" to indicate if meter creation will include policy
or not. Meter creation will keep the same without it.

With "policy-mtr", the policy is introduced. API create_meter_policy
is to create a policy. API create_meter_rule will use it to create
a meter. The value of it is used to specify meter policy green color
actions.

Signed-off-by: Haifei Luo <redacted>
Signed-off-by: Jiawei Wang <redacted>
Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
 app/test-flow-perf/main.c      | 806 +++++++++++++++++++--------------
 doc/guides/tools/flow-perf.rst |   3 +
 2 files changed, 466 insertions(+), 343 deletions(-)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index c1ad9bb0a3..a960e5b245 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -37,6 +37,7 @@
 #include <rte_mtr.h>
 
 #include "config.h"
+#include "actions_gen.h"
 #include "flow_gen.h"
 
 #define MAX_BATCHES_COUNT          100
@@ -49,10 +50,13 @@ static uint8_t flow_group;
 
 static uint64_t encap_data;
 static uint64_t decap_data;
+static uint64_t all_actions[RTE_COLORS][MAX_ACTIONS_NUM];
+static char *actions_str[RTE_COLORS];
 
 static uint64_t flow_items[MAX_ITEMS_NUM];
 static uint64_t flow_actions[MAX_ACTIONS_NUM];
 static uint64_t flow_attrs[MAX_ATTRS_NUM];
+static uint32_t policy_id[MAX_PORTS];
 static uint8_t items_idx, actions_idx, attrs_idx;
 
 static uint64_t ports_mask;
@@ -63,6 +67,7 @@ static bool delete_flag;
 static bool dump_socket_mem_flag;
 static bool enable_fwd;
 static bool unique_data;
+static bool policy_mtr;
 
 static uint8_t rx_queues_count;
 static uint8_t tx_queues_count;
@@ -124,6 +129,337 @@ static struct multi_cores_pool mc_pool = {
 	.cores_count = 1,
 };
 
+static const struct option_dict {
+	const char *str;
+	const uint64_t mask;
+	uint64_t *map;
+	uint8_t *map_idx;
+
+} flow_options[] = {
+	{
+		.str = "ether",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ETH),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "ipv4",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "ipv6",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV6),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "vlan",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VLAN),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "tcp",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TCP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "udp",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "vxlan",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "vxlan-gpe",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN_GPE),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "gre",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GRE),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "geneve",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GENEVE),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "gtp",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GTP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "meta",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_META),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "tag",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TAG),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "icmpv4",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "icmpv6",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP6),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "ingress",
+		.mask = INGRESS,
+		.map = &flow_attrs[0],
+		.map_idx = &attrs_idx
+	},
+	{
+		.str = "egress",
+		.mask = EGRESS,
+		.map = &flow_attrs[0],
+		.map_idx = &attrs_idx
+	},
+	{
+		.str = "transfer",
+		.mask = TRANSFER,
+		.map = &flow_attrs[0],
+		.map_idx = &attrs_idx
+	},
+	{
+		.str = "port-id",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_ID),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "rss",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_RSS),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "queue",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_QUEUE),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "jump",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_JUMP),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "mark",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_MARK),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "count",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_COUNT),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-meta",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_META),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-tag",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_TAG),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "drop",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_DROP),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-mac",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_MAC_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-mac",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_MAC_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-ipv4",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-ipv4",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-ipv6",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-ipv6",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-tp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_TP_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-tp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_TP_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "inc-tcp-ack",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_INC_TCP_ACK
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "dec-tcp-ack",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "inc-tcp-seq",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "dec-tcp-seq",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-ttl",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_TTL
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "dec-ttl",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_DEC_TTL
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-ipv4-dscp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-ipv6-dscp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "flag",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_FLAG
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "meter",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_METER
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "vxlan-encap",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "vxlan-decap",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_VXLAN_DECAP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+};
+
 static void
 usage(char *progname)
 {
@@ -143,7 +479,8 @@ usage(char *progname)
 	printf("  --portmask=N: hexadecimal bitmask of ports used\n");
 	printf("  --unique-data: flag to set using unique data for all"
 		" actions that support data, such as header modify and encap actions\n");
-
+	printf("  --policy-mtr=\"g1,g2:y1:r1\": To create meter with specified "
+		"color actions\n");
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
 	printf("  --egress: set egress attribute in flows\n");
@@ -236,6 +573,44 @@ usage(char *progname)
 	printf("  --vxlan-decap: add vxlan_decap action to flow actions\n");
 }
 
+static void
+handle_meter_policy(char *prog, char *arg)
+{
+	char *token;
+	size_t i, j, k;
+	j = 0;
+	k = 0;
+	policy_mtr = true;
+	token = strsep(&arg, ":\0");
+	while (token != NULL && j < RTE_COLORS) {
+		actions_str[j++] = token;
+		token = strsep(&arg, ":\0");
+	}
+	j = 0;
+	token = strtok(actions_str[0], ",\0");
+	while (token == NULL && j < RTE_COLORS - 1)
+		token = strtok(actions_str[++j], ",\0");
+	while (j < RTE_COLORS && token != NULL) {
+		for (i = 0; i < RTE_DIM(flow_options); i++) {
+			if (!strcmp(token, flow_options[i].str)) {
+				all_actions[j][k++] = flow_options[i].mask;
+				break;
+			}
+		}
+		/* Reached last item with no match */
+		if (i >= RTE_DIM(flow_options)) {
+			fprintf(stderr, "Invalid actions item: %s\n", token);
+			usage(prog);
+			rte_exit(EXIT_SUCCESS, "Invalid actions item\n");
+		}
+		token = strtok(NULL, ",\0");
+		while (!token && j < RTE_COLORS - 1) {
+			token = strtok(actions_str[++j], ",\0");
+			k = 0;
+		}
+	}
+}
+
 static void
 args_parse(int argc, char **argv)
 {
@@ -247,337 +622,6 @@ args_parse(int argc, char **argv)
 	int opt_idx;
 	size_t i;
 
-	static const struct option_dict {
-		const char *str;
-		const uint64_t mask;
-		uint64_t *map;
-		uint8_t *map_idx;
-
-	} flow_options[] = {
-		{
-			.str = "ether",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ETH),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "ipv4",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "ipv6",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV6),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "vlan",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VLAN),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "tcp",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TCP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "udp",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "vxlan",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "vxlan-gpe",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN_GPE),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "gre",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GRE),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "geneve",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GENEVE),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "gtp",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GTP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "meta",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_META),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "tag",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TAG),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "icmpv4",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "icmpv6",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP6),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "ingress",
-			.mask = INGRESS,
-			.map = &flow_attrs[0],
-			.map_idx = &attrs_idx
-		},
-		{
-			.str = "egress",
-			.mask = EGRESS,
-			.map = &flow_attrs[0],
-			.map_idx = &attrs_idx
-		},
-		{
-			.str = "transfer",
-			.mask = TRANSFER,
-			.map = &flow_attrs[0],
-			.map_idx = &attrs_idx
-		},
-		{
-			.str = "port-id",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_ID),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "rss",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_RSS),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "queue",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_QUEUE),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "jump",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_JUMP),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "mark",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_MARK),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "count",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_COUNT),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-meta",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_META),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-tag",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_TAG),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "drop",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_DROP),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-mac",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_MAC_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-mac",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_MAC_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-ipv4",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-ipv4",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-ipv6",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-ipv6",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-tp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_TP_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-tp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_TP_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "inc-tcp-ack",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_INC_TCP_ACK
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "dec-tcp-ack",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "inc-tcp-seq",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "dec-tcp-seq",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-ttl",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_TTL
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "dec-ttl",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_DEC_TTL
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-ipv4-dscp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-ipv6-dscp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "flag",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_FLAG
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "meter",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_METER
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "vxlan-encap",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "vxlan-decap",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_VXLAN_DECAP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-	};
-
 	static const struct option lgopts[] = {
 		/* Control */
 		{ "help",                       0, 0, 0 },
@@ -653,6 +697,7 @@ args_parse(int argc, char **argv)
 		{ "raw-decap",                  1, 0, 0 },
 		{ "vxlan-encap",                0, 0, 0 },
 		{ "vxlan-decap",                0, 0, 0 },
+		{ "policy-mtr",                 1, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -869,6 +914,8 @@ args_parse(int argc, char **argv)
 						RTE_MAX_LCORE);
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
+				handle_meter_policy(argv[0], optarg);
 			break;
 		default:
 			usage(argv[0]);
@@ -979,12 +1026,68 @@ has_meter(void)
 	return 0;
 }
 
+static void
+create_meter_policy(void)
+{
+	struct rte_mtr_error error;
+	int ret, port_id;
+	struct rte_mtr_meter_policy_params policy;
+	uint16_t nr_ports;
+	struct rte_flow_action actions[RTE_COLORS][MAX_ACTIONS_NUM];
+	int i;
+
+	memset(actions, 0, sizeof(actions));
+	memset(&policy, 0, sizeof(policy));
+	nr_ports = rte_eth_dev_count_avail();
+	for (port_id = 0; port_id < nr_ports; port_id++) {
+		for (i = 0; i < RTE_COLORS; i++)
+			fill_actions(actions[i], all_actions[i], 0, 0, 0,
+				     0, 0, 0, unique_data, rx_queues_count,
+				     dst_ports[port_id]);
+		policy.actions[RTE_COLOR_GREEN] = actions[RTE_COLOR_GREEN];
+		policy.actions[RTE_COLOR_YELLOW] = actions[RTE_COLOR_YELLOW];
+		policy.actions[RTE_COLOR_RED] = actions[RTE_COLOR_RED];
+		policy_id[port_id] = port_id + 10;
+		ret = rte_mtr_meter_policy_add(port_id, policy_id[port_id],
+					       &policy, &error);
+		if (ret) {
+			fprintf(stderr, "meter policy add failed port_id %d\n",
+				port_id);
+			policy_id[port_id] = UINT32_MAX;
+		}
+		memset(actions, 0, sizeof(actions));
+	}
+}
+
+
+static void
+destroy_meter_policy(void)
+{
+	struct rte_mtr_error error;
+	uint16_t nr_ports;
+	int port_id;
+
+	nr_ports = rte_eth_dev_count_avail();
+	for (port_id = 0; port_id < nr_ports; port_id++) {
+		/* If port outside portmask */
+		if (!((ports_mask >> port_id) & 0x1))
+			continue;
+
+		if (rte_mtr_meter_policy_delete
+			(port_id, policy_id[port_id], &error)) {
+			fprintf(stderr, "Port %u del policy error(%d) message: %s\n",
+				port_id, error.type,
+				error.message ? error.message : "(no stated reason)");
+			rte_exit(EXIT_FAILURE, "Error: Destroy meter policy Failed!\n");
+		}
+	}
+}
+
 static void
 create_meter_rule(int port_id, uint32_t counter)
 {
 	int ret;
 	struct rte_mtr_params params;
-	uint32_t default_prof_id = 100;
 	struct rte_mtr_error error;
 
 	memset(&params, 0, sizeof(struct rte_mtr_params));
@@ -994,8 +1097,15 @@ create_meter_rule(int port_id, uint32_t counter)
 	params.dscp_table = NULL;
 
 	/*create meter*/
-	params.meter_profile_id = default_prof_id;
-	ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+	params.meter_profile_id = DEFAULT_METER_PROF_ID;
+
+	if (!policy_mtr) {
+		ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+	} else {
+		params.meter_policy_id = policy_id[port_id];
+		ret = rte_mtr_create(port_id, counter, &params, 0, &error);
+	}
+
 	if (ret != 0) {
 		printf("Port %u create meter idx(%d) error(%d) message: %s\n",
 			port_id, counter, error.type,
@@ -1009,11 +1119,17 @@ destroy_meter_rule(int port_id, uint32_t counter)
 {
 	struct rte_mtr_error error;
 
+	if (policy_mtr && policy_id[port_id] != UINT32_MAX) {
+		if (rte_mtr_meter_policy_delete(port_id, policy_id[port_id],
+					&error))
+			fprintf(stderr, "error delete policy %d\n", counter+1);
+		policy_id[port_id] = UINT32_MAX;
+	}
 	if (rte_mtr_destroy(port_id, counter, &error)) {
-		printf("Port %u destroy meter(%d) error(%d) message: %s\n",
-			port_id, counter, error.type,
-			error.message ? error.message : "(no stated reason)");
-		rte_exit(EXIT_FAILURE, "Error in deleting meter rule\n");
+		fprintf(stderr, "Port %u destroy meter(%d) error(%d) message: %s\n",
+		port_id, counter, error.type,
+		error.message ? error.message : "(no stated reason)");
+		rte_exit(EXIT_FAILURE, "Error in deleting meter rule");
 	}
 }
 
@@ -1118,12 +1234,10 @@ create_meter_profile(void)
 		/* If port outside portmask */
 		if (!((ports_mask >> port_id) & 0x1))
 			continue;
-
 		mp.alg = RTE_MTR_SRTCM_RFC2697;
 		mp.srtcm_rfc2697.cir = METER_CIR;
 		mp.srtcm_rfc2697.cbs = METER_CIR / 8;
 		mp.srtcm_rfc2697.ebs = 0;
-
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
@@ -1992,16 +2106,22 @@ main(int argc, char **argv)
 
 	printf(":: Flows Count per port: %d\n\n", rules_count);
 
-	if (has_meter())
+	if (has_meter()) {
 		create_meter_profile();
+		if (policy_mtr)
+			create_meter_policy();
+	}
 	rte_eal_mp_remote_launch(run_rte_flow_handler_cores, NULL, CALL_MAIN);
 
 	if (enable_fwd) {
 		init_lcore_info();
 		rte_eal_mp_remote_launch(start_forwarding, NULL, CALL_MAIN);
 	}
-	if (has_meter() && delete_flag)
+	if (has_meter() && delete_flag) {
 		destroy_meter_profile();
+		if (policy_mtr)
+			destroy_meter_policy();
+	}
 
 	RTE_ETH_FOREACH_DEV(port) {
 		rte_flow_flush(port, &error);
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index e608a44c24..a23b94bb55 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -383,3 +383,6 @@ Actions:
 *       ``--meter``
         Add meter action to all flows actions.
         Currently, 1 meter profile -> N meter rules -> N rte flows.
+
+*       ``--policy-mtr=<str>``
+        Add policy-mtr to create meter with policy and specify policy actions.
-- 
2.27.0

[dpdk-dev] [PATCH v6 2/3] app/flow-perf: add meter-profile to support cir cbs and ebs

From: Rongwei Liu <hidden>
Date: 2021-11-08 09:58:51

Change meter-cir option to meter-profile to cover CIR/CBS/EBS all.

The usage is as below:
--meter-profile=N1,N2,N3 default value is 1250000 156250 0.

Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
 app/test-flow-perf/main.c      | 28 ++++++++++++++++++++++++----
 doc/guides/tools/flow-perf.rst |  3 ++-
 2 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index a960e5b245..23ee5d2431 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -83,6 +83,7 @@ static uint32_t rules_count;
 static uint32_t rules_batch;
 static uint32_t hairpin_queues_num; /* total hairpin q number - default: 0 */
 static uint32_t nb_lcores;
+static uint64_t meter_profile_values[3]; /* CIR CBS EBS values. */
 
 #define MAX_PKT_BURST    32
 #define LCORE_MODE_PKT    1
@@ -481,6 +482,9 @@ usage(char *progname)
 		" actions that support data, such as header modify and encap actions\n");
 	printf("  --policy-mtr=\"g1,g2:y1:r1\": To create meter with specified "
 		"color actions\n");
+	printf("  --meter-profile=cir,cbs,ebs: set CIR CBS EBS parameters in meter"
+		" profile, default is %d,%d,%d\n", METER_CIR, METER_CIR / 8, 0);
+
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
 	printf("  --egress: set egress attribute in flows\n");
@@ -618,9 +622,10 @@ args_parse(int argc, char **argv)
 	char **argvopt;
 	char *token;
 	char *end;
+	char *arg;
 	int n, opt;
 	int opt_idx;
-	size_t i;
+	size_t i, j;
 
 	static const struct option lgopts[] = {
 		/* Control */
@@ -698,6 +703,7 @@ args_parse(int argc, char **argv)
 		{ "vxlan-encap",                0, 0, 0 },
 		{ "vxlan-decap",                0, 0, 0 },
 		{ "policy-mtr",                 1, 0, 0 },
+		{ "meter-profile",              1, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -914,6 +920,18 @@ args_parse(int argc, char **argv)
 						RTE_MAX_LCORE);
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name,
+						"meter-profile") == 0) {
+				arg = optarg;
+				j = 0;
+				token = strsep(&arg, ",\0");
+				while (token != NULL && j < sizeof(
+						meter_profile_values) /
+						sizeof(uint64_t)) {
+					meter_profile_values[j++] = atol(token);
+					token = strsep(&arg, ",\0");
+				}
+			}
 			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
 				handle_meter_policy(argv[0], optarg);
 			break;
@@ -1235,9 +1253,11 @@ create_meter_profile(void)
 		if (!((ports_mask >> port_id) & 0x1))
 			continue;
 		mp.alg = RTE_MTR_SRTCM_RFC2697;
-		mp.srtcm_rfc2697.cir = METER_CIR;
-		mp.srtcm_rfc2697.cbs = METER_CIR / 8;
-		mp.srtcm_rfc2697.ebs = 0;
+		mp.srtcm_rfc2697.cir = meter_profile_values[0] ?
+			meter_profile_values[0] : METER_CIR;
+		mp.srtcm_rfc2697.cbs = meter_profile_values[1] ?
+			meter_profile_values[1] : METER_CIR / 8;
+		mp.srtcm_rfc2697.ebs = meter_profile_values[2];
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index a23b94bb55..641600aaf9 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -130,7 +130,8 @@ The command line options are:
 *	``--total-mbuf-count=N``
 	Set the count of total mbuf number, default count is 32000.
 
-Attributes:
+*	``--meter-profile=N1,N2,N3``
+	Set the CIR, CBS and EBS parameter, default value is 1250000, 156250 and 0.
 
 *	``--ingress``
 	Set Ingress attribute to all flows attributes.
-- 
2.27.0

[dpdk-dev] [PATCH v6 3/3] app/flow-perf: add packet mode metering mode

From: Rongwei Liu <hidden>
Date: 2021-11-08 09:58:58

The flow perf application used the srtcm_rfc2697 as meter profile
while doing the meter testing.

This patch adds the support new configuration parameter
'--packet-mode' to generate the meter flows with the packet mode.

Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
 app/test-flow-perf/main.c      | 6 ++++++
 doc/guides/tools/flow-perf.rst | 3 +++
 2 files changed, 9 insertions(+)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 23ee5d2431..374eeba3e3 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -68,6 +68,7 @@ static bool dump_socket_mem_flag;
 static bool enable_fwd;
 static bool unique_data;
 static bool policy_mtr;
+static bool packet_mode;
 
 static uint8_t rx_queues_count;
 static uint8_t tx_queues_count;
@@ -484,6 +485,7 @@ usage(char *progname)
 		"color actions\n");
 	printf("  --meter-profile=cir,cbs,ebs: set CIR CBS EBS parameters in meter"
 		" profile, default is %d,%d,%d\n", METER_CIR, METER_CIR / 8, 0);
+	printf("  --packet-mode: To enable packet mode for meter profile\n");
 
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
@@ -704,6 +706,7 @@ args_parse(int argc, char **argv)
 		{ "vxlan-decap",                0, 0, 0 },
 		{ "policy-mtr",                 1, 0, 0 },
 		{ "meter-profile",              1, 0, 0 },
+		{ "packet-mode",                0, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -932,6 +935,8 @@ args_parse(int argc, char **argv)
 					token = strsep(&arg, ",\0");
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name, "packet-mode") == 0)
+				packet_mode = true;
 			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
 				handle_meter_policy(argv[0], optarg);
 			break;
@@ -1258,6 +1263,7 @@ create_meter_profile(void)
 		mp.srtcm_rfc2697.cbs = meter_profile_values[1] ?
 			meter_profile_values[1] : METER_CIR / 8;
 		mp.srtcm_rfc2697.ebs = meter_profile_values[2];
+		mp.packet_mode = packet_mode;
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 641600aaf9..d77046433c 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -133,6 +133,9 @@ The command line options are:
 *	``--meter-profile=N1,N2,N3``
 	Set the CIR, CBS and EBS parameter, default value is 1250000, 156250 and 0.
 
+*	``--packet-mode``
+	Enable packets mode for meter profile.
+
 *	``--ingress``
 	Set Ingress attribute to all flows attributes.
 
-- 
2.27.0

Re: [dpdk-dev] [PATCH v6 1/3] app/flow-perf: support meter policy API

From: Thomas Monjalon <hidden>
Date: 2021-11-08 10:09:02

08/11/2021 10:58, Rongwei Liu:
quoted hunk
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -383,3 +383,6 @@ Actions:
 *       ``--meter``
         Add meter action to all flows actions.
         Currently, 1 meter profile -> N meter rules -> N rte flows.
+
+*       ``--policy-mtr=<str>``
+        Add policy-mtr to create meter with policy and specify policy actions.
These 2 options are clearly not indented correctly.
And in general, adding at the end of the list is not appropriate.
Please find where it fits in the list.

Re: [dpdk-dev] [PATCH v6 2/3] app/flow-perf: add meter-profile to support cir cbs and ebs

From: Thomas Monjalon <hidden>
Date: 2021-11-08 10:10:09

08/11/2021 10:58, Rongwei Liu:
quoted hunk
Change meter-cir option to meter-profile to cover CIR/CBS/EBS all.

The usage is as below:
--meter-profile=N1,N2,N3 default value is 1250000 156250 0.

Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
-Attributes:
+*	``--meter-profile=N1,N2,N3``
+	Set the CIR, CBS and EBS parameter, default value is 1250000, 156250 and 0.
Why removing "Attributes"?


[dpdk-dev] [PATCH v7 0/3] add meter policy support in flow-perf

From: Rongwei Liu <hidden>
Date: 2021-11-08 11:11:12

Add meter policy support and provide options to specify
green/yellow/red corlor actions and cir/cbs/ebs values.

v2: add option to specify green color actions.
v3: support yellow color action and ebs options.
v4: rebase on top of master-net-mlx.
v5: fix intermediate werror.
v6: rebase on top of main.
v7: rebase on top of dpdk.org/main and fix existed styles.

Rongwei Liu (3):
  app/flow-perf: support meter policy API
  app/flow-perf: add meter-profile to support cir cbs and ebs
  app/flow-perf: add packet mode metering mode

 app/test-flow-perf/main.c      | 851 +++++++++++++++++++--------------
 doc/guides/tools/flow-perf.rst |  15 +-
 2 files changed, 509 insertions(+), 357 deletions(-)

-- 
2.27.0

[dpdk-dev] [PATCH v7 1/3] app/flow-perf: support meter policy API

From: Rongwei Liu <hidden>
Date: 2021-11-08 11:11:17

Add option "policy-mtr" to indicate if meter creation will include policy
or not. Meter creation will keep the same without it.

With "policy-mtr", the policy is introduced. API create_meter_policy
is to create a policy. API create_meter_rule will use it to create
a meter. The value of it is used to specify meter policy green color
actions.

Signed-off-by: Haifei Luo <redacted>
Signed-off-by: Jiawei Wang <redacted>
Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
 app/test-flow-perf/main.c      | 818 +++++++++++++++++++--------------
 doc/guides/tools/flow-perf.rst |   9 +-
 2 files changed, 474 insertions(+), 353 deletions(-)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index c1477b14a1..4d5d2d7a8f 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -37,6 +37,7 @@
 #include <rte_mtr.h>
 
 #include "config.h"
+#include "actions_gen.h"
 #include "flow_gen.h"
 
 #define MAX_BATCHES_COUNT          100
@@ -49,10 +50,13 @@ static uint8_t flow_group;
 
 static uint64_t encap_data;
 static uint64_t decap_data;
+static uint64_t all_actions[RTE_COLORS][MAX_ACTIONS_NUM];
+static char *actions_str[RTE_COLORS];
 
 static uint64_t flow_items[MAX_ITEMS_NUM];
 static uint64_t flow_actions[MAX_ACTIONS_NUM];
 static uint64_t flow_attrs[MAX_ATTRS_NUM];
+static uint32_t policy_id[MAX_PORTS];
 static uint8_t items_idx, actions_idx, attrs_idx;
 
 static uint64_t ports_mask;
@@ -63,6 +67,7 @@ static bool delete_flag;
 static bool dump_socket_mem_flag;
 static bool enable_fwd;
 static bool unique_data;
+static bool policy_mtr;
 
 static uint8_t rx_queues_count;
 static uint8_t tx_queues_count;
@@ -126,6 +131,337 @@ static struct multi_cores_pool mc_pool = {
 	.cores_count = 1,
 };
 
+static const struct option_dict {
+	const char *str;
+	const uint64_t mask;
+	uint64_t *map;
+	uint8_t *map_idx;
+
+} flow_options[] = {
+	{
+		.str = "ether",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ETH),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "ipv4",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "ipv6",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV6),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "vlan",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VLAN),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "tcp",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TCP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "udp",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "vxlan",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "vxlan-gpe",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN_GPE),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "gre",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GRE),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "geneve",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GENEVE),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "gtp",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GTP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "meta",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_META),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "tag",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TAG),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "icmpv4",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "icmpv6",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP6),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "ingress",
+		.mask = INGRESS,
+		.map = &flow_attrs[0],
+		.map_idx = &attrs_idx
+	},
+	{
+		.str = "egress",
+		.mask = EGRESS,
+		.map = &flow_attrs[0],
+		.map_idx = &attrs_idx
+	},
+	{
+		.str = "transfer",
+		.mask = TRANSFER,
+		.map = &flow_attrs[0],
+		.map_idx = &attrs_idx
+	},
+	{
+		.str = "port-id",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_ID),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "rss",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_RSS),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "queue",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_QUEUE),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "jump",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_JUMP),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "mark",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_MARK),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "count",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_COUNT),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-meta",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_META),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-tag",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_TAG),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "drop",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_DROP),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-mac",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_MAC_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-mac",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_MAC_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-ipv4",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-ipv4",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-ipv6",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-ipv6",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-tp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_TP_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-tp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_TP_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "inc-tcp-ack",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_INC_TCP_ACK
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "dec-tcp-ack",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "inc-tcp-seq",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "dec-tcp-seq",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-ttl",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_TTL
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "dec-ttl",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_DEC_TTL
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-ipv4-dscp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-ipv6-dscp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "flag",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_FLAG
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "meter",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_METER
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "vxlan-encap",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "vxlan-decap",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_VXLAN_DECAP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+};
+
 static void
 usage(char *progname)
 {
@@ -148,13 +484,6 @@ usage(char *progname)
 		"and S as seed for pseudo-random number generator\n");
 	printf("  --unique-data: flag to set using unique data for all"
 		" actions that support data, such as header modify and encap actions\n");
-
-	printf("To set flow attributes:\n");
-	printf("  --ingress: set ingress attribute in flows\n");
-	printf("  --egress: set egress attribute in flows\n");
-	printf("  --transfer: set transfer attribute in flows\n");
-	printf("  --group=N: set group for all flows,"
-		" default is %d\n", DEFAULT_GROUP);
 	printf("  --cores=N: to set the number of needed "
 		"cores to insert rte_flow rules, default is 1\n");
 	printf("  --rxq=N: to set the count of receive queues\n");
@@ -165,6 +494,12 @@ usage(char *progname)
 	printf("  --mbuf-cache-size=N: to set the size of mbuf cache\n");
 	printf("  --total-mbuf-count=N: to set the count of total mbuf count\n");
 
+	printf("To set flow attributes:\n");
+	printf("  --ingress: set ingress attribute in flows\n");
+	printf("  --egress: set egress attribute in flows\n");
+	printf("  --transfer: set transfer attribute in flows\n");
+	printf("  --group=N: set group for all flows,"
+		" default is %d\n", DEFAULT_GROUP);
 
 	printf("To set flow items:\n");
 	printf("  --ether: add ether layer in flow items\n");
@@ -229,6 +564,8 @@ usage(char *progname)
 		"ipv6 dscp value to be set is random each flow\n");
 	printf("  --flag: add flag action to flow actions\n");
 	printf("  --meter: add meter action to flow actions\n");
+	printf("  --policy-mtr=\"g1,g2:y1:r1\": To create meter with specified "
+		"color actions\n");
 	printf("  --raw-encap=<data>: add raw encap action to flow actions\n"
 		"Data is the data needed to be encaped\n"
 		"Example: raw-encap=ether,ipv4,udp,vxlan\n");
@@ -241,6 +578,44 @@ usage(char *progname)
 	printf("  --vxlan-decap: add vxlan_decap action to flow actions\n");
 }
 
+static void
+handle_meter_policy(char *prog, char *arg)
+{
+	char *token;
+	size_t i, j, k;
+	j = 0;
+	k = 0;
+	policy_mtr = true;
+	token = strsep(&arg, ":\0");
+	while (token != NULL && j < RTE_COLORS) {
+		actions_str[j++] = token;
+		token = strsep(&arg, ":\0");
+	}
+	j = 0;
+	token = strtok(actions_str[0], ",\0");
+	while (token == NULL && j < RTE_COLORS - 1)
+		token = strtok(actions_str[++j], ",\0");
+	while (j < RTE_COLORS && token != NULL) {
+		for (i = 0; i < RTE_DIM(flow_options); i++) {
+			if (!strcmp(token, flow_options[i].str)) {
+				all_actions[j][k++] = flow_options[i].mask;
+				break;
+			}
+		}
+		/* Reached last item with no match */
+		if (i >= RTE_DIM(flow_options)) {
+			fprintf(stderr, "Invalid actions item: %s\n", token);
+			usage(prog);
+			rte_exit(EXIT_SUCCESS, "Invalid actions item\n");
+		}
+		token = strtok(NULL, ",\0");
+		while (!token && j < RTE_COLORS - 1) {
+			token = strtok(actions_str[++j], ",\0");
+			k = 0;
+		}
+	}
+}
+
 static void
 args_parse(int argc, char **argv)
 {
@@ -253,337 +628,6 @@ args_parse(int argc, char **argv)
 	int opt_idx;
 	size_t i;
 
-	static const struct option_dict {
-		const char *str;
-		const uint64_t mask;
-		uint64_t *map;
-		uint8_t *map_idx;
-
-	} flow_options[] = {
-		{
-			.str = "ether",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ETH),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "ipv4",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "ipv6",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV6),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "vlan",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VLAN),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "tcp",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TCP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "udp",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "vxlan",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "vxlan-gpe",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN_GPE),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "gre",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GRE),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "geneve",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GENEVE),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "gtp",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GTP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "meta",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_META),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "tag",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TAG),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "icmpv4",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "icmpv6",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP6),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "ingress",
-			.mask = INGRESS,
-			.map = &flow_attrs[0],
-			.map_idx = &attrs_idx
-		},
-		{
-			.str = "egress",
-			.mask = EGRESS,
-			.map = &flow_attrs[0],
-			.map_idx = &attrs_idx
-		},
-		{
-			.str = "transfer",
-			.mask = TRANSFER,
-			.map = &flow_attrs[0],
-			.map_idx = &attrs_idx
-		},
-		{
-			.str = "port-id",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_ID),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "rss",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_RSS),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "queue",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_QUEUE),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "jump",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_JUMP),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "mark",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_MARK),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "count",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_COUNT),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-meta",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_META),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-tag",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_TAG),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "drop",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_DROP),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-mac",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_MAC_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-mac",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_MAC_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-ipv4",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-ipv4",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-ipv6",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-ipv6",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-tp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_TP_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-tp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_TP_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "inc-tcp-ack",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_INC_TCP_ACK
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "dec-tcp-ack",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "inc-tcp-seq",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "dec-tcp-seq",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-ttl",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_TTL
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "dec-ttl",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_DEC_TTL
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-ipv4-dscp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-ipv6-dscp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "flag",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_FLAG
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "meter",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_METER
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "vxlan-encap",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "vxlan-decap",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_VXLAN_DECAP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-	};
-
 	static const struct option lgopts[] = {
 		/* Control */
 		{ "help",                       0, 0, 0 },
@@ -660,6 +704,7 @@ args_parse(int argc, char **argv)
 		{ "raw-decap",                  1, 0, 0 },
 		{ "vxlan-encap",                0, 0, 0 },
 		{ "vxlan-decap",                0, 0, 0 },
+		{ "policy-mtr",                 1, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -877,6 +922,8 @@ args_parse(int argc, char **argv)
 						RTE_MAX_LCORE);
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
+				handle_meter_policy(argv[0], optarg);
 			break;
 		default:
 			usage(argv[0]);
@@ -981,7 +1028,6 @@ print_rules_batches(double *cpu_time_per_batch)
 	}
 }
 
-
 static inline int
 has_meter(void)
 {
@@ -997,12 +1043,67 @@ has_meter(void)
 	return 0;
 }
 
+static void
+create_meter_policy(void)
+{
+	struct rte_mtr_error error;
+	int ret, port_id;
+	struct rte_mtr_meter_policy_params policy;
+	uint16_t nr_ports;
+	struct rte_flow_action actions[RTE_COLORS][MAX_ACTIONS_NUM];
+	int i;
+
+	memset(actions, 0, sizeof(actions));
+	memset(&policy, 0, sizeof(policy));
+	nr_ports = rte_eth_dev_count_avail();
+	for (port_id = 0; port_id < nr_ports; port_id++) {
+		for (i = 0; i < RTE_COLORS; i++)
+			fill_actions(actions[i], all_actions[i], 0, 0, 0,
+				     0, 0, 0, unique_data, rx_queues_count,
+				     dst_ports[port_id]);
+		policy.actions[RTE_COLOR_GREEN] = actions[RTE_COLOR_GREEN];
+		policy.actions[RTE_COLOR_YELLOW] = actions[RTE_COLOR_YELLOW];
+		policy.actions[RTE_COLOR_RED] = actions[RTE_COLOR_RED];
+		policy_id[port_id] = port_id + 10;
+		ret = rte_mtr_meter_policy_add(port_id, policy_id[port_id],
+					       &policy, &error);
+		if (ret) {
+			fprintf(stderr, "meter policy add failed port_id %d\n",
+				port_id);
+			policy_id[port_id] = UINT32_MAX;
+		}
+		memset(actions, 0, sizeof(actions));
+	}
+}
+
+static void
+destroy_meter_policy(void)
+{
+	struct rte_mtr_error error;
+	uint16_t nr_ports;
+	int port_id;
+
+	nr_ports = rte_eth_dev_count_avail();
+	for (port_id = 0; port_id < nr_ports; port_id++) {
+		/* If port outside portmask */
+		if (!((ports_mask >> port_id) & 0x1))
+			continue;
+
+		if (rte_mtr_meter_policy_delete
+			(port_id, policy_id[port_id], &error)) {
+			fprintf(stderr, "Port %u del policy error(%d) message: %s\n",
+				port_id, error.type,
+				error.message ? error.message : "(no stated reason)");
+			rte_exit(EXIT_FAILURE, "Error: Destroy meter policy Failed!\n");
+		}
+	}
+}
+
 static void
 create_meter_rule(int port_id, uint32_t counter)
 {
 	int ret;
 	struct rte_mtr_params params;
-	uint32_t default_prof_id = 100;
 	struct rte_mtr_error error;
 
 	memset(&params, 0, sizeof(struct rte_mtr_params));
@@ -1012,8 +1113,15 @@ create_meter_rule(int port_id, uint32_t counter)
 	params.dscp_table = NULL;
 
 	/*create meter*/
-	params.meter_profile_id = default_prof_id;
-	ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+	params.meter_profile_id = DEFAULT_METER_PROF_ID;
+
+	if (!policy_mtr) {
+		ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+	} else {
+		params.meter_policy_id = policy_id[port_id];
+		ret = rte_mtr_create(port_id, counter, &params, 0, &error);
+	}
+
 	if (ret != 0) {
 		printf("Port %u create meter idx(%d) error(%d) message: %s\n",
 			port_id, counter, error.type,
@@ -1027,11 +1135,17 @@ destroy_meter_rule(int port_id, uint32_t counter)
 {
 	struct rte_mtr_error error;
 
+	if (policy_mtr && policy_id[port_id] != UINT32_MAX) {
+		if (rte_mtr_meter_policy_delete(port_id, policy_id[port_id],
+					&error))
+			fprintf(stderr, "error delete policy %d\n", counter+1);
+		policy_id[port_id] = UINT32_MAX;
+	}
 	if (rte_mtr_destroy(port_id, counter, &error)) {
-		printf("Port %u destroy meter(%d) error(%d) message: %s\n",
-			port_id, counter, error.type,
-			error.message ? error.message : "(no stated reason)");
-		rte_exit(EXIT_FAILURE, "Error in deleting meter rule\n");
+		fprintf(stderr, "Port %u destroy meter(%d) error(%d) message: %s\n",
+		port_id, counter, error.type,
+		error.message ? error.message : "(no stated reason)");
+		rte_exit(EXIT_FAILURE, "Error in deleting meter rule");
 	}
 }
 
@@ -1136,12 +1250,10 @@ create_meter_profile(void)
 		/* If port outside portmask */
 		if (!((ports_mask >> port_id) & 0x1))
 			continue;
-
 		mp.alg = RTE_MTR_SRTCM_RFC2697;
 		mp.srtcm_rfc2697.cir = METER_CIR;
 		mp.srtcm_rfc2697.cbs = METER_CIR / 8;
 		mp.srtcm_rfc2697.ebs = 0;
-
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
@@ -2012,16 +2124,22 @@ main(int argc, char **argv)
 
 	rte_srand(rand_seed);
 
-	if (has_meter())
+	if (has_meter()) {
 		create_meter_profile();
+		if (policy_mtr)
+			create_meter_policy();
+	}
 	rte_eal_mp_remote_launch(run_rte_flow_handler_cores, NULL, CALL_MAIN);
 
 	if (enable_fwd) {
 		init_lcore_info();
 		rte_eal_mp_remote_launch(start_forwarding, NULL, CALL_MAIN);
 	}
-	if (has_meter() && delete_flag)
+	if (has_meter() && delete_flag) {
 		destroy_meter_profile();
+		if (policy_mtr)
+			destroy_meter_policy();
+	}
 
 	RTE_ETH_FOREACH_DEV(port) {
 		rte_flow_flush(port, &error);
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 7d986f0158..9b131bad8c 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -384,6 +384,9 @@ Actions:
 *	``--vxlan-decap``
 	Add vxlan decap action to all flows actions.
 
-*       ``--meter``
-        Add meter action to all flows actions.
-        Currently, 1 meter profile -> N meter rules -> N rte flows.
+*	``--policy-mtr=<str>``
+	Add policy-mtr to create meter with policy and specify policy actions.
+
+*	``--meter``
+	Add meter action to all flows actions.
+	Currently, 1 meter profile -> N meter rules -> N rte flows.
-- 
2.27.0

[dpdk-dev] [PATCH v7 2/3] app/flow-perf: add meter-profile to support cir cbs and ebs

From: Rongwei Liu <hidden>
Date: 2021-11-08 11:11:25

Change meter-cir option to meter-profile to cover CIR/CBS/EBS all.

The usage is as below:
--meter-profile=N1,N2,N3 default value is 1250000 156250 0.

Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
 app/test-flow-perf/main.c      | 27 +++++++++++++++++++++++----
 doc/guides/tools/flow-perf.rst |  3 +++
 2 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 4d5d2d7a8f..63675bfcb4 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -85,6 +85,7 @@ static uint32_t hairpin_queues_num; /* total hairpin q number - default: 0 */
 static uint32_t nb_lcores;
 static uint8_t max_priority;
 static uint32_t rand_seed;
+static uint64_t meter_profile_values[3]; /* CIR CBS EBS values. */
 
 #define MAX_PKT_BURST    32
 #define LCORE_MODE_PKT    1
@@ -493,6 +494,8 @@ usage(char *progname)
 	printf("  --mbuf-size=N: to set the size of mbuf\n");
 	printf("  --mbuf-cache-size=N: to set the size of mbuf cache\n");
 	printf("  --total-mbuf-count=N: to set the count of total mbuf count\n");
+	printf("  --meter-profile=cir,cbs,ebs: set CIR CBS EBS parameters in meter"
+		" profile, default is %d,%d,%d\n", METER_CIR, METER_CIR / 8, 0);
 
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
@@ -624,9 +627,10 @@ args_parse(int argc, char **argv)
 	uint32_t prio;
 	char *token;
 	char *end;
+	char *arg;
 	int n, opt;
 	int opt_idx;
-	size_t i;
+	size_t i, j;
 
 	static const struct option lgopts[] = {
 		/* Control */
@@ -705,6 +709,7 @@ args_parse(int argc, char **argv)
 		{ "vxlan-encap",                0, 0, 0 },
 		{ "vxlan-decap",                0, 0, 0 },
 		{ "policy-mtr",                 1, 0, 0 },
+		{ "meter-profile",              1, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -922,6 +927,18 @@ args_parse(int argc, char **argv)
 						RTE_MAX_LCORE);
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name,
+						"meter-profile") == 0) {
+				arg = optarg;
+				j = 0;
+				token = strsep(&arg, ",\0");
+				while (token != NULL && j < sizeof(
+						meter_profile_values) /
+						sizeof(uint64_t)) {
+					meter_profile_values[j++] = atol(token);
+					token = strsep(&arg, ",\0");
+				}
+			}
 			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
 				handle_meter_policy(argv[0], optarg);
 			break;
@@ -1251,9 +1268,11 @@ create_meter_profile(void)
 		if (!((ports_mask >> port_id) & 0x1))
 			continue;
 		mp.alg = RTE_MTR_SRTCM_RFC2697;
-		mp.srtcm_rfc2697.cir = METER_CIR;
-		mp.srtcm_rfc2697.cbs = METER_CIR / 8;
-		mp.srtcm_rfc2697.ebs = 0;
+		mp.srtcm_rfc2697.cir = meter_profile_values[0] ?
+			meter_profile_values[0] : METER_CIR;
+		mp.srtcm_rfc2697.cbs = meter_profile_values[1] ?
+			meter_profile_values[1] : METER_CIR / 8;
+		mp.srtcm_rfc2697.ebs = meter_profile_values[2];
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 9b131bad8c..4074b0a94d 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -134,6 +134,9 @@ The command line options are:
 *	``--total-mbuf-count=N``
 	Set the count of total mbuf number, default count is 32000.
 
+*	``--meter-profile=N1,N2,N3``
+	Set the CIR, CBS and EBS parameter, default value is 1250000, 156250 and 0.
+
 Attributes:
 
 *	``--ingress``
-- 
2.27.0

[dpdk-dev] [PATCH v7 3/3] app/flow-perf: add packet mode metering mode

From: Rongwei Liu <hidden>
Date: 2021-11-08 11:11:30

The flow perf application used the srtcm_rfc2697 as meter profile
while doing the meter testing.

This patch adds the support new configuration parameter
'--packet-mode' to generate the meter flows with the packet mode.

Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
 app/test-flow-perf/main.c      | 6 ++++++
 doc/guides/tools/flow-perf.rst | 3 +++
 2 files changed, 9 insertions(+)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 63675bfcb4..0c5fe6b026 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -68,6 +68,7 @@ static bool dump_socket_mem_flag;
 static bool enable_fwd;
 static bool unique_data;
 static bool policy_mtr;
+static bool packet_mode;
 
 static uint8_t rx_queues_count;
 static uint8_t tx_queues_count;
@@ -496,6 +497,7 @@ usage(char *progname)
 	printf("  --total-mbuf-count=N: to set the count of total mbuf count\n");
 	printf("  --meter-profile=cir,cbs,ebs: set CIR CBS EBS parameters in meter"
 		" profile, default is %d,%d,%d\n", METER_CIR, METER_CIR / 8, 0);
+	printf("  --packet-mode: To enable packet mode for meter profile\n");
 
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
@@ -710,6 +712,7 @@ args_parse(int argc, char **argv)
 		{ "vxlan-decap",                0, 0, 0 },
 		{ "policy-mtr",                 1, 0, 0 },
 		{ "meter-profile",              1, 0, 0 },
+		{ "packet-mode",                0, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -939,6 +942,8 @@ args_parse(int argc, char **argv)
 					token = strsep(&arg, ",\0");
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name, "packet-mode") == 0)
+				packet_mode = true;
 			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
 				handle_meter_policy(argv[0], optarg);
 			break;
@@ -1273,6 +1278,7 @@ create_meter_profile(void)
 		mp.srtcm_rfc2697.cbs = meter_profile_values[1] ?
 			meter_profile_values[1] : METER_CIR / 8;
 		mp.srtcm_rfc2697.ebs = meter_profile_values[2];
+		mp.packet_mode = packet_mode;
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 4074b0a94d..57a3653f4f 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -137,6 +137,9 @@ The command line options are:
 *	``--meter-profile=N1,N2,N3``
 	Set the CIR, CBS and EBS parameter, default value is 1250000, 156250 and 0.
 
+*	``--packet-mode``
+	Enable packets mode for meter profile.
+
 Attributes:
 
 *	``--ingress``
-- 
2.27.0

[dpdk-dev] [PATCH v8 0/3] add meter policy support in flow-perf

From: Rongwei Liu <hidden>
Date: 2021-11-10 12:57:48

Add meter policy support and provide options to specify
green/yellow/red corlor actions and cir/cbs/ebs values.

v2: add option to specify green color actions.
v3: support yellow color action and ebs options.
v4: rebase on top of master-net-mlx.
v5: fix intermediate werror.
v6: rebase on top of main.
v7: rebase on top of dpdk.org/main and fix existed styles.
v8: clean log.

Rongwei Liu (3):
  app/flow-perf: support meter policy API
  app/flow-perf: support dynamic values for meter profile
  app/flow-perf: add packet metering mode

 app/test-flow-perf/main.c      | 834 +++++++++++++++++++--------------
 doc/guides/tools/flow-perf.rst |  16 +-
 2 files changed, 501 insertions(+), 349 deletions(-)

-- 
2.27.0

[dpdk-dev] [PATCH v8 2/3] app/flow-perf: support dynamic values for meter profile

From: Rongwei Liu <hidden>
Date: 2021-11-10 12:57:53

Change meter-cir option to meter-profile to cover user input for CIR,
CBS & EBS values.

The usage is as below:
--meter-profile=N1,N2,N3 default value is 1250000 156250 0.

Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
 app/test-flow-perf/main.c      | 24 +++++++++++++++++++++---
 doc/guides/tools/flow-perf.rst |  3 +++
 2 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 89596eb3f6..01bfa20db7 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -85,6 +85,7 @@ static uint32_t hairpin_queues_num; /* total hairpin q number - default: 0 */
 static uint32_t nb_lcores;
 static uint8_t max_priority;
 static uint32_t rand_seed;
+static uint64_t meter_profile_values[3]; /* CIR CBS EBS values. */
 
 #define MAX_PKT_BURST    32
 #define LCORE_MODE_PKT    1
@@ -484,6 +485,9 @@ usage(char *progname)
 		"and S as seed for pseudo-random number generator\n");
 	printf("  --unique-data: flag to set using unique data for all"
 		" actions that support data, such as header modify and encap actions\n");
+	printf("  --meter-profile=cir,cbs,ebs: set CIR CBS EBS parameters in meter"
+		" profile, default values are %d,%d,%d\n", METER_CIR,
+		METER_CIR / 8, 0);
 
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
@@ -707,6 +711,7 @@ args_parse(int argc, char **argv)
 		{ "vxlan-encap",                0, 0, 0 },
 		{ "vxlan-decap",                0, 0, 0 },
 		{ "policy-mtr",                 1, 0, 0 },
+		{ "meter-profile",              1, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -926,6 +931,17 @@ args_parse(int argc, char **argv)
 			}
 			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
 				read_meter_policy(argv[0], optarg);
+			if (strcmp(lgopts[opt_idx].name,
+						"meter-profile") == 0) {
+				i = 0;
+				token = strsep(&optarg, ",\0");
+				while (token != NULL && i < sizeof(
+						meter_profile_values) /
+						sizeof(uint64_t)) {
+					meter_profile_values[i++] = atol(token);
+					token = strsep(&optarg, ",\0");
+				}
+			}
 			break;
 		default:
 			usage(argv[0]);
@@ -1251,9 +1267,11 @@ create_meter_profile(void)
 		if (!((ports_mask >> port_id) & 0x1))
 			continue;
 		mp.alg = RTE_MTR_SRTCM_RFC2697;
-		mp.srtcm_rfc2697.cir = METER_CIR;
-		mp.srtcm_rfc2697.cbs = METER_CIR / 8;
-		mp.srtcm_rfc2697.ebs = 0;
+		mp.srtcm_rfc2697.cir = meter_profile_values[0] ?
+			meter_profile_values[0] : METER_CIR;
+		mp.srtcm_rfc2697.cbs = meter_profile_values[1] ?
+			meter_profile_values[1] : METER_CIR / 8;
+		mp.srtcm_rfc2697.ebs = meter_profile_values[2];
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index ec6994e412..3f1e5986e3 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -134,6 +134,9 @@ The command line options are:
 *	``--total-mbuf-count=N``
 	Set the count of total mbuf number, default count is 32000.
 
+*	``--meter-profile=N1,N2,N3``
+	Set the CIR, CBS and EBS parameters, default values are 1250000, 156250 and 0.
+
 Attributes:
 
 *	``--ingress``
-- 
2.27.0

[dpdk-dev] [PATCH v8 1/3] app/flow-perf: support meter policy API

From: Rongwei Liu <hidden>
Date: 2021-11-10 12:57:59

Add option "policy-mtr" to indicate if meter creation will include policy
or not. Meter creation will keep unchanged without it.

With "policy-mtr", the policy is introduced. API create_meter_policy
is to create a policy. API create_meter_rule will use it to create
a meter. The value of it is used to specify meter policy actions.

Signed-off-by: Haifei Luo <redacted>
Signed-off-by: Jiawei Wang <redacted>
Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
 app/test-flow-perf/main.c      | 804 +++++++++++++++++++--------------
 doc/guides/tools/flow-perf.rst |  10 +-
 2 files changed, 468 insertions(+), 346 deletions(-)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index c1477b14a1..89596eb3f6 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -37,6 +37,7 @@
 #include <rte_mtr.h>
 
 #include "config.h"
+#include "actions_gen.h"
 #include "flow_gen.h"
 
 #define MAX_BATCHES_COUNT          100
@@ -49,10 +50,13 @@ static uint8_t flow_group;
 
 static uint64_t encap_data;
 static uint64_t decap_data;
+static uint64_t all_actions[RTE_COLORS][MAX_ACTIONS_NUM];
+static char *actions_str[RTE_COLORS];
 
 static uint64_t flow_items[MAX_ITEMS_NUM];
 static uint64_t flow_actions[MAX_ACTIONS_NUM];
 static uint64_t flow_attrs[MAX_ATTRS_NUM];
+static uint32_t policy_id[MAX_PORTS];
 static uint8_t items_idx, actions_idx, attrs_idx;
 
 static uint64_t ports_mask;
@@ -63,6 +67,7 @@ static bool delete_flag;
 static bool dump_socket_mem_flag;
 static bool enable_fwd;
 static bool unique_data;
+static bool policy_mtr;
 
 static uint8_t rx_queues_count;
 static uint8_t tx_queues_count;
@@ -126,6 +131,337 @@ static struct multi_cores_pool mc_pool = {
 	.cores_count = 1,
 };
 
+static const struct option_dict {
+	const char *str;
+	const uint64_t mask;
+	uint64_t *map;
+	uint8_t *map_idx;
+
+} flow_options[] = {
+	{
+		.str = "ether",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ETH),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "ipv4",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "ipv6",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV6),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "vlan",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VLAN),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "tcp",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TCP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "udp",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "vxlan",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "vxlan-gpe",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN_GPE),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "gre",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GRE),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "geneve",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GENEVE),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "gtp",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GTP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "meta",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_META),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "tag",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TAG),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "icmpv4",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "icmpv6",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP6),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "ingress",
+		.mask = INGRESS,
+		.map = &flow_attrs[0],
+		.map_idx = &attrs_idx
+	},
+	{
+		.str = "egress",
+		.mask = EGRESS,
+		.map = &flow_attrs[0],
+		.map_idx = &attrs_idx
+	},
+	{
+		.str = "transfer",
+		.mask = TRANSFER,
+		.map = &flow_attrs[0],
+		.map_idx = &attrs_idx
+	},
+	{
+		.str = "port-id",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_ID),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "rss",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_RSS),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "queue",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_QUEUE),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "jump",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_JUMP),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "mark",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_MARK),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "count",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_COUNT),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-meta",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_META),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-tag",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_TAG),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "drop",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_DROP),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-mac",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_MAC_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-mac",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_MAC_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-ipv4",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-ipv4",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-ipv6",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-ipv6",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-tp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_TP_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-tp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_TP_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "inc-tcp-ack",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_INC_TCP_ACK
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "dec-tcp-ack",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "inc-tcp-seq",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "dec-tcp-seq",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-ttl",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_TTL
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "dec-ttl",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_DEC_TTL
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-ipv4-dscp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-ipv6-dscp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "flag",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_FLAG
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "meter",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_METER
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "vxlan-encap",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "vxlan-decap",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_VXLAN_DECAP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+};
+
 static void
 usage(char *progname)
 {
@@ -229,6 +565,8 @@ usage(char *progname)
 		"ipv6 dscp value to be set is random each flow\n");
 	printf("  --flag: add flag action to flow actions\n");
 	printf("  --meter: add meter action to flow actions\n");
+	printf("  --policy-mtr=\"g1,g2:y1:r1\": to create meter with specified "
+		"colored actions\n");
 	printf("  --raw-encap=<data>: add raw encap action to flow actions\n"
 		"Data is the data needed to be encaped\n"
 		"Example: raw-encap=ether,ipv4,udp,vxlan\n");
@@ -241,6 +579,45 @@ usage(char *progname)
 	printf("  --vxlan-decap: add vxlan_decap action to flow actions\n");
 }
 
+static void
+read_meter_policy(char *prog, char *arg)
+{
+	char *token;
+	size_t i, j, k;
+
+	j = 0;
+	k = 0;
+	policy_mtr = true;
+	token = strsep(&arg, ":\0");
+	while (token != NULL && j < RTE_COLORS) {
+		actions_str[j++] = token;
+		token = strsep(&arg, ":\0");
+	}
+	j = 0;
+	token = strtok(actions_str[0], ",\0");
+	while (token == NULL && j < RTE_COLORS - 1)
+		token = strtok(actions_str[++j], ",\0");
+	while (j < RTE_COLORS && token != NULL) {
+		for (i = 0; i < RTE_DIM(flow_options); i++) {
+			if (!strcmp(token, flow_options[i].str)) {
+				all_actions[j][k++] = flow_options[i].mask;
+				break;
+			}
+		}
+		/* Reached last action with no match */
+		if (i >= RTE_DIM(flow_options)) {
+			fprintf(stderr, "Invalid colored actions: %s\n", token);
+			usage(prog);
+			rte_exit(EXIT_SUCCESS, "Invalid colored actions\n");
+		}
+		token = strtok(NULL, ",\0");
+		while (!token && j < RTE_COLORS - 1) {
+			token = strtok(actions_str[++j], ",\0");
+			k = 0;
+		}
+	}
+}
+
 static void
 args_parse(int argc, char **argv)
 {
@@ -253,337 +630,6 @@ args_parse(int argc, char **argv)
 	int opt_idx;
 	size_t i;
 
-	static const struct option_dict {
-		const char *str;
-		const uint64_t mask;
-		uint64_t *map;
-		uint8_t *map_idx;
-
-	} flow_options[] = {
-		{
-			.str = "ether",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ETH),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "ipv4",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "ipv6",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV6),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "vlan",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VLAN),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "tcp",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TCP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "udp",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "vxlan",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "vxlan-gpe",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN_GPE),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "gre",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GRE),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "geneve",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GENEVE),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "gtp",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GTP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "meta",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_META),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "tag",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TAG),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "icmpv4",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "icmpv6",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP6),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "ingress",
-			.mask = INGRESS,
-			.map = &flow_attrs[0],
-			.map_idx = &attrs_idx
-		},
-		{
-			.str = "egress",
-			.mask = EGRESS,
-			.map = &flow_attrs[0],
-			.map_idx = &attrs_idx
-		},
-		{
-			.str = "transfer",
-			.mask = TRANSFER,
-			.map = &flow_attrs[0],
-			.map_idx = &attrs_idx
-		},
-		{
-			.str = "port-id",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_ID),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "rss",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_RSS),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "queue",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_QUEUE),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "jump",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_JUMP),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "mark",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_MARK),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "count",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_COUNT),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-meta",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_META),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-tag",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_TAG),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "drop",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_DROP),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-mac",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_MAC_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-mac",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_MAC_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-ipv4",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-ipv4",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-ipv6",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-ipv6",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-tp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_TP_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-tp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_TP_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "inc-tcp-ack",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_INC_TCP_ACK
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "dec-tcp-ack",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "inc-tcp-seq",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "dec-tcp-seq",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-ttl",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_TTL
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "dec-ttl",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_DEC_TTL
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-ipv4-dscp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-ipv6-dscp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "flag",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_FLAG
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "meter",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_METER
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "vxlan-encap",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "vxlan-decap",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_VXLAN_DECAP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-	};
-
 	static const struct option lgopts[] = {
 		/* Control */
 		{ "help",                       0, 0, 0 },
@@ -660,6 +706,7 @@ args_parse(int argc, char **argv)
 		{ "raw-decap",                  1, 0, 0 },
 		{ "vxlan-encap",                0, 0, 0 },
 		{ "vxlan-decap",                0, 0, 0 },
+		{ "policy-mtr",                 1, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -877,6 +924,8 @@ args_parse(int argc, char **argv)
 						RTE_MAX_LCORE);
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
+				read_meter_policy(argv[0], optarg);
 			break;
 		default:
 			usage(argv[0]);
@@ -981,7 +1030,6 @@ print_rules_batches(double *cpu_time_per_batch)
 	}
 }
 
-
 static inline int
 has_meter(void)
 {
@@ -997,12 +1045,66 @@ has_meter(void)
 	return 0;
 }
 
+static void
+create_meter_policy(void)
+{
+	struct rte_mtr_error error;
+	int ret, port_id;
+	struct rte_mtr_meter_policy_params policy;
+	uint16_t nr_ports;
+	struct rte_flow_action actions[RTE_COLORS][MAX_ACTIONS_NUM];
+	int i;
+
+	memset(actions, 0, sizeof(actions));
+	memset(&policy, 0, sizeof(policy));
+	nr_ports = rte_eth_dev_count_avail();
+	for (port_id = 0; port_id < nr_ports; port_id++) {
+		for (i = 0; i < RTE_COLORS; i++)
+			fill_actions(actions[i], all_actions[i], 0, 0, 0,
+				     0, 0, 0, unique_data, rx_queues_count,
+				     dst_ports[port_id]);
+		policy.actions[RTE_COLOR_GREEN] = actions[RTE_COLOR_GREEN];
+		policy.actions[RTE_COLOR_YELLOW] = actions[RTE_COLOR_YELLOW];
+		policy.actions[RTE_COLOR_RED] = actions[RTE_COLOR_RED];
+		policy_id[port_id] = port_id + 10;
+		ret = rte_mtr_meter_policy_add(port_id, policy_id[port_id],
+					       &policy, &error);
+		if (ret) {
+			fprintf(stderr, "port %d: failed to create meter policy\n",
+				port_id);
+			policy_id[port_id] = UINT32_MAX;
+		}
+		memset(actions, 0, sizeof(actions));
+	}
+}
+
+static void
+destroy_meter_policy(void)
+{
+	struct rte_mtr_error error;
+	uint16_t nr_ports;
+	int port_id;
+
+	nr_ports = rte_eth_dev_count_avail();
+	for (port_id = 0; port_id < nr_ports; port_id++) {
+		/* If port outside portmask */
+		if (!((ports_mask >> port_id) & 0x1))
+			continue;
+
+		if (rte_mtr_meter_policy_delete
+			(port_id, policy_id[port_id], &error)) {
+			fprintf(stderr, "port %u:  failed to  delete meter policy\n",
+				port_id);
+			rte_exit(EXIT_FAILURE, "Error: Failed to delete meter policy.\n");
+		}
+	}
+}
+
 static void
 create_meter_rule(int port_id, uint32_t counter)
 {
 	int ret;
 	struct rte_mtr_params params;
-	uint32_t default_prof_id = 100;
 	struct rte_mtr_error error;
 
 	memset(&params, 0, sizeof(struct rte_mtr_params));
@@ -1012,8 +1114,15 @@ create_meter_rule(int port_id, uint32_t counter)
 	params.dscp_table = NULL;
 
 	/*create meter*/
-	params.meter_profile_id = default_prof_id;
-	ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+	params.meter_profile_id = DEFAULT_METER_PROF_ID;
+
+	if (!policy_mtr) {
+		ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+	} else {
+		params.meter_policy_id = policy_id[port_id];
+		ret = rte_mtr_create(port_id, counter, &params, 0, &error);
+	}
+
 	if (ret != 0) {
 		printf("Port %u create meter idx(%d) error(%d) message: %s\n",
 			port_id, counter, error.type,
@@ -1027,11 +1136,16 @@ destroy_meter_rule(int port_id, uint32_t counter)
 {
 	struct rte_mtr_error error;
 
+	if (policy_mtr && policy_id[port_id] != UINT32_MAX) {
+		if (rte_mtr_meter_policy_delete(port_id, policy_id[port_id],
+					&error))
+			fprintf(stderr, "Error: Failed to delete meter policy\n");
+		policy_id[port_id] = UINT32_MAX;
+	}
 	if (rte_mtr_destroy(port_id, counter, &error)) {
-		printf("Port %u destroy meter(%d) error(%d) message: %s\n",
-			port_id, counter, error.type,
-			error.message ? error.message : "(no stated reason)");
-		rte_exit(EXIT_FAILURE, "Error in deleting meter rule\n");
+		fprintf(stderr, "Port %d: Failed to delete meter.\n",
+				port_id);
+		rte_exit(EXIT_FAILURE, "Error in deleting meter rule");
 	}
 }
 
@@ -1136,12 +1250,10 @@ create_meter_profile(void)
 		/* If port outside portmask */
 		if (!((ports_mask >> port_id) & 0x1))
 			continue;
-
 		mp.alg = RTE_MTR_SRTCM_RFC2697;
 		mp.srtcm_rfc2697.cir = METER_CIR;
 		mp.srtcm_rfc2697.cbs = METER_CIR / 8;
 		mp.srtcm_rfc2697.ebs = 0;
-
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
@@ -2012,16 +2124,22 @@ main(int argc, char **argv)
 
 	rte_srand(rand_seed);
 
-	if (has_meter())
+	if (has_meter()) {
 		create_meter_profile();
+		if (policy_mtr)
+			create_meter_policy();
+	}
 	rte_eal_mp_remote_launch(run_rte_flow_handler_cores, NULL, CALL_MAIN);
 
 	if (enable_fwd) {
 		init_lcore_info();
 		rte_eal_mp_remote_launch(start_forwarding, NULL, CALL_MAIN);
 	}
-	if (has_meter() && delete_flag)
+	if (has_meter() && delete_flag) {
 		destroy_meter_profile();
+		if (policy_mtr)
+			destroy_meter_policy();
+	}
 
 	RTE_ETH_FOREACH_DEV(port) {
 		rte_flow_flush(port, &error);
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 7d986f0158..ec6994e412 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -384,6 +384,10 @@ Actions:
 *	``--vxlan-decap``
 	Add vxlan decap action to all flows actions.
 
-*       ``--meter``
-        Add meter action to all flows actions.
-        Currently, 1 meter profile -> N meter rules -> N rte flows.
+*	``--policy-mtr=<str>``
+	Add policy-mtr to create meter with policy and specify policy actions.
+	Example: policy-mtr=rss,mark::drop
+
+*	``--meter``
+	Add meter action to all flows actions.
+	Currently, 1 meter profile -> N meter rules -> N rte flows.
-- 
2.27.0

[dpdk-dev] [PATCH v8 3/3] app/flow-perf: add packet metering mode

From: Rongwei Liu <hidden>
Date: 2021-11-10 12:58:08

The flow perf application uses the srtcm_rfc2697 as meter profile
while doing the meter testing.

This patch adds new configuration parameter '--packet-mode' to
generate the meter flows with packet cir instead of byte cir.

Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Monther <redacted>
---
 app/test-flow-perf/main.c      | 6 ++++++
 doc/guides/tools/flow-perf.rst | 3 +++
 2 files changed, 9 insertions(+)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 01bfa20db7..2b612aa32c 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -68,6 +68,7 @@ static bool dump_socket_mem_flag;
 static bool enable_fwd;
 static bool unique_data;
 static bool policy_mtr;
+static bool packet_mode;
 
 static uint8_t rx_queues_count;
 static uint8_t tx_queues_count;
@@ -488,6 +489,7 @@ usage(char *progname)
 	printf("  --meter-profile=cir,cbs,ebs: set CIR CBS EBS parameters in meter"
 		" profile, default values are %d,%d,%d\n", METER_CIR,
 		METER_CIR / 8, 0);
+	printf("  --packet-mode: to enable packet mode for meter profile\n");
 
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
@@ -712,6 +714,7 @@ args_parse(int argc, char **argv)
 		{ "vxlan-decap",                0, 0, 0 },
 		{ "policy-mtr",                 1, 0, 0 },
 		{ "meter-profile",              1, 0, 0 },
+		{ "packet-mode",                0, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -942,6 +945,8 @@ args_parse(int argc, char **argv)
 					token = strsep(&optarg, ",\0");
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name, "packet-mode") == 0)
+				packet_mode = true;
 			break;
 		default:
 			usage(argv[0]);
@@ -1272,6 +1277,7 @@ create_meter_profile(void)
 		mp.srtcm_rfc2697.cbs = meter_profile_values[1] ?
 			meter_profile_values[1] : METER_CIR / 8;
 		mp.srtcm_rfc2697.ebs = meter_profile_values[2];
+		mp.packet_mode = packet_mode;
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 3f1e5986e3..41eae15470 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -137,6 +137,9 @@ The command line options are:
 *	``--meter-profile=N1,N2,N3``
 	Set the CIR, CBS and EBS parameters, default values are 1250000, 156250 and 0.
 
+*	``--packet-mode``
+	Enable packet mode for meter profile.
+
 Attributes:
 
 *	``--ingress``
-- 
2.27.0

[PATCH v9 0/5] add meter policy support in flow-perf

From: Rongwei Liu <hidden>
Date: 2021-11-11 14:24:00

Add meter policy support and provide options to specify
green/yellow/red colored actions and cir/cbs/ebs values.

v9: split into more commits.
v8: clean log.
v7: rebase on top of dpdk.org/main and fix existed styles.
v6: rebase on top of main.
v5: fix intermediate werror.
v4: rebase on top of master-net-mlx.
v3: support yellow color action and ebs options.
v2: add option to specify green color actions.

Rongwei Liu (5):
  app/flow-perf: define flow-options as global
  app/flow-perf: support meter policy API
  app/flow-perf: support dynamic values for meter profile
  app/flow-perf: add packet metering mode
  app/flow-perf: fix previous wrong indentation

 app/test-flow-perf/main.c      | 834 +++++++++++++++++++--------------
 doc/guides/tools/flow-perf.rst |  16 +-
 2 files changed, 501 insertions(+), 349 deletions(-)

-- 
2.27.0

[PATCH v9 1/5] app/flow-perf: define flow-options as global

From: Rongwei Liu <hidden>
Date: 2021-11-11 14:24:04

With flow-options defined as global struct, it's possible
to use sub-functions to handle run-time options.

It's helpful to avoid too many tabs warnings.

Signed-off-by: Rongwei Liu <redacted>
---
 app/test-flow-perf/main.c | 662 +++++++++++++++++++-------------------
 1 file changed, 331 insertions(+), 331 deletions(-)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index c1477b14a1..42d13ec495 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -126,6 +126,337 @@ static struct multi_cores_pool mc_pool = {
 	.cores_count = 1,
 };
 
+static const struct option_dict {
+	const char *str;
+	const uint64_t mask;
+	uint64_t *map;
+	uint8_t *map_idx;
+
+} flow_options[] = {
+	{
+		.str = "ether",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ETH),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "ipv4",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "ipv6",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV6),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "vlan",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VLAN),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "tcp",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TCP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "udp",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "vxlan",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "vxlan-gpe",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN_GPE),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "gre",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GRE),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "geneve",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GENEVE),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "gtp",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GTP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "meta",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_META),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "tag",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TAG),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "icmpv4",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "icmpv6",
+		.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP6),
+		.map = &flow_items[0],
+		.map_idx = &items_idx
+	},
+	{
+		.str = "ingress",
+		.mask = INGRESS,
+		.map = &flow_attrs[0],
+		.map_idx = &attrs_idx
+	},
+	{
+		.str = "egress",
+		.mask = EGRESS,
+		.map = &flow_attrs[0],
+		.map_idx = &attrs_idx
+	},
+	{
+		.str = "transfer",
+		.mask = TRANSFER,
+		.map = &flow_attrs[0],
+		.map_idx = &attrs_idx
+	},
+	{
+		.str = "port-id",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_ID),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "rss",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_RSS),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "queue",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_QUEUE),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "jump",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_JUMP),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "mark",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_MARK),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "count",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_COUNT),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-meta",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_META),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-tag",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_TAG),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "drop",
+		.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_DROP),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-mac",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_MAC_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-mac",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_MAC_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-ipv4",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-ipv4",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-ipv6",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-ipv6",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-src-tp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_TP_SRC
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-dst-tp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_TP_DST
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "inc-tcp-ack",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_INC_TCP_ACK
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "dec-tcp-ack",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "inc-tcp-seq",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "dec-tcp-seq",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-ttl",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_TTL
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "dec-ttl",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_DEC_TTL
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-ipv4-dscp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "set-ipv6-dscp",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "flag",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_FLAG
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "meter",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_METER
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "vxlan-encap",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+	{
+		.str = "vxlan-decap",
+		.mask = FLOW_ACTION_MASK(
+			RTE_FLOW_ACTION_TYPE_VXLAN_DECAP
+		),
+		.map = &flow_actions[0],
+		.map_idx = &actions_idx
+	},
+};
+
 static void
 usage(char *progname)
 {
@@ -253,337 +584,6 @@ args_parse(int argc, char **argv)
 	int opt_idx;
 	size_t i;
 
-	static const struct option_dict {
-		const char *str;
-		const uint64_t mask;
-		uint64_t *map;
-		uint8_t *map_idx;
-
-	} flow_options[] = {
-		{
-			.str = "ether",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ETH),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "ipv4",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "ipv6",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV6),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "vlan",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VLAN),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "tcp",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TCP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "udp",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "vxlan",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "vxlan-gpe",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_VXLAN_GPE),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "gre",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GRE),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "geneve",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GENEVE),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "gtp",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_GTP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "meta",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_META),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "tag",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_TAG),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "icmpv4",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "icmpv6",
-			.mask = FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_ICMP6),
-			.map = &flow_items[0],
-			.map_idx = &items_idx
-		},
-		{
-			.str = "ingress",
-			.mask = INGRESS,
-			.map = &flow_attrs[0],
-			.map_idx = &attrs_idx
-		},
-		{
-			.str = "egress",
-			.mask = EGRESS,
-			.map = &flow_attrs[0],
-			.map_idx = &attrs_idx
-		},
-		{
-			.str = "transfer",
-			.mask = TRANSFER,
-			.map = &flow_attrs[0],
-			.map_idx = &attrs_idx
-		},
-		{
-			.str = "port-id",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_PORT_ID),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "rss",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_RSS),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "queue",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_QUEUE),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "jump",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_JUMP),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "mark",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_MARK),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "count",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_COUNT),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-meta",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_META),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-tag",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_SET_TAG),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "drop",
-			.mask = FLOW_ACTION_MASK(RTE_FLOW_ACTION_TYPE_DROP),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-mac",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_MAC_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-mac",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_MAC_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-ipv4",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-ipv4",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV4_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-ipv6",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV6_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-ipv6",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV6_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-src-tp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_TP_SRC
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-dst-tp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_TP_DST
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "inc-tcp-ack",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_INC_TCP_ACK
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "dec-tcp-ack",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "inc-tcp-seq",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "dec-tcp-seq",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-ttl",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_TTL
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "dec-ttl",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_DEC_TTL
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-ipv4-dscp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV4_DSCP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "set-ipv6-dscp",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "flag",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_FLAG
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "meter",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_METER
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "vxlan-encap",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-		{
-			.str = "vxlan-decap",
-			.mask = FLOW_ACTION_MASK(
-				RTE_FLOW_ACTION_TYPE_VXLAN_DECAP
-			),
-			.map = &flow_actions[0],
-			.map_idx = &actions_idx
-		},
-	};
-
 	static const struct option lgopts[] = {
 		/* Control */
 		{ "help",                       0, 0, 0 },
-- 
2.27.0

[PATCH v9 2/5] app/flow-perf: support meter policy API

From: Rongwei Liu <hidden>
Date: 2021-11-11 14:24:11

Add option "policy-mtr" to indicate if meter creation will include policy
or not. Meter creation will keep unchanged without it.

With "policy-mtr", the policy is introduced. API create_meter_policy
is to create a policy. API create_meter_rule will use it to create
a meter. The value of it is used to specify meter policy actions.

Signed-off-by: Haifei Luo <redacted>
Signed-off-by: Jiawei Wang <redacted>
Signed-off-by: Rongwei Liu <redacted>
---
 app/test-flow-perf/main.c      | 142 ++++++++++++++++++++++++++++++---
 doc/guides/tools/flow-perf.rst |   4 +
 2 files changed, 134 insertions(+), 12 deletions(-)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 42d13ec495..89596eb3f6 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -37,6 +37,7 @@
 #include <rte_mtr.h>
 
 #include "config.h"
+#include "actions_gen.h"
 #include "flow_gen.h"
 
 #define MAX_BATCHES_COUNT          100
@@ -49,10 +50,13 @@ static uint8_t flow_group;
 
 static uint64_t encap_data;
 static uint64_t decap_data;
+static uint64_t all_actions[RTE_COLORS][MAX_ACTIONS_NUM];
+static char *actions_str[RTE_COLORS];
 
 static uint64_t flow_items[MAX_ITEMS_NUM];
 static uint64_t flow_actions[MAX_ACTIONS_NUM];
 static uint64_t flow_attrs[MAX_ATTRS_NUM];
+static uint32_t policy_id[MAX_PORTS];
 static uint8_t items_idx, actions_idx, attrs_idx;
 
 static uint64_t ports_mask;
@@ -63,6 +67,7 @@ static bool delete_flag;
 static bool dump_socket_mem_flag;
 static bool enable_fwd;
 static bool unique_data;
+static bool policy_mtr;
 
 static uint8_t rx_queues_count;
 static uint8_t tx_queues_count;
@@ -560,6 +565,8 @@ usage(char *progname)
 		"ipv6 dscp value to be set is random each flow\n");
 	printf("  --flag: add flag action to flow actions\n");
 	printf("  --meter: add meter action to flow actions\n");
+	printf("  --policy-mtr=\"g1,g2:y1:r1\": to create meter with specified "
+		"colored actions\n");
 	printf("  --raw-encap=<data>: add raw encap action to flow actions\n"
 		"Data is the data needed to be encaped\n"
 		"Example: raw-encap=ether,ipv4,udp,vxlan\n");
@@ -572,6 +579,45 @@ usage(char *progname)
 	printf("  --vxlan-decap: add vxlan_decap action to flow actions\n");
 }
 
+static void
+read_meter_policy(char *prog, char *arg)
+{
+	char *token;
+	size_t i, j, k;
+
+	j = 0;
+	k = 0;
+	policy_mtr = true;
+	token = strsep(&arg, ":\0");
+	while (token != NULL && j < RTE_COLORS) {
+		actions_str[j++] = token;
+		token = strsep(&arg, ":\0");
+	}
+	j = 0;
+	token = strtok(actions_str[0], ",\0");
+	while (token == NULL && j < RTE_COLORS - 1)
+		token = strtok(actions_str[++j], ",\0");
+	while (j < RTE_COLORS && token != NULL) {
+		for (i = 0; i < RTE_DIM(flow_options); i++) {
+			if (!strcmp(token, flow_options[i].str)) {
+				all_actions[j][k++] = flow_options[i].mask;
+				break;
+			}
+		}
+		/* Reached last action with no match */
+		if (i >= RTE_DIM(flow_options)) {
+			fprintf(stderr, "Invalid colored actions: %s\n", token);
+			usage(prog);
+			rte_exit(EXIT_SUCCESS, "Invalid colored actions\n");
+		}
+		token = strtok(NULL, ",\0");
+		while (!token && j < RTE_COLORS - 1) {
+			token = strtok(actions_str[++j], ",\0");
+			k = 0;
+		}
+	}
+}
+
 static void
 args_parse(int argc, char **argv)
 {
@@ -660,6 +706,7 @@ args_parse(int argc, char **argv)
 		{ "raw-decap",                  1, 0, 0 },
 		{ "vxlan-encap",                0, 0, 0 },
 		{ "vxlan-decap",                0, 0, 0 },
+		{ "policy-mtr",                 1, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -877,6 +924,8 @@ args_parse(int argc, char **argv)
 						RTE_MAX_LCORE);
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
+				read_meter_policy(argv[0], optarg);
 			break;
 		default:
 			usage(argv[0]);
@@ -981,7 +1030,6 @@ print_rules_batches(double *cpu_time_per_batch)
 	}
 }
 
-
 static inline int
 has_meter(void)
 {
@@ -997,12 +1045,66 @@ has_meter(void)
 	return 0;
 }
 
+static void
+create_meter_policy(void)
+{
+	struct rte_mtr_error error;
+	int ret, port_id;
+	struct rte_mtr_meter_policy_params policy;
+	uint16_t nr_ports;
+	struct rte_flow_action actions[RTE_COLORS][MAX_ACTIONS_NUM];
+	int i;
+
+	memset(actions, 0, sizeof(actions));
+	memset(&policy, 0, sizeof(policy));
+	nr_ports = rte_eth_dev_count_avail();
+	for (port_id = 0; port_id < nr_ports; port_id++) {
+		for (i = 0; i < RTE_COLORS; i++)
+			fill_actions(actions[i], all_actions[i], 0, 0, 0,
+				     0, 0, 0, unique_data, rx_queues_count,
+				     dst_ports[port_id]);
+		policy.actions[RTE_COLOR_GREEN] = actions[RTE_COLOR_GREEN];
+		policy.actions[RTE_COLOR_YELLOW] = actions[RTE_COLOR_YELLOW];
+		policy.actions[RTE_COLOR_RED] = actions[RTE_COLOR_RED];
+		policy_id[port_id] = port_id + 10;
+		ret = rte_mtr_meter_policy_add(port_id, policy_id[port_id],
+					       &policy, &error);
+		if (ret) {
+			fprintf(stderr, "port %d: failed to create meter policy\n",
+				port_id);
+			policy_id[port_id] = UINT32_MAX;
+		}
+		memset(actions, 0, sizeof(actions));
+	}
+}
+
+static void
+destroy_meter_policy(void)
+{
+	struct rte_mtr_error error;
+	uint16_t nr_ports;
+	int port_id;
+
+	nr_ports = rte_eth_dev_count_avail();
+	for (port_id = 0; port_id < nr_ports; port_id++) {
+		/* If port outside portmask */
+		if (!((ports_mask >> port_id) & 0x1))
+			continue;
+
+		if (rte_mtr_meter_policy_delete
+			(port_id, policy_id[port_id], &error)) {
+			fprintf(stderr, "port %u:  failed to  delete meter policy\n",
+				port_id);
+			rte_exit(EXIT_FAILURE, "Error: Failed to delete meter policy.\n");
+		}
+	}
+}
+
 static void
 create_meter_rule(int port_id, uint32_t counter)
 {
 	int ret;
 	struct rte_mtr_params params;
-	uint32_t default_prof_id = 100;
 	struct rte_mtr_error error;
 
 	memset(&params, 0, sizeof(struct rte_mtr_params));
@@ -1012,8 +1114,15 @@ create_meter_rule(int port_id, uint32_t counter)
 	params.dscp_table = NULL;
 
 	/*create meter*/
-	params.meter_profile_id = default_prof_id;
-	ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+	params.meter_profile_id = DEFAULT_METER_PROF_ID;
+
+	if (!policy_mtr) {
+		ret = rte_mtr_create(port_id, counter, &params, 1, &error);
+	} else {
+		params.meter_policy_id = policy_id[port_id];
+		ret = rte_mtr_create(port_id, counter, &params, 0, &error);
+	}
+
 	if (ret != 0) {
 		printf("Port %u create meter idx(%d) error(%d) message: %s\n",
 			port_id, counter, error.type,
@@ -1027,11 +1136,16 @@ destroy_meter_rule(int port_id, uint32_t counter)
 {
 	struct rte_mtr_error error;
 
+	if (policy_mtr && policy_id[port_id] != UINT32_MAX) {
+		if (rte_mtr_meter_policy_delete(port_id, policy_id[port_id],
+					&error))
+			fprintf(stderr, "Error: Failed to delete meter policy\n");
+		policy_id[port_id] = UINT32_MAX;
+	}
 	if (rte_mtr_destroy(port_id, counter, &error)) {
-		printf("Port %u destroy meter(%d) error(%d) message: %s\n",
-			port_id, counter, error.type,
-			error.message ? error.message : "(no stated reason)");
-		rte_exit(EXIT_FAILURE, "Error in deleting meter rule\n");
+		fprintf(stderr, "Port %d: Failed to delete meter.\n",
+				port_id);
+		rte_exit(EXIT_FAILURE, "Error in deleting meter rule");
 	}
 }
 
@@ -1136,12 +1250,10 @@ create_meter_profile(void)
 		/* If port outside portmask */
 		if (!((ports_mask >> port_id) & 0x1))
 			continue;
-
 		mp.alg = RTE_MTR_SRTCM_RFC2697;
 		mp.srtcm_rfc2697.cir = METER_CIR;
 		mp.srtcm_rfc2697.cbs = METER_CIR / 8;
 		mp.srtcm_rfc2697.ebs = 0;
-
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
@@ -2012,16 +2124,22 @@ main(int argc, char **argv)
 
 	rte_srand(rand_seed);
 
-	if (has_meter())
+	if (has_meter()) {
 		create_meter_profile();
+		if (policy_mtr)
+			create_meter_policy();
+	}
 	rte_eal_mp_remote_launch(run_rte_flow_handler_cores, NULL, CALL_MAIN);
 
 	if (enable_fwd) {
 		init_lcore_info();
 		rte_eal_mp_remote_launch(start_forwarding, NULL, CALL_MAIN);
 	}
-	if (has_meter() && delete_flag)
+	if (has_meter() && delete_flag) {
 		destroy_meter_profile();
+		if (policy_mtr)
+			destroy_meter_policy();
+	}
 
 	RTE_ETH_FOREACH_DEV(port) {
 		rte_flow_flush(port, &error);
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 7d986f0158..e4083f053e 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -384,6 +384,10 @@ Actions:
 *	``--vxlan-decap``
 	Add vxlan decap action to all flows actions.
 
+*	``--policy-mtr=<str>``
+	Add policy-mtr to create meter with policy and specify policy actions.
+	Example: policy-mtr=rss,mark::drop
+
 *       ``--meter``
         Add meter action to all flows actions.
         Currently, 1 meter profile -> N meter rules -> N rte flows.
-- 
2.27.0

[PATCH v9 3/5] app/flow-perf: support dynamic values for meter profile

From: Rongwei Liu <hidden>
Date: 2021-11-11 14:24:21

Change meter-cir option to meter-profile to cover user input for CIR,
CBS & EBS values.

The usage is as below:
--meter-profile=N1,N2,N3 default value is 1250000 156250 0.

Signed-off-by: Rongwei Liu <redacted>
---
 app/test-flow-perf/main.c      | 24 +++++++++++++++++++++---
 doc/guides/tools/flow-perf.rst |  3 +++
 2 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 89596eb3f6..01bfa20db7 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -85,6 +85,7 @@ static uint32_t hairpin_queues_num; /* total hairpin q number - default: 0 */
 static uint32_t nb_lcores;
 static uint8_t max_priority;
 static uint32_t rand_seed;
+static uint64_t meter_profile_values[3]; /* CIR CBS EBS values. */
 
 #define MAX_PKT_BURST    32
 #define LCORE_MODE_PKT    1
@@ -484,6 +485,9 @@ usage(char *progname)
 		"and S as seed for pseudo-random number generator\n");
 	printf("  --unique-data: flag to set using unique data for all"
 		" actions that support data, such as header modify and encap actions\n");
+	printf("  --meter-profile=cir,cbs,ebs: set CIR CBS EBS parameters in meter"
+		" profile, default values are %d,%d,%d\n", METER_CIR,
+		METER_CIR / 8, 0);
 
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
@@ -707,6 +711,7 @@ args_parse(int argc, char **argv)
 		{ "vxlan-encap",                0, 0, 0 },
 		{ "vxlan-decap",                0, 0, 0 },
 		{ "policy-mtr",                 1, 0, 0 },
+		{ "meter-profile",              1, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -926,6 +931,17 @@ args_parse(int argc, char **argv)
 			}
 			if (strcmp(lgopts[opt_idx].name, "policy-mtr") == 0)
 				read_meter_policy(argv[0], optarg);
+			if (strcmp(lgopts[opt_idx].name,
+						"meter-profile") == 0) {
+				i = 0;
+				token = strsep(&optarg, ",\0");
+				while (token != NULL && i < sizeof(
+						meter_profile_values) /
+						sizeof(uint64_t)) {
+					meter_profile_values[i++] = atol(token);
+					token = strsep(&optarg, ",\0");
+				}
+			}
 			break;
 		default:
 			usage(argv[0]);
@@ -1251,9 +1267,11 @@ create_meter_profile(void)
 		if (!((ports_mask >> port_id) & 0x1))
 			continue;
 		mp.alg = RTE_MTR_SRTCM_RFC2697;
-		mp.srtcm_rfc2697.cir = METER_CIR;
-		mp.srtcm_rfc2697.cbs = METER_CIR / 8;
-		mp.srtcm_rfc2697.ebs = 0;
+		mp.srtcm_rfc2697.cir = meter_profile_values[0] ?
+			meter_profile_values[0] : METER_CIR;
+		mp.srtcm_rfc2697.cbs = meter_profile_values[1] ?
+			meter_profile_values[1] : METER_CIR / 8;
+		mp.srtcm_rfc2697.ebs = meter_profile_values[2];
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index e4083f053e..24f0fefcd8 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -134,6 +134,9 @@ The command line options are:
 *	``--total-mbuf-count=N``
 	Set the count of total mbuf number, default count is 32000.
 
+*	``--meter-profile=N1,N2,N3``
+	Set the CIR, CBS and EBS parameters, default values are 1250000, 156250 and 0.
+
 Attributes:
 
 *	``--ingress``
-- 
2.27.0

[PATCH v9 4/5] app/flow-perf: add packet metering mode

From: Rongwei Liu <hidden>
Date: 2021-11-11 14:24:29

The flow perf application uses the srtcm_rfc2697 as meter profile
while doing the meter testing.

This patch adds new configuration parameter '--packet-mode' to
generate the meter flows with packet cir instead of byte cir.

Signed-off-by: Rongwei Liu <redacted>
---
 app/test-flow-perf/main.c      | 6 ++++++
 doc/guides/tools/flow-perf.rst | 3 +++
 2 files changed, 9 insertions(+)
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 01bfa20db7..2b612aa32c 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -68,6 +68,7 @@ static bool dump_socket_mem_flag;
 static bool enable_fwd;
 static bool unique_data;
 static bool policy_mtr;
+static bool packet_mode;
 
 static uint8_t rx_queues_count;
 static uint8_t tx_queues_count;
@@ -488,6 +489,7 @@ usage(char *progname)
 	printf("  --meter-profile=cir,cbs,ebs: set CIR CBS EBS parameters in meter"
 		" profile, default values are %d,%d,%d\n", METER_CIR,
 		METER_CIR / 8, 0);
+	printf("  --packet-mode: to enable packet mode for meter profile\n");
 
 	printf("To set flow attributes:\n");
 	printf("  --ingress: set ingress attribute in flows\n");
@@ -712,6 +714,7 @@ args_parse(int argc, char **argv)
 		{ "vxlan-decap",                0, 0, 0 },
 		{ "policy-mtr",                 1, 0, 0 },
 		{ "meter-profile",              1, 0, 0 },
+		{ "packet-mode",                0, 0, 0 },
 	};
 
 	RTE_ETH_FOREACH_DEV(i)
@@ -942,6 +945,8 @@ args_parse(int argc, char **argv)
 					token = strsep(&optarg, ",\0");
 				}
 			}
+			if (strcmp(lgopts[opt_idx].name, "packet-mode") == 0)
+				packet_mode = true;
 			break;
 		default:
 			usage(argv[0]);
@@ -1272,6 +1277,7 @@ create_meter_profile(void)
 		mp.srtcm_rfc2697.cbs = meter_profile_values[1] ?
 			meter_profile_values[1] : METER_CIR / 8;
 		mp.srtcm_rfc2697.ebs = meter_profile_values[2];
+		mp.packet_mode = packet_mode;
 		ret = rte_mtr_meter_profile_add
 			(port_id, DEFAULT_METER_PROF_ID, &mp, &error);
 		if (ret != 0) {
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 24f0fefcd8..0176e9c5cb 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -137,6 +137,9 @@ The command line options are:
 *	``--meter-profile=N1,N2,N3``
 	Set the CIR, CBS and EBS parameters, default values are 1250000, 156250 and 0.
 
+*	``--packet-mode``
+	Enable packet mode for meter profile.
+
 Attributes:
 
 *	``--ingress``
-- 
2.27.0

[PATCH v9 5/5] app/flow-perf: fix previous wrong indentation

From: Rongwei Liu <hidden>
Date: 2021-11-11 14:24:36

--meter section used wrong indentation previously.

Fixes: 6a2cf58a045f ("app/flow-perf: support meter action")
Cc: <redacted>
Cc: <redacted>

Signed-off-by: Rongwei Liu <redacted>
---
 doc/guides/tools/flow-perf.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 0176e9c5cb..41eae15470 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -394,6 +394,6 @@ Actions:
 	Add policy-mtr to create meter with policy and specify policy actions.
 	Example: policy-mtr=rss,mark::drop
 
-*       ``--meter``
-        Add meter action to all flows actions.
-        Currently, 1 meter profile -> N meter rules -> N rte flows.
+*	``--meter``
+	Add meter action to all flows actions.
+	Currently, 1 meter profile -> N meter rules -> N rte flows.
-- 
2.27.0

RE: [PATCH v9 1/5] app/flow-perf: define flow-options as global

From: Wisam Monther <hidden>
Date: 2021-11-16 10:05:07

Hi,

-----Original Message-----
From: Rongwei Liu <redacted>
Sent: Thursday, November 11, 2021 4:24 PM
To: Matan Azrad <redacted>; Slava Ovsiienko
[off-list ref]; Ori Kam [off-list ref]; NBU-Contact-
Thomas Monjalon [off-list ref]; Wisam Monther
[off-list ref]
Cc: <redacted>; Raslan Darawsheh <redacted>
Subject: [PATCH v9 1/5] app/flow-perf: define flow-options as global

With flow-options defined as global struct, it's possible to use sub-functions
to handle run-time options.

It's helpful to avoid too many tabs warnings.

Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Jaddo <redacted>

BRs,
Wisam Jaddo

RE: [PATCH v9 2/5] app/flow-perf: support meter policy API

From: Wisam Monther <hidden>
Date: 2021-11-16 10:05:12

Hi,
-----Original Message-----
From: Rongwei Liu <redacted>
Sent: Thursday, November 11, 2021 4:24 PM
To: Matan Azrad <redacted>; Slava Ovsiienko
[off-list ref]; Ori Kam [off-list ref]; NBU-Contact-
Thomas Monjalon [off-list ref]; Wisam Monther
[off-list ref]
Cc: <redacted>; Raslan Darawsheh <redacted>; Haifei Luo
[off-list ref]; Jiawei(Jonny) Wang [off-list ref]
Subject: [PATCH v9 2/5] app/flow-perf: support meter policy API

Add option "policy-mtr" to indicate if meter creation will include policy or not.
Meter creation will keep unchanged without it.

With "policy-mtr", the policy is introduced. API create_meter_policy is to
create a policy. API create_meter_rule will use it to create a meter. The value
of it is used to specify meter policy actions.

Signed-off-by: Haifei Luo <redacted>
Signed-off-by: Jiawei Wang <redacted>
Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Jaddo <redacted>

BRs,
Wisam Jaddo

RE: [PATCH v9 3/5] app/flow-perf: support dynamic values for meter profile

From: Wisam Monther <hidden>
Date: 2021-11-16 10:05:18

Hi,
-----Original Message-----
From: Rongwei Liu <redacted>
Sent: Thursday, November 11, 2021 4:24 PM
To: Matan Azrad <redacted>; Slava Ovsiienko
[off-list ref]; Ori Kam [off-list ref]; NBU-Contact-
Thomas Monjalon [off-list ref]; Wisam Monther
[off-list ref]
Cc: <redacted>; Raslan Darawsheh <redacted>
Subject: [PATCH v9 3/5] app/flow-perf: support dynamic values for meter
profile

Change meter-cir option to meter-profile to cover user input for CIR, CBS &
EBS values.

The usage is as below:
--meter-profile=N1,N2,N3 default value is 1250000 156250 0.

Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Jaddo <redacted>

BRs,
Wisam Jaddo

RE: [PATCH v9 4/5] app/flow-perf: add packet metering mode

From: Wisam Monther <hidden>
Date: 2021-11-16 10:05:25

Hi,
-----Original Message-----
From: Rongwei Liu <redacted>
Sent: Thursday, November 11, 2021 4:24 PM
To: Matan Azrad <redacted>; Slava Ovsiienko
[off-list ref]; Ori Kam [off-list ref]; NBU-Contact-
Thomas Monjalon [off-list ref]; Wisam Monther
[off-list ref]
Cc: <redacted>; Raslan Darawsheh <redacted>
Subject: [PATCH v9 4/5] app/flow-perf: add packet metering mode

The flow perf application uses the srtcm_rfc2697 as meter profile while doing
the meter testing.

This patch adds new configuration parameter '--packet-mode' to generate
the meter flows with packet cir instead of byte cir.

Signed-off-by: Rongwei Liu <redacted>
Acked-by: Wisam Jaddo <redacted>

BRs,
Wisam Jaddo

RE: [PATCH v9 5/5] app/flow-perf: fix previous wrong indentation

From: Wisam Monther <hidden>
Date: 2021-11-16 10:05:31

Hi,
-----Original Message-----
From: Rongwei Liu <redacted>
Sent: Thursday, November 11, 2021 4:24 PM
To: Matan Azrad <redacted>; Slava Ovsiienko
[off-list ref]; Ori Kam [off-list ref]; NBU-Contact-
Thomas Monjalon [off-list ref]; Wisam Monther
[off-list ref]; Bill Zhou [off-list ref]; Alexander
Kozyrev [off-list ref]
Cc: <redacted>; Raslan Darawsheh <redacted>;
stable@dpdk.org
Subject: [PATCH v9 5/5] app/flow-perf: fix previous wrong indentation
fix previous wrong indentation -> Fix meter doc indentation
--meter section used wrong indentation previously.
Remove the  -- from the body.
quoted hunk
Fixes: 6a2cf58a045f ("app/flow-perf: support meter action")
Cc: <redacted>
Cc: <redacted>

Signed-off-by: Rongwei Liu <redacted>
---
 doc/guides/tools/flow-perf.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 0176e9c5cb..41eae15470 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -394,6 +394,6 @@ Actions:
 	Add policy-mtr to create meter with policy and specify policy actions.
 	Example: policy-mtr=rss,mark::drop

-*       ``--meter``
-        Add meter action to all flows actions.
-        Currently, 1 meter profile -> N meter rules -> N rte flows.
+*	``--meter``
+	Add meter action to all flows actions.
+	Currently, 1 meter profile -> N meter rules -> N rte flows.
--
2.27.0

RE: [PATCH v9 5/5] app/flow-perf: fix previous wrong indentation

From: Rongwei Liu <hidden>
Date: 2021-11-16 10:07:53

Hi,
quoted
-----Original Message-----
From: Rongwei Liu <redacted>
Sent: Thursday, November 11, 2021 4:24 PM
To: Matan Azrad <redacted>; Slava Ovsiienko
[off-list ref]; Ori Kam [off-list ref]; NBU-Contact-
Thomas Monjalon [off-list ref]; Wisam Monther
[off-list ref]; Bill Zhou [off-list ref]; Alexander
Kozyrev [off-list ref]
Cc: <redacted>; Raslan Darawsheh <redacted>;
stable@dpdk.org
Subject: [PATCH v9 5/5] app/flow-perf: fix previous wrong indentation
fix previous wrong indentation -> Fix meter doc indentation
quoted
--meter section used wrong indentation previously.
Remove the  -- from the body.
Please let me know if v10  needed or we can handle this change when merging?
quoted
Fixes: 6a2cf58a045f ("app/flow-perf: support meter action")
Cc: <redacted>
Cc: <redacted>

Signed-off-by: Rongwei Liu <redacted>
---
 doc/guides/tools/flow-perf.rst | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/doc/guides/tools/flow-perf.rst
b/doc/guides/tools/flow-perf.rst index 0176e9c5cb..41eae15470 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -394,6 +394,6 @@ Actions:
 	Add policy-mtr to create meter with policy and specify policy actions.
 	Example: policy-mtr=rss,mark::drop

-*       ``--meter``
-        Add meter action to all flows actions.
-        Currently, 1 meter profile -> N meter rules -> N rte flows.
+*	``--meter``
+	Add meter action to all flows actions.
+	Currently, 1 meter profile -> N meter rules -> N rte flows.
--
2.27.0

Re: [PATCH v9 0/5] add meter policy support in flow-perf

From: Thomas Monjalon <hidden>
Date: 2021-11-16 11:34:06

11/11/2021 15:23, Rongwei Liu:
Add meter policy support and provide options to specify
green/yellow/red colored actions and cir/cbs/ebs values.

v9: split into more commits.
v8: clean log.
v7: rebase on top of dpdk.org/main and fix existed styles.
v6: rebase on top of main.
v5: fix intermediate werror.
v4: rebase on top of master-net-mlx.
v3: support yellow color action and ebs options.
v2: add option to specify green color actions.

Rongwei Liu (5):
  app/flow-perf: define flow-options as global
  app/flow-perf: support meter policy API
  app/flow-perf: support dynamic values for meter profile
  app/flow-perf: add packet metering mode
  app/flow-perf: fix previous wrong indentation
Applied, thanks.


Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help