[dpdk-dev] [PATCH v3 1/5] table: added bulk add/delete functions for table

Marcin Kerlin marcinx.kerlin at intel.com
Tue Oct 13 09:34:25 CEST 2015


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 at intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu at 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 b218d64..9bc3ee4 100644
--- a/lib/librte_table/rte_table_lpm.c
+++ b/lib/librte_table/rte_table_lpm.c
@@ -373,6 +373,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 ff4a9c2..f6852e3 100644
--- a/lib/librte_table/rte_table_lpm_ipv6.c
+++ b/lib/librte_table/rte_table_lpm_ipv6.c
@@ -387,6 +387,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

--------------------------------------------------------------
Intel Shannon Limited
Registered in Ireland
Registered Office: Collinstown Industrial Park, Leixlip, County Kildare
Registered Number: 308263
Business address: Dromore House, East Park, Shannon, Co. Clare

This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.




More information about the dev mailing list