DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 01/12] examples/ip_pipeline: add rule list per table
@ 2018-11-02 11:36 Cristian Dumitrescu
  2018-11-02 11:36 ` [dpdk-dev] [PATCH 02/12] examples/ip_pipeline: track table rules on add Cristian Dumitrescu
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: Cristian Dumitrescu @ 2018-11-02 11:36 UTC (permalink / raw)
  To: dev; +Cc: Jasvinder Singh, Hongjun Ni

For each pipeline table, have the master thread maintain the list of
rules that are currently stored in the table. This list allows the
master thread to handle table queries with minimal impact for the
data plane threads: requests to read the current set of table rules
are fully handled by the master thread with no involvement from
data plane threads, requests to read the per table rule moving data
(such as stats counters or timestamp associated with specific
actions) are handled by the data plane threads through plain memory
reads rather than key lookup.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Signed-off-by: Hongjun Ni <hongjun.ni@intel.com>
---
 examples/ip_pipeline/pipeline.c | 88 +++++++++++++++++++++++++++++++++++++++++
 examples/ip_pipeline/pipeline.h | 36 +++++++++++++++++
 2 files changed, 124 insertions(+)

diff --git a/examples/ip_pipeline/pipeline.c b/examples/ip_pipeline/pipeline.c
index b23d6c0..78d590d 100644
--- a/examples/ip_pipeline/pipeline.c
+++ b/examples/ip_pipeline/pipeline.c
@@ -1041,7 +1041,95 @@ pipeline_table_create(const char *pipeline_name,
 	memcpy(&table->params, params, sizeof(*params));
 	table->ap = ap;
 	table->a = action;
+	TAILQ_INIT(&table->rules);
+	table->rule_default = NULL;
+
 	pipeline->n_tables++;
 
 	return 0;
 }
+
+struct table_rule *
+table_rule_find(struct table *table,
+    struct table_rule_match *match)
+{
+	struct table_rule *rule;
+
+	TAILQ_FOREACH(rule, &table->rules, node)
+		if (memcmp(&rule->match, match, sizeof(*match)) == 0)
+			return rule;
+
+	return NULL;
+}
+
+void
+table_rule_add(struct table *table,
+    struct table_rule *new_rule)
+{
+	struct table_rule *existing_rule;
+
+	existing_rule = table_rule_find(table, &new_rule->match);
+	if (existing_rule == NULL)
+		TAILQ_INSERT_TAIL(&table->rules, new_rule, node);
+	else {
+		TAILQ_INSERT_AFTER(&table->rules, existing_rule, new_rule, node);
+		TAILQ_REMOVE(&table->rules, existing_rule, node);
+		free(existing_rule);
+	}
+}
+
+void
+table_rule_add_bulk(struct table *table,
+    struct table_rule_list *list,
+    uint32_t n_rules)
+{
+	uint32_t i;
+
+	for (i = 0; i < n_rules; i++) {
+		struct table_rule *existing_rule, *new_rule;
+
+		new_rule = TAILQ_FIRST(list);
+		if (new_rule == NULL)
+			break;
+
+		TAILQ_REMOVE(list, new_rule, node);
+
+		existing_rule = table_rule_find(table, &new_rule->match);
+		if (existing_rule == NULL)
+			TAILQ_INSERT_TAIL(&table->rules, new_rule, node);
+		else {
+			TAILQ_INSERT_AFTER(&table->rules, existing_rule, new_rule, node);
+			TAILQ_REMOVE(&table->rules, existing_rule, node);
+			free(existing_rule);
+		}
+	}
+}
+
+void
+table_rule_delete(struct table *table,
+    struct table_rule_match *match)
+{
+	struct table_rule *rule;
+
+	rule = table_rule_find(table, match);
+	if (rule == NULL)
+		return;
+
+	TAILQ_REMOVE(&table->rules, rule, node);
+	free(rule);
+}
+
+void
+table_rule_default_add(struct table *table,
+	struct table_rule *rule)
+{
+	free(table->rule_default);
+	table->rule_default = rule;
+}
+
+void
+table_rule_default_delete(struct table *table)
+{
+	free(table->rule_default);
+	table->rule_default = NULL;
+}
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
index e5b1d5d..2034504 100644
--- a/examples/ip_pipeline/pipeline.h
+++ b/examples/ip_pipeline/pipeline.h
@@ -143,6 +143,10 @@ struct table_params {
 	const char *action_profile_name;
 };
 
+struct table_rule;
+
+TAILQ_HEAD(table_rule_list, table_rule);
+
 struct port_in {
 	struct port_in_params params;
 	struct port_in_action_profile *ap;
@@ -153,6 +157,8 @@ struct table {
 	struct table_params params;
 	struct table_action_profile *ap;
 	struct rte_table_action *a;
+	struct table_rule_list rules;
+	struct table_rule *rule_default;
 };
 
 struct pipeline {
@@ -286,6 +292,13 @@ struct table_rule_action {
 	struct rte_table_action_decap_params decap;
 };
 
+struct table_rule {
+	TAILQ_ENTRY(table_rule) node;
+	struct table_rule_match match;
+	struct table_rule_action action;
+	void *data;
+};
+
 int
 pipeline_port_in_stats_read(const char *pipeline_name,
 	uint32_t port_id,
@@ -380,5 +393,28 @@ pipeline_table_rule_ttl_read(const char *pipeline_name,
 	void *data,
 	struct rte_table_action_ttl_counters *stats,
 	int clear);
+struct table_rule *
+table_rule_find(struct table *table,
+	struct table_rule_match *match);
+
+void
+table_rule_add(struct table *table,
+	struct table_rule *rule);
+
+void
+table_rule_add_bulk(struct table *table,
+	struct table_rule_list *list,
+	uint32_t n_rules);
+
+void
+table_rule_delete(struct table *table,
+	struct table_rule_match *match);
+
+void
+table_rule_default_add(struct table *table,
+	struct table_rule *rule);
+
+void
+table_rule_default_delete(struct table *table);
 
 #endif /* _INCLUDE_PIPELINE_H_ */
-- 
2.7.4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 02/12] examples/ip_pipeline: track table rules on add
  2018-11-02 11:36 [dpdk-dev] [PATCH 01/12] examples/ip_pipeline: add rule list per table Cristian Dumitrescu
@ 2018-11-02 11:36 ` Cristian Dumitrescu
  2018-11-02 11:36 ` [dpdk-dev] [PATCH 03/12] examples/ip_pipeline: track table rules on add bulk Cristian Dumitrescu
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Cristian Dumitrescu @ 2018-11-02 11:36 UTC (permalink / raw)
  To: dev; +Cc: Jasvinder Singh, Hongjun Ni

Support table rule tracking on table rule add operation.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Signed-off-by: Hongjun Ni <hongjun.ni@intel.com>
---
 examples/ip_pipeline/cli.c      |  4 +---
 examples/ip_pipeline/pipeline.h |  3 +--
 examples/ip_pipeline/thread.c   | 45 ++++++++++++++++++++++++++++++-----------
 3 files changed, 35 insertions(+), 17 deletions(-)

diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
index d1e5540..65600b7 100644
--- a/examples/ip_pipeline/cli.c
+++ b/examples/ip_pipeline/cli.c
@@ -4321,7 +4321,6 @@ cmd_pipeline_table_rule_add(char **tokens,
 	struct table_rule_match m;
 	struct table_rule_action a;
 	char *pipeline_name;
-	void *data;
 	uint32_t table_id, t0, n_tokens_parsed;
 	int status;
 
@@ -4379,8 +4378,7 @@ cmd_pipeline_table_rule_add(char **tokens,
 		return;
 	}
 
-	status = pipeline_table_rule_add(pipeline_name, table_id,
-		&m, &a, &data);
+	status = pipeline_table_rule_add(pipeline_name, table_id, &m, &a);
 	if (status) {
 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
 		return;
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
index 2034504..58067ed 100644
--- a/examples/ip_pipeline/pipeline.h
+++ b/examples/ip_pipeline/pipeline.h
@@ -329,8 +329,7 @@ int
 pipeline_table_rule_add(const char *pipeline_name,
 	uint32_t table_id,
 	struct table_rule_match *match,
-	struct table_rule_action *action,
-	void **data);
+	struct table_rule_action *action);
 
 int
 pipeline_table_rule_add_bulk(const char *pipeline_name,
diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
index 4bd971f..5019de9 100644
--- a/examples/ip_pipeline/thread.c
+++ b/examples/ip_pipeline/thread.c
@@ -1210,19 +1210,19 @@ int
 pipeline_table_rule_add(const char *pipeline_name,
 	uint32_t table_id,
 	struct table_rule_match *match,
-	struct table_rule_action *action,
-	void **data)
+	struct table_rule_action *action)
 {
 	struct pipeline *p;
+	struct table *table;
 	struct pipeline_msg_req *req;
 	struct pipeline_msg_rsp *rsp;
+	struct table_rule *rule;
 	int status;
 
 	/* Check input params */
 	if ((pipeline_name == NULL) ||
 		(match == NULL) ||
-		(action == NULL) ||
-		(data == NULL))
+		(action == NULL))
 		return -1;
 
 	p = pipeline_find(pipeline_name);
@@ -1232,16 +1232,26 @@ pipeline_table_rule_add(const char *pipeline_name,
 		action_check(action, p, table_id))
 		return -1;
 
+	table = &p->table[table_id];
+
+	rule = calloc(1, sizeof(struct table_rule));
+	if (rule == NULL)
+		return -1;
+
+	memcpy(&rule->match, match, sizeof(*match));
+	memcpy(&rule->action, action, sizeof(*action));
+
 	if (!pipeline_is_running(p)) {
-		struct rte_table_action *a = p->table[table_id].a;
 		union table_rule_match_low_level match_ll;
 		struct rte_pipeline_table_entry *data_in, *data_out;
 		int key_found;
 		uint8_t *buffer;
 
 		buffer = calloc(TABLE_RULE_ACTION_SIZE_MAX, sizeof(uint8_t));
-		if (buffer == NULL)
+		if (buffer == NULL) {
+			free(rule);
 			return -1;
+		}
 
 		/* Table match-action rule conversion */
 		data_in = (struct rte_pipeline_table_entry *)buffer;
@@ -1249,12 +1259,14 @@ pipeline_table_rule_add(const char *pipeline_name,
 		status = match_convert(match, &match_ll, 1);
 		if (status) {
 			free(buffer);
+			free(rule);
 			return -1;
 		}
 
-		status = action_convert(a, action, data_in);
+		status = action_convert(table->a, action, data_in);
 		if (status) {
 			free(buffer);
+			free(rule);
 			return -1;
 		}
 
@@ -1267,11 +1279,13 @@ pipeline_table_rule_add(const char *pipeline_name,
 				&data_out);
 		if (status) {
 			free(buffer);
+			free(rule);
 			return -1;
 		}
 
 		/* Write Response */
-		*data = data_out;
+		rule->data = data_out;
+		table_rule_add(table, rule);
 
 		free(buffer);
 		return 0;
@@ -1279,8 +1293,10 @@ pipeline_table_rule_add(const char *pipeline_name,
 
 	/* Allocate request */
 	req = pipeline_msg_alloc();
-	if (req == NULL)
+	if (req == NULL) {
+		free(rule);
 		return -1;
+	}
 
 	/* Write request */
 	req->type = PIPELINE_REQ_TABLE_RULE_ADD;
@@ -1290,13 +1306,18 @@ pipeline_table_rule_add(const char *pipeline_name,
 
 	/* Send request and wait for response */
 	rsp = pipeline_msg_send_recv(p, req);
-	if (rsp == NULL)
+	if (rsp == NULL) {
+		free(rule);
 		return -1;
+	}
 
 	/* Read response */
 	status = rsp->status;
-	if (status == 0)
-		*data = rsp->table_rule_add.data;
+	if (status == 0) {
+		rule->data = rsp->table_rule_add.data;
+		table_rule_add(table, rule);
+	} else
+		free(rule);
 
 	/* Free response */
 	pipeline_msg_free(rsp);
-- 
2.7.4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 03/12] examples/ip_pipeline: track table rules on add bulk
  2018-11-02 11:36 [dpdk-dev] [PATCH 01/12] examples/ip_pipeline: add rule list per table Cristian Dumitrescu
  2018-11-02 11:36 ` [dpdk-dev] [PATCH 02/12] examples/ip_pipeline: track table rules on add Cristian Dumitrescu
@ 2018-11-02 11:36 ` Cristian Dumitrescu
  2018-11-02 11:36 ` [dpdk-dev] [PATCH 04/12] examples/ip_pipeline: track rules on add default Cristian Dumitrescu
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Cristian Dumitrescu @ 2018-11-02 11:36 UTC (permalink / raw)
  To: dev; +Cc: Jasvinder Singh

