Improve the internal table entry helper routines for key comparison, entry duplication and checks.
Signed-off-by: Cristian Dumitrescu <cristian.dumitre...@intel.com> --- lib/librte_pipeline/rte_swx_ctl.c | 100 ++++++++++++++++-------------- 1 file changed, 52 insertions(+), 48 deletions(-) diff --git a/lib/librte_pipeline/rte_swx_ctl.c b/lib/librte_pipeline/rte_swx_ctl.c index ee6df4544..3dfbc4aec 100644 --- a/lib/librte_pipeline/rte_swx_ctl.c +++ b/lib/librte_pipeline/rte_swx_ctl.c @@ -234,6 +234,26 @@ table_entry_alloc(struct table *table) return NULL; } +static int +table_entry_key_check_em(struct table *table, struct rte_swx_table_entry *entry) +{ + uint8_t *key_mask0 = table->params.key_mask0; + uint32_t key_size = table->params.key_size, i; + + if (!entry->key_mask) + return 0; + + for (i = 0; i < key_size; i++) { + uint8_t km0 = key_mask0[i]; + uint8_t km = entry->key_mask[i]; + + if ((km & km0) != km0) + return -EINVAL; + } + + return 0; +} + static int table_entry_check(struct rte_swx_ctl_pipeline *ctl, uint32_t table_id, @@ -242,6 +262,7 @@ table_entry_check(struct rte_swx_ctl_pipeline *ctl, int data_check) { struct table *table = &ctl->tables[table_id]; + int status; CHECK(entry, EINVAL); @@ -266,7 +287,9 @@ table_entry_check(struct rte_swx_ctl_pipeline *ctl, break; case RTE_SWX_TABLE_MATCH_EXACT: - CHECK(!entry->key_mask, EINVAL); + status = table_entry_key_check_em(table, entry); + if (status) + return status; break; default: @@ -327,10 +350,7 @@ table_entry_duplicate(struct rte_swx_ctl_pipeline *ctl, new_entry->key_signature = entry->key_signature; /* key_mask. */ - if (table->params.match_type != RTE_SWX_TABLE_MATCH_EXACT) { - if (!entry->key_mask) - goto error; - + if (entry->key_mask) { new_entry->key_mask = malloc(table->params.key_size); if (!new_entry->key_mask) goto error; @@ -378,58 +398,36 @@ table_entry_duplicate(struct rte_swx_ctl_pipeline *ctl, return NULL; } -static int -entry_keycmp_em(struct rte_swx_table_entry *e0, - struct rte_swx_table_entry *e1, - uint32_t key_size) -{ - if (e0->key_signature != e1->key_signature) - return 1; /* Not equal. */ - - if (memcmp(e0->key, e1->key, key_size)) - return 1; /* Not equal. */ - - return 0; /* Equal */ -} - -static int -entry_keycmp_wm(struct rte_swx_table_entry *e0 __rte_unused, - struct rte_swx_table_entry *e1 __rte_unused, - uint32_t key_size __rte_unused) -{ - /* TBD */ - - return 1; /* Not equal */ -} - -static int -entry_keycmp_lpm(struct rte_swx_table_entry *e0 __rte_unused, - struct rte_swx_table_entry *e1 __rte_unused, - uint32_t key_size __rte_unused) -{ - /* TBD */ - - return 1; /* Not equal */ -} - static int table_entry_keycmp(struct table *table, struct rte_swx_table_entry *e0, struct rte_swx_table_entry *e1) { - switch (table->params.match_type) { - case RTE_SWX_TABLE_MATCH_EXACT: - return entry_keycmp_em(e0, e1, table->params.key_size); + uint32_t key_size = table->params.key_size; + uint32_t i; + + for (i = 0; i < key_size; i++) { + uint8_t *key_mask0 = table->params.key_mask0; + uint8_t km0, km[2], k[2]; + + km0 = key_mask0 ? key_mask0[i] : 0xFF; + + km[0] = e0->key_mask ? e0->key_mask[i] : 0xFF; + km[1] = e1->key_mask ? e1->key_mask[i] : 0xFF; - case RTE_SWX_TABLE_MATCH_WILDCARD: - return entry_keycmp_wm(e0, e1, table->params.key_size); + k[0] = e0->key[i]; + k[1] = e1->key[i]; - case RTE_SWX_TABLE_MATCH_LPM: - return entry_keycmp_lpm(e0, e1, table->params.key_size); + /* Mask comparison. */ + if ((km[0] & km0) != (km[1] & km0)) + return 1; /* Not equal. */ - default: - return 1; /* Not equal. */ + /* Value comparison. */ + if ((k[0] & km[0] & km0) != (k[1] & km[1] & km0)) + return 1; /* Not equal. */ } + + return 0; /* Equal. */ } static struct rte_swx_table_entry * @@ -893,6 +891,9 @@ rte_swx_ctl_pipeline_table_entry_add(struct rte_swx_ctl_pipeline *ctl, CHECK(table, EINVAL); table_id = table - ctl->tables; + CHECK(entry, EINVAL); + CHECK(!table_entry_check(ctl, table_id, entry, 1, 1), EINVAL); + new_entry = table_entry_duplicate(ctl, table_id, entry, 1, 1); CHECK(new_entry, ENOMEM); @@ -1095,6 +1096,9 @@ rte_swx_ctl_pipeline_table_default_entry_add(struct rte_swx_ctl_pipeline *ctl, table_id = table - ctl->tables; CHECK(!table->info.default_action_is_const, EINVAL); + CHECK(entry, EINVAL); + CHECK(!table_entry_check(ctl, table_id, entry, 0, 1), EINVAL); + new_entry = table_entry_duplicate(ctl, table_id, entry, 0, 1); CHECK(new_entry, ENOMEM); -- 2.17.1