* [dpdk-dev] [PATCH v4 1/5] table: added bulk add/delete functions for table
2015-10-20 13:01 [dpdk-dev] [PATCH v4 0/5] pipeline: add bulk add/delete functions for table Michal Jastrzebski
@ 2015-10-20 13:01 ` Michal Jastrzebski
2015-10-20 13:01 ` [dpdk-dev] [PATCH v4 2/5] pipeline: " Michal Jastrzebski
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Michal Jastrzebski @ 2015-10-20 13:01 UTC (permalink / raw)
To: dev
From: Marcin Kerlin <marcinx.kerlin@intel.com>
New functions prototypes for bulk add/delete added to table API. New
functions allows adding/deleting multiple records with single function
call. For now those functions are implemented only for ACL table. For
other tables these function pointers are set to NULL.
Signed-off-by: Maciej Gajdzica <maciejx.t.gajdzica@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
lib/librte_table/rte_table.h | 85 ++++++++-
lib/librte_table/rte_table_acl.c | 309 ++++++++++++++++++++++++++++++++
lib/librte_table/rte_table_array.c | 2 +
lib/librte_table/rte_table_hash_ext.c | 4 +
lib/librte_table/rte_table_hash_key16.c | 4 +
lib/librte_table/rte_table_hash_key32.c | 4 +
lib/librte_table/rte_table_hash_key8.c | 8 +
lib/librte_table/rte_table_hash_lru.c | 4 +
lib/librte_table/rte_table_lpm.c | 2 +
lib/librte_table/rte_table_lpm_ipv6.c | 2 +
lib/librte_table/rte_table_stub.c | 2 +
11 files changed, 420 insertions(+), 6 deletions(-)
diff --git a/lib/librte_table/rte_table.h b/lib/librte_table/rte_table.h
index c13d40d..720514e 100644
--- a/lib/librte_table/rte_table.h
+++ b/lib/librte_table/rte_table.h
@@ -154,6 +154,77 @@ typedef int (*rte_table_op_entry_delete)(
void *entry);
/**
+ * Lookup table entry add bulk
+ *
+ * @param table
+ * Handle to lookup table instance
+ * @param key
+ * Array containing lookup keys
+ * @param entries
+ * Array containing data to be associated with each key. Every item in the
+ * array has to point to a valid memory buffer where the first entry_size
+ * bytes (table create parameter) are populated with the data.
+ * @param n_keys
+ * Number of keys to add
+ * @param key_found
+ * After successful invocation, key_found for every item in the array is set
+ * to a value different than 0 if the current key is already present in the
+ * table and to 0 if not. This pointer has to be set to a valid memory
+ * location before the table entry add function is called.
+ * @param entries_ptr
+ * After successful invocation, array *entries_ptr stores the handle to the
+ * table entry containing the data associated with every key. This handle can
+ * be used to perform further read-write accesses to this entry. This handle
+ * is valid until the key is deleted from the table or the same key is
+ * re-added to the table, typically to associate it with different data. This
+ * pointer has to be set to a valid memory location before the function is
+ * called.
+ * @return
+ * 0 on success, error code otherwise
+ */
+typedef int (*rte_table_op_entry_add_bulk)(
+ void *table,
+ void **keys,
+ void **entries,
+ uint32_t n_keys,
+ int *key_found,
+ void **entries_ptr);
+
+/**
+ * Lookup table entry delete bulk
+ *
+ * @param table
+ * Handle to lookup table instance
+ * @param key
+ * Array containing lookup keys
+ * @param n_keys
+ * Number of keys to delete
+ * @param key_found
+ * After successful invocation, key_found for every item in the array is set
+ * to a value different than 0if the current key was present in the table
+ * before the delete operation was performed and to 0 if not. This pointer
+ * has to be set to a valid memory location before the table entry delete
+ * function is called.
+ * @param entries
+ * If entries pointer is NULL, this pointer is ignored for every entry found.
+ * Else, after successful invocation, if specific key is found in the table
+ * (key_found is different than 0 for this item after function call is
+ * completed) and item of entry array points to a valid buffer (entry is set
+ * to a value different than NULL before the function is called), then the
+ * first entry_size bytes (table create parameter) in *entry store a copy of
+ * table entry that contained the data associated with the current key before
+ * the key was deleted.
+ * @return
+ * 0 on success, error code otherwise
+ */
+typedef int (*rte_table_op_entry_delete_bulk)(
+ void *table,
+ void **keys,
+ uint32_t n_keys,
+ int *key_found,
+ void **entries);
+
+/**
* Lookup table lookup
*
* @param table
@@ -213,12 +284,14 @@ typedef int (*rte_table_op_stats_read)(
/** Lookup table interface defining the lookup table operation */
struct rte_table_ops {
- rte_table_op_create f_create; /**< Create */
- rte_table_op_free f_free; /**< Free */
- rte_table_op_entry_add f_add; /**< Entry add */
- rte_table_op_entry_delete f_delete; /**< Entry delete */
- rte_table_op_lookup f_lookup; /**< Lookup */
- rte_table_op_stats_read f_stats; /**< Stats */
+ rte_table_op_create f_create; /**< Create */
+ rte_table_op_free f_free; /**< Free */
+ rte_table_op_entry_add f_add; /**< Entry add */
+ rte_table_op_entry_delete f_delete; /**< Entry delete */
+ rte_table_op_entry_add_bulk f_add_bulk; /**< Add entry bulk */
+ rte_table_op_entry_delete_bulk f_delete_bulk; /**< Delete entry bulk */
+ rte_table_op_lookup f_lookup; /**< Lookup */
+ rte_table_op_stats_read f_stats; /**< Stats */
};
#ifdef __cplusplus
diff --git a/lib/librte_table/rte_table_acl.c b/lib/librte_table/rte_table_acl.c
index f02de3e..c1eb848 100644
--- a/lib/librte_table/rte_table_acl.c
+++ b/lib/librte_table/rte_table_acl.c
@@ -444,6 +444,313 @@ rte_table_acl_entry_delete(
}
static int
+rte_table_acl_entry_add_bulk(
+ void *table,
+ void **keys,
+ void **entries,
+ uint32_t n_keys,
+ int *key_found,
+ void **entries_ptr)
+{
+ struct rte_table_acl *acl = (struct rte_table_acl *) table;
+ struct rte_acl_ctx *ctx;
+ uint32_t rule_pos[n_keys];
+ uint32_t i;
+ int err = 0, build = 0;
+ int status;
+
+ /* Check input parameters */
+ if (table == NULL) {
+ RTE_LOG(ERR, TABLE, "%s: table parameter is NULL\n", __func__);
+ return -EINVAL;
+ }
+ if (keys == NULL) {
+ RTE_LOG(ERR, TABLE, "%s: keys parameter is NULL\n", __func__);
+ return -EINVAL;
+ }
+ if (entries == NULL) {
+ RTE_LOG(ERR, TABLE, "%s: entries parameter is NULL\n", __func__);
+ return -EINVAL;
+ }
+ if (n_keys == 0) {
+ RTE_LOG(ERR, TABLE, "%s: 0 rules to add\n", __func__);
+ return -EINVAL;
+ }
+ if (key_found == NULL) {
+ RTE_LOG(ERR, TABLE, "%s: key_found parameter is NULL\n",
+ __func__);
+ return -EINVAL;
+ }
+ if (entries_ptr == NULL) {
+ RTE_LOG(ERR, TABLE, "%s: entries_ptr parameter is NULL\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ /* Check input parameters in arrays */
+ for (i = 0; i < n_keys; i++) {
+ struct rte_table_acl_rule_add_params *rule;
+
+ if (keys[i] == NULL) {
+ RTE_LOG(ERR, TABLE, "%s: keys[%" PRIu32 "] parameter is NULL\n",
+ __func__, i);
+ return -EINVAL;
+ }
+
+ if (entries[i] == NULL) {
+ RTE_LOG(ERR, TABLE, "%s: entries[%" PRIu32 "] parameter is NULL\n",
+ __func__, i);
+ return -EINVAL;
+ }
+
+ if (entries_ptr[i] == NULL) {
+ RTE_LOG(ERR, TABLE, "%s: entries_ptr[%" PRIu32 "] parameter is NULL\n",
+ __func__, i);
+ return -EINVAL;
+ }
+
+ rule = (struct rte_table_acl_rule_add_params *) keys[i];
+ if (rule->priority > RTE_ACL_MAX_PRIORITY) {
+ RTE_LOG(ERR, TABLE, "%s: Priority is too high\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ memset(rule_pos, 0, n_keys * sizeof(uint32_t));
+ memset(key_found, 0, n_keys * sizeof(int));
+ for (i = 0; i < n_keys; i++) {
+ struct rte_table_acl_rule_add_params *rule =
+ (struct rte_table_acl_rule_add_params *) keys[i];
+ struct rte_pipeline_acl_rule acl_rule;
+ struct rte_acl_rule *rule_location;
+ uint32_t free_pos, free_pos_valid, j;
+
+ /* Setup rule data structure */
+ memset(&acl_rule, 0, sizeof(acl_rule));
+ acl_rule.data.category_mask = 1;
+ acl_rule.data.priority = RTE_ACL_MAX_PRIORITY - rule->priority;
+ acl_rule.data.userdata = 0; /* To be set up later */
+ memcpy(&acl_rule.field[0],
+ &rule->field_value[0],
+ acl->cfg.num_fields * sizeof(struct rte_acl_field));
+
+ /* Look to see if the rule exists already in the table */
+ free_pos = 0;
+ free_pos_valid = 0;
+ for (j = 1; j < acl->n_rules; j++) {
+ if (acl->acl_rule_list[j] == NULL) {
+ if (free_pos_valid == 0) {
+ free_pos = j;
+ free_pos_valid = 1;
+ }
+
+ continue;
+ }
+
+ /* Compare the key fields */
+ status = memcmp(&acl->acl_rule_list[j]->field[0],
+ &rule->field_value[0],
+ acl->cfg.num_fields * sizeof(struct rte_acl_field));
+
+ /* Rule found: update data associated with the rule */
+ if (status == 0) {
+ key_found[i] = 1;
+ entries_ptr[i] = &acl->memory[j * acl->entry_size];
+ memcpy(entries_ptr[i], entries[i], acl->entry_size);
+
+ break;
+ }
+ }
+
+ /* Key already in the table */
+ if (key_found[i] != 0)
+ continue;
+
+ /* Maximum number of rules reached */
+ if (free_pos_valid == 0) {
+ err = 1;
+ break;
+ }
+
+ /* Add the new rule to the rule set */
+ acl_rule.data.userdata = free_pos;
+ rule_location = (struct rte_acl_rule *)
+ &acl->acl_rule_memory[free_pos * acl->acl_params.rule_size];
+ memcpy(rule_location, &acl_rule, acl->acl_params.rule_size);
+ acl->acl_rule_list[free_pos] = rule_location;
+ rule_pos[i] = free_pos;
+ build = 1;
+ }
+
+ if (err != 0) {
+ for (i = 0; i < n_keys; i++) {
+ if (rule_pos[i] == 0)
+ continue;
+
+ acl->acl_rule_list[rule_pos[i]] = NULL;
+ }
+
+ return -ENOSPC;
+ }
+
+ if (build == 0)
+ return 0;
+
+ /* Build low level ACL table */
+ acl->name_id ^= 1;
+ acl->acl_params.name = acl->name[acl->name_id];
+ status = rte_table_acl_build(acl, &ctx);
+ if (status != 0) {
+ /* Roll back changes */
+ for (i = 0; i < n_keys; i++) {
+ if (rule_pos[i] == 0)
+ continue;
+
+ acl->acl_rule_list[rule_pos[i]] = NULL;
+ }
+ acl->name_id ^= 1;
+
+ return -EINVAL;
+ }
+
+ /* Commit changes */
+ if (acl->ctx != NULL)
+ rte_acl_free(acl->ctx);
+ acl->ctx = ctx;
+
+ for (i = 0; i < n_keys; i++) {
+ if (rule_pos[i] == 0)
+ continue;
+
+ key_found[i] = 0;
+ entries_ptr[i] = &acl->memory[rule_pos[i] * acl->entry_size];
+ memcpy(entries_ptr[i], entries[i], acl->entry_size);
+ }
+
+ return 0;
+}
+
+static int
+rte_table_acl_entry_delete_bulk(
+ void *table,
+ void **keys,
+ uint32_t n_keys,
+ int *key_found,
+ void **entries)
+{
+ struct rte_table_acl *acl = (struct rte_table_acl *) table;
+ struct rte_acl_rule *deleted_rules[n_keys];
+ uint32_t rule_pos[n_keys];
+ struct rte_acl_ctx *ctx;
+ uint32_t i;
+ int status;
+ int build = 0;
+
+ /* Check input parameters */
+ if (table == NULL) {
+ RTE_LOG(ERR, TABLE, "%s: table parameter is NULL\n", __func__);
+ return -EINVAL;
+ }
+ if (keys == NULL) {
+ RTE_LOG(ERR, TABLE, "%s: key parameter is NULL\n", __func__);
+ return -EINVAL;
+ }
+ if (n_keys == 0) {
+ RTE_LOG(ERR, TABLE, "%s: 0 rules to delete\n", __func__);
+ return -EINVAL;
+ }
+ if (key_found == NULL) {
+ RTE_LOG(ERR, TABLE, "%s: key_found parameter is NULL\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < n_keys; i++) {
+ if (keys[i] == NULL) {
+ RTE_LOG(ERR, TABLE, "%s: keys[%" PRIu32 "] parameter is NULL\n",
+ __func__, i);
+ return -EINVAL;
+ }
+ }
+
+ memset(deleted_rules, 0, n_keys * sizeof(struct rte_acl_rule *));
+ memset(rule_pos, 0, n_keys * sizeof(uint32_t));
+ for (i = 0; i < n_keys; i++) {
+ struct rte_table_acl_rule_delete_params *rule =
+ (struct rte_table_acl_rule_delete_params *) keys[i];
+ uint32_t pos_valid, j;
+
+ /* Look for the rule in the table */
+ pos_valid = 0;
+ for (j = 1; j < acl->n_rules; j++) {
+ if (acl->acl_rule_list[j] == NULL)
+ continue;
+
+ /* Compare the key fields */
+ status = memcmp(&acl->acl_rule_list[j]->field[0],
+ &rule->field_value[0],
+ acl->cfg.num_fields * sizeof(struct rte_acl_field));
+
+ /* Rule found: remove from table */
+ if (status == 0) {
+ pos_valid = 1;
+
+ deleted_rules[i] = acl->acl_rule_list[j];
+ acl->acl_rule_list[j] = NULL;
+ rule_pos[i] = j;
+
+ build = 1;
+ }
+ }
+
+ if (pos_valid == 0) {
+ key_found[i] = 0;
+ continue;
+ }
+ }
+
+ /* Return if no changes to acl table */
+ if (build == 0) {
+ return 0;
+ }
+
+ /* Build low level ACL table */
+ acl->name_id ^= 1;
+ acl->acl_params.name = acl->name[acl->name_id];
+ status = rte_table_acl_build(acl, &ctx);
+ if (status != 0) {
+ /* Roll back changes */
+ for (i = 0; i < n_keys; i++) {
+ if (rule_pos[i] == 0)
+ continue;
+
+ acl->acl_rule_list[rule_pos[i]] = deleted_rules[i];
+ }
+
+ acl->name_id ^= 1;
+
+ return -EINVAL;
+ }
+
+ /* Commit changes */
+ if (acl->ctx != NULL)
+ rte_acl_free(acl->ctx);
+
+ acl->ctx = ctx;
+ for (i = 0; i < n_keys; i++) {
+ if (rule_pos[i] == 0)
+ continue;
+
+ key_found[i] = 1;
+ if (entries != NULL && entries[i] != NULL)
+ memcpy(entries[i], &acl->memory[rule_pos[i] * acl->entry_size],
+ acl->entry_size);
+ }
+
+ return 0;
+}
+
+static int
rte_table_acl_lookup(
void *table,
struct rte_mbuf **pkts,
@@ -521,6 +828,8 @@ struct rte_table_ops rte_table_acl_ops = {
.f_free = rte_table_acl_free,
.f_add = rte_table_acl_entry_add,
.f_delete = rte_table_acl_entry_delete,
+ .f_add_bulk = rte_table_acl_entry_add_bulk,
+ .f_delete_bulk = rte_table_acl_entry_delete_bulk,
.f_lookup = rte_table_acl_lookup,
.f_stats = rte_table_acl_stats_read,
};
diff --git a/lib/librte_table/rte_table_array.c b/lib/librte_table/rte_table_array.c
index 422f8c3..3bb68d1 100644
--- a/lib/librte_table/rte_table_array.c
+++ b/lib/librte_table/rte_table_array.c
@@ -230,6 +230,8 @@ struct rte_table_ops rte_table_array_ops = {
.f_free = rte_table_array_free,
.f_add = rte_table_array_entry_add,
.f_delete = NULL,
+ .f_add_bulk = NULL,
+ .f_delete_bulk = NULL,
.f_lookup = rte_table_array_lookup,
.f_stats = rte_table_array_stats_read,
};
diff --git a/lib/librte_table/rte_table_hash_ext.c b/lib/librte_table/rte_table_hash_ext.c
index 1fa15c8..ebe952b 100644
--- a/lib/librte_table/rte_table_hash_ext.c
+++ b/lib/librte_table/rte_table_hash_ext.c
@@ -1139,6 +1139,8 @@ struct rte_table_ops rte_table_hash_ext_ops = {
.f_free = rte_table_hash_ext_free,
.f_add = rte_table_hash_ext_entry_add,
.f_delete = rte_table_hash_ext_entry_delete,
+ .f_add_bulk = NULL,
+ .f_delete_bulk = NULL,
.f_lookup = rte_table_hash_ext_lookup,
.f_stats = rte_table_hash_ext_stats_read,
};
@@ -1148,6 +1150,8 @@ struct rte_table_ops rte_table_hash_ext_dosig_ops = {
.f_free = rte_table_hash_ext_free,
.f_add = rte_table_hash_ext_entry_add,
.f_delete = rte_table_hash_ext_entry_delete,
+ .f_add_bulk = NULL,
+ .f_delete_bulk = NULL,
.f_lookup = rte_table_hash_ext_lookup_dosig,
.f_stats = rte_table_hash_ext_stats_read,
};
diff --git a/lib/librte_table/rte_table_hash_key16.c b/lib/librte_table/rte_table_hash_key16.c
index f6a3306..35b7f10 100644
--- a/lib/librte_table/rte_table_hash_key16.c
+++ b/lib/librte_table/rte_table_hash_key16.c
@@ -1103,6 +1103,8 @@ struct rte_table_ops rte_table_hash_key16_lru_ops = {
.f_free = rte_table_hash_free_key16_lru,
.f_add = rte_table_hash_entry_add_key16_lru,
.f_delete = rte_table_hash_entry_delete_key16_lru,
+ .f_add_bulk = NULL,
+ .f_delete_bulk = NULL,
.f_lookup = rte_table_hash_lookup_key16_lru,
.f_stats = rte_table_hash_key16_stats_read,
};
@@ -1112,6 +1114,8 @@ struct rte_table_ops rte_table_hash_key16_ext_ops = {
.f_free = rte_table_hash_free_key16_ext,
.f_add = rte_table_hash_entry_add_key16_ext,
.f_delete = rte_table_hash_entry_delete_key16_ext,
+ .f_add_bulk = NULL,
+ .f_delete_bulk = NULL,
.f_lookup = rte_table_hash_lookup_key16_ext,
.f_stats = rte_table_hash_key16_stats_read,
};
diff --git a/lib/librte_table/rte_table_hash_key32.c b/lib/librte_table/rte_table_hash_key32.c
index 5fe4161..b3ae73e 100644
--- a/lib/librte_table/rte_table_hash_key32.c
+++ b/lib/librte_table/rte_table_hash_key32.c
@@ -1123,6 +1123,8 @@ struct rte_table_ops rte_table_hash_key32_lru_ops = {
.f_free = rte_table_hash_free_key32_lru,
.f_add = rte_table_hash_entry_add_key32_lru,
.f_delete = rte_table_hash_entry_delete_key32_lru,
+ .f_add_bulk = NULL,
+ .f_delete_bulk = NULL,
.f_lookup = rte_table_hash_lookup_key32_lru,
.f_stats = rte_table_hash_key32_stats_read,
};
@@ -1132,6 +1134,8 @@ struct rte_table_ops rte_table_hash_key32_ext_ops = {
.f_free = rte_table_hash_free_key32_ext,
.f_add = rte_table_hash_entry_add_key32_ext,
.f_delete = rte_table_hash_entry_delete_key32_ext,
+ .f_add_bulk = NULL,
+ .f_delete_bulk = NULL,
.f_lookup = rte_table_hash_lookup_key32_ext,
.f_stats = rte_table_hash_key32_stats_read,
};
diff --git a/lib/librte_table/rte_table_hash_key8.c b/lib/librte_table/rte_table_hash_key8.c
index b351a49..379748e 100644
--- a/lib/librte_table/rte_table_hash_key8.c
+++ b/lib/librte_table/rte_table_hash_key8.c
@@ -1394,6 +1394,8 @@ struct rte_table_ops rte_table_hash_key8_lru_ops = {
.f_free = rte_table_hash_free_key8_lru,
.f_add = rte_table_hash_entry_add_key8_lru,
.f_delete = rte_table_hash_entry_delete_key8_lru,
+ .f_add_bulk = NULL,
+ .f_delete_bulk = NULL,
.f_lookup = rte_table_hash_lookup_key8_lru,
.f_stats = rte_table_hash_key8_stats_read,
};
@@ -1403,6 +1405,8 @@ struct rte_table_ops rte_table_hash_key8_lru_dosig_ops = {
.f_free = rte_table_hash_free_key8_lru,
.f_add = rte_table_hash_entry_add_key8_lru,
.f_delete = rte_table_hash_entry_delete_key8_lru,
+ .f_add_bulk = NULL,
+ .f_delete_bulk = NULL,
.f_lookup = rte_table_hash_lookup_key8_lru_dosig,
.f_stats = rte_table_hash_key8_stats_read,
};
@@ -1412,6 +1416,8 @@ struct rte_table_ops rte_table_hash_key8_ext_ops = {
.f_free = rte_table_hash_free_key8_ext,
.f_add = rte_table_hash_entry_add_key8_ext,
.f_delete = rte_table_hash_entry_delete_key8_ext,
+ .f_add_bulk = NULL,
+ .f_delete_bulk = NULL,
.f_lookup = rte_table_hash_lookup_key8_ext,
.f_stats = rte_table_hash_key8_stats_read,
};
@@ -1421,6 +1427,8 @@ struct rte_table_ops rte_table_hash_key8_ext_dosig_ops = {
.f_free = rte_table_hash_free_key8_ext,
.f_add = rte_table_hash_entry_add_key8_ext,
.f_delete = rte_table_hash_entry_delete_key8_ext,
+ .f_add_bulk = NULL,
+ .f_delete_bulk = NULL,
.f_lookup = rte_table_hash_lookup_key8_ext_dosig,
.f_stats = rte_table_hash_key8_stats_read,
};
diff --git a/lib/librte_table/rte_table_hash_lru.c b/lib/librte_table/rte_table_hash_lru.c
index 1640dc9..14e9072 100644
--- a/lib/librte_table/rte_table_hash_lru.c
+++ b/lib/librte_table/rte_table_hash_lru.c
@@ -1082,6 +1082,8 @@ struct rte_table_ops rte_table_hash_lru_ops = {
.f_free = rte_table_hash_lru_free,
.f_add = rte_table_hash_lru_entry_add,
.f_delete = rte_table_hash_lru_entry_delete,
+ .f_add_bulk = NULL,
+ .f_delete_bulk = NULL,
.f_lookup = rte_table_hash_lru_lookup,
.f_stats = rte_table_hash_lru_stats_read,
};
@@ -1091,6 +1093,8 @@ struct rte_table_ops rte_table_hash_lru_dosig_ops = {
.f_free = rte_table_hash_lru_free,
.f_add = rte_table_hash_lru_entry_add,
.f_delete = rte_table_hash_lru_entry_delete,
+ .f_add_bulk = NULL,
+ .f_delete_bulk = NULL,
.f_lookup = rte_table_hash_lru_lookup_dosig,
.f_stats = rte_table_hash_lru_stats_read,
};
diff --git a/lib/librte_table/rte_table_lpm.c b/lib/librte_table/rte_table_lpm.c
index 849d899..673f401 100644
--- a/lib/librte_table/rte_table_lpm.c
+++ b/lib/librte_table/rte_table_lpm.c
@@ -377,6 +377,8 @@ struct rte_table_ops rte_table_lpm_ops = {
.f_free = rte_table_lpm_free,
.f_add = rte_table_lpm_entry_add,
.f_delete = rte_table_lpm_entry_delete,
+ .f_add_bulk = NULL,
+ .f_delete_bulk = NULL,
.f_lookup = rte_table_lpm_lookup,
.f_stats = rte_table_lpm_stats_read,
};
diff --git a/lib/librte_table/rte_table_lpm_ipv6.c b/lib/librte_table/rte_table_lpm_ipv6.c
index e9bc6a7..836f4cf 100644
--- a/lib/librte_table/rte_table_lpm_ipv6.c
+++ b/lib/librte_table/rte_table_lpm_ipv6.c
@@ -391,6 +391,8 @@ struct rte_table_ops rte_table_lpm_ipv6_ops = {
.f_free = rte_table_lpm_ipv6_free,
.f_add = rte_table_lpm_ipv6_entry_add,
.f_delete = rte_table_lpm_ipv6_entry_delete,
+ .f_add_bulk = NULL,
+ .f_delete_bulk = NULL,
.f_lookup = rte_table_lpm_ipv6_lookup,
.f_stats = rte_table_lpm_ipv6_stats_read,
};
diff --git a/lib/librte_table/rte_table_stub.c b/lib/librte_table/rte_table_stub.c
index c1065ef..691d681 100644
--- a/lib/librte_table/rte_table_stub.c
+++ b/lib/librte_table/rte_table_stub.c
@@ -114,6 +114,8 @@ struct rte_table_ops rte_table_stub_ops = {
.f_free = NULL,
.f_add = NULL,
.f_delete = NULL,
+ .f_add_bulk = NULL,
+ .f_delete_bulk = NULL,
.f_lookup = rte_table_stub_lookup,
.f_stats = rte_table_stub_stats_read,
};
--
1.9.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [dpdk-dev] [PATCH v4 2/5] pipeline: added bulk add/delete functions for table
2015-10-20 13:01 [dpdk-dev] [PATCH v4 0/5] pipeline: add bulk add/delete functions for table Michal Jastrzebski
2015-10-20 13:01 ` [dpdk-dev] [PATCH v4 1/5] table: added " Michal Jastrzebski
@ 2015-10-20 13:01 ` Michal Jastrzebski
2015-10-20 13:01 ` [dpdk-dev] [PATCH v4 3/5] test_table: added check for bulk add/delete to acl table unit test Michal Jastrzebski
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Michal Jastrzebski @ 2015-10-20 13:01 UTC (permalink / raw)
To: dev
From: Marcin Kerlin <marcinx.kerlin@intel.com>
Added functions for adding/deleting multiple records to table owned by
pipeline. The LIBABIVER number is incremented for table and pipeline
libraries.
Signed-off-by: Maciej Gajdzica <maciejx.t.gajdzica@intel.com>
Signed-off-by: Marcin Kerlin <marcinx.kerlin@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
lib/librte_pipeline/Makefile | 2 +-
lib/librte_pipeline/rte_pipeline.c | 106 +++++++++++++++++++++++++++
lib/librte_pipeline/rte_pipeline.h | 64 ++++++++++++++++
lib/librte_pipeline/rte_pipeline_version.map | 9 +++
4 files changed, 180 insertions(+), 1 deletion(-)
diff --git a/lib/librte_pipeline/Makefile b/lib/librte_pipeline/Makefile
index 15e406b..1166d3c 100644
--- a/lib/librte_pipeline/Makefile
+++ b/lib/librte_pipeline/Makefile
@@ -41,7 +41,7 @@ CFLAGS += $(WERROR_FLAGS)
EXPORT_MAP := rte_pipeline_version.map
-LIBABIVER := 1
+LIBABIVER := 2
#
# all source are stored in SRCS-y
diff --git a/lib/librte_pipeline/rte_pipeline.c b/lib/librte_pipeline/rte_pipeline.c
index bd700d2..56022f4 100644
--- a/lib/librte_pipeline/rte_pipeline.c
+++ b/lib/librte_pipeline/rte_pipeline.c
@@ -587,6 +587,112 @@ rte_pipeline_table_entry_delete(struct rte_pipeline *p,
return (table->ops.f_delete)(table->h_table, key, key_found, entry);
}
+int rte_pipeline_table_entry_add_bulk(struct rte_pipeline *p,
+ uint32_t table_id,
+ void **keys,
+ struct rte_pipeline_table_entry **entries,
+ uint32_t n_keys,
+ int *key_found,
+ struct rte_pipeline_table_entry **entries_ptr)
+{
+ struct rte_table *table;
+ uint32_t i;
+
+ /* Check input arguments */
+ if (p == NULL) {
+ RTE_LOG(ERR, PIPELINE, "%s: pipeline parameter is NULL\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (keys == NULL) {
+ RTE_LOG(ERR, PIPELINE, "%s: keys parameter is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ if (entries == NULL) {
+ RTE_LOG(ERR, PIPELINE, "%s: entries parameter is NULL\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (table_id >= p->num_tables) {
+ RTE_LOG(ERR, PIPELINE,
+ "%s: table_id %d out of range\n", __func__, table_id);
+ return -EINVAL;
+ }
+
+ table = &p->tables[table_id];
+
+ if (table->ops.f_add_bulk == NULL) {
+ RTE_LOG(ERR, PIPELINE, "%s: f_add_bulk function pointer NULL\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < n_keys; i++) {
+ if ((entries[i]->action == RTE_PIPELINE_ACTION_TABLE) &&
+ table->table_next_id_valid &&
+ (entries[i]->table_id != table->table_next_id)) {
+ RTE_LOG(ERR, PIPELINE,
+ "%s: Tree-like topologies not allowed\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ /* Add entry */
+ for (i = 0; i < n_keys; i++) {
+ if ((entries[i]->action == RTE_PIPELINE_ACTION_TABLE) &&
+ (table->table_next_id_valid == 0)) {
+ table->table_next_id = entries[i]->table_id;
+ table->table_next_id_valid = 1;
+ }
+ }
+
+ return (table->ops.f_add_bulk)(table->h_table, keys, (void **) entries,
+ n_keys, key_found, (void **) entries_ptr);
+}
+
+int rte_pipeline_table_entry_delete_bulk(struct rte_pipeline *p,
+ uint32_t table_id,
+ void **keys,
+ uint32_t n_keys,
+ int *key_found,
+ struct rte_pipeline_table_entry **entries)
+{
+ struct rte_table *table;
+
+ /* Check input arguments */
+ if (p == NULL) {
+ RTE_LOG(ERR, PIPELINE, "%s: pipeline parameter NULL\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (keys == NULL) {
+ RTE_LOG(ERR, PIPELINE, "%s: key parameter is NULL\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (table_id >= p->num_tables) {
+ RTE_LOG(ERR, PIPELINE,
+ "%s: table_id %d out of range\n", __func__, table_id);
+ return -EINVAL;
+ }
+
+ table = &p->tables[table_id];
+
+ if (table->ops.f_delete_bulk == NULL) {
+ RTE_LOG(ERR, PIPELINE,
+ "%s: f_delete function pointer NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ return (table->ops.f_delete_bulk)(table->h_table, keys, n_keys, key_found,
+ (void **) entries);
+}
+
/*
* Port
*
diff --git a/lib/librte_pipeline/rte_pipeline.h b/lib/librte_pipeline/rte_pipeline.h
index 59e0710..5459324 100644
--- a/lib/librte_pipeline/rte_pipeline.h
+++ b/lib/librte_pipeline/rte_pipeline.h
@@ -466,6 +466,70 @@ int rte_pipeline_table_entry_delete(struct rte_pipeline *p,
struct rte_pipeline_table_entry *entry);
/**
+ * Pipeline table entry add bulk
+ *
+ * @param p
+ * Handle to pipeline instance
+ * @param table_id
+ * Table ID (returned by previous invocation of pipeline table create)
+ * @param keys
+ * Array containing table entry keys
+ * @param entries
+ * Array containung new contents for every table entry identified by key
+ * @param n_keys
+ * Number of keys to add
+ * @param key_found
+ * On successful invocation, key_found for every item in the array is set to
+ * TRUE (value different than 0) if key was already present in the table
+ * before the add operation and to FALSE (value 0) if not
+ * @param entries_ptr
+ * On successful invocation, array *entries_ptr stores pointer to every table
+ * entry associated with key. This can be used for further read-write accesses
+ * to this table entry and is valid until the key is deleted from the table or
+ * re-added (usually for associating different actions and/or action meta-data
+ * to the current key)
+ * @return
+ * 0 on success, error code otherwise
+ */
+int rte_pipeline_table_entry_add_bulk(struct rte_pipeline *p,
+ uint32_t table_id,
+ void **keys,
+ struct rte_pipeline_table_entry **entries,
+ uint32_t n_keys,
+ int *key_found,
+ struct rte_pipeline_table_entry **entries_ptr);
+
+/**
+ * Pipeline table entry delete bulk
+ *
+ * @param p
+ * Handle to pipeline instance
+ * @param table_id
+ * Table ID (returned by previous invocation of pipeline table create)
+ * @param keys
+ * Array containing table entry keys
+ * @param n_keys
+ * Number of keys to delete
+ * @param key_found
+ * On successful invocation, key_found for every item in the array is set to
+ * TRUE (value different than 0) if key was found in the table before the
+ * delete operation and to FALSE (value 0) if not
+ * @param entries
+ * If entries pointer is NULL, this pointer is ignored for every entry found.
+ * Else, after successful invocation, if specific key is found in the table
+ * and entry points to a valid buffer, the table entry contents (as it was
+ * before the delete was performed) is copied to this buffer.
+ * @return
+ * 0 on success, error code otherwise
+ */
+int rte_pipeline_table_entry_delete_bulk(struct rte_pipeline *p,
+ uint32_t table_id,
+ void **keys,
+ uint32_t n_keys,
+ int *key_found,
+ struct rte_pipeline_table_entry **entries);
+
+/**
* Read pipeline table stats.
*
* This function reads table statistics identified by *table_id* of given
diff --git a/lib/librte_pipeline/rte_pipeline_version.map b/lib/librte_pipeline/rte_pipeline_version.map
index 8f25d0f..1ff953e 100644
--- a/lib/librte_pipeline/rte_pipeline_version.map
+++ b/lib/librte_pipeline/rte_pipeline_version.map
@@ -29,3 +29,12 @@ DPDK_2.1 {
rte_pipeline_table_stats_read;
} DPDK_2.0;
+
+
+DPDK_2.2 {
+ global:
+
+ rte_pipeline_table_entry_add_bulk;
+ rte_pipeline_table_entry_delete_bulk;
+
+} DPDK_2.1;
\ No newline at end of file
--
1.9.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [dpdk-dev] [PATCH v4 3/5] test_table: added check for bulk add/delete to acl table unit test
2015-10-20 13:01 [dpdk-dev] [PATCH v4 0/5] pipeline: add bulk add/delete functions for table Michal Jastrzebski
2015-10-20 13:01 ` [dpdk-dev] [PATCH v4 1/5] table: added " Michal Jastrzebski
2015-10-20 13:01 ` [dpdk-dev] [PATCH v4 2/5] pipeline: " Michal Jastrzebski
@ 2015-10-20 13:01 ` Michal Jastrzebski
2015-10-20 13:01 ` [dpdk-dev] [PATCH v4 4/5] ip_pipline: added cli commands for bulk add/delete to firewall pipeline Michal Jastrzebski
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Michal Jastrzebski @ 2015-10-20 13:01 UTC (permalink / raw)
To: dev
From: Marcin Kerlin <marcinx.kerlin@intel.com>
Added to acl table unit test check for bulk add and bulk delete.
Signed-off-by: Maciej Gajdzica <maciejx.t.gajdzica@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
app/test/test_table_acl.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 166 insertions(+)
diff --git a/app/test/test_table_acl.c b/app/test/test_table_acl.c
index e4e9b9c..fe8e545 100644
--- a/app/test/test_table_acl.c
+++ b/app/test/test_table_acl.c
@@ -253,6 +253,94 @@ parse_cb_ipv4_rule(char *str, struct rte_table_acl_rule_add_params *v)
return 0;
}
+static int
+parse_cb_ipv4_rule_del(char *str, struct rte_table_acl_rule_delete_params *v)
+{
+ int i, rc;
+ char *s, *sp, *in[CB_FLD_NUM];
+ static const char *dlm = " \t\n";
+
+ /*
+ ** Skip leading '@'
+ */
+ if (strchr(str, '@') != str)
+ return -EINVAL;
+
+ s = str + 1;
+
+ /*
+ * Populate the 'in' array with the location of each
+ * field in the string we're parsing
+ */
+ for (i = 0; i != DIM(in); i++) {
+ in[i] = strtok_r(s, dlm, &sp);
+ if (in[i] == NULL)
+ return -EINVAL;
+ s = NULL;
+ }
+
+ /* Parse x.x.x.x/x */
+ rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR],
+ &v->field_value[SRC_FIELD_IPV4].value.u32,
+ &v->field_value[SRC_FIELD_IPV4].mask_range.u32);
+ if (rc != 0) {
+ RTE_LOG(ERR, PIPELINE, "failed to read src address/mask: %s\n",
+ in[CB_FLD_SRC_ADDR]);
+ return rc;
+ }
+
+ printf("V=%u, mask=%u\n", v->field_value[SRC_FIELD_IPV4].value.u32,
+ v->field_value[SRC_FIELD_IPV4].mask_range.u32);
+
+ /* Parse x.x.x.x/x */
+ rc = parse_ipv4_net(in[CB_FLD_DST_ADDR],
+ &v->field_value[DST_FIELD_IPV4].value.u32,
+ &v->field_value[DST_FIELD_IPV4].mask_range.u32);
+ if (rc != 0) {
+ RTE_LOG(ERR, PIPELINE, "failed to read dest address/mask: %s\n",
+ in[CB_FLD_DST_ADDR]);
+ return rc;
+ }
+
+ printf("V=%u, mask=%u\n", v->field_value[DST_FIELD_IPV4].value.u32,
+ v->field_value[DST_FIELD_IPV4].mask_range.u32);
+ /* Parse n:n */
+ rc = parse_port_range(in[CB_FLD_SRC_PORT_RANGE],
+ &v->field_value[SRCP_FIELD_IPV4].value.u16,
+ &v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
+ if (rc != 0) {
+ RTE_LOG(ERR, PIPELINE, "failed to read source port range: %s\n",
+ in[CB_FLD_SRC_PORT_RANGE]);
+ return rc;
+ }
+
+ printf("V=%u, mask=%u\n", v->field_value[SRCP_FIELD_IPV4].value.u16,
+ v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
+ /* Parse n:n */
+ rc = parse_port_range(in[CB_FLD_DST_PORT_RANGE],
+ &v->field_value[DSTP_FIELD_IPV4].value.u16,
+ &v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
+ if (rc != 0) {
+ RTE_LOG(ERR, PIPELINE, "failed to read dest port range: %s\n",
+ in[CB_FLD_DST_PORT_RANGE]);
+ return rc;
+ }
+
+ printf("V=%u, mask=%u\n", v->field_value[DSTP_FIELD_IPV4].value.u16,
+ v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
+ /* parse 0/0xnn */
+ GET_CB_FIELD(in[CB_FLD_PROTO],
+ v->field_value[PROTO_FIELD_IPV4].value.u8,
+ 0, UINT8_MAX, '/');
+ GET_CB_FIELD(in[CB_FLD_PROTO],
+ v->field_value[PROTO_FIELD_IPV4].mask_range.u8,
+ 0, UINT8_MAX, 0);
+
+ printf("V=%u, mask=%u\n",
+ (unsigned int)v->field_value[PROTO_FIELD_IPV4].value.u8,
+ v->field_value[PROTO_FIELD_IPV4].mask_range.u8);
+ return 0;
+}
/*
* The format for these rules DO NOT need the port ranges to be
@@ -393,6 +481,84 @@ setup_acl_pipeline(void)
}
}
+ /* Add bulk entries to tables */
+ for (i = 0; i < N_PORTS; i++) {
+ struct rte_table_acl_rule_add_params keys[5];
+ struct rte_pipeline_table_entry entries[5];
+ struct rte_table_acl_rule_add_params *key_array[5];
+ struct rte_pipeline_table_entry *table_entries[5];
+ int key_found[5];
+ struct rte_pipeline_table_entry *table_entries_ptr[5];
+ struct rte_pipeline_table_entry entries_ptr[5];
+
+ parser = parse_cb_ipv4_rule;
+ for (n = 0; n < 5; n++) {
+ memset(&keys[n], 0, sizeof(struct rte_table_acl_rule_add_params));
+ key_array[n] = &keys[n];
+
+ snprintf(line, sizeof(line), "%s", lines[n]);
+ printf("PARSING [%s]\n", line);
+
+ ret = parser(line, &keys[n]);
+ if (ret != 0) {
+ RTE_LOG(ERR, PIPELINE,
+ "line %u: parse_cb_ipv4vlan_rule"
+ " failed, error code: %d (%s)\n",
+ n, ret, strerror(-ret));
+ return ret;
+ }
+
+ keys[n].priority = RTE_ACL_MAX_PRIORITY - n - 1;
+
+ entries[n].action = RTE_PIPELINE_ACTION_PORT;
+ entries[n].port_id = port_out_id[i^1];
+ table_entries[n] = &entries[n];
+ table_entries_ptr[n] = &entries_ptr[n];
+ }
+
+ ret = rte_pipeline_table_entry_add_bulk(p, table_id[i],
+ (void **)key_array, table_entries, 5, key_found, table_entries_ptr);
+ if (ret < 0) {
+ rte_panic("Add entry bulk to table %u failed (%d)\n",
+ table_id[i], ret);
+ goto fail;
+ }
+ }
+
+ /* Delete bulk entries from tables */
+ for (i = 0; i < N_PORTS; i++) {
+ struct rte_table_acl_rule_delete_params keys[5];
+ struct rte_table_acl_rule_delete_params *key_array[5];
+ struct rte_pipeline_table_entry *table_entries[5];
+ int key_found[5];
+
+ for (n = 0; n < 5; n++) {
+ memset(&keys[n], 0, sizeof(struct rte_table_acl_rule_delete_params));
+ key_array[n] = &keys[n];
+
+ snprintf(line, sizeof(line), "%s", lines[n]);
+ printf("PARSING [%s]\n", line);
+
+ ret = parse_cb_ipv4_rule_del(line, &keys[n]);
+ if (ret != 0) {
+ RTE_LOG(ERR, PIPELINE,
+ "line %u: parse_cb_ipv4vlan_rule"
+ " failed, error code: %d (%s)\n",
+ n, ret, strerror(-ret));
+ return ret;
+ }
+ }
+
+ ret = rte_pipeline_table_entry_delete_bulk(p, table_id[i],
+ (void **)key_array, 5, key_found, table_entries);
+ if (ret < 0) {
+ rte_panic("Delete bulk entries from table %u failed (%d)\n",
+ table_id[i], ret);
+ goto fail;
+ } else
+ printf("Bulk deleted rules.\n");
+ }
+
/* Add entries to tables */
for (i = 0; i < N_PORTS; i++) {
struct rte_pipeline_table_entry table_entry = {
--
1.9.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [dpdk-dev] [PATCH v4 4/5] ip_pipline: added cli commands for bulk add/delete to firewall pipeline
2015-10-20 13:01 [dpdk-dev] [PATCH v4 0/5] pipeline: add bulk add/delete functions for table Michal Jastrzebski
` (2 preceding siblings ...)
2015-10-20 13:01 ` [dpdk-dev] [PATCH v4 3/5] test_table: added check for bulk add/delete to acl table unit test Michal Jastrzebski
@ 2015-10-20 13:01 ` Michal Jastrzebski
2015-10-20 13:01 ` [dpdk-dev] [PATCH v4 5/5] doc: modify release notes and deprecation notice for table and pipeline Michal Jastrzebski
2015-11-25 22:20 ` [dpdk-dev] [PATCH v4 0/5] pipeline: add bulk add/delete functions for table Thomas Monjalon
5 siblings, 0 replies; 7+ messages in thread
From: Michal Jastrzebski @ 2015-10-20 13:01 UTC (permalink / raw)
To: dev
From: Marcin Kerlin <marcinx.kerlin@intel.com>
Added two new cli commands to firewall pipeline. Commands bulk add and
bulk delete takes as argument a file with rules to add/delete. The file
is parsed, and then rules are passed to backend functions which
add/delete records from pipeline tables.
Signed-off-by: Maciej Gajdzica <maciejx.t.gajdzica@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
examples/ip_pipeline/pipeline/pipeline_firewall.c | 858 +++++++++++++++++++++
examples/ip_pipeline/pipeline/pipeline_firewall.h | 14 +
.../ip_pipeline/pipeline/pipeline_firewall_be.c | 157 ++++
.../ip_pipeline/pipeline/pipeline_firewall_be.h | 38 +
4 files changed, 1067 insertions(+)
diff --git a/examples/ip_pipeline/pipeline/pipeline_firewall.c b/examples/ip_pipeline/pipeline/pipeline_firewall.c
index f6924ab..4137923 100644
--- a/examples/ip_pipeline/pipeline/pipeline_firewall.c
+++ b/examples/ip_pipeline/pipeline/pipeline_firewall.c
@@ -51,6 +51,8 @@
#include "pipeline_common_fe.h"
#include "pipeline_firewall.h"
+#define BUF_SIZE 1024
+
struct app_pipeline_firewall_rule {
struct pipeline_firewall_key key;
int32_t priority;
@@ -73,6 +75,18 @@ struct app_pipeline_firewall {
void *default_rule_entry_ptr;
};
+struct app_pipeline_add_bulk_params {
+ struct pipeline_firewall_key *keys;
+ uint32_t n_keys;
+ uint32_t *priorities;
+ uint32_t *port_ids;
+};
+
+struct app_pipeline_del_bulk_params {
+ struct pipeline_firewall_key *keys;
+ uint32_t n_keys;
+};
+
static void
print_firewall_ipv4_rule(struct app_pipeline_firewall_rule *rule)
{
@@ -256,6 +270,358 @@ app_pipeline_firewall_key_check_and_normalize(struct pipeline_firewall_key *key)
}
}
+static int
+app_pipeline_add_bulk_parse_file(char *filename,
+ struct app_pipeline_add_bulk_params *params)
+{
+ FILE *f;
+ char file_buf[BUF_SIZE];
+ uint32_t i;
+ int status = 0;
+
+ f = fopen(filename, "r");
+ if (f == NULL)
+ return -1;
+
+ params->n_keys = 0;
+ while (fgets(file_buf, BUF_SIZE, f) != NULL)
+ params->n_keys++;
+ rewind(f);
+
+ if (params->n_keys == 0) {
+ status = -1;
+ goto end;
+ }
+
+ params->keys = rte_malloc(NULL,
+ params->n_keys * sizeof(struct pipeline_firewall_key),
+ RTE_CACHE_LINE_SIZE);
+ if (params->keys == NULL) {
+ status = -1;
+ goto end;
+ }
+
+ params->priorities = rte_malloc(NULL,
+ params->n_keys * sizeof(uint32_t),
+ RTE_CACHE_LINE_SIZE);
+ if (params->priorities == NULL) {
+ status = -1;
+ goto end;
+ }
+
+ params->port_ids = rte_malloc(NULL,
+ params->n_keys * sizeof(uint32_t),
+ RTE_CACHE_LINE_SIZE);
+ if (params->port_ids == NULL) {
+ status = -1;
+ goto end;
+ }
+
+ i = 0;
+ while (fgets(file_buf, BUF_SIZE, f) != NULL) {
+ char *str;
+
+ str = strtok(file_buf, " ");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->priorities[i] = atoi(str);
+
+ str = strtok(NULL, " .");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.src_ip = atoi(str)<<24;
+
+ str = strtok(NULL, " .");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str)<<16;
+
+ str = strtok(NULL, " .");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str)<<8;
+
+ str = strtok(NULL, " .");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str);
+
+ str = strtok(NULL, " ");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.src_ip_mask = atoi(str);
+
+ str = strtok(NULL, " .");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.dst_ip = atoi(str)<<24;
+
+ str = strtok(NULL, " .");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.dst_ip |= atoi(str)<<16;
+
+ str = strtok(NULL, " .");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.dst_ip |= atoi(str)<<8;
+
+ str = strtok(NULL, " .");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.dst_ip |= atoi(str);
+
+ str = strtok(NULL, " ");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.dst_ip_mask = atoi(str);
+
+ str = strtok(NULL, " ");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.src_port_from = atoi(str);
+
+ str = strtok(NULL, " ");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.src_port_to = atoi(str);
+
+ str = strtok(NULL, " ");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.dst_port_from = atoi(str);
+
+ str = strtok(NULL, " ");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.dst_port_to = atoi(str);
+
+ str = strtok(NULL, " ");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.proto = atoi(str);
+
+ str = strtok(NULL, " ");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ /* Need to add 2 to str to skip leading 0x */
+ params->keys[i].key.ipv4_5tuple.proto_mask = strtol(str+2, NULL, 16);
+
+ str = strtok(NULL, " ");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->port_ids[i] = atoi(str);
+ params->keys[i].type = PIPELINE_FIREWALL_IPV4_5TUPLE;
+
+ i++;
+ }
+
+end:
+ fclose(f);
+ return status;
+}
+
+static int
+app_pipeline_del_bulk_parse_file(char *filename,
+ struct app_pipeline_del_bulk_params *params)
+{
+ FILE *f;
+ char file_buf[BUF_SIZE];
+ uint32_t i;
+ int status = 0;
+
+ f = fopen(filename, "r");
+ if (f == NULL)
+ return -1;
+
+ params->n_keys = 0;
+ while (fgets(file_buf, BUF_SIZE, f) != NULL)
+ params->n_keys++;
+ rewind(f);
+
+ if (params->n_keys == 0) {
+ status = -1;
+ goto end;
+ }
+
+ params->keys = rte_malloc(NULL,
+ params->n_keys * sizeof(struct pipeline_firewall_key),
+ RTE_CACHE_LINE_SIZE);
+ if (params->keys == NULL) {
+ status = -1;
+ goto end;
+ }
+
+ i = 0;
+ while (fgets(file_buf, BUF_SIZE, f) != NULL) {
+ char *str;
+
+ str = strtok(file_buf, " .");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.src_ip = atoi(str)<<24;
+
+ str = strtok(NULL, " .");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str)<<16;
+
+ str = strtok(NULL, " .");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str)<<8;
+
+ str = strtok(NULL, " .");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.src_ip |= atoi(str);
+
+ str = strtok(NULL, " ");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.src_ip_mask = atoi(str);
+
+ str = strtok(NULL, " .");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.dst_ip = atoi(str)<<24;
+
+ str = strtok(NULL, " .");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.dst_ip |= atoi(str)<<16;
+
+ str = strtok(NULL, " .");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.dst_ip |= atoi(str)<<8;
+
+ str = strtok(NULL, " .");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.dst_ip |= atoi(str);
+
+ str = strtok(NULL, " ");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.dst_ip_mask = atoi(str);
+
+ str = strtok(NULL, " ");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.src_port_from = atoi(str);
+
+ str = strtok(NULL, " ");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.src_port_to = atoi(str);
+
+ str = strtok(NULL, " ");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.dst_port_from = atoi(str);
+
+ str = strtok(NULL, " ");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.dst_port_to = atoi(str);
+
+ str = strtok(NULL, " ");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ params->keys[i].key.ipv4_5tuple.proto = atoi(str);
+
+ str = strtok(NULL, " ");
+ if (str == NULL) {
+ status = -1;
+ goto end;
+ }
+ /* Need to add 2 to str to skip leading 0x */
+ params->keys[i].key.ipv4_5tuple.proto_mask = strtol(str+2, NULL, 16);
+
+ params->keys[i].type = PIPELINE_FIREWALL_IPV4_5TUPLE;
+
+ i++;
+ }
+
+ for (i = 0; i < params->n_keys; i++) {
+ if (app_pipeline_firewall_key_check_and_normalize(¶ms->keys[i]) != 0) {
+ status = -1;
+ goto end;
+ }
+ }
+
+end:
+ fclose(f);
+ return status;
+}
+
int
app_pipeline_firewall_add_rule(struct app_params *app,
uint32_t pipeline_id,
@@ -407,6 +773,332 @@ app_pipeline_firewall_delete_rule(struct app_params *app,
}
int
+app_pipeline_firewall_add_bulk(struct app_params *app,
+ uint32_t pipeline_id,
+ struct pipeline_firewall_key *keys,
+ uint32_t n_keys,
+ uint32_t *priorities,
+ uint32_t *port_ids)
+{
+ struct app_pipeline_firewall *p;
+ struct pipeline_firewall_add_bulk_msg_req *req;
+ struct pipeline_firewall_add_bulk_msg_rsp *rsp;
+
+ struct app_pipeline_firewall_rule **rules;
+ int *new_rules;
+
+ int *keys_found;
+ void **entries_ptr;
+
+ uint32_t i;
+ int status = 0;
+
+ /* Check input arguments */
+ if (app == NULL)
+ return -1;
+
+ p = app_pipeline_data_fe(app, pipeline_id);
+ if (p == NULL)
+ return -1;
+
+ rules = rte_malloc(NULL,
+ n_keys * sizeof(struct app_pipeline_firewall_rule *),
+ RTE_CACHE_LINE_SIZE);
+ if (rules == NULL)
+ return -1;
+
+ new_rules = rte_malloc(NULL,
+ n_keys * sizeof(int),
+ RTE_CACHE_LINE_SIZE);
+ if (new_rules == NULL) {
+ rte_free(rules);
+ return -1;
+ }
+
+ /* check data integrity and add to rule list */
+ for (i = 0; i < n_keys; i++) {
+ if (port_ids[i] >= p->n_ports_out) {
+ rte_free(rules);
+ rte_free(new_rules);
+ return -1;
+ }
+
+ if (app_pipeline_firewall_key_check_and_normalize(&keys[i]) != 0) {
+ rte_free(rules);
+ rte_free(new_rules);
+ return -1;
+ }
+
+ rules[i] = app_pipeline_firewall_rule_find(p, &keys[i]);
+ new_rules[i] = (rules[i] == NULL);
+ if (rules[i] == NULL) {
+ rules[i] = rte_malloc(NULL, sizeof(rules[i]),
+ RTE_CACHE_LINE_SIZE);
+
+ if (rules[i] == NULL) {
+ uint32_t j;
+
+ for (j = 0; j <= i; j++)
+ if (new_rules[j])
+ rte_free(rules[j]);
+
+ rte_free(rules);
+ rte_free(new_rules);
+ return -1;
+ }
+ }
+ }
+
+ keys_found = rte_malloc(NULL,
+ n_keys * sizeof(int),
+ RTE_CACHE_LINE_SIZE);
+ if (keys_found == NULL) {
+ uint32_t j;
+
+ for (j = 0; j < n_keys; j++)
+ if (new_rules[j])
+ rte_free(rules[j]);
+
+ rte_free(rules);
+ rte_free(new_rules);
+ return -1;
+ }
+
+ entries_ptr = rte_malloc(NULL,
+ n_keys * sizeof(struct rte_pipeline_table_entry *),
+ RTE_CACHE_LINE_SIZE);
+ if (entries_ptr == NULL) {
+ uint32_t j;
+
+ for (j = 0; j < n_keys; j++)
+ if (new_rules[j])
+ rte_free(rules[j]);
+
+ rte_free(rules);
+ rte_free(new_rules);
+ rte_free(keys_found);
+ return -1;
+ }
+ for (i = 0; i < n_keys; i++) {
+ entries_ptr[i] = rte_malloc(NULL,
+ sizeof(struct rte_pipeline_table_entry),
+ RTE_CACHE_LINE_SIZE);
+
+ if (entries_ptr[i] == NULL) {
+ uint32_t j;
+
+ for (j = 0; j < n_keys; j++)
+ if (new_rules[j])
+ rte_free(rules[j]);
+
+ for (j = 0; j <= i; j++)
+ rte_free(entries_ptr[j]);
+
+ rte_free(rules);
+ rte_free(new_rules);
+ rte_free(keys_found);
+ rte_free(entries_ptr);
+ return -1;
+ }
+ }
+
+ /* Allocate and write request */
+ req = app_msg_alloc(app);
+ if (req == NULL) {
+ uint32_t j;
+
+ for (j = 0; j < n_keys; j++)
+ if (new_rules[j])
+ rte_free(rules[j]);
+
+ for (j = 0; j < n_keys; j++)
+ rte_free(entries_ptr[j]);
+
+ rte_free(rules);
+ rte_free(new_rules);
+ rte_free(keys_found);
+ rte_free(entries_ptr);
+ return -1;
+ }
+
+ req->type = PIPELINE_MSG_REQ_CUSTOM;
+ req->subtype = PIPELINE_FIREWALL_MSG_REQ_ADD_BULK;
+
+ req->keys = keys;
+ req->n_keys = n_keys;
+ req->port_ids = port_ids;
+ req->priorities = priorities;
+ req->keys_found = keys_found;
+ req->entries_ptr = entries_ptr;
+
+ /* Send request and wait for response */
+ rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
+ if (rsp == NULL) {
+ uint32_t j;
+
+ for (j = 0; j < n_keys; j++)
+ if (new_rules[j])
+ rte_free(rules[j]);
+
+ for (j = 0; j < n_keys; j++)
+ rte_free(entries_ptr[j]);
+
+ rte_free(rules);
+ rte_free(new_rules);
+ rte_free(keys_found);
+ rte_free(entries_ptr);
+ return -1;
+ }
+
+ if (rsp->status) {
+ for (i = 0; i < n_keys; i++)
+ if (new_rules[i])
+ rte_free(rules[i]);
+
+ for (i = 0; i < n_keys; i++)
+ rte_free(entries_ptr[i]);
+
+ status = -1;
+ goto cleanup;
+ }
+
+ for (i = 0; i < n_keys; i++) {
+ if (entries_ptr[i] == NULL ||
+ ((new_rules[i] == 0) && (keys_found[i] == 0)) ||
+ ((new_rules[i] == 1) && (keys_found[i] == 1))) {
+ for (i = 0; i < n_keys; i++)
+ if (new_rules[i])
+ rte_free(rules[i]);
+
+ for (i = 0; i < n_keys; i++)
+ rte_free(entries_ptr[i]);
+
+ status = -1;
+ goto cleanup;
+ }
+ }
+
+ for (i = 0; i < n_keys; i++) {
+ memcpy(&rules[i]->key, &keys[i], sizeof(keys[i]));
+ rules[i]->priority = priorities[i];
+ rules[i]->port_id = port_ids[i];
+ rules[i]->entry_ptr = entries_ptr[i];
+
+ /* Commit rule */
+ if (new_rules[i]) {
+ TAILQ_INSERT_TAIL(&p->rules, rules[i], node);
+ p->n_rules++;
+ }
+
+ print_firewall_ipv4_rule(rules[i]);
+ }
+
+cleanup:
+ app_msg_free(app, rsp);
+ rte_free(rules);
+ rte_free(new_rules);
+ rte_free(keys_found);
+ rte_free(entries_ptr);
+
+ return status;
+}
+
+int
+app_pipeline_firewall_delete_bulk(struct app_params *app,
+ uint32_t pipeline_id,
+ struct pipeline_firewall_key *keys,
+ uint32_t n_keys)
+{
+ struct app_pipeline_firewall *p;
+ struct pipeline_firewall_del_bulk_msg_req *req;
+ struct pipeline_firewall_del_bulk_msg_rsp *rsp;
+
+ struct app_pipeline_firewall_rule **rules;
+ int *keys_found;
+
+ uint32_t i;
+ int status = 0;
+
+ /* Check input arguments */
+ if (app == NULL)
+ return -1;
+
+ p = app_pipeline_data_fe(app, pipeline_id);
+ if (p == NULL)
+ return -1;
+
+ rules = rte_malloc(NULL,
+ n_keys * sizeof(struct app_pipeline_firewall_rule *),
+ RTE_CACHE_LINE_SIZE);
+ if (rules == NULL)
+ return -1;
+
+ for (i = 0; i < n_keys; i++) {
+ if (app_pipeline_firewall_key_check_and_normalize(&keys[i]) != 0) {
+ return -1;
+ }
+
+ rules[i] = app_pipeline_firewall_rule_find(p, &keys[i]);
+ }
+
+ keys_found = rte_malloc(NULL,
+ n_keys * sizeof(int),
+ RTE_CACHE_LINE_SIZE);
+ if (keys_found == NULL) {
+ rte_free(rules);
+ return -1;
+ }
+
+ /* Allocate and write request */
+ req = app_msg_alloc(app);
+ if (req == NULL) {
+ rte_free(rules);
+ rte_free(keys_found);
+ return -1;
+ }
+
+ req->type = PIPELINE_MSG_REQ_CUSTOM;
+ req->subtype = PIPELINE_FIREWALL_MSG_REQ_DEL_BULK;
+
+ req->keys = keys;
+ req->n_keys = n_keys;
+ req->keys_found = keys_found;
+
+ /* Send request and wait for response */
+ rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
+ if (rsp == NULL) {
+ rte_free(rules);
+ rte_free(keys_found);
+ return -1;
+ }
+
+ if (rsp->status) {
+ status = -1;
+ goto cleanup;
+ }
+
+ for (i = 0; i < n_keys; i++) {
+ if (keys_found[i] == 0) {
+ status = -1;
+ goto cleanup;
+ }
+ }
+
+ for (i = 0; i < n_keys; i++) {
+ TAILQ_REMOVE(&p->rules, rules[i], node);
+ p->n_rules--;
+ rte_free(rules[i]);
+ }
+
+cleanup:
+ app_msg_free(app, rsp);
+ rte_free(rules);
+ rte_free(keys_found);
+
+ return status;
+}
+
+int
app_pipeline_firewall_add_default_rule(struct app_params *app,
uint32_t pipeline_id,
uint32_t port_id)
@@ -795,6 +1487,170 @@ cmdline_parse_inst_t cmd_firewall_del_ipv4 = {
};
/*
+ * p firewall add bulk
+ */
+
+struct cmd_firewall_add_bulk_result {
+ cmdline_fixed_string_t p_string;
+ uint32_t pipeline_id;
+ cmdline_fixed_string_t firewall_string;
+ cmdline_fixed_string_t add_string;
+ cmdline_fixed_string_t bulk_string;
+ cmdline_fixed_string_t file_path;
+};
+
+static void
+cmd_firewall_add_bulk_parsed(
+ void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ void *data)
+{
+ struct cmd_firewall_add_bulk_result *params = parsed_result;
+ struct app_params *app = data;
+ int status;
+
+ struct app_pipeline_add_bulk_params add_bulk_params;
+
+ status = app_pipeline_add_bulk_parse_file(params->file_path, &add_bulk_params);
+ if (status != 0) {
+ printf("Command failed\n");
+ goto end;
+ }
+
+ status = app_pipeline_firewall_add_bulk(app, params->pipeline_id, add_bulk_params.keys,
+ add_bulk_params.n_keys, add_bulk_params.priorities, add_bulk_params.port_ids);
+ if (status != 0) {
+ printf("Command failed\n");
+ goto end;
+ }
+
+end:
+ rte_free(add_bulk_params.keys);
+ rte_free(add_bulk_params.priorities);
+ rte_free(add_bulk_params.port_ids);
+}
+
+cmdline_parse_token_string_t cmd_firewall_add_bulk_p_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_bulk_result, p_string,
+ "p");
+
+cmdline_parse_token_num_t cmd_firewall_add_bulk_pipeline_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_firewall_add_bulk_result, pipeline_id,
+ UINT32);
+
+cmdline_parse_token_string_t cmd_firewall_add_bulk_firewall_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_bulk_result,
+ firewall_string, "firewall");
+
+cmdline_parse_token_string_t cmd_firewall_add_bulk_add_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_bulk_result,
+ add_string, "add");
+
+cmdline_parse_token_string_t cmd_firewall_add_bulk_bulk_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_bulk_result,
+ bulk_string, "bulk");
+
+cmdline_parse_token_string_t cmd_firewall_add_bulk_file_path_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_firewall_add_bulk_result,
+ file_path, NULL);
+
+cmdline_parse_inst_t cmd_firewall_add_bulk = {
+ .f = cmd_firewall_add_bulk_parsed,
+ .data = NULL,
+ .help_str = "Firewall rule add bulk",
+ .tokens = {
+ (void *) &cmd_firewall_add_bulk_p_string,
+ (void *) &cmd_firewall_add_bulk_pipeline_id,
+ (void *) &cmd_firewall_add_bulk_firewall_string,
+ (void *) &cmd_firewall_add_bulk_add_string,
+ (void *) &cmd_firewall_add_bulk_bulk_string,
+ (void *) &cmd_firewall_add_bulk_file_path_string,
+ NULL,
+ },
+};
+
+/*
+ * p firewall del bulk
+ */
+
+struct cmd_firewall_del_bulk_result {
+ cmdline_fixed_string_t p_string;
+ uint32_t pipeline_id;
+ cmdline_fixed_string_t firewall_string;
+ cmdline_fixed_string_t del_string;
+ cmdline_fixed_string_t bulk_string;
+ cmdline_fixed_string_t file_path;
+};
+
+static void
+cmd_firewall_del_bulk_parsed(
+ void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ void *data)
+{
+ struct cmd_firewall_del_bulk_result *params = parsed_result;
+ struct app_params *app = data;
+ int status;
+
+ struct app_pipeline_del_bulk_params del_bulk_params;
+
+ status = app_pipeline_del_bulk_parse_file(params->file_path, &del_bulk_params);
+ if (status != 0) {
+ printf("Command failed\n");
+ goto end;
+ }
+
+ status = app_pipeline_firewall_delete_bulk(app, params->pipeline_id,
+ del_bulk_params.keys, del_bulk_params.n_keys);
+ if (status != 0) {
+ printf("Command failed\n");
+ goto end;
+ }
+
+end:
+ rte_free(del_bulk_params.keys);
+}
+
+cmdline_parse_token_string_t cmd_firewall_del_bulk_p_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_bulk_result, p_string,
+ "p");
+
+cmdline_parse_token_num_t cmd_firewall_del_bulk_pipeline_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_firewall_del_bulk_result, pipeline_id,
+ UINT32);
+
+cmdline_parse_token_string_t cmd_firewall_del_bulk_firewall_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_bulk_result,
+ firewall_string, "firewall");
+
+cmdline_parse_token_string_t cmd_firewall_del_bulk_add_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_bulk_result,
+ del_string, "del");
+
+cmdline_parse_token_string_t cmd_firewall_del_bulk_bulk_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_bulk_result,
+ bulk_string, "bulk");
+
+cmdline_parse_token_string_t cmd_firewall_del_bulk_file_path_string =
+ TOKEN_STRING_INITIALIZER(struct cmd_firewall_del_bulk_result,
+ file_path, NULL);
+
+cmdline_parse_inst_t cmd_firewall_del_bulk = {
+ .f = cmd_firewall_del_bulk_parsed,
+ .data = NULL,
+ .help_str = "Firewall rule del bulk",
+ .tokens = {
+ (void *) &cmd_firewall_del_bulk_p_string,
+ (void *) &cmd_firewall_del_bulk_pipeline_id,
+ (void *) &cmd_firewall_del_bulk_firewall_string,
+ (void *) &cmd_firewall_del_bulk_add_string,
+ (void *) &cmd_firewall_del_bulk_bulk_string,
+ (void *) &cmd_firewall_del_bulk_file_path_string,
+ NULL,
+ },
+};
+
+/*
* p firewall add default
*/
struct cmd_firewall_add_default_result {
@@ -984,6 +1840,8 @@ cmdline_parse_inst_t cmd_firewall_ls = {
static cmdline_parse_ctx_t pipeline_cmds[] = {
(cmdline_parse_inst_t *) &cmd_firewall_add_ipv4,
(cmdline_parse_inst_t *) &cmd_firewall_del_ipv4,
+ (cmdline_parse_inst_t *) &cmd_firewall_add_bulk,
+ (cmdline_parse_inst_t *) &cmd_firewall_del_bulk,
(cmdline_parse_inst_t *) &cmd_firewall_add_default,
(cmdline_parse_inst_t *) &cmd_firewall_del_default,
(cmdline_parse_inst_t *) &cmd_firewall_ls,
diff --git a/examples/ip_pipeline/pipeline/pipeline_firewall.h b/examples/ip_pipeline/pipeline/pipeline_firewall.h
index 82e905d..ccc4e64 100644
--- a/examples/ip_pipeline/pipeline/pipeline_firewall.h
+++ b/examples/ip_pipeline/pipeline/pipeline_firewall.h
@@ -50,6 +50,20 @@ app_pipeline_firewall_delete_rule(struct app_params *app,
struct pipeline_firewall_key *key);
int
+app_pipeline_firewall_add_bulk(struct app_params *app,
+ uint32_t pipeline_id,
+ struct pipeline_firewall_key *keys,
+ uint32_t n_keys,
+ uint32_t *priorities,
+ uint32_t *port_ids);
+
+int
+app_pipeline_firewall_delete_bulk(struct app_params *app,
+ uint32_t pipeline_id,
+ struct pipeline_firewall_key *keys,
+ uint32_t n_keys);
+
+int
app_pipeline_firewall_add_default_rule(struct app_params *app,
uint32_t pipeline_id,
uint32_t port_id);
diff --git a/examples/ip_pipeline/pipeline/pipeline_firewall_be.c b/examples/ip_pipeline/pipeline/pipeline_firewall_be.c
index b6f305f..1c376f7 100644
--- a/examples/ip_pipeline/pipeline/pipeline_firewall_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_firewall_be.c
@@ -80,6 +80,12 @@ static void *
pipeline_firewall_msg_req_del_handler(struct pipeline *p, void *msg);
static void *
+pipeline_firewall_msg_req_add_bulk_handler(struct pipeline *p, void *msg);
+
+static void *
+pipeline_firewall_msg_req_del_bulk_handler(struct pipeline *p, void *msg);
+
+static void *
pipeline_firewall_msg_req_add_default_handler(struct pipeline *p, void *msg);
static void *
@@ -90,6 +96,10 @@ static pipeline_msg_req_handler custom_handlers[] = {
pipeline_firewall_msg_req_add_handler,
[PIPELINE_FIREWALL_MSG_REQ_DEL] =
pipeline_firewall_msg_req_del_handler,
+ [PIPELINE_FIREWALL_MSG_REQ_ADD_BULK] =
+ pipeline_firewall_msg_req_add_bulk_handler,
+ [PIPELINE_FIREWALL_MSG_REQ_DEL_BULK] =
+ pipeline_firewall_msg_req_del_bulk_handler,
[PIPELINE_FIREWALL_MSG_REQ_ADD_DEFAULT] =
pipeline_firewall_msg_req_add_default_handler,
[PIPELINE_FIREWALL_MSG_REQ_DEL_DEFAULT] =
@@ -698,6 +708,153 @@ pipeline_firewall_msg_req_del_handler(struct pipeline *p, void *msg)
return rsp;
}
+static void *
+pipeline_firewall_msg_req_add_bulk_handler(struct pipeline *p, void *msg)
+{
+ struct pipeline_firewall_add_bulk_msg_req *req = msg;
+ struct pipeline_firewall_add_bulk_msg_rsp *rsp = msg;
+
+ struct rte_table_acl_rule_add_params *params[req->n_keys];
+ struct firewall_table_entry *entries[req->n_keys];
+
+ uint32_t i, n_keys;
+
+ n_keys = req->n_keys;
+
+ for (i = 0; i < n_keys; i++) {
+ entries[i] = rte_malloc(NULL,
+ sizeof(struct firewall_table_entry),
+ RTE_CACHE_LINE_SIZE);
+ if (entries[i] == NULL) {
+ rsp->status = -1;
+ return rsp;
+ }
+
+ params[i] = rte_malloc(NULL,
+ sizeof(struct rte_table_acl_rule_add_params),
+ RTE_CACHE_LINE_SIZE);
+ if (params[i] == NULL) {
+ rsp->status = -1;
+ return rsp;
+ }
+
+ entries[i]->head.action = RTE_PIPELINE_ACTION_PORT;
+ entries[i]->head.port_id = p->port_out_id[req->port_ids[i]];
+
+ switch (req->keys[i].type) {
+ case PIPELINE_FIREWALL_IPV4_5TUPLE:
+ params[i]->priority = req->priorities[i];
+ params[i]->field_value[0].value.u8 =
+ req->keys[i].key.ipv4_5tuple.proto;
+ params[i]->field_value[0].mask_range.u8 =
+ req->keys[i].key.ipv4_5tuple.proto_mask;
+ params[i]->field_value[1].value.u32 =
+ req->keys[i].key.ipv4_5tuple.src_ip;
+ params[i]->field_value[1].mask_range.u32 =
+ req->keys[i].key.ipv4_5tuple.src_ip_mask;
+ params[i]->field_value[2].value.u32 =
+ req->keys[i].key.ipv4_5tuple.dst_ip;
+ params[i]->field_value[2].mask_range.u32 =
+ req->keys[i].key.ipv4_5tuple.dst_ip_mask;
+ params[i]->field_value[3].value.u16 =
+ req->keys[i].key.ipv4_5tuple.src_port_from;
+ params[i]->field_value[3].mask_range.u16 =
+ req->keys[i].key.ipv4_5tuple.src_port_to;
+ params[i]->field_value[4].value.u16 =
+ req->keys[i].key.ipv4_5tuple.dst_port_from;
+ params[i]->field_value[4].mask_range.u16 =
+ req->keys[i].key.ipv4_5tuple.dst_port_to;
+ break;
+
+ default:
+ rsp->status = -1; /* Error */
+
+ for (i = 0; i < n_keys; i++) {
+ rte_free(entries[i]);
+ rte_free(params[i]);
+ }
+
+ return rsp;
+ }
+ }
+
+ rsp->status = rte_pipeline_table_entry_add_bulk(p->p, p->table_id[0],
+ (void *)params, (struct rte_pipeline_table_entry **)entries,
+ n_keys, req->keys_found,
+ (struct rte_pipeline_table_entry **)req->entries_ptr);
+
+ for (i = 0; i < n_keys; i++) {
+ rte_free(entries[i]);
+ rte_free(params[i]);
+ }
+
+ return rsp;
+}
+
+static void *
+pipeline_firewall_msg_req_del_bulk_handler(struct pipeline *p, void *msg)
+{
+ struct pipeline_firewall_del_bulk_msg_req *req = msg;
+ struct pipeline_firewall_del_bulk_msg_rsp *rsp = msg;
+
+ struct rte_table_acl_rule_delete_params *params[req->n_keys];
+
+ uint32_t i, n_keys;
+
+ n_keys = req->n_keys;
+
+ for (i = 0; i < n_keys; i++) {
+ params[i] = rte_malloc(NULL,
+ sizeof(struct rte_table_acl_rule_delete_params),
+ RTE_CACHE_LINE_SIZE);
+ if (params[i] == NULL) {
+ rsp->status = -1;
+ return rsp;
+ }
+
+ switch (req->keys[i].type) {
+ case PIPELINE_FIREWALL_IPV4_5TUPLE:
+ params[i]->field_value[0].value.u8 =
+ req->keys[i].key.ipv4_5tuple.proto;
+ params[i]->field_value[0].mask_range.u8 =
+ req->keys[i].key.ipv4_5tuple.proto_mask;
+ params[i]->field_value[1].value.u32 =
+ req->keys[i].key.ipv4_5tuple.src_ip;
+ params[i]->field_value[1].mask_range.u32 =
+ req->keys[i].key.ipv4_5tuple.src_ip_mask;
+ params[i]->field_value[2].value.u32 =
+ req->keys[i].key.ipv4_5tuple.dst_ip;
+ params[i]->field_value[2].mask_range.u32 =
+ req->keys[i].key.ipv4_5tuple.dst_ip_mask;
+ params[i]->field_value[3].value.u16 =
+ req->keys[i].key.ipv4_5tuple.src_port_from;
+ params[i]->field_value[3].mask_range.u16 =
+ req->keys[i].key.ipv4_5tuple.src_port_to;
+ params[i]->field_value[4].value.u16 =
+ req->keys[i].key.ipv4_5tuple.dst_port_from;
+ params[i]->field_value[4].mask_range.u16 =
+ req->keys[i].key.ipv4_5tuple.dst_port_to;
+ break;
+
+ default:
+ rsp->status = -1; /* Error */
+
+ for (i = 0; i < n_keys; i++)
+ rte_free(params[i]);
+
+ return rsp;
+ }
+ }
+
+ rsp->status = rte_pipeline_table_entry_delete_bulk(p->p, p->table_id[0],
+ (void **)¶ms, n_keys, req->keys_found, NULL);
+
+ for (i = 0; i < n_keys; i++)
+ rte_free(params[i]);
+
+ return rsp;
+}
+
void *
pipeline_firewall_msg_req_add_default_handler(struct pipeline *p, void *msg)
{
diff --git a/examples/ip_pipeline/pipeline/pipeline_firewall_be.h b/examples/ip_pipeline/pipeline/pipeline_firewall_be.h
index 8e1fd69..f5b0522 100644
--- a/examples/ip_pipeline/pipeline/pipeline_firewall_be.h
+++ b/examples/ip_pipeline/pipeline/pipeline_firewall_be.h
@@ -63,6 +63,8 @@ struct pipeline_firewall_key {
enum pipeline_firewall_msg_req_type {
PIPELINE_FIREWALL_MSG_REQ_ADD = 0,
PIPELINE_FIREWALL_MSG_REQ_DEL,
+ PIPELINE_FIREWALL_MSG_REQ_ADD_BULK,
+ PIPELINE_FIREWALL_MSG_REQ_DEL_BULK,
PIPELINE_FIREWALL_MSG_REQ_ADD_DEFAULT,
PIPELINE_FIREWALL_MSG_REQ_DEL_DEFAULT,
PIPELINE_FIREWALL_MSG_REQS
@@ -106,6 +108,42 @@ struct pipeline_firewall_del_msg_rsp {
};
/*
+ * MSG ADD BULK
+ */
+struct pipeline_firewall_add_bulk_msg_req {
+ enum pipeline_msg_req_type type;
+ enum pipeline_firewall_msg_req_type subtype;
+
+ struct pipeline_firewall_key *keys;
+ uint32_t n_keys;
+
+ uint32_t *priorities;
+ uint32_t *port_ids;
+ int *keys_found;
+ void **entries_ptr;
+};
+struct pipeline_firewall_add_bulk_msg_rsp {
+ int status;
+};
+
+/*
+ * MSG DEL BULK
+ */
+struct pipeline_firewall_del_bulk_msg_req {
+ enum pipeline_msg_req_type type;
+ enum pipeline_firewall_msg_req_type subtype;
+
+ /* key */
+ struct pipeline_firewall_key *keys;
+ uint32_t n_keys;
+ int *keys_found;
+};
+
+struct pipeline_firewall_del_bulk_msg_rsp {
+ int status;
+};
+
+/*
* MSG ADD DEFAULT
*/
struct pipeline_firewall_add_default_msg_req {
--
1.9.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [dpdk-dev] [PATCH v4 5/5] doc: modify release notes and deprecation notice for table and pipeline
2015-10-20 13:01 [dpdk-dev] [PATCH v4 0/5] pipeline: add bulk add/delete functions for table Michal Jastrzebski
` (3 preceding siblings ...)
2015-10-20 13:01 ` [dpdk-dev] [PATCH v4 4/5] ip_pipline: added cli commands for bulk add/delete to firewall pipeline Michal Jastrzebski
@ 2015-10-20 13:01 ` Michal Jastrzebski
2015-11-25 22:20 ` [dpdk-dev] [PATCH v4 0/5] pipeline: add bulk add/delete functions for table Thomas Monjalon
5 siblings, 0 replies; 7+ messages in thread
From: Michal Jastrzebski @ 2015-10-20 13:01 UTC (permalink / raw)
To: dev
From: Marcin Kerlin <marcinx.kerlin@intel.com>
The release notes is updated and the deprecation announce is removed.
Signed-off-by: Maciej Gajdzica <maciejx.t.gajdzica@intel.com>
Signed-off-by: Marcin Kerlin <marcinx.kerlin@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
doc/guides/rel_notes/deprecation.rst | 3 ---
doc/guides/rel_notes/release_2_2.rst | 2 +-
2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 018a119..5be498a 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -45,9 +45,6 @@ Deprecation Notices
the value of macros CFG_NAME_LEN and CFG_NAME_VAL will be increased.
Most likely, the new values will be 64 and 256, respectively.
-* librte_table: New functions for table entry bulk add/delete will be added
- to the table operations structure.
-
* librte_table hash: Key mask parameter will be added to the hash table
parameter structure for 8-byte key and 16-byte key extendible bucket and
LRU tables.
diff --git a/doc/guides/rel_notes/release_2_2.rst b/doc/guides/rel_notes/release_2_2.rst
index 89cba4d..fa85c9f 100644
--- a/doc/guides/rel_notes/release_2_2.rst
+++ b/doc/guides/rel_notes/release_2_2.rst
@@ -128,7 +128,7 @@ The libraries prepended with a plus sign were incremented in this version.
+ librte_mbuf.so.2
librte_mempool.so.1
librte_meter.so.1
- librte_pipeline.so.1
+ + librte_pipeline.so.2
librte_pmd_bond.so.1
+ librte_pmd_ring.so.2
+ librte_port.so.2
--
1.9.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [dpdk-dev] [PATCH v4 0/5] pipeline: add bulk add/delete functions for table
2015-10-20 13:01 [dpdk-dev] [PATCH v4 0/5] pipeline: add bulk add/delete functions for table Michal Jastrzebski
` (4 preceding siblings ...)
2015-10-20 13:01 ` [dpdk-dev] [PATCH v4 5/5] doc: modify release notes and deprecation notice for table and pipeline Michal Jastrzebski
@ 2015-11-25 22:20 ` Thomas Monjalon
5 siblings, 0 replies; 7+ messages in thread
From: Thomas Monjalon @ 2015-11-25 22:20 UTC (permalink / raw)
To: Michal Jastrzebski; +Cc: dev
2015-10-20 15:01, Michal Jastrzebski:
> From: Marcin Kerlin <marcinx.kerlin@intel.com>
>
> This patch adds bulk add/delete functions for tables used by pipelines. It
> allows for adding/deleting many rules to pipeline tables in one function call.
> It is particulary useful for firewall pipeline which is using ACL table. After
> every add or delete, table is rebuild which leads to very long times when
> trying to add/delete many entries.
>
> v2:
> * Incremented the LIBABIVER number
> * Updated release notes
> * Removed deprecation announce
>
> v3:
> * Updated a Doxygen comment
>
> v4:
> * Moved .map file to the second patch
>
> Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
>
> Maciej Gajdzica (5):
> table: added bulk add/delete functions for table
> pipeline: added bulk add/delete functions for table
> test_table: added check for bulk add/delete to acl table unit test
> ip_pipline: added cli commands for bulk add/delete to firewall
> pipeline
> doc: modify release notes and deprecation notice for table and
> pipeline
Applied, thanks
^ permalink raw reply [flat|nested] 7+ messages in thread