Support table rule tracking on table rule add bulk operation.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 examples/ip_pipeline/cli.c      | 149 +++++++-------
 examples/ip_pipeline/pipeline.h |   7 +-
 examples/ip_pipeline/thread.c   | 429 ++++++++++++++++++++--------------------
 3 files changed, 299 insertions(+), 286 deletions(-)

diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
index 65600b7..5011cad 100644
--- a/examples/ip_pipeline/cli.c
+++ b/examples/ip_pipeline/cli.c
@@ -4523,7 +4523,7 @@ cmd_pipeline_table_rule_add_default(char **tokens,
 
 
 static const char cmd_pipeline_table_rule_add_bulk_help[] =
-"pipeline <pipeline_name> table <table_id> rule add bulk <file_name> <n_rules>\n"
+"pipeline <pipeline_name> table <table_id> rule add bulk <file_name>\n"
 "\n"
 "  File <file_name>:\n"
 "  - line format: match <match> action <action>\n";
@@ -4531,8 +4531,7 @@ static const char cmd_pipeline_table_rule_add_bulk_help[] =
 static int
 cli_rule_file_process(const char *file_name,
 	size_t line_len_max,
-	struct table_rule_match *m,
-	struct table_rule_action *a,
+	struct table_rule_list **rule_list,
 	uint32_t *n_rules,
 	uint32_t *line_number,
 	char *out,
@@ -4544,14 +4543,12 @@ cmd_pipeline_table_rule_add_bulk(char **tokens,
 	char *out,
 	size_t out_size)
 {
-	struct table_rule_match *match;
-	struct table_rule_action *action;
-	void **data;
+	struct table_rule_list *list = NULL;
 	char *pipeline_name, *file_name;
-	uint32_t table_id, n_rules, n_rules_parsed, line_number;
+	uint32_t table_id, n_rules, n_rules_added, n_rules_not_added, line_number;
 	int status;
 
-	if (n_tokens != 9) {
+	if (n_tokens != 8) {
 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
 		return;
 	}
@@ -4585,68 +4582,33 @@ cmd_pipeline_table_rule_add_bulk(char **tokens,
 
 	file_name = tokens[7];
 
-	if ((parser_read_uint32(&n_rules, tokens[8]) != 0) ||
-		(n_rules == 0)) {
-		snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
-		return;
-	}
-
-	/* Memory allocation. */
-	match = calloc(n_rules, sizeof(struct table_rule_match));
-	action = calloc(n_rules, sizeof(struct table_rule_action));
-	data = calloc(n_rules, sizeof(void *));
-	if ((match == NULL) || (action == NULL) || (data == NULL)) {
-		snprintf(out, out_size, MSG_OUT_OF_MEMORY);
-		free(data);
-		free(action);
-		free(match);
-		return;
-	}
-
-	/* Load rule file */
-	n_rules_parsed = n_rules;
+	/* Load rules from file. */
 	status = cli_rule_file_process(file_name,
 		1024,
-		match,
-		action,
-		&n_rules_parsed,
+		&list,
+		&n_rules,
 		&line_number,
 		out,
 		out_size);
 	if (status) {
 		snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
-		free(data);
-		free(action);
-		free(match);
-		return;
-	}
-	if (n_rules_parsed != n_rules) {
-		snprintf(out, out_size, MSG_FILE_NOT_ENOUGH, file_name);
-		free(data);
-		free(action);
-		free(match);
 		return;
 	}
 
 	/* Rule bulk add */
 	status = pipeline_table_rule_add_bulk(pipeline_name,
 		table_id,
-		match,
-		action,
-		data,
-		&n_rules);
+		list,
+		&n_rules_added,
+		&n_rules_not_added);
 	if (status) {
 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
-		free(data);
-		free(action);
-		free(match);
 		return;
 	}
 
-	/* Memory free */
-	free(data);
-	free(action);
-	free(match);
+	snprintf(out, out_size, "Added %u rules out of %u.\n",
+		n_rules_added,
+		n_rules);
 }
 
 
@@ -5950,44 +5912,56 @@ cli_script_process(const char *file_name,
 static int
 cli_rule_file_process(const char *file_name,
 	size_t line_len_max,
-	struct table_rule_match *m,
-	struct table_rule_action *a,
+	struct table_rule_list **rule_list,
 	uint32_t *n_rules,
 	uint32_t *line_number,
 	char *out,
 	size_t out_size)
 {
-	FILE *f = NULL;
+	struct table_rule_list *list = NULL;
 	char *line = NULL;
-	uint32_t rule_id, line_id;
+	FILE *f = NULL;
+	uint32_t rule_id = 0, line_id = 0;
 	int status = 0;
 
 	/* Check input arguments */
 	if ((file_name == NULL) ||
 		(strlen(file_name) == 0) ||
-		(line_len_max == 0)) {
-		*line_number = 0;
-		return -EINVAL;
+		(line_len_max == 0) ||
+		(rule_list == NULL) ||
+		(n_rules == NULL) ||
+		(line_number == NULL) ||
+		(out == NULL)) {
+		status = -EINVAL;
+		goto cli_rule_file_process_free;
 	}
 
 	/* Memory allocation */
+	list = malloc(sizeof(struct table_rule_list));
+	if (list == NULL) {
+		status = -ENOMEM;
+		goto cli_rule_file_process_free;
+	}
+
+	TAILQ_INIT(list);
+
 	line = malloc(line_len_max + 1);
 	if (line == NULL) {
-		*line_number = 0;
-		return -ENOMEM;
+		status = -ENOMEM;
+		goto cli_rule_file_process_free;
 	}
 
 	/* Open file */
 	f = fopen(file_name, "r");
 	if (f == NULL) {
-		*line_number = 0;
-		free(line);
-		return -EIO;
+		status = -EIO;
+		goto cli_rule_file_process_free;
 	}
 
 	/* Read file */
-	for (line_id = 1, rule_id = 0; rule_id < *n_rules; line_id++) {
+	for (line_id = 1, rule_id = 0; ; line_id++) {
 		char *tokens[CMD_MAX_TOKENS];
+		struct table_rule *rule = NULL;
 		uint32_t n_tokens, n_tokens_parsed, t0;
 
 		/* Read next line from file. */
@@ -6003,7 +5977,7 @@ cli_rule_file_process(const char *file_name,
 		status = parse_tokenize_string(line, tokens, &n_tokens);
 		if (status) {
 			status = -EINVAL;
-			break;
+			goto cli_rule_file_process_free;
 		}
 
 		/* Empty line. */
@@ -6011,15 +5985,24 @@ cli_rule_file_process(const char *file_name,
 			continue;
 		t0 = 0;
 
+		/* Rule alloc and insert. */
+		rule = calloc(1, sizeof(struct table_rule));
+		if (rule == NULL) {
+			status = -ENOMEM;
+			goto cli_rule_file_process_free;
+		}
+
+		TAILQ_INSERT_TAIL(list, rule, node);
+
 		/* Rule match. */
 		n_tokens_parsed = parse_match(tokens + t0,
 			n_tokens - t0,
 			out,
 			out_size,
-			&m[rule_id]);
+			&rule->match);
 		if (n_tokens_parsed == 0) {
 			status = -EINVAL;
-			break;
+			goto cli_rule_file_process_free;
 		}
 		t0 += n_tokens_parsed;
 
@@ -6028,17 +6011,17 @@ cli_rule_file_process(const char *file_name,
 			n_tokens - t0,
 			out,
 			out_size,
-			&a[rule_id]);
+			&rule->action);
 		if (n_tokens_parsed == 0) {
 			status = -EINVAL;
-			break;
+			goto cli_rule_file_process_free;
 		}
 		t0 += n_tokens_parsed;
 
 		/* Line completed. */
 		if (t0 < n_tokens) {
 			status = -EINVAL;
-			break;
+			goto cli_rule_file_process_free;
 		}
 
 		/* Increment rule count */
@@ -6051,7 +6034,31 @@ cli_rule_file_process(const char *file_name,
 	/* Memory free */
 	free(line);
 
+	*rule_list = list;
+	*n_rules = rule_id;
+	*line_number = line_id;
+	return 0;
+
+cli_rule_file_process_free:
+	*rule_list = NULL;
 	*n_rules = rule_id;
 	*line_number = line_id;
+
+	for ( ; ; ) {
+		struct table_rule *rule;
+
+		rule = TAILQ_FIRST(list);
+		if (rule == NULL)
+			break;
+
+		TAILQ_REMOVE(list, rule, node);
+		free(rule);
+	}
+
+	if (f)
+		fclose(f);
+	free(line);
+	free(list);
+
 	return status;
 }
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
index 58067ed..8a364a9 100644
--- a/examples/ip_pipeline/pipeline.h
+++ b/examples/ip_pipeline/pipeline.h
@@ -334,10 +334,9 @@ pipeline_table_rule_add(const char *pipeline_name,
 int
 pipeline_table_rule_add_bulk(const char *pipeline_name,
 	uint32_t table_id,
-	struct table_rule_match *match,
-	struct table_rule_action *action,
-	void **data,
-	uint32_t *n_rules);
+	struct table_rule_list *list,
+	uint32_t *n_rules_added,
+	uint32_t *n_rules_not_added);
 
 int
 pipeline_table_rule_add_default(const char *pipeline_name,
diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
index 5019de9..2c0570f 100644
--- a/examples/ip_pipeline/thread.c
+++ b/examples/ip_pipeline/thread.c
@@ -609,10 +609,7 @@ struct pipeline_msg_req_table_rule_add_default {
 };
 
 struct pipeline_msg_req_table_rule_add_bulk {
-	struct table_rule_match *match;
-	struct table_rule_action *action;
-	void **data;
-	uint32_t n_rules;
+	struct table_rule_list *list;
 	int bulk;
 };
 
@@ -1206,6 +1203,128 @@ action_convert(struct rte_table_action *a,
 	struct table_rule_action *action,
 	struct rte_pipeline_table_entry *data);
 
+struct table_ll {
+	struct rte_pipeline *p;
+	int table_id;
+	struct rte_table_action *a;
+	int bulk_supported;
+};
+
+static int
+table_rule_add_bulk_ll(struct table_ll *table,
+	struct table_rule_list *list,
+	uint32_t *n_rules)
+{
+	union table_rule_match_low_level *match_ll = NULL;
+	uint8_t *action_ll = NULL;
+	void **match_ll_ptr = NULL;
+	struct rte_pipeline_table_entry **action_ll_ptr = NULL;
+	struct rte_pipeline_table_entry **entries_ptr = NULL;
+	int *found = NULL;
+	struct table_rule *rule;
+	uint32_t n, i;
+	int status = 0;
+
+	n = 0;
+	TAILQ_FOREACH(rule, list, node)
+		n++;
+
+	/* Memory allocation */
+	match_ll = calloc(n, sizeof(union table_rule_match_low_level));
+	action_ll = calloc(n, TABLE_RULE_ACTION_SIZE_MAX);
+
+	match_ll_ptr = calloc(n, sizeof(void *));
+	action_ll_ptr = calloc(n, sizeof(struct rte_pipeline_table_entry *));
+
+	entries_ptr = calloc(n, sizeof(struct rte_pipeline_table_entry *));
+	found = calloc(n, sizeof(int));
+
+	if (match_ll == NULL ||
+		action_ll == NULL ||
+		match_ll_ptr == NULL ||
+		action_ll_ptr == NULL ||
+		entries_ptr == NULL ||
+		found == NULL) {
+			status = -ENOMEM;
+			goto table_rule_add_bulk_ll_free;
+	}
+
+	/* Init */
+	for (i = 0; i < n; i++) {
+		match_ll_ptr[i] = (void *)&match_ll[i];
+		action_ll_ptr[i] = (struct rte_pipeline_table_entry *)
+			&action_ll[i * TABLE_RULE_ACTION_SIZE_MAX];
+	}
+
+	/* Rule (match, action) conversion */
+	i = 0;
+	TAILQ_FOREACH(rule, list, node) {
+		status = match_convert(&rule->match, match_ll_ptr[i], 1);
+		if (status)
+			goto table_rule_add_bulk_ll_free;
+
+		status = action_convert(table->a, &rule->action, action_ll_ptr[i]);
+		if (status)
+			goto table_rule_add_bulk_ll_free;
+
+		i++;
+	}
+
+	/* Add rule (match, action) to table */
+	if (table->bulk_supported) {
+		status = rte_pipeline_table_entry_add_bulk(table->p,
+			table->table_id,
+			match_ll_ptr,
+			action_ll_ptr,
+			n,
+			found,
+			entries_ptr);
+		if (status)
+			goto table_rule_add_bulk_ll_free;
+	} else
+		for (i = 0; i < n; i++) {
+			status = rte_pipeline_table_entry_add(table->p,
+				table->table_id,
+				match_ll_ptr[i],
+				action_ll_ptr[i],
+				&found[i],
+				&entries_ptr[i]);
+			if (status) {
+				if (i == 0)
+					goto table_rule_add_bulk_ll_free;
+
+				/* No roll-back. */
+				status = 0;
+				n = i;
+				break;
+			}
+		}
+
+	/* Write back to the rule list. */
+	i = 0;
+	TAILQ_FOREACH(rule, list, node) {
+		if (i >= n)
+			break;
+
+		rule->data = entries_ptr[i];
+
+		i++;
+	}
+
+	*n_rules = n;
+
+	/* Free */
+table_rule_add_bulk_ll_free:
+	free(found);
+	free(entries_ptr);
+	free(action_ll_ptr);
+	free(match_ll_ptr);
+	free(action_ll);
+	free(match_ll);
+
+	return status;
+}
+
 int
 pipeline_table_rule_add(const char *pipeline_name,
 	uint32_t table_id,
@@ -1408,156 +1527,119 @@ pipeline_table_rule_add_default(const char *pipeline_name,
 	return status;
 }
 
+static uint32_t
+table_rule_list_free(struct table_rule_list *list)
+{
+	uint32_t n = 0;
+
+	if (!list)
+		return 0;
+
+	for ( ; ; ) {
+		struct table_rule *rule;
+
+		rule = TAILQ_FIRST(list);
+		if (rule == NULL)
+			break;
+
+		TAILQ_REMOVE(list, rule, node);
+		free(rule);
+		n++;
+	}
+
+	free(list);
+	return n;
+}
+
 int
 pipeline_table_rule_add_bulk(const char *pipeline_name,
 	uint32_t table_id,
-	struct table_rule_match *match,
-	struct table_rule_action *action,
-	void **data,
-	uint32_t *n_rules)
+	struct table_rule_list *list,
+	uint32_t *n_rules_added,
+	uint32_t *n_rules_not_added)
 {
 	struct pipeline *p;
+	struct table *table;
 	struct pipeline_msg_req *req;
 	struct pipeline_msg_rsp *rsp;
-	uint32_t i;
-	int status;
+	struct table_rule *rule;
+	int status = 0;
 
 	/* Check input params */
 	if ((pipeline_name == NULL) ||
-		(match == NULL) ||
-		(action == NULL) ||
-		(data == NULL) ||
-		(n_rules == NULL) ||
-		(*n_rules == 0))
-		return -1;
+		(list == NULL) ||
+		TAILQ_EMPTY(list) ||
+		(n_rules_added == NULL) ||
+		(n_rules_not_added == NULL)) {
+		table_rule_list_free(list);
+		return -EINVAL;
+	}
 
 	p = pipeline_find(pipeline_name);
 	if ((p == NULL) ||
-		(table_id >= p->n_tables))
-		return -1;
-
-	for (i = 0; i < *n_rules; i++)
-		if (match_check(match, p, table_id) ||
-			action_check(action, p, table_id))
-			return -1;
-
-	if (!pipeline_is_running(p)) {
-		struct rte_table_action *a = p->table[table_id].a;
-		union table_rule_match_low_level *match_ll;
-		uint8_t *action_ll;
-		void **match_ll_ptr;
-		struct rte_pipeline_table_entry **action_ll_ptr;
-		struct rte_pipeline_table_entry **entries_ptr =
-			(struct rte_pipeline_table_entry **)data;
-		uint32_t bulk =
-			(p->table[table_id].params.match_type == TABLE_ACL) ? 1 : 0;
-		int *found;
-
-		/* Memory allocation */
-		match_ll = calloc(*n_rules, sizeof(union table_rule_match_low_level));
-		action_ll = calloc(*n_rules, TABLE_RULE_ACTION_SIZE_MAX);
-		match_ll_ptr = calloc(*n_rules, sizeof(void *));
-		action_ll_ptr =
-			calloc(*n_rules, sizeof(struct rte_pipeline_table_entry *));
-		found = calloc(*n_rules, sizeof(int));
-
-		if (match_ll == NULL ||
-			action_ll == NULL ||
-			match_ll_ptr == NULL ||
-			action_ll_ptr == NULL ||
-			found == NULL)
-			goto fail;
-
-		for (i = 0; i < *n_rules; i++) {
-			match_ll_ptr[i] = (void *)&match_ll[i];
-			action_ll_ptr[i] =
-				(struct rte_pipeline_table_entry *)&action_ll[i * TABLE_RULE_ACTION_SIZE_MAX];
-		}
+		(table_id >= p->n_tables)) {
+		table_rule_list_free(list);
+		return -EINVAL;
+	}
 
-		/* Rule match conversion */
-		for (i = 0; i < *n_rules; i++) {
-			status = match_convert(&match[i], match_ll_ptr[i], 1);
-			if (status)
-				goto fail;
-		}
+	table = &p->table[table_id];
 
-		/* Rule action conversion */
-		for (i = 0; i < *n_rules; i++) {
-			status = action_convert(a, &action[i], action_ll_ptr[i]);
-			if (status)
-				goto fail;
+	TAILQ_FOREACH(rule, list, node)
+		if (match_check(&rule->match, p, table_id) ||
+			action_check(&rule->action, p, table_id)) {
+			table_rule_list_free(list);
+			return -EINVAL;
 		}
 
-		/* Add rule (match, action) to table */
-		if (bulk) {
-			status = rte_pipeline_table_entry_add_bulk(p->p,
-				table_id,
-				match_ll_ptr,
-				action_ll_ptr,
-				*n_rules,
-				found,
-				entries_ptr);
-			if (status)
-				*n_rules = 0;
-		} else {
-			for (i = 0; i < *n_rules; i++) {
-				status = rte_pipeline_table_entry_add(p->p,
-					table_id,
-					match_ll_ptr[i],
-					action_ll_ptr[i],
-					&found[i],
-					&entries_ptr[i]);
-				if (status) {
-					*n_rules = i;
-					break;
-				}
-			}
+	if (!pipeline_is_running(p)) {
+		struct table_ll table_ll = {
+			.p = p->p,
+			.table_id = table_id,
+			.a = table->a,
+			.bulk_supported = table->params.match_type == TABLE_ACL,
+		};
+
+		status = table_rule_add_bulk_ll(&table_ll, list, n_rules_added);
+		if (status) {
+			table_rule_list_free(list);
+			return status;
 		}
 
-		/* Free */
-		free(found);
-		free(action_ll_ptr);
-		free(match_ll_ptr);
-		free(action_ll);
-		free(match_ll);
-
-		return status;
-
-fail:
-		free(found);
-		free(action_ll_ptr);
-		free(match_ll_ptr);
-		free(action_ll);
-		free(match_ll);
-
-		*n_rules = 0;
-		return -1;
+		table_rule_add_bulk(table, list, *n_rules_added);
+		*n_rules_not_added = table_rule_list_free(list);
+		return 0;
 	}
 
 	/* Allocate request */
 	req = pipeline_msg_alloc();
-	if (req == NULL)
-		return -1;
+	if (req == NULL) {
+		table_rule_list_free(list);
+		return -ENOMEM;
+	}
 
 	/* Write request */
 	req->type = PIPELINE_REQ_TABLE_RULE_ADD_BULK;
 	req->id = table_id;
-	req->table_rule_add_bulk.match = match;
-	req->table_rule_add_bulk.action = action;
-	req->table_rule_add_bulk.data = data;
-	req->table_rule_add_bulk.n_rules = *n_rules;
-	req->table_rule_add_bulk.bulk =
-		(p->table[table_id].params.match_type == TABLE_ACL) ? 1 : 0;
+	req->table_rule_add_bulk.list = list;
+	req->table_rule_add_bulk.bulk = table->params.match_type == TABLE_ACL;
 
 	/* Send request and wait for response */
 	rsp = pipeline_msg_send_recv(p, req);
-	if (rsp == NULL)
-		return -1;
+	if (rsp == NULL) {
+		table_rule_list_free(list);
+		return -ENOMEM;
+	}
 
 	/* Read response */
 	status = rsp->status;
-	if (status == 0)
-		*n_rules = rsp->table_rule_add_bulk.n_rules;
+	if (status == 0) {
+		*n_rules_added = rsp->table_rule_add_bulk.n_rules;
+
+		table_rule_add_bulk(table, list, *n_rules_added);
+		*n_rules_not_added = table_rule_list_free(list);
+	} else
+		table_rule_list_free(list);
+
 
 	/* Free response */
 	pipeline_msg_free(rsp);
@@ -2626,107 +2708,32 @@ static struct pipeline_msg_rsp *
 pipeline_msg_handle_table_rule_add_bulk(struct pipeline_data *p,
 	struct pipeline_msg_req *req)
 {
-
 	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
 
 	uint32_t table_id = req->id;
-	struct table_rule_match *match = req->table_rule_add_bulk.match;
-	struct table_rule_action *action = req->table_rule_add_bulk.action;
-	struct rte_pipeline_table_entry **data =
-		(struct rte_pipeline_table_entry **)req->table_rule_add_bulk.data;
-	uint32_t n_rules = req->table_rule_add_bulk.n_rules;
+	struct table_rule_list *list = req->table_rule_add_bulk.list;
 	uint32_t bulk = req->table_rule_add_bulk.bulk;
 
-	struct rte_table_action *a = p->table_data[table_id].a;
-	union table_rule_match_low_level *match_ll;
-	uint8_t *action_ll;
-	void **match_ll_ptr;
-	struct rte_pipeline_table_entry **action_ll_ptr;
-	int *found, status;
-	uint32_t i;
-
-	/* Memory allocation */
-	match_ll = calloc(n_rules, sizeof(union table_rule_match_low_level));
-	action_ll = calloc(n_rules, TABLE_RULE_ACTION_SIZE_MAX);
-	match_ll_ptr = calloc(n_rules, sizeof(void *));
-	action_ll_ptr =
-		calloc(n_rules, sizeof(struct rte_pipeline_table_entry *));
-	found = calloc(n_rules, sizeof(int));
-
-	if ((match_ll == NULL) ||
-		(action_ll == NULL) ||
-		(match_ll_ptr == NULL) ||
-		(action_ll_ptr == NULL) ||
-		(found == NULL))
-		goto fail;
-
-	for (i = 0; i < n_rules; i++) {
-		match_ll_ptr[i] = (void *)&match_ll[i];
-		action_ll_ptr[i] =
-			(struct rte_pipeline_table_entry *)&action_ll[i * TABLE_RULE_ACTION_SIZE_MAX];
-	}
+	uint32_t n_rules_added;
+	int status;
 
-	/* Rule match conversion */
-	for (i = 0; i < n_rules; i++) {
-		status = match_convert(&match[i], match_ll_ptr[i], 1);
-		if (status)
-			goto fail;
-	}
+	struct table_ll table_ll = {
+		.p = p->p,
+		.table_id = table_id,
+		.a = p->table_data[table_id].a,
+		.bulk_supported = bulk,
+	};
 
-	/* Rule action conversion */
-	for (i = 0; i < n_rules; i++) {
-		status = action_convert(a, &action[i], action_ll_ptr[i]);
-		if (status)
-			goto fail;
+	status = table_rule_add_bulk_ll(&table_ll, list, &n_rules_added);
+	if (status) {
+		rsp->status = -1;
+		rsp->table_rule_add_bulk.n_rules = 0;
+		return rsp;
 	}
 
-	/* Add rule (match, action) to table */
-	if (bulk) {
-		status = rte_pipeline_table_entry_add_bulk(p->p,
-			table_id,
-			match_ll_ptr,
-			action_ll_ptr,
-			n_rules,
-			found,
-			data);
-		if (status)
-			n_rules = 0;
-	} else
-		for (i = 0; i < n_rules; i++) {
-			status = rte_pipeline_table_entry_add(p->p,
-				table_id,
-				match_ll_ptr[i],
-				action_ll_ptr[i],
-				&found[i],
-				&data[i]);
-			if (status) {
-				n_rules = i;
-				break;
-			}
-		}
-
 	/* Write response */
 	rsp->status = 0;
-	rsp->table_rule_add_bulk.n_rules = n_rules;
-
-	/* Free */
-	free(found);
-	free(action_ll_ptr);
-	free(match_ll_ptr);
-	free(action_ll);
-	free(match_ll);
-
-	return rsp;
-
-fail:
-	free(found);
-	free(action_ll_ptr);
-	free(match_ll_ptr);
-	free(action_ll);
-	free(match_ll);
-
-	rsp->status = -1;
-	rsp->table_rule_add_bulk.n_rules = 0;
+	rsp->table_rule_add_bulk.n_rules = n_rules_added;
 	return rsp;
 }
 
-- 
2.7.4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 04/12] examples/ip_pipeline: track rules on add default
  2018-11-02 11:36 [dpdk-dev] [PATCH 01/12] examples/ip_pipeline: add rule list per table Cristian Dumitrescu
  2018-11-02 11:36 ` [dpdk-dev] [PATCH 02/12] examples/ip_pipeline: track table rules on add Cristian Dumitrescu
  2018-11-02 11:36 ` [dpdk-dev] [PATCH 03/12] examples/ip_pipeline: track table rules on add bulk Cristian Dumitrescu
@ 2018-11-02 11:36 ` Cristian Dumitrescu
  2018-11-02 11:36 ` [dpdk-dev] [PATCH 05/12] examples/ip_pipeline: track table rules on delete Cristian Dumitrescu
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Cristian Dumitrescu @ 2018-11-02 11:36 UTC (permalink / raw)
  To: dev; +Cc: Jasvinder Singh

Support table rule tracking on table rule add default operation.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 examples/ip_pipeline/cli.c      |  4 +---
 examples/ip_pipeline/pipeline.h |  3 +--
 examples/ip_pipeline/thread.c   | 39 +++++++++++++++++++++++++++++----------
 3 files changed, 31 insertions(+), 15 deletions(-)

diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
index 5011cad..54d347c 100644
--- a/examples/ip_pipeline/cli.c
+++ b/examples/ip_pipeline/cli.c
@@ -4407,7 +4407,6 @@ cmd_pipeline_table_rule_add_default(char **tokens,
 	size_t out_size)
 {
 	struct table_rule_action action;
-	void *data;
 	char *pipeline_name;
 	uint32_t table_id;
 	int status;
@@ -4513,8 +4512,7 @@ cmd_pipeline_table_rule_add_default(char **tokens,
 
 	status = pipeline_table_rule_add_default(pipeline_name,
 		table_id,
-		&action,
-		&data);
+		&action);
 	if (status) {
 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
 		return;
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
index 8a364a9..15a38fd 100644
--- a/examples/ip_pipeline/pipeline.h
+++ b/examples/ip_pipeline/pipeline.h
@@ -341,8 +341,7 @@ pipeline_table_rule_add_bulk(const char *pipeline_name,
 int
 pipeline_table_rule_add_default(const char *pipeline_name,
 	uint32_t table_id,
-	struct table_rule_action *action,
-	void **data);
+	struct table_rule_action *action);
 
 int
 pipeline_table_rule_delete(const char *pipeline_name,
diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
index 2c0570f..d2daacc 100644
--- a/examples/ip_pipeline/thread.c
+++ b/examples/ip_pipeline/thread.c
@@ -1447,18 +1447,18 @@ pipeline_table_rule_add(const char *pipeline_name,
 int
 pipeline_table_rule_add_default(const char *pipeline_name,
 	uint32_t table_id,
-	struct table_rule_action *action,
-	void **data)
+	struct table_rule_action *action)
 {
 	struct pipeline *p;
+	struct table *table;
 	struct pipeline_msg_req *req;
 	struct pipeline_msg_rsp *rsp;
+	struct table_rule *rule;
 	int status;
 
 	/* Check input params */
 	if ((pipeline_name == NULL) ||
-		(action == NULL) ||
-		(data == NULL))
+		(action == NULL))
 		return -1;
 
 	p = pipeline_find(pipeline_name);
@@ -1467,13 +1467,23 @@ pipeline_table_rule_add_default(const char *pipeline_name,
 		action_default_check(action, p, table_id))
 		return -1;
 
+	table = &p->table[table_id];
+
+	rule = calloc(1, sizeof(struct table_rule));
+	if (rule == NULL)
+		return -1;
+
+	memcpy(&rule->action, action, sizeof(*action));
+
 	if (!pipeline_is_running(p)) {
 		struct rte_pipeline_table_entry *data_in, *data_out;
 		uint8_t *buffer;
 
 		buffer = calloc(TABLE_RULE_ACTION_SIZE_MAX, sizeof(uint8_t));
-		if (buffer == NULL)
+		if (buffer == NULL) {
+			free(rule);
 			return -1;
+		}
 
 		/* Apply actions */
 		data_in = (struct rte_pipeline_table_entry *)buffer;
@@ -1491,11 +1501,13 @@ pipeline_table_rule_add_default(const char *pipeline_name,
 				&data_out);
 		if (status) {
 			free(buffer);
+			free(rule);
 			return -1;
 		}
 
 		/* Write Response */
-		*data = data_out;
+		rule->data = data_out;
+		table_rule_default_add(table, rule);
 
 		free(buffer);
 		return 0;
@@ -1503,8 +1515,10 @@ pipeline_table_rule_add_default(const char *pipeline_name,
 
 	/* Allocate request */
 	req = pipeline_msg_alloc();
-	if (req == NULL)
+	if (req == NULL) {
+		free(rule);
 		return -1;
+	}
 
 	/* Write request */
 	req->type = PIPELINE_REQ_TABLE_RULE_ADD_DEFAULT;
@@ -1513,13 +1527,18 @@ pipeline_table_rule_add_default(const char *pipeline_name,
 
 	/* Send request and wait for response */
 	rsp = pipeline_msg_send_recv(p, req);
-	if (rsp == NULL)
+	if (rsp == NULL) {
+		free(rule);
 		return -1;
+	}
 
 	/* Read response */
 	status = rsp->status;
-	if (status == 0)
-		*data = rsp->table_rule_add_default.data;
+	if (status == 0) {
+		rule->data = rsp->table_rule_add_default.data;
+		table_rule_default_add(table, rule);
+	} else
+		free(rule);
 
 	/* Free response */
 	pipeline_msg_free(rsp);
-- 
2.7.4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 05/12] examples/ip_pipeline: track table rules on delete
  2018-11-02 11:36 [dpdk-dev] [PATCH 01/12] examples/ip_pipeline: add rule list per table Cristian Dumitrescu
                   ` (2 preceding siblings ...)
  2018-11-02 11:36 ` [dpdk-dev] [PATCH 04/12] examples/ip_pipeline: track rules on add default Cristian Dumitrescu
@ 2018-11-02 11:36 ` Cristian Dumitrescu
  2018-11-02 11:36 ` [dpdk-dev] [PATCH 06/12] examples/ip_pipeline: track rules on delete default Cristian Dumitrescu
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Cristian Dumitrescu @ 2018-11-02 11:36 UTC (permalink / raw)
  To: dev; +Cc: Jasvinder Singh, Hongjun Ni

Support table rule tracking on table rule delete operation.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Signed-off-by: Hongjun Ni <hongjun.ni@intel.com>
---
 examples/ip_pipeline/thread.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
index d2daacc..a3cd3c0 100644
--- a/examples/ip_pipeline/thread.c
+++ b/examples/ip_pipeline/thread.c
@@ -1672,6 +1672,7 @@ pipeline_table_rule_delete(const char *pipeline_name,
 	struct table_rule_match *match)
 {
 	struct pipeline *p;
+	struct table *table;
 	struct pipeline_msg_req *req;
 	struct pipeline_msg_rsp *rsp;
 	int status;
@@ -1687,6 +1688,8 @@ pipeline_table_rule_delete(const char *pipeline_name,
 		match_check(match, p, table_id))
 		return -1;
 
+	table = &p->table[table_id];
+
 	if (!pipeline_is_running(p)) {
 		union table_rule_match_low_level match_ll;
 		int key_found;
@@ -1701,6 +1704,9 @@ pipeline_table_rule_delete(const char *pipeline_name,
 				&key_found,
 				NULL);
 
+		if (status == 0)
+			table_rule_delete(table, match);
+
 		return status;
 	}
 
@@ -1721,6 +1727,8 @@ pipeline_table_rule_delete(const char *pipeline_name,
 
 	/* Read response */
 	status = rsp->status;
+	if (status == 0)
+		table_rule_delete(table, match);
 
 	/* Free response */
 	pipeline_msg_free(rsp);
-- 
2.7.4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 06/12] examples/ip_pipeline: track rules on delete default
  2018-11-02 11:36 [dpdk-dev] [PATCH 01/12] examples/ip_pipeline: add rule list per table Cristian Dumitrescu
                   ` (3 preceding siblings ...)
  2018-11-02 11:36 ` [dpdk-dev] [PATCH 05/12] examples/ip_pipeline: track table rules on delete Cristian Dumitrescu
@ 2018-11-02 11:36 ` Cristian Dumitrescu
  2018-11-02 11:36 ` [dpdk-dev] [PATCH 07/12] examples/ip_pipeline: support rule stats read Cristian Dumitrescu
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Cristian Dumitrescu @ 2018-11-02 11:36 UTC (permalink / raw)
  To: dev; +Cc: Jasvinder Singh

Support table rule tracking on table rule delete default operation.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 examples/ip_pipeline/thread.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
index a3cd3c0..1baad67 100644
--- a/examples/ip_pipeline/thread.c
+++ b/examples/ip_pipeline/thread.c
@@ -1741,6 +1741,7 @@ pipeline_table_rule_delete_default(const char *pipeline_name,
 	uint32_t table_id)
 {
 	struct pipeline *p;
+	struct table *table;
 	struct pipeline_msg_req *req;
 	struct pipeline_msg_rsp *rsp;
 	int status;
@@ -1754,11 +1755,16 @@ pipeline_table_rule_delete_default(const char *pipeline_name,
 		(table_id >= p->n_tables))
 		return -1;
 
+	table = &p->table[table_id];
+
 	if (!pipeline_is_running(p)) {
 		status = rte_pipeline_table_default_entry_delete(p->p,
 			table_id,
 			NULL);
 
+		if (status == 0)
+			table_rule_default_delete(table);
+
 		return status;
 	}
 
@@ -1778,6 +1784,8 @@ pipeline_table_rule_delete_default(const char *pipeline_name,
 
 	/* Read response */
 	status = rsp->status;
+	if (status == 0)
+		table_rule_default_delete(table);
 
 	/* Free response */
 	pipeline_msg_free(rsp);
-- 
2.7.4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 07/12] examples/ip_pipeline: support rule stats read
  2018-11-02 11:36 [dpdk-dev] [PATCH 01/12] examples/ip_pipeline: add rule list per table Cristian Dumitrescu
                   ` (4 preceding siblings ...)
  2018-11-02 11:36 ` [dpdk-dev] [PATCH 06/12] examples/ip_pipeline: track rules on delete default Cristian Dumitrescu
@ 2018-11-02 11:36 ` Cristian Dumitrescu
  2018-11-02 11:36 ` [dpdk-dev] [PATCH 08/12] examples/ip_pipeline: support meter " Cristian Dumitrescu
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Cristian Dumitrescu @ 2018-11-02 11:36 UTC (permalink / raw)
  To: dev; +Cc: Jasvinder Singh

Add support for rule stats read operation.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 examples/ip_pipeline/cli.c      | 105 ++++++++++++++++++++++++++++++++++++++--
 examples/ip_pipeline/pipeline.h |   2 +-
 examples/ip_pipeline/thread.c   |  24 +++++----
 3 files changed, 117 insertions(+), 14 deletions(-)

diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
index 54d347c..e7ad93e 100644
--- a/examples/ip_pipeline/cli.c
+++ b/examples/ip_pipeline/cli.c
@@ -4741,17 +4741,114 @@ cmd_pipeline_table_rule_delete_default(char **tokens,
 
 
 static const char cmd_pipeline_table_rule_stats_read_help[] =
-"pipeline <pipeline_name> table <table_id> rule read stats [clear]\n";
+"pipeline <pipeline_name> table <table_id> rule read stats [clear]\n"
+"     match <match>\n";
 
 static void
 cmd_pipeline_table_rule_stats_read(char **tokens,
-	uint32_t n_tokens __rte_unused,
+	uint32_t n_tokens,
 	char *out,
 	size_t out_size)
 {
-	snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
-}
+	struct table_rule_match m;
+	struct rte_table_action_stats_counters stats;
+	char *pipeline_name;
+	uint32_t table_id, n_tokens_parsed;
+	int clear = 0, status;
+
+	if (n_tokens < 7) {
+		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+		return;
+	}
+
+	pipeline_name = tokens[1];
+
+	if (strcmp(tokens[2], "table") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
+		return;
+	}
+
+	if (parser_read_uint32(&table_id, tokens[3]) != 0) {
+		snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
+		return;
+	}
+
+	if (strcmp(tokens[4], "rule") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
+		return;
+	}
+
+	if (strcmp(tokens[5], "read") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
+		return;
+	}
+
+	if (strcmp(tokens[6], "stats") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
+		return;
+	}
+
+	n_tokens -= 7;
+	tokens += 7;
+
+	/* clear */
+	if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
+		clear = 1;
+
+		n_tokens--;
+		tokens++;
+	}
+
+	/* match */
+	if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
+		return;
+	}
+
+	n_tokens_parsed = parse_match(tokens,
+		n_tokens,
+		out,
+		out_size,
+		&m);
+	if (n_tokens_parsed == 0)
+		return;
+	n_tokens -= n_tokens_parsed;
+	tokens += n_tokens_parsed;
+
+	/* end */
+	if (n_tokens) {
+		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
+		return;
+	}
+
+	/* Read table rule stats. */
+	status = pipeline_table_rule_stats_read(pipeline_name,
+		table_id,
+		&m,
+		&stats,
+		clear);
+	if (status) {
+		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
+		return;
+	}
 
+	/* Print stats. */
+	if (stats.n_packets_valid && stats.n_bytes_valid)
+		snprintf(out, out_size, "Packets: %" PRIu64 "; Bytes: %" PRIu64 "\n",
+			stats.n_packets,
+			stats.n_bytes);
+
+	if (stats.n_packets_valid && !stats.n_bytes_valid)
+		snprintf(out, out_size, "Packets: %" PRIu64 "; Bytes: N/A\n",
+			stats.n_packets);
+
+	if (!stats.n_packets_valid && stats.n_bytes_valid)
+		snprintf(out, out_size, "Packets: N/A; Bytes: %" PRIu64 "\n",
+			stats.n_bytes);
+
+	if (!stats.n_packets_valid && !stats.n_bytes_valid)
+		snprintf(out, out_size, "Packets: N/A ; Bytes: N/A\n");
+}
 
 static const char cmd_pipeline_table_meter_profile_add_help[] =
 "pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>\n"
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
index 15a38fd..2c42e0d 100644
--- a/examples/ip_pipeline/pipeline.h
+++ b/examples/ip_pipeline/pipeline.h
@@ -355,7 +355,7 @@ pipeline_table_rule_delete_default(const char *pipeline_name,
 int
 pipeline_table_rule_stats_read(const char *pipeline_name,
 	uint32_t table_id,
-	void *data,
+	struct table_rule_match *match,
 	struct rte_table_action_stats_counters *stats,
 	int clear);
 
diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
index 1baad67..b172f91 100644
--- a/examples/ip_pipeline/thread.c
+++ b/examples/ip_pipeline/thread.c
@@ -1796,31 +1796,37 @@ pipeline_table_rule_delete_default(const char *pipeline_name,
 int
 pipeline_table_rule_stats_read(const char *pipeline_name,
 	uint32_t table_id,
-	void *data,
+	struct table_rule_match *match,
 	struct rte_table_action_stats_counters *stats,
 	int clear)
 {
 	struct pipeline *p;
+	struct table *table;
 	struct pipeline_msg_req *req;
 	struct pipeline_msg_rsp *rsp;
+	struct table_rule *rule;
 	int status;
 
 	/* Check input params */
 	if ((pipeline_name == NULL) ||
-		(data == NULL) ||
+		(match == NULL) ||
 		(stats == NULL))
 		return -1;
 
 	p = pipeline_find(pipeline_name);
 	if ((p == NULL) ||
-		(table_id >= p->n_tables))
+		(table_id >= p->n_tables) ||
+		match_check(match, p, table_id))
 		return -1;
 
-	if (!pipeline_is_running(p)) {
-		struct rte_table_action *a = p->table[table_id].a;
+	table = &p->table[table_id];
+	rule = table_rule_find(table, match);
+	if (rule == NULL)
+		return -1;
 
-		status = rte_table_action_stats_read(a,
-			data,
+	if (!pipeline_is_running(p)) {
+		status = rte_table_action_stats_read(table->a,
+			rule->data,
 			stats,
 			clear);
 
@@ -1835,7 +1841,7 @@ pipeline_table_rule_stats_read(const char *pipeline_name,
 	/* Write request */
 	req->type = PIPELINE_REQ_TABLE_RULE_STATS_READ;
 	req->id = table_id;
-	req->table_rule_stats_read.data = data;
+	req->table_rule_stats_read.data = rule->data;
 	req->table_rule_stats_read.clear = clear;
 
 	/* Send request and wait for response */
@@ -1845,7 +1851,7 @@ pipeline_table_rule_stats_read(const char *pipeline_name,
 
 	/* Read response */
 	status = rsp->status;
-	if (status)
+	if (status == 0)
 		memcpy(stats, &rsp->table_rule_stats_read.stats, sizeof(*stats));
 
 	/* Free response */
-- 
2.7.4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 08/12] examples/ip_pipeline: support meter stats read
  2018-11-02 11:36 [dpdk-dev] [PATCH 01/12] examples/ip_pipeline: add rule list per table Cristian Dumitrescu
                   ` (5 preceding siblings ...)
  2018-11-02 11:36 ` [dpdk-dev] [PATCH 07/12] examples/ip_pipeline: support rule stats read Cristian Dumitrescu
@ 2018-11-02 11:36 ` Cristian Dumitrescu
  2018-11-02 11:37 ` [dpdk-dev] [PATCH 09/12] examples/ip_pipeline: support rule TTL " Cristian Dumitrescu
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Cristian Dumitrescu @ 2018-11-02 11:36 UTC (permalink / raw)
  To: dev; +Cc: Jasvinder Singh

Add support for the rule meter stats read operation.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 examples/ip_pipeline/cli.c      | 89 +++++++++++++++++++++++++++++++++++++++--
 examples/ip_pipeline/pipeline.h |  3 +-
 examples/ip_pipeline/thread.c   | 28 ++++++++-----
 3 files changed, 105 insertions(+), 15 deletions(-)

diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
index e7ad93e..78539d1 100644
--- a/examples/ip_pipeline/cli.c
+++ b/examples/ip_pipeline/cli.c
@@ -5065,15 +5065,98 @@ cmd_pipeline_table_meter_profile_delete(char **tokens,
 
 
 static const char cmd_pipeline_table_rule_meter_read_help[] =
-"pipeline <pipeline_name> table <table_id> rule read meter [clear]\n";
+"pipeline <pipeline_name> table <table_id> rule read meter [clear]\n"
+"     match <match>\n";
 
 static void
 cmd_pipeline_table_rule_meter_read(char **tokens,
-	uint32_t n_tokens __rte_unused,
+	uint32_t n_tokens,
 	char *out,
 	size_t out_size)
 {
-	snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
+	struct table_rule_match m;
+	struct rte_table_action_mtr_counters stats;
+	char *pipeline_name;
+	uint32_t table_id, n_tokens_parsed;
+	int clear = 0, status;
+
+	if (n_tokens < 7) {
+		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+		return;
+	}
+
+	pipeline_name = tokens[1];
+
+	if (strcmp(tokens[2], "table") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
+		return;
+	}
+
+	if (parser_read_uint32(&table_id, tokens[3]) != 0) {
+		snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
+		return;
+	}
+
+	if (strcmp(tokens[4], "rule") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
+		return;
+	}
+
+	if (strcmp(tokens[5], "read") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
+		return;
+	}
+
+	if (strcmp(tokens[6], "meter") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
+		return;
+	}
+
+	n_tokens -= 7;
+	tokens += 7;
+
+	/* clear */
+	if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
+		clear = 1;
+
+		n_tokens--;
+		tokens++;
+	}
+
+	/* match */
+	if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
+		return;
+	}
+
+	n_tokens_parsed = parse_match(tokens,
+		n_tokens,
+		out,
+		out_size,
+		&m);
+	if (n_tokens_parsed == 0)
+		return;
+	n_tokens -= n_tokens_parsed;
+	tokens += n_tokens_parsed;
+
+	/* end */
+	if (n_tokens) {
+		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
+		return;
+	}
+
+	/* Read table rule meter stats. */
+	status = pipeline_table_rule_mtr_read(pipeline_name,
+		table_id,
+		&m,
+		&stats,
+		clear);
+	if (status) {
+		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
+		return;
+	}
+
+	/* Print stats. */
 }
 
 
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
index 2c42e0d..57553bd 100644
--- a/examples/ip_pipeline/pipeline.h
+++ b/examples/ip_pipeline/pipeline.h
@@ -373,8 +373,7 @@ pipeline_table_mtr_profile_delete(const char *pipeline_name,
 int
 pipeline_table_rule_mtr_read(const char *pipeline_name,
 	uint32_t table_id,
-	void *data,
-	uint32_t tc_mask,
+	struct table_rule_match *match,
 	struct rte_table_action_mtr_counters *stats,
 	int clear);
 
diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
index b172f91..0252db9 100644
--- a/examples/ip_pipeline/thread.c
+++ b/examples/ip_pipeline/thread.c
@@ -1971,32 +1971,40 @@ pipeline_table_mtr_profile_delete(const char *pipeline_name,
 int
 pipeline_table_rule_mtr_read(const char *pipeline_name,
 	uint32_t table_id,
-	void *data,
-	uint32_t tc_mask,
+	struct table_rule_match *match,
 	struct rte_table_action_mtr_counters *stats,
 	int clear)
 {
 	struct pipeline *p;
+	struct table *table;
 	struct pipeline_msg_req *req;
 	struct pipeline_msg_rsp *rsp;
+	struct table_rule *rule;
+	uint32_t tc_mask;
 	int status;
 
 	/* Check input params */
 	if ((pipeline_name == NULL) ||
-		(data == NULL) ||
+		(match == NULL) ||
 		(stats == NULL))
 		return -1;
 
 	p = pipeline_find(pipeline_name);
 	if ((p == NULL) ||
-		(table_id >= p->n_tables))
+		(table_id >= p->n_tables) ||
+		match_check(match, p, table_id))
 		return -1;
 
-	if (!pipeline_is_running(p)) {
-		struct rte_table_action *a = p->table[table_id].a;
+	table = &p->table[table_id];
+	tc_mask = (1 << table->ap->params.mtr.n_tc) - 1;
 
-		status = rte_table_action_meter_read(a,
-				data,
+	rule = table_rule_find(table, match);
+	if (rule == NULL)
+		return -1;
+
+	if (!pipeline_is_running(p)) {
+		status = rte_table_action_meter_read(table->a,
+				rule->data,
 				tc_mask,
 				stats,
 				clear);
@@ -2012,7 +2020,7 @@ pipeline_table_rule_mtr_read(const char *pipeline_name,
 	/* Write request */
 	req->type = PIPELINE_REQ_TABLE_RULE_MTR_READ;
 	req->id = table_id;
-	req->table_rule_mtr_read.data = data;
+	req->table_rule_mtr_read.data = rule->data;
 	req->table_rule_mtr_read.tc_mask = tc_mask;
 	req->table_rule_mtr_read.clear = clear;
 
@@ -2023,7 +2031,7 @@ pipeline_table_rule_mtr_read(const char *pipeline_name,
 
 	/* Read response */
 	status = rsp->status;
-	if (status)
+	if (status == 0)
 		memcpy(stats, &rsp->table_rule_mtr_read.stats, sizeof(*stats));
 
 	/* Free response */
-- 
2.7.4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 09/12] examples/ip_pipeline: support rule TTL stats read
  2018-11-02 11:36 [dpdk-dev] [PATCH 01/12] examples/ip_pipeline: add rule list per table Cristian Dumitrescu
                   ` (6 preceding siblings ...)
  2018-11-02 11:36 ` [dpdk-dev] [PATCH 08/12] examples/ip_pipeline: support meter " Cristian Dumitrescu
@ 2018-11-02 11:37 ` Cristian Dumitrescu
  2018-11-02 11:37 ` [dpdk-dev] [PATCH 10/12] examples/ip_pipeline: support rule time read Cristian Dumitrescu
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Cristian Dumitrescu @ 2018-11-02 11:37 UTC (permalink / raw)
  To: dev; +Cc: Jasvinder Singh

Add support for the table rule TTL stats read operation.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 examples/ip_pipeline/cli.c      | 91 +++++++++++++++++++++++++++++++++++++++--
 examples/ip_pipeline/pipeline.h |  2 +-
 examples/ip_pipeline/thread.c   | 27 ++++++++----
 3 files changed, 107 insertions(+), 13 deletions(-)

diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
index 78539d1..6561152 100644
--- a/examples/ip_pipeline/cli.c
+++ b/examples/ip_pipeline/cli.c
@@ -5311,15 +5311,100 @@ cmd_pipeline_table_dscp(char **tokens,
 
 
 static const char cmd_pipeline_table_rule_ttl_read_help[] =
-"pipeline <pipeline_name> table <table_id> rule read ttl [clear]\n";
+"pipeline <pipeline_name> table <table_id> rule read ttl [clear]\n"
+"     match <match>\n";
 
 static void
 cmd_pipeline_table_rule_ttl_read(char **tokens,
-	uint32_t n_tokens __rte_unused,
+	uint32_t n_tokens,
 	char *out,
 	size_t out_size)
 {
-	snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
+	struct table_rule_match m;
+	struct rte_table_action_ttl_counters stats;
+	char *pipeline_name;
+	uint32_t table_id, n_tokens_parsed;
+	int clear = 0, status;
+
+	if (n_tokens < 7) {
+		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+		return;
+	}
+
+	pipeline_name = tokens[1];
+
+	if (strcmp(tokens[2], "table") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
+		return;
+	}
+
+	if (parser_read_uint32(&table_id, tokens[3]) != 0) {
+		snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
+		return;
+	}
+
+	if (strcmp(tokens[4], "rule") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
+		return;
+	}
+
+	if (strcmp(tokens[5], "read") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
+		return;
+	}
+
+	if (strcmp(tokens[6], "ttl") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ttl");
+		return;
+	}
+
+	n_tokens -= 7;
+	tokens += 7;
+
+	/* clear */
+	if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
+		clear = 1;
+
+		n_tokens--;
+		tokens++;
+	}
+
+	/* match */
+	if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
+		return;
+	}
+
+	n_tokens_parsed = parse_match(tokens,
+		n_tokens,
+		out,
+		out_size,
+		&m);
+	if (n_tokens_parsed == 0)
+		return;
+	n_tokens -= n_tokens_parsed;
+	tokens += n_tokens_parsed;
+
+	/* end */
+	if (n_tokens) {
+		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
+		return;
+	}
+
+	/* Read table rule TTL stats. */
+	status = pipeline_table_rule_ttl_read(pipeline_name,
+		table_id,
+		&m,
+		&stats,
+		clear);
+	if (status) {
+		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
+		return;
+	}
+
+	/* Print stats. */
+	snprintf(out, out_size, "Packets: %" PRIu64 "\n",
+		stats.n_packets);
 }
 
 
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
index 57553bd..4e2d328 100644
--- a/examples/ip_pipeline/pipeline.h
+++ b/examples/ip_pipeline/pipeline.h
@@ -386,7 +386,7 @@ pipeline_table_dscp_table_update(const char *pipeline_name,
 int
 pipeline_table_rule_ttl_read(const char *pipeline_name,
 	uint32_t table_id,
-	void *data,
+	struct table_rule_match *match,
 	struct rte_table_action_ttl_counters *stats,
 	int clear);
 struct table_rule *
diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
index 0252db9..e1142d9 100644
--- a/examples/ip_pipeline/thread.c
+++ b/examples/ip_pipeline/thread.c
@@ -2100,31 +2100,40 @@ pipeline_table_dscp_table_update(const char *pipeline_name,
 int
 pipeline_table_rule_ttl_read(const char *pipeline_name,
 	uint32_t table_id,
-	void *data,
+	struct table_rule_match *match,
 	struct rte_table_action_ttl_counters *stats,
 	int clear)
 {
 	struct pipeline *p;
+	struct table *table;
 	struct pipeline_msg_req *req;
 	struct pipeline_msg_rsp *rsp;
+	struct table_rule *rule;
 	int status;
 
 	/* Check input params */
 	if ((pipeline_name == NULL) ||
-		(data == NULL) ||
+		(match == NULL) ||
 		(stats == NULL))
 		return -1;
 
 	p = pipeline_find(pipeline_name);
 	if ((p == NULL) ||
-		(table_id >= p->n_tables))
+		(table_id >= p->n_tables) ||
+		match_check(match, p, table_id))
 		return -1;
 
-	if (!pipeline_is_running(p)) {
-		struct rte_table_action *a = p->table[table_id].a;
+	table = &p->table[table_id];
+	if (!table->ap->params.ttl.n_packets_enabled)
+		return -1;
+
+	rule = table_rule_find(table, match);
+	if (rule == NULL)
+		return -1;
 
-		status = rte_table_action_ttl_read(a,
-				data,
+	if (!pipeline_is_running(p)) {
+		status = rte_table_action_ttl_read(table->a,
+				rule->data,
 				stats,
 				clear);
 
@@ -2139,7 +2148,7 @@ pipeline_table_rule_ttl_read(const char *pipeline_name,
 	/* Write request */
 	req->type = PIPELINE_REQ_TABLE_RULE_TTL_READ;
 	req->id = table_id;
-	req->table_rule_ttl_read.data = data;
+	req->table_rule_ttl_read.data = rule->data;
 	req->table_rule_ttl_read.clear = clear;
 
 	/* Send request and wait for response */
@@ -2149,7 +2158,7 @@ pipeline_table_rule_ttl_read(const char *pipeline_name,
 
 	/* Read response */
 	status = rsp->status;
-	if (status)
+	if (status == 0)
 		memcpy(stats, &rsp->table_rule_ttl_read.stats, sizeof(*stats));
 
 	/* Free response */
-- 
2.7.4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 10/12] examples/ip_pipeline: support rule time read
  2018-11-02 11:36 [dpdk-dev] [PATCH 01/12] examples/ip_pipeline: add rule list per table Cristian Dumitrescu
                   ` (7 preceding siblings ...)
  2018-11-02 11:37 ` [dpdk-dev] [PATCH 09/12] examples/ip_pipeline: support rule TTL " Cristian Dumitrescu
@ 2018-11-02 11:37 ` Cristian Dumitrescu
  2018-11-02 11:37 ` [dpdk-dev] [PATCH 11/12] examples/ip_pipeline: support table rule show Cristian Dumitrescu
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Cristian Dumitrescu @ 2018-11-02 11:37 UTC (permalink / raw)
  To: dev; +Cc: Jasvinder Singh

Add support for the table rule timestamp read operation.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 examples/ip_pipeline/cli.c      | 106 ++++++++++++++++++++++++++++++++++++++++
 examples/ip_pipeline/pipeline.h |   7 +++
 examples/ip_pipeline/thread.c   |  96 ++++++++++++++++++++++++++++++++++++
 3 files changed, 209 insertions(+)

diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
index 6561152..552e0df 100644
--- a/examples/ip_pipeline/cli.c
+++ b/examples/ip_pipeline/cli.c
@@ -5407,6 +5407,92 @@ cmd_pipeline_table_rule_ttl_read(char **tokens,
 		stats.n_packets);
 }
 
+static const char cmd_pipeline_table_rule_time_read_help[] =
+"pipeline <pipeline_name> table <table_id> rule read time\n"
+"     match <match>\n";
+
+static void
+cmd_pipeline_table_rule_time_read(char **tokens,
+	uint32_t n_tokens,
+	char *out,
+	size_t out_size)
+{
+	struct table_rule_match m;
+	char *pipeline_name;
+	uint64_t timestamp;
+	uint32_t table_id, n_tokens_parsed;
+	int status;
+
+	if (n_tokens < 7) {
+		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+		return;
+	}
+
+	pipeline_name = tokens[1];
+
+	if (strcmp(tokens[2], "table") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
+		return;
+	}
+
+	if (parser_read_uint32(&table_id, tokens[3]) != 0) {
+		snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
+		return;
+	}
+
+	if (strcmp(tokens[4], "rule") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
+		return;
+	}
+
+	if (strcmp(tokens[5], "read") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
+		return;
+	}
+
+	if (strcmp(tokens[6], "time") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "time");
+		return;
+	}
+
+	n_tokens -= 7;
+	tokens += 7;
+
+	/* match */
+	if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
+		return;
+	}
+
+	n_tokens_parsed = parse_match(tokens,
+		n_tokens,
+		out,
+		out_size,
+		&m);
+	if (n_tokens_parsed == 0)
+		return;
+	n_tokens -= n_tokens_parsed;
+	tokens += n_tokens_parsed;
+
+	/* end */
+	if (n_tokens) {
+		snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
+		return;
+	}
+
+	/* Read table rule timestamp. */
+	status = pipeline_table_rule_time_read(pipeline_name,
+		table_id,
+		&m,
+		&timestamp);
+	if (status) {
+		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
+		return;
+	}
+
+	/* Print stats. */
+	snprintf(out, out_size, "Packets: %" PRIu64 "\n", timestamp);
+}
 
 static const char cmd_thread_pipeline_enable_help[] =
 "thread <thread_id> pipeline <pipeline_name> enable\n";
@@ -5537,6 +5623,7 @@ cmd_help(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
 			"\tpipeline table rule meter read\n"
 			"\tpipeline table dscp\n"
 			"\tpipeline table rule ttl read\n"
+			"\tpipeline table rule time read\n"
 			"\tthread pipeline enable\n"
 			"\tthread pipeline disable\n\n");
 		return;
@@ -5788,6 +5875,15 @@ cmd_help(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
 				cmd_pipeline_table_rule_ttl_read_help);
 			return;
 		}
+
+		if ((n_tokens == 5) &&
+			(strcmp(tokens[2], "rule") == 0) &&
+			(strcmp(tokens[3], "time") == 0) &&
+			(strcmp(tokens[4], "read") == 0)) {
+			snprintf(out, out_size, "\n%s\n",
+				cmd_pipeline_table_rule_time_read_help);
+			return;
+		}
 	}
 
 	if ((n_tokens == 3) &&
@@ -6096,6 +6192,16 @@ cli_process(char *in, char *out, size_t out_size)
 				out, out_size);
 			return;
 		}
+
+		if ((n_tokens >= 7) &&
+			(strcmp(tokens[2], "table") == 0) &&
+			(strcmp(tokens[4], "rule") == 0) &&
+			(strcmp(tokens[5], "read") == 0) &&
+			(strcmp(tokens[6], "time") == 0)) {
+			cmd_pipeline_table_rule_time_read(tokens, n_tokens,
+				out, out_size);
+			return;
+		}
 	}
 
 	if (strcmp(tokens[0], "thread") == 0) {
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
index 4e2d328..278775c 100644
--- a/examples/ip_pipeline/pipeline.h
+++ b/examples/ip_pipeline/pipeline.h
@@ -389,6 +389,13 @@ pipeline_table_rule_ttl_read(const char *pipeline_name,
 	struct table_rule_match *match,
 	struct rte_table_action_ttl_counters *stats,
 	int clear);
+
+int
+pipeline_table_rule_time_read(const char *pipeline_name,
+	uint32_t table_id,
+	struct table_rule_match *match,
+	uint64_t *timestamp);
+
 struct table_rule *
 table_rule_find(struct table *table,
 	struct table_rule_match *match);
diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
index e1142d9..e1b6fb6 100644
--- a/examples/ip_pipeline/thread.c
+++ b/examples/ip_pipeline/thread.c
@@ -584,6 +584,7 @@ enum pipeline_req_type {
 	PIPELINE_REQ_TABLE_RULE_MTR_READ,
 	PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE,
 	PIPELINE_REQ_TABLE_RULE_TTL_READ,
+	PIPELINE_REQ_TABLE_RULE_TIME_READ,
 	PIPELINE_REQ_MAX
 };
 
@@ -647,6 +648,10 @@ struct pipeline_msg_req_table_rule_ttl_read {
 	int clear;
 };
 
+struct pipeline_msg_req_table_rule_time_read {
+	void *data;
+};
+
 struct pipeline_msg_req {
 	enum pipeline_req_type type;
 	uint32_t id; /* Port IN, port OUT or table ID */
@@ -666,6 +671,7 @@ struct pipeline_msg_req {
 		struct pipeline_msg_req_table_rule_mtr_read table_rule_mtr_read;
 		struct pipeline_msg_req_table_dscp_table_update table_dscp_table_update;
 		struct pipeline_msg_req_table_rule_ttl_read table_rule_ttl_read;
+		struct pipeline_msg_req_table_rule_time_read table_rule_time_read;
 	};
 };
 
@@ -705,6 +711,10 @@ struct pipeline_msg_rsp_table_rule_ttl_read {
 	struct rte_table_action_ttl_counters stats;
 };
 
+struct pipeline_msg_rsp_table_rule_time_read {
+	uint64_t timestamp;
+};
+
 struct pipeline_msg_rsp {
 	int status;
 
@@ -719,6 +729,7 @@ struct pipeline_msg_rsp {
 		struct pipeline_msg_rsp_table_rule_stats_read table_rule_stats_read;
 		struct pipeline_msg_rsp_table_rule_mtr_read table_rule_mtr_read;
 		struct pipeline_msg_rsp_table_rule_ttl_read table_rule_ttl_read;
+		struct pipeline_msg_rsp_table_rule_time_read table_rule_time_read;
 	};
 };
 
@@ -2167,6 +2178,71 @@ pipeline_table_rule_ttl_read(const char *pipeline_name,
 	return status;
 }
 
+int
+pipeline_table_rule_time_read(const char *pipeline_name,
+	uint32_t table_id,
+	struct table_rule_match *match,
+	uint64_t *timestamp)
+{
+	struct pipeline *p;
+	struct table *table;
+	struct pipeline_msg_req *req;
+	struct pipeline_msg_rsp *rsp;
+	struct table_rule *rule;
+	int status;
+
+	/* Check input params */
+	if ((pipeline_name == NULL) ||
+		(match == NULL) ||
+		(timestamp == NULL))
+		return -1;
+
+	p = pipeline_find(pipeline_name);
+	if ((p == NULL) ||
+		(table_id >= p->n_tables) ||
+		match_check(match, p, table_id))
+		return -1;
+
+	table = &p->table[table_id];
+
+	rule = table_rule_find(table, match);
+	if (rule == NULL)
+		return -1;
+
+	if (!pipeline_is_running(p)) {
+		status = rte_table_action_time_read(table->a,
+				rule->data,
+				timestamp);
+
+		return status;
+	}
+
+	/* Allocate request */
+	req = pipeline_msg_alloc();
+	if (req == NULL)
+		return -1;
+
+	/* Write request */
+	req->type = PIPELINE_REQ_TABLE_RULE_TIME_READ;
+	req->id = table_id;
+	req->table_rule_time_read.data = rule->data;
+
+	/* Send request and wait for response */
+	rsp = pipeline_msg_send_recv(p, req);
+	if (rsp == NULL)
+		return -1;
+
+	/* Read response */
+	status = rsp->status;
+	if (status == 0)
+		*timestamp = rsp->table_rule_time_read.timestamp;
+
+	/* Free response */
+	pipeline_msg_free(rsp);
+
+	return status;
+}
+
 /**
  * Data plane threads: message handling
  */
@@ -2942,6 +3018,22 @@ pipeline_msg_handle_table_rule_ttl_read(struct pipeline_data *p,
 	return rsp;
 }
 
+static struct pipeline_msg_rsp *
+pipeline_msg_handle_table_rule_time_read(struct pipeline_data *p,
+	struct pipeline_msg_req *req)
+{
+	struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
+	uint32_t table_id = req->id;
+	void *data = req->table_rule_time_read.data;
+	struct rte_table_action *a = p->table_data[table_id].a;
+
+	rsp->status = rte_table_action_time_read(a,
+		data,
+		&rsp->table_rule_time_read.timestamp);
+
+	return rsp;
+}
+
 static void
 pipeline_msg_handle(struct pipeline_data *p)
 {
@@ -3018,6 +3110,10 @@ pipeline_msg_handle(struct pipeline_data *p)
 			rsp = pipeline_msg_handle_table_rule_ttl_read(p, req);
 			break;
 
+		case PIPELINE_REQ_TABLE_RULE_TIME_READ:
+			rsp = pipeline_msg_handle_table_rule_time_read(p, req);
+			break;
+
 		default:
 			rsp = (struct pipeline_msg_rsp *) req;
 			rsp->status = -1;
-- 
2.7.4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 11/12] examples/ip_pipeline: support table rule show
  2018-11-02 11:36 [dpdk-dev] [PATCH 01/12] examples/ip_pipeline: add rule list per table Cristian Dumitrescu
                   ` (8 preceding siblings ...)
  2018-11-02 11:37 ` [dpdk-dev] [PATCH 10/12] examples/ip_pipeline: support rule time read Cristian Dumitrescu
@ 2018-11-02 11:37 ` Cristian Dumitrescu
  2018-11-02 11:37 ` [dpdk-dev] [PATCH 12/12] examples/ip_pipeline: fix port and table stats read Cristian Dumitrescu
  2018-11-02 12:39 ` [dpdk-dev] [PATCH 01/12] examples/ip_pipeline: add rule list per table Dumitrescu, Cristian
  11 siblings, 0 replies; 13+ messages in thread
From: Cristian Dumitrescu @ 2018-11-02 11:37 UTC (permalink / raw)
  To: dev; +Cc: Jasvinder Singh

Add support for the table rule show operation.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 examples/ip_pipeline/cli.c | 432 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 432 insertions(+)

diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
index 552e0df..3de6206 100644
--- a/examples/ip_pipeline/cli.c
+++ b/examples/ip_pipeline/cli.c
@@ -4739,6 +4739,420 @@ cmd_pipeline_table_rule_delete_default(char **tokens,
 	}
 }
 
+static void
+ether_addr_show(FILE *f, struct ether_addr *addr)
+{
+	fprintf(f, "%02x:%02x:%02x:%02x:%02x:%02x",
+		(uint32_t)addr->addr_bytes[0], (uint32_t)addr->addr_bytes[1],
+		(uint32_t)addr->addr_bytes[2], (uint32_t)addr->addr_bytes[3],
+		(uint32_t)addr->addr_bytes[4], (uint32_t)addr->addr_bytes[5]);
+}
+
+static void
+ipv4_addr_show(FILE *f, uint32_t addr)
+{
+	fprintf(f, "%u.%u.%u.%u",
+		addr >> 24,
+		(addr >> 16) & 0xFF,
+		(addr >> 8) & 0xFF,
+		addr & 0xFF);
+}
+
+static void
+ipv6_addr_show(FILE *f, uint8_t *addr)
+{
+	fprintf(f, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:"
+		"%02x%02x:%02x%02x:%02x%02x:%02x%02x:",
+		(uint32_t)addr[0], (uint32_t)addr[1],
+		(uint32_t)addr[2], (uint32_t)addr[3],
+		(uint32_t)addr[4], (uint32_t)addr[5],
+		(uint32_t)addr[6], (uint32_t)addr[7],
+		(uint32_t)addr[8], (uint32_t)addr[9],
+		(uint32_t)addr[10], (uint32_t)addr[11],
+		(uint32_t)addr[12], (uint32_t)addr[13],
+		(uint32_t)addr[14], (uint32_t)addr[15]);
+}
+
+static const char *
+policer_action_string(enum rte_table_action_policer action) {
+	switch (action) {
+		case RTE_TABLE_ACTION_POLICER_COLOR_GREEN: return "G";
+		case RTE_TABLE_ACTION_POLICER_COLOR_YELLOW: return "Y";
+		case RTE_TABLE_ACTION_POLICER_COLOR_RED: return "R";
+		case RTE_TABLE_ACTION_POLICER_DROP: return "D";
+		default: return "?";
+	}
+}
+
+static int
+table_rule_show(const char *pipeline_name,
+	uint32_t table_id,
+	const char *file_name)
+{
+	struct pipeline *p;
+	struct table *table;
+	struct table_rule *rule;
+	FILE *f = NULL;
+	uint32_t i;
+
+	/* Check input params. */
+	if ((pipeline_name == NULL) ||
+		(file_name == NULL))
+		return -1;
+
+	p = pipeline_find(pipeline_name);
+	if ((p == NULL) ||
+		(table_id >= p->n_tables))
+		return -1;
+
+	table = &p->table[table_id];
+
+	/* Open file. */
+	f = fopen(file_name, "w");
+	if (f == NULL)
+		return -1;
+
+	/* Write table rules to file. */
+	TAILQ_FOREACH(rule, &table->rules, node) {
+		struct table_rule_match *m = &rule->match;
+		struct table_rule_action *a = &rule->action;
+
+		fprintf(f, "match ");
+		switch (m->match_type) {
+		case TABLE_ACL:
+			fprintf(f, "acl priority %u ",
+				m->match.acl.priority);
+
+			fprintf(f, m->match.acl.ip_version ? "ipv4 " : "ipv6 ");
+
+			if (m->match.acl.ip_version)
+				ipv4_addr_show(f, m->match.acl.ipv4.sa);
+			else
+				ipv6_addr_show(f, m->match.acl.ipv6.sa);
+
+			fprintf(f, "%u",	m->match.acl.sa_depth);
+
+			if (m->match.acl.ip_version)
+				ipv4_addr_show(f, m->match.acl.ipv4.da);
+			else
+				ipv6_addr_show(f, m->match.acl.ipv6.da);
+
+			fprintf(f, "%u",	m->match.acl.da_depth);
+
+			fprintf(f, "%u %u %u %u %u ",
+				(uint32_t)m->match.acl.sp0,
+				(uint32_t)m->match.acl.sp1,
+				(uint32_t)m->match.acl.dp0,
+				(uint32_t)m->match.acl.dp1,
+				(uint32_t)m->match.acl.proto);
+			break;
+
+		case TABLE_ARRAY:
+			fprintf(f, "array %u ",
+				m->match.array.pos);
+			break;
+
+		case TABLE_HASH:
+			fprintf(f, "hash raw ");
+			for (i = 0; i < table->params.match.hash.key_size; i++)
+				fprintf(f, "%02x", m->match.hash.key[i]);
+			fprintf(f, " ");
+			break;
+
+		case TABLE_LPM:
+			fprintf(f, "lpm ");
+
+			fprintf(f, m->match.lpm.ip_version ? "ipv4 " : "ipv6 ");
+
+			if (m->match.acl.ip_version)
+				ipv4_addr_show(f, m->match.lpm.ipv4);
+			else
+				ipv6_addr_show(f, m->match.lpm.ipv6);
+
+			fprintf(f, "%u ",
+				(uint32_t)m->match.lpm.depth);
+			break;
+
+		default:
+			fprintf(f, "unknown ");
+		}
+
+		fprintf(f, "action ");
+		if (a->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
+			fprintf(f, "fwd ");
+			switch (a->fwd.action) {
+			case RTE_PIPELINE_ACTION_DROP:
+				fprintf(f, "drop ");
+				break;
+
+			case RTE_PIPELINE_ACTION_PORT:
+				fprintf(f, "port %u ", a->fwd.id);
+				break;
+
+			case RTE_PIPELINE_ACTION_PORT_META:
+				fprintf(f, "meta ");
+				break;
+
+			case RTE_PIPELINE_ACTION_TABLE:
+			default:
+				fprintf(f, "table %u ", a->fwd.id);
+			}
+		}
+
+		if (a->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
+			fprintf(f, "balance ");
+			for (i = 0; i < RTE_DIM(a->lb.out); i++)
+				fprintf(f, "%u ", a->lb.out[i]);
+		}
+
+		if (a->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
+			fprintf(f, "mtr ");
+			for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++)
+				if (a->mtr.tc_mask & (1 << i)) {
+					struct rte_table_action_mtr_tc_params *p =
+						&a->mtr.mtr[i];
+					enum rte_table_action_policer ga =
+						p->policer[e_RTE_METER_GREEN];
+					enum rte_table_action_policer ya =
+						p->policer[e_RTE_METER_YELLOW];
+					enum rte_table_action_policer ra =
+						p->policer[e_RTE_METER_RED];
+
+					fprintf(f, "tc%u meter %u policer g %s y %s r %s ",
+						i,
+						a->mtr.mtr[i].meter_profile_id,
+						policer_action_string(ga),
+						policer_action_string(ya),
+						policer_action_string(ra));
+				}
+		}
+
+		if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TM))
+			fprintf(f, "tm subport %u pipe %u ",
+				a->tm.subport_id,
+				a->tm.pipe_id);
+
+		if (a->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
+			fprintf(f, "encap ");
+			switch (a->encap.type) {
+			case RTE_TABLE_ACTION_ENCAP_ETHER:
+				fprintf(f, "ether ");
+				ether_addr_show(f, &a->encap.ether.ether.da);
+				fprintf(f, " ");
+				ether_addr_show(f, &a->encap.ether.ether.sa);
+				fprintf(f, " ");
+				break;
+
+			case RTE_TABLE_ACTION_ENCAP_VLAN:
+				fprintf(f, "vlan ");
+				ether_addr_show(f, &a->encap.vlan.ether.da);
+				fprintf(f, " ");
+				ether_addr_show(f, &a->encap.vlan.ether.sa);
+				fprintf(f, " pcp %u dei %u vid %u ",
+					a->encap.vlan.vlan.pcp,
+					a->encap.vlan.vlan.dei,
+					a->encap.vlan.vlan.vid);
+				break;
+
+			case RTE_TABLE_ACTION_ENCAP_QINQ:
+				fprintf(f, "qinq ");
+				ether_addr_show(f, &a->encap.qinq.ether.da);
+				fprintf(f, " ");
+				ether_addr_show(f, &a->encap.qinq.ether.sa);
+				fprintf(f, " pcp %u dei %u vid %u pcp %u dei %u vid %u ",
+					a->encap.qinq.svlan.pcp,
+					a->encap.qinq.svlan.dei,
+					a->encap.qinq.svlan.vid,
+					a->encap.qinq.cvlan.pcp,
+					a->encap.qinq.cvlan.dei,
+					a->encap.qinq.cvlan.vid);
+				break;
+
+			case RTE_TABLE_ACTION_ENCAP_MPLS:
+				fprintf(f, "mpls %s ", (a->encap.mpls.unicast) ?
+					"unicast " : "multicast ");
+				ether_addr_show(f, &a->encap.mpls.ether.da);
+				fprintf(f, " ");
+				ether_addr_show(f, &a->encap.mpls.ether.sa);
+				fprintf(f, " ");
+				for (i = 0; i < a->encap.mpls.mpls_count; i++) {
+					struct rte_table_action_mpls_hdr *l =
+						&a->encap.mpls.mpls[i];
+
+					fprintf(f, "label%u %u %u %u ",
+						i,
+						l->label,
+						l->tc,
+						l->ttl);
+				}
+				break;
+
+			case RTE_TABLE_ACTION_ENCAP_PPPOE:
+				fprintf(f, "pppoe ");
+				ether_addr_show(f, &a->encap.pppoe.ether.da);
+				fprintf(f, " ");
+				ether_addr_show(f, &a->encap.pppoe.ether.sa);
+				fprintf(f, " %u ", a->encap.pppoe.pppoe.session_id);
+				break;
+
+			case RTE_TABLE_ACTION_ENCAP_VXLAN:
+				fprintf(f, "vxlan ether ");
+				ether_addr_show(f, &a->encap.vxlan.ether.da);
+				fprintf(f, " ");
+				ether_addr_show(f, &a->encap.vxlan.ether.sa);
+				if (table->ap->params.encap.vxlan.vlan)
+					fprintf(f, " vlan pcp %u dei %u vid %u ",
+						a->encap.vxlan.vlan.pcp,
+						a->encap.vxlan.vlan.dei,
+						a->encap.vxlan.vlan.vid);
+				if (table->ap->params.encap.vxlan.ip_version) {
+					fprintf(f, " ipv4 ");
+					ipv4_addr_show(f, a->encap.vxlan.ipv4.sa);
+					fprintf(f, " ");
+					ipv4_addr_show(f, a->encap.vxlan.ipv4.da);
+					fprintf(f, " %u %u ",
+						(uint32_t)a->encap.vxlan.ipv4.dscp,
+						(uint32_t)a->encap.vxlan.ipv4.ttl);
+				} else {
+					fprintf(f, " ipv6 ");
+					ipv6_addr_show(f, a->encap.vxlan.ipv6.sa);
+					fprintf(f, " ");
+					ipv6_addr_show(f, a->encap.vxlan.ipv6.da);
+					fprintf(f, " %u %u %u ",
+						a->encap.vxlan.ipv6.flow_label,
+						(uint32_t)a->encap.vxlan.ipv6.dscp,
+						(uint32_t)a->encap.vxlan.ipv6.hop_limit);
+					fprintf(f, " udp %u %u vxlan %u ",
+						a->encap.vxlan.udp.sp,
+						a->encap.vxlan.udp.dp,
+						a->encap.vxlan.vxlan.vni);
+				}
+				break;
+
+			default:
+				fprintf(f, "unknown ");
+			}
+		}
+
+		if (a->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
+			fprintf(f, "nat %s ", (a->nat.ip_version) ? "ipv4 " : "ipv6 ");
+			if (a->nat.ip_version)
+				ipv4_addr_show(f, a->nat.addr.ipv4);
+			else
+				ipv6_addr_show(f, a->nat.addr.ipv6);
+			fprintf(f, " %u ", (uint32_t)(a->nat.port));
+		}
+
+		if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TTL))
+			fprintf(f, "ttl %s ", (a->ttl.decrement) ? "dec" : "keep");
+
+		if (a->action_mask & (1LLU << RTE_TABLE_ACTION_STATS))
+			fprintf(f, "stats ");
+
+		if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TIME))
+			fprintf(f, "time ");
+
+		if (a->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO))
+			fprintf(f, "sym_crypto ");
+
+		if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TAG))
+			fprintf(f, "tag %u ", a->tag.tag);
+
+		if (a->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP))
+			fprintf(f, "decap %u ", a->decap.n);
+
+		/* end */
+		fprintf(f, "\n");
+	}
+
+	/* Write table default rule to file. */
+	if (table->rule_default) {
+		struct table_rule_action *a = &table->rule_default->action;
+
+		fprintf(f, "# match default action fwd ");
+
+		switch (a->fwd.action) {
+		case RTE_PIPELINE_ACTION_DROP:
+			fprintf(f, "drop ");
+			break;
+
+		case RTE_PIPELINE_ACTION_PORT:
+			fprintf(f, "port %u ", a->fwd.id);
+			break;
+
+		case RTE_PIPELINE_ACTION_PORT_META:
+			fprintf(f, "meta ");
+			break;
+
+		case RTE_PIPELINE_ACTION_TABLE:
+		default:
+			fprintf(f, "table %u ", a->fwd.id);
+		}
+	} else
+		fprintf(f, "# match default action fwd drop ");
+
+	fprintf(f, "\n");
+
+	/* Close file. */
+	fclose(f);
+
+	return 0;
+}
+
+static const char cmd_pipeline_table_rule_show_help[] =
+"pipeline <pipeline_name> table <table_id> rule show\n"
+"     file <file_name>\n";
+
+static void
+cmd_pipeline_table_rule_show(char **tokens,
+	uint32_t n_tokens,
+	char *out,
+	size_t out_size)
+{
+	char *file_name = NULL, *pipeline_name;
+	uint32_t table_id;
+	int status;
+
+	if (n_tokens != 8) {
+		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+		return;
+	}
+
+	pipeline_name = tokens[1];
+
+	if (strcmp(tokens[2], "table") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
+		return;
+	}
+
+	if (parser_read_uint32(&table_id, tokens[3]) != 0) {
+		snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
+		return;
+	}
+
+	if (strcmp(tokens[4], "rule") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
+		return;
+	}
+
+	if (strcmp(tokens[5], "show") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "show");
+		return;
+	}
+
+	if (strcmp(tokens[6], "file") != 0) {
+		snprintf(out, out_size, MSG_ARG_NOT_FOUND, "file");
+		return;
+	}
+
+	file_name = tokens[7];
+
+	status = table_rule_show(pipeline_name, table_id, file_name);
+	if (status) {
+		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
+		return;
+	}
+}
 
 static const char cmd_pipeline_table_rule_stats_read_help[] =
 "pipeline <pipeline_name> table <table_id> rule read stats [clear]\n"
@@ -5617,6 +6031,7 @@ cmd_help(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
 			"\tpipeline table rule add bulk\n"
 			"\tpipeline table rule delete\n"
 			"\tpipeline table rule delete default\n"
+			"\tpipeline table rule show\n"
 			"\tpipeline table rule stats read\n"
 			"\tpipeline table meter profile add\n"
 			"\tpipeline table meter profile delete\n"
@@ -5831,6 +6246,14 @@ cmd_help(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
 			return;
 		}
 
+		if ((n_tokens == 4) &&
+			(strcmp(tokens[2], "rule") == 0) &&
+			(strcmp(tokens[3], "show") == 0)) {
+			snprintf(out, out_size, "\n%s\n",
+				cmd_pipeline_table_rule_show_help);
+			return;
+		}
+
 		if ((n_tokens == 5) &&
 			(strcmp(tokens[2], "rule") == 0) &&
 			(strcmp(tokens[3], "stats") == 0) &&
@@ -6135,6 +6558,15 @@ cli_process(char *in, char *out, size_t out_size)
 			return;
 		}
 
+		if ((n_tokens >= 6) &&
+			(strcmp(tokens[2], "table") == 0) &&
+			(strcmp(tokens[4], "rule") == 0) &&
+			(strcmp(tokens[5], "show") == 0)) {
+			cmd_pipeline_table_rule_show(tokens, n_tokens,
+				out, out_size);
+			return;
+		}
+
 		if ((n_tokens >= 7) &&
 			(strcmp(tokens[2], "table") == 0) &&
 			(strcmp(tokens[4], "rule") == 0) &&
-- 
2.7.4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [dpdk-dev] [PATCH 12/12] examples/ip_pipeline: fix port and table stats read
  2018-11-02 11:36 [dpdk-dev] [PATCH 01/12] examples/ip_pipeline: add rule list per table Cristian Dumitrescu
                   ` (9 preceding siblings ...)
  2018-11-02 11:37 ` [dpdk-dev] [PATCH 11/12] examples/ip_pipeline: support table rule show Cristian Dumitrescu
@ 2018-11-02 11:37 ` Cristian Dumitrescu
  2018-11-02 12:39 ` [dpdk-dev] [PATCH 01/12] examples/ip_pipeline: add rule list per table Dumitrescu, Cristian
  11 siblings, 0 replies; 13+ messages in thread
From: Cristian Dumitrescu @ 2018-11-02 11:37 UTC (permalink / raw)
  To: dev; +Cc: Jasvinder Singh, Hongjun Ni

Fix the pipeline port and table stats read operation.

Fixes: 50e73d051806 ("examples/ip_pipeline: add stats read commands")

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Signed-off-by: Hongjun Ni <hongjun.ni@intel.com>
---
 examples/ip_pipeline/thread.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
index e1b6fb6..272fbbe 100644
--- a/examples/ip_pipeline/thread.c
+++ b/examples/ip_pipeline/thread.c
@@ -820,7 +820,7 @@ pipeline_port_in_stats_read(const char *pipeline_name,
 
 	/* Read response */
 	status = rsp->status;
-	if (status)
+	if (status == 0)
 		memcpy(stats, &rsp->port_in_stats_read.stats, sizeof(*stats));
 
 	/* Free response */
@@ -968,7 +968,7 @@ pipeline_port_out_stats_read(const char *pipeline_name,
 
 	/* Read response */
 	status = rsp->status;
-	if (status)
+	if (status == 0)
 		memcpy(stats, &rsp->port_out_stats_read.stats, sizeof(*stats));
 
 	/* Free response */
@@ -1024,7 +1024,7 @@ pipeline_table_stats_read(const char *pipeline_name,
 
 	/* Read response */
 	status = rsp->status;
-	if (status)
+	if (status == 0)
 		memcpy(stats, &rsp->table_stats_read.stats, sizeof(*stats));
 
 	/* Free response */
-- 
2.7.4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [dpdk-dev] [PATCH 01/12] examples/ip_pipeline: add rule list per table
  2018-11-02 11:36 [dpdk-dev] [PATCH 01/12] examples/ip_pipeline: add rule list per table Cristian Dumitrescu
                   ` (10 preceding siblings ...)
  2018-11-02 11:37 ` [dpdk-dev] [PATCH 12/12] examples/ip_pipeline: fix port and table stats read Cristian Dumitrescu
@ 2018-11-02 12:39 ` Dumitrescu, Cristian
  11 siblings, 0 replies; 13+ messages in thread
From: Dumitrescu, Cristian @ 2018-11-02 12:39 UTC (permalink / raw)
  To: dev; +Cc: Singh, Jasvinder, Ni, Hongjun



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Cristian Dumitrescu
> Sent: Friday, November 2, 2018 11:37 AM
> To: dev@dpdk.org
> Cc: Singh, Jasvinder <jasvinder.singh@intel.com>; Ni, Hongjun
> <hongjun.ni@intel.com>
> Subject: [dpdk-dev] [PATCH 01/12] examples/ip_pipeline: add rule list per
> table
> 
> For each pipeline table, have the master thread maintain the list of
> rules that are currently stored in the table. This list allows the
> master thread to handle table queries with minimal impact for the
> data plane threads: requests to read the current set of table rules
> are fully handled by the master thread with no involvement from
> data plane threads, requests to read the per table rule moving data
> (such as stats counters or timestamp associated with specific
> actions) are handled by the data plane threads through plain memory
> reads rather than key lookup.
> 
> Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
> Signed-off-by: Hongjun Ni <hongjun.ni@intel.com>
> ---

Applied to next-pipeline tree, thanks!

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2018-11-02 12:39 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-02 11:36 [dpdk-dev] [PATCH 01/12] examples/ip_pipeline: add rule list per table Cristian Dumitrescu
2018-11-02 11:36 ` [dpdk-dev] [PATCH 02/12] examples/ip_pipeline: track table rules on add Cristian Dumitrescu
2018-11-02 11:36 ` [dpdk-dev] [PATCH 03/12] examples/ip_pipeline: track table rules on add bulk Cristian Dumitrescu
2018-11-02 11:36 ` [dpdk-dev] [PATCH 04/12] examples/ip_pipeline: track rules on add default Cristian Dumitrescu
2018-11-02 11:36 ` [dpdk-dev] [PATCH 05/12] examples/ip_pipeline: track table rules on delete Cristian Dumitrescu
2018-11-02 11:36 ` [dpdk-dev] [PATCH 06/12] examples/ip_pipeline: track rules on delete default Cristian Dumitrescu
2018-11-02 11:36 ` [dpdk-dev] [PATCH 07/12] examples/ip_pipeline: support rule stats read Cristian Dumitrescu
2018-11-02 11:36 ` [dpdk-dev] [PATCH 08/12] examples/ip_pipeline: support meter " Cristian Dumitrescu
2018-11-02 11:37 ` [dpdk-dev] [PATCH 09/12] examples/ip_pipeline: support rule TTL " Cristian Dumitrescu
2018-11-02 11:37 ` [dpdk-dev] [PATCH 10/12] examples/ip_pipeline: support rule time read Cristian Dumitrescu
2018-11-02 11:37 ` [dpdk-dev] [PATCH 11/12] examples/ip_pipeline: support table rule show Cristian Dumitrescu
2018-11-02 11:37 ` [dpdk-dev] [PATCH 12/12] examples/ip_pipeline: fix port and table stats read Cristian Dumitrescu
2018-11-02 12:39 ` [dpdk-dev] [PATCH 01/12] examples/ip_pipeline: add rule list per table Dumitrescu, Cristian

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).