* [dpdk-dev] [PATCH 0/8] ACL: various fixes and cleanups
@ 2015-06-03 23:10 Konstantin Ananyev
2015-06-03 23:10 ` [dpdk-dev] [PATCH 1/8] ACL: fix invalid rule wildness calculation for RTE_ACL_FIELD_TYPE_BITMASK Konstantin Ananyev
` (8 more replies)
0 siblings, 9 replies; 21+ messages in thread
From: Konstantin Ananyev @ 2015-06-03 23:10 UTC (permalink / raw)
To: dev
This patch-set is based on:
[PATCHv2 0/3] ACL: Fix bug in acl_merge_trie() and add a new test-case for it to the UT.
Konstantin Ananyev (8):
ACL: fix invalid rule wildness calculation for RTE_ACL_FIELD_TYPE_BITMASK
ACL: code cleanup - use global RTE_LEN2MASK macro
ACL: add function to check rte_acl_build() input parameters
ACL: fix rebuilding a trie for subset of rules
ACL: introduce RTE_ACL_MASKLEN_TO_BITMASK macro
ACL: cleanup remove unused code from acl_bld.c
ACL: fix remove ambiguity between rules at UT
ACL: add new test-cases into UT
app/test-acl/main.c | 3 +-
app/test/test_acl.c | 431 +++++++++++++++++++++++++++++++++++++-
app/test/test_acl.h | 52 ++---
lib/librte_acl/acl_bld.c | 455 +++++++----------------------------------
lib/librte_acl/rte_acl.c | 3 +-
lib/librte_acl/rte_acl.h | 5 +-
lib/librte_acl/rte_acl_osdep.h | 2 -
7 files changed, 530 insertions(+), 421 deletions(-)
--
1.8.5.3
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCH 1/8] ACL: fix invalid rule wildness calculation for RTE_ACL_FIELD_TYPE_BITMASK
2015-06-03 23:10 [dpdk-dev] [PATCH 0/8] ACL: various fixes and cleanups Konstantin Ananyev
@ 2015-06-03 23:10 ` Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 0/8] acl: various fixes and cleanups Konstantin Ananyev
2015-06-03 23:10 ` [dpdk-dev] [PATCH 2/8] ACL: code cleanup - use global RTE_LEN2MASK macro Konstantin Ananyev
` (7 subsequent siblings)
8 siblings, 1 reply; 21+ messages in thread
From: Konstantin Ananyev @ 2015-06-03 23:10 UTC (permalink / raw)
To: dev
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
lib/librte_acl/acl_bld.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/lib/librte_acl/acl_bld.c b/lib/librte_acl/acl_bld.c
index db23b7b..e2db9bf 100644
--- a/lib/librte_acl/acl_bld.c
+++ b/lib/librte_acl/acl_bld.c
@@ -1362,6 +1362,9 @@ acl_calc_wildness(struct rte_acl_build_rule *head,
for (n = 0; n < config->num_fields; n++) {
double wild = 0;
+ uint64_t msk_val =
+ RTE_LEN2MASK(CHAR_BIT * config->defs[n].size,
+ typeof(msk_val));
double size = CHAR_BIT * config->defs[n].size;
int field_index = config->defs[n].field_index;
const struct rte_acl_field *fld = rule->f->field +
@@ -1369,8 +1372,8 @@ acl_calc_wildness(struct rte_acl_build_rule *head,
switch (rule->config->defs[n].type) {
case RTE_ACL_FIELD_TYPE_BITMASK:
- wild = (size - __builtin_popcount(
- fld->mask_range.u8)) /
+ wild = (size - __builtin_popcountll(
+ fld->mask_range.u64 & msk_val)) /
size;
break;
--
1.8.5.3
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCH 2/8] ACL: code cleanup - use global RTE_LEN2MASK macro
2015-06-03 23:10 [dpdk-dev] [PATCH 0/8] ACL: various fixes and cleanups Konstantin Ananyev
2015-06-03 23:10 ` [dpdk-dev] [PATCH 1/8] ACL: fix invalid rule wildness calculation for RTE_ACL_FIELD_TYPE_BITMASK Konstantin Ananyev
@ 2015-06-03 23:10 ` Konstantin Ananyev
2015-06-03 23:10 ` [dpdk-dev] [PATCH 3/8] ACL: add function to check rte_acl_build() input parameters Konstantin Ananyev
` (6 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Konstantin Ananyev @ 2015-06-03 23:10 UTC (permalink / raw)
To: dev
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
app/test-acl/main.c | 3 ++-
lib/librte_acl/acl_bld.c | 3 ++-
lib/librte_acl/rte_acl.c | 3 ++-
lib/librte_acl/rte_acl.h | 2 +-
lib/librte_acl/rte_acl_osdep.h | 2 --
5 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/app/test-acl/main.c b/app/test-acl/main.c
index 524c43a..be3d773 100644
--- a/app/test-acl/main.c
+++ b/app/test-acl/main.c
@@ -739,7 +739,8 @@ add_cb_rules(FILE *f, struct rte_acl_ctx *ctx)
return rc;
}
- v.data.category_mask = LEN2MASK(RTE_ACL_MAX_CATEGORIES);
+ v.data.category_mask = RTE_LEN2MASK(RTE_ACL_MAX_CATEGORIES,
+ typeof(v.data.category_mask));
v.data.priority = RTE_ACL_MAX_PRIORITY - n;
v.data.userdata = n;
diff --git a/lib/librte_acl/acl_bld.c b/lib/librte_acl/acl_bld.c
index e2db9bf..19a4178 100644
--- a/lib/librte_acl/acl_bld.c
+++ b/lib/librte_acl/acl_bld.c
@@ -1772,7 +1772,8 @@ acl_bld(struct acl_build_context *bcx, struct rte_acl_ctx *ctx,
bcx->pool.alignment = ACL_POOL_ALIGN;
bcx->pool.min_alloc = ACL_POOL_ALLOC_MIN;
bcx->cfg = *cfg;
- bcx->category_mask = LEN2MASK(bcx->cfg.num_categories);
+ bcx->category_mask = RTE_LEN2MASK(bcx->cfg.num_categories,
+ typeof(bcx->category_mask));
bcx->node_max = node_max;
rc = sigsetjmp(bcx->pool.fail, 0);
diff --git a/lib/librte_acl/rte_acl.c b/lib/librte_acl/rte_acl.c
index b6ddeeb..a54d531 100644
--- a/lib/librte_acl/rte_acl.c
+++ b/lib/librte_acl/rte_acl.c
@@ -271,7 +271,8 @@ acl_add_rules(struct rte_acl_ctx *ctx, const void *rules, uint32_t num)
static int
acl_check_rule(const struct rte_acl_rule_data *rd)
{
- if ((rd->category_mask & LEN2MASK(RTE_ACL_MAX_CATEGORIES)) == 0 ||
+ if ((RTE_LEN2MASK(RTE_ACL_MAX_CATEGORIES, typeof(rd->category_mask)) &
+ rd->category_mask) == 0 ||
rd->priority > RTE_ACL_MAX_PRIORITY ||
rd->priority < RTE_ACL_MIN_PRIORITY ||
rd->userdata == RTE_ACL_INVALID_USERDATA)
diff --git a/lib/librte_acl/rte_acl.h b/lib/librte_acl/rte_acl.h
index 3a93730..8d9bbe5 100644
--- a/lib/librte_acl/rte_acl.h
+++ b/lib/librte_acl/rte_acl.h
@@ -115,7 +115,7 @@ struct rte_acl_field {
enum {
RTE_ACL_TYPE_SHIFT = 29,
- RTE_ACL_MAX_INDEX = LEN2MASK(RTE_ACL_TYPE_SHIFT),
+ RTE_ACL_MAX_INDEX = RTE_LEN2MASK(RTE_ACL_TYPE_SHIFT, uint32_t),
RTE_ACL_MAX_PRIORITY = RTE_ACL_MAX_INDEX,
RTE_ACL_MIN_PRIORITY = 0,
};
diff --git a/lib/librte_acl/rte_acl_osdep.h b/lib/librte_acl/rte_acl_osdep.h
index 81fdefb..41f7e3d 100644
--- a/lib/librte_acl/rte_acl_osdep.h
+++ b/lib/librte_acl/rte_acl_osdep.h
@@ -56,8 +56,6 @@
* Common defines.
*/
-#define LEN2MASK(ln) ((uint32_t)(((uint64_t)1 << (ln)) - 1))
-
#define DIM(x) RTE_DIM(x)
#include <rte_common.h>
--
1.8.5.3
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCH 3/8] ACL: add function to check rte_acl_build() input parameters
2015-06-03 23:10 [dpdk-dev] [PATCH 0/8] ACL: various fixes and cleanups Konstantin Ananyev
2015-06-03 23:10 ` [dpdk-dev] [PATCH 1/8] ACL: fix invalid rule wildness calculation for RTE_ACL_FIELD_TYPE_BITMASK Konstantin Ananyev
2015-06-03 23:10 ` [dpdk-dev] [PATCH 2/8] ACL: code cleanup - use global RTE_LEN2MASK macro Konstantin Ananyev
@ 2015-06-03 23:10 ` Konstantin Ananyev
2015-06-03 23:10 ` [dpdk-dev] [PATCH 4/8] ACL: fix rebuilding a trie for subset of rules Konstantin Ananyev
` (5 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Konstantin Ananyev @ 2015-06-03 23:10 UTC (permalink / raw)
To: dev
Move check for build parameters into a separate function.
Simplify acl_calc_wildness() function.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
lib/librte_acl/acl_bld.c | 107 ++++++++++++++++++++++++-----------------------
1 file changed, 54 insertions(+), 53 deletions(-)
diff --git a/lib/librte_acl/acl_bld.c b/lib/librte_acl/acl_bld.c
index 19a4178..8315d84 100644
--- a/lib/librte_acl/acl_bld.c
+++ b/lib/librte_acl/acl_bld.c
@@ -1350,7 +1350,7 @@ build_trie(struct acl_build_context *context, struct rte_acl_build_rule *head,
return trie;
}
-static int
+static void
acl_calc_wildness(struct rte_acl_build_rule *head,
const struct rte_acl_config *config)
{
@@ -1362,10 +1362,10 @@ acl_calc_wildness(struct rte_acl_build_rule *head,
for (n = 0; n < config->num_fields; n++) {
double wild = 0;
- uint64_t msk_val =
- RTE_LEN2MASK(CHAR_BIT * config->defs[n].size,
+ uint32_t bit_len = CHAR_BIT * config->defs[n].size;
+ uint64_t msk_val = RTE_LEN2MASK(bit_len,
typeof(msk_val));
- double size = CHAR_BIT * config->defs[n].size;
+ double size = bit_len;
int field_index = config->defs[n].field_index;
const struct rte_acl_field *fld = rule->f->field +
field_index;
@@ -1382,54 +1382,15 @@ acl_calc_wildness(struct rte_acl_build_rule *head,
break;
case RTE_ACL_FIELD_TYPE_RANGE:
- switch (rule->config->defs[n].size) {
- case sizeof(uint8_t):
- wild = ((double)fld->mask_range.u8 -
- fld->value.u8) / UINT8_MAX;
- break;
- case sizeof(uint16_t):
- wild = ((double)fld->mask_range.u16 -
- fld->value.u16) / UINT16_MAX;
- break;
- case sizeof(uint32_t):
- wild = ((double)fld->mask_range.u32 -
- fld->value.u32) / UINT32_MAX;
- break;
- case sizeof(uint64_t):
- wild = ((double)fld->mask_range.u64 -
- fld->value.u64) / UINT64_MAX;
- break;
- default:
- RTE_LOG(ERR, ACL,
- "%s(rule: %u) invalid %u-th "
- "field, type: %hhu, "
- "unknown size: %hhu\n",
- __func__,
- rule->f->data.userdata,
- n,
- rule->config->defs[n].type,
- rule->config->defs[n].size);
- return -EINVAL;
- }
+ wild = (fld->mask_range.u64 & msk_val) -
+ (fld->value.u64 & msk_val);
+ wild = wild / msk_val;
break;
-
- default:
- RTE_LOG(ERR, ACL,
- "%s(rule: %u) invalid %u-th "
- "field, unknown type: %hhu\n",
- __func__,
- rule->f->data.userdata,
- n,
- rule->config->defs[n].type);
- return -EINVAL;
-
}
rule->wildness[field_index] = (uint32_t)(wild * 100);
}
}
-
- return 0;
}
static void
@@ -1602,7 +1563,6 @@ static int
acl_build_tries(struct acl_build_context *context,
struct rte_acl_build_rule *head)
{
- int32_t rc;
uint32_t n, num_tries;
struct rte_acl_config *config;
struct rte_acl_build_rule *last;
@@ -1621,9 +1581,7 @@ acl_build_tries(struct acl_build_context *context,
context->tries[0].type = RTE_ACL_FULL_TRIE;
/* calc wildness of each field of each rule */
- rc = acl_calc_wildness(head, config);
- if (rc != 0)
- return rc;
+ acl_calc_wildness(head, config);
for (n = 0;; n = num_tries) {
@@ -1801,6 +1759,49 @@ acl_bld(struct acl_build_context *bcx, struct rte_acl_ctx *ctx,
return rc;
}
+/*
+ * Check that parameters for acl_build() are valid.
+ */
+static int
+acl_check_bld_param(struct rte_acl_ctx *ctx, const struct rte_acl_config *cfg)
+{
+ static const size_t field_sizes[] = {
+ sizeof(uint8_t), sizeof(uint16_t),
+ sizeof(uint32_t), sizeof(uint64_t),
+ };
+
+ uint32_t i, j;
+
+ if (ctx == NULL || cfg == NULL || cfg->num_categories == 0 ||
+ cfg->num_categories > RTE_ACL_MAX_CATEGORIES ||
+ cfg->num_fields == 0 ||
+ cfg->num_fields > RTE_ACL_MAX_FIELDS)
+ return -EINVAL;
+
+ for (i = 0; i != cfg->num_fields; i++) {
+ if (cfg->defs[i].type > RTE_ACL_FIELD_TYPE_BITMASK) {
+ RTE_LOG(ERR, ACL,
+ "ACL context: %s, invalid type: %hhu for %u-th field\n",
+ ctx->name, cfg->defs[i].type, i);
+ return -EINVAL;
+ }
+ for (j = 0;
+ j != RTE_DIM(field_sizes) &&
+ cfg->defs[i].size != field_sizes[j];
+ j++)
+ ;
+
+ if (j == RTE_DIM(field_sizes)) {
+ RTE_LOG(ERR, ACL,
+ "ACL context: %s, invalid size: %hhu for %u-th field\n",
+ ctx->name, cfg->defs[i].size, i);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
int
rte_acl_build(struct rte_acl_ctx *ctx, const struct rte_acl_config *cfg)
{
@@ -1809,9 +1810,9 @@ rte_acl_build(struct rte_acl_ctx *ctx, const struct rte_acl_config *cfg)
size_t max_size;
struct acl_build_context bcx;
- if (ctx == NULL || cfg == NULL || cfg->num_categories == 0 ||
- cfg->num_categories > RTE_ACL_MAX_CATEGORIES)
- return -EINVAL;
+ rc = acl_check_bld_param(ctx, cfg);
+ if (rc != 0)
+ return rc;
acl_build_reset(ctx);
--
1.8.5.3
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCH 4/8] ACL: fix rebuilding a trie for subset of rules
2015-06-03 23:10 [dpdk-dev] [PATCH 0/8] ACL: various fixes and cleanups Konstantin Ananyev
` (2 preceding siblings ...)
2015-06-03 23:10 ` [dpdk-dev] [PATCH 3/8] ACL: add function to check rte_acl_build() input parameters Konstantin Ananyev
@ 2015-06-03 23:10 ` Konstantin Ananyev
2015-06-03 23:10 ` [dpdk-dev] [PATCH 5/8] ACL: introduce RTE_ACL_MASKLEN_TO_BITMASK macro Konstantin Ananyev
` (4 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Konstantin Ananyev @ 2015-06-03 23:10 UTC (permalink / raw)
To: dev
When rebuilding a trie for limited rule-set,
don't try to split the rule-set even further.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
lib/librte_acl/acl_bld.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/lib/librte_acl/acl_bld.c b/lib/librte_acl/acl_bld.c
index 8315d84..4bcf637 100644
--- a/lib/librte_acl/acl_bld.c
+++ b/lib/librte_acl/acl_bld.c
@@ -97,6 +97,7 @@ struct acl_build_context {
struct rte_acl_build_rule *build_rules;
struct rte_acl_config cfg;
int32_t node_max;
+ int32_t cur_node_max;
uint32_t node;
uint32_t num_nodes;
uint32_t category_mask;
@@ -1337,7 +1338,7 @@ build_trie(struct acl_build_context *context, struct rte_acl_build_rule *head,
return NULL;
node_count = context->num_nodes - node_count;
- if (node_count > context->node_max) {
+ if (node_count > context->cur_node_max) {
*last = prev;
return trie;
}
@@ -1536,7 +1537,7 @@ acl_build_index(const struct rte_acl_config *config, uint32_t *data_index)
static struct rte_acl_build_rule *
build_one_trie(struct acl_build_context *context,
struct rte_acl_build_rule *rule_sets[RTE_ACL_MAX_TRIES],
- uint32_t n)
+ uint32_t n, int32_t node_max)
{
struct rte_acl_build_rule *last;
struct rte_acl_config *config;
@@ -1553,6 +1554,8 @@ build_one_trie(struct acl_build_context *context,
context->data_indexes[n]);
context->tries[n].data_index = context->data_indexes[n];
+ context->cur_node_max = node_max;
+
context->bld_tries[n].trie = build_trie(context, rule_sets[n],
&last, &context->tries[n].count);
@@ -1587,7 +1590,7 @@ acl_build_tries(struct acl_build_context *context,
num_tries = n + 1;
- last = build_one_trie(context, rule_sets, n);
+ last = build_one_trie(context, rule_sets, n, context->node_max);
if (context->bld_tries[n].trie == NULL) {
RTE_LOG(ERR, ACL, "Build of %u-th trie failed\n", n);
return -ENOMEM;
@@ -1618,8 +1621,11 @@ acl_build_tries(struct acl_build_context *context,
head = head->next)
head->config = config;
- /* Rebuild the trie for the reduced rule-set. */
- last = build_one_trie(context, rule_sets, n);
+ /*
+ * Rebuild the trie for the reduced rule-set.
+ * Don't try to split it any further.
+ */
+ last = build_one_trie(context, rule_sets, n, INT32_MAX);
if (context->bld_tries[n].trie == NULL || last != NULL) {
RTE_LOG(ERR, ACL, "Build of %u-th trie failed\n", n);
return -ENOMEM;
--
1.8.5.3
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCH 5/8] ACL: introduce RTE_ACL_MASKLEN_TO_BITMASK macro
2015-06-03 23:10 [dpdk-dev] [PATCH 0/8] ACL: various fixes and cleanups Konstantin Ananyev
` (3 preceding siblings ...)
2015-06-03 23:10 ` [dpdk-dev] [PATCH 4/8] ACL: fix rebuilding a trie for subset of rules Konstantin Ananyev
@ 2015-06-03 23:10 ` Konstantin Ananyev
2015-06-03 23:10 ` [dpdk-dev] [PATCH 6/8] ACL: cleanup remove unused code from acl_bld.c Konstantin Ananyev
` (3 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Konstantin Ananyev @ 2015-06-03 23:10 UTC (permalink / raw)
To: dev
Introduce new RTE_ACL_MASKLEN_TO_BITMASK macro, that will be used
in several places inside librte_acl and it's UT.
Simplify iand cleanup build_trie() code a bit.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
lib/librte_acl/acl_bld.c | 16 +++-------------
lib/librte_acl/rte_acl.h | 3 +++
2 files changed, 6 insertions(+), 13 deletions(-)
diff --git a/lib/librte_acl/acl_bld.c b/lib/librte_acl/acl_bld.c
index 4bcf637..e144503 100644
--- a/lib/librte_acl/acl_bld.c
+++ b/lib/librte_acl/acl_bld.c
@@ -1262,19 +1262,9 @@ build_trie(struct acl_build_context *context, struct rte_acl_build_rule *head,
* all higher bits.
*/
uint64_t mask;
-
- if (fld->mask_range.u32 == 0) {
- mask = 0;
-
- /*
- * arithmetic right shift for the length of
- * the mask less the msb.
- */
- } else {
- mask = -1 <<
- (rule->config->defs[n].size *
- CHAR_BIT - fld->mask_range.u32);
- }
+ mask = RTE_ACL_MASKLEN_TO_BITMASK(
+ fld->mask_range.u32,
+ rule->config->defs[n].size);
/* gen a mini-trie for this field */
merge = acl_gen_mask_trie(context,
diff --git a/lib/librte_acl/rte_acl.h b/lib/librte_acl/rte_acl.h
index 8d9bbe5..bd8f892 100644
--- a/lib/librte_acl/rte_acl.h
+++ b/lib/librte_acl/rte_acl.h
@@ -122,6 +122,9 @@ enum {
#define RTE_ACL_INVALID_USERDATA 0
+#define RTE_ACL_MASKLEN_TO_BITMASK(v, s) \
+((v) == 0 ? (v) : (typeof(v))((uint64_t)-1 << ((s) * CHAR_BIT - (v))))
+
/**
* Miscellaneous data for ACL rule.
*/
--
1.8.5.3
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCH 6/8] ACL: cleanup remove unused code from acl_bld.c
2015-06-03 23:10 [dpdk-dev] [PATCH 0/8] ACL: various fixes and cleanups Konstantin Ananyev
` (4 preceding siblings ...)
2015-06-03 23:10 ` [dpdk-dev] [PATCH 5/8] ACL: introduce RTE_ACL_MASKLEN_TO_BITMASK macro Konstantin Ananyev
@ 2015-06-03 23:10 ` Konstantin Ananyev
2015-06-03 23:10 ` [dpdk-dev] [PATCH 7/8] ACL: fix remove ambiguity between rules at UT Konstantin Ananyev
` (2 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Konstantin Ananyev @ 2015-06-03 23:10 UTC (permalink / raw)
To: dev
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
lib/librte_acl/acl_bld.c | 310 -----------------------------------------------
1 file changed, 310 deletions(-)
diff --git a/lib/librte_acl/acl_bld.c b/lib/librte_acl/acl_bld.c
index e144503..83669ac 100644
--- a/lib/librte_acl/acl_bld.c
+++ b/lib/librte_acl/acl_bld.c
@@ -120,10 +120,6 @@ static int acl_merge_trie(struct acl_build_context *context,
struct rte_acl_node *node_a, struct rte_acl_node *node_b,
uint32_t level, struct rte_acl_node **node_c);
-static int acl_merge(struct acl_build_context *context,
- struct rte_acl_node *node_a, struct rte_acl_node *node_b,
- int move, int a_subset, int level);
-
static void
acl_deref_ptr(struct acl_build_context *context,
struct rte_acl_node *node, int index);
@@ -415,58 +411,6 @@ acl_intersect_type(const struct rte_acl_bitset *a_bits,
}
/*
- * Check if all bits in the bitset are on
- */
-static int
-acl_full(struct rte_acl_node *node)
-{
- uint32_t n;
- bits_t all_bits = -1;
-
- for (n = 0; n < RTE_ACL_BIT_SET_SIZE; n++)
- all_bits &= node->values.bits[n];
- return all_bits == -1;
-}
-
-/*
- * Check if all bits in the bitset are off
- */
-static int
-acl_empty(struct rte_acl_node *node)
-{
- uint32_t n;
-
- if (node->ref_count == 0) {
- for (n = 0; n < RTE_ACL_BIT_SET_SIZE; n++) {
- if (0 != node->values.bits[n])
- return 0;
- }
- return 1;
- } else {
- return 0;
- }
-}
-
-/*
- * Compute intersection of A and B
- * return 1 if there is an intersection else 0.
- */
-static int
-acl_intersect(struct rte_acl_bitset *a_bits,
- struct rte_acl_bitset *b_bits,
- struct rte_acl_bitset *intersect)
-{
- uint32_t n;
- bits_t all_bits = 0;
-
- for (n = 0; n < RTE_ACL_BIT_SET_SIZE; n++) {
- intersect->bits[n] = a_bits->bits[n] & b_bits->bits[n];
- all_bits |= intersect->bits[n];
- }
- return all_bits != 0;
-}
-
-/*
* Duplicate a node
*/
static struct rte_acl_node *
@@ -534,63 +478,6 @@ acl_deref_ptr(struct acl_build_context *context,
}
/*
- * Exclude bitset from a node pointer
- * returns 0 if poiter was deref'd
- * 1 otherwise.
- */
-static int
-acl_exclude_ptr(struct acl_build_context *context,
- struct rte_acl_node *node,
- int index,
- struct rte_acl_bitset *b_bits)
-{
- int retval = 1;
-
- /*
- * remove bitset from node pointer and deref
- * if the bitset becomes empty.
- */
- if (!acl_exclude(&node->ptrs[index].values,
- &node->ptrs[index].values,
- b_bits)) {
- acl_deref_ptr(context, node, index);
- node->ptrs[index].ptr = NULL;
- retval = 0;
- }
-
- /* exclude bits from the composite bits for the node */
- acl_exclude(&node->values, &node->values, b_bits);
- return retval;
-}
-
-/*
- * Remove a bitset from src ptr and move remaining ptr to dst
- */
-static int
-acl_move_ptr(struct acl_build_context *context,
- struct rte_acl_node *dst,
- struct rte_acl_node *src,
- int index,
- struct rte_acl_bitset *b_bits)
-{
- int rc;
-
- if (b_bits != NULL)
- if (!acl_exclude_ptr(context, src, index, b_bits))
- return 0;
-
- /* add src pointer to dst node */
- rc = acl_add_ptr(context, dst, src->ptrs[index].ptr,
- &src->ptrs[index].values);
- if (rc < 0)
- return rc;
-
- /* remove ptr from src */
- acl_exclude_ptr(context, src, index, &src->ptrs[index].values);
- return 1;
-}
-
-/*
* acl_exclude rte_acl_bitset from src and copy remaining pointer to dst
*/
static int
@@ -650,203 +537,6 @@ acl_compact_node_ptrs(struct rte_acl_node *node_a)
}
}
-/*
- * acl_merge helper routine.
- */
-static int
-acl_merge_intersect(struct acl_build_context *context,
- struct rte_acl_node *node_a, uint32_t idx_a,
- struct rte_acl_node *node_b, uint32_t idx_b,
- int next_move, int level,
- struct rte_acl_bitset *intersect_ptr)
-{
- struct rte_acl_node *node_c;
-
- /* Duplicate A for intersection */
- node_c = acl_dup_node(context, node_a->ptrs[idx_a].ptr);
-
- /* Remove intersection from A */
- acl_exclude_ptr(context, node_a, idx_a, intersect_ptr);
-
- /*
- * Added link from A to C for all transitions
- * in the intersection
- */
- if (acl_add_ptr(context, node_a, node_c, intersect_ptr) < 0)
- return -1;
-
- /* merge B->node into C */
- return acl_merge(context, node_c, node_b->ptrs[idx_b].ptr, next_move,
- 0, level + 1);
-}
-
-
-/*
- * Merge the children of nodes A and B together.
- *
- * if match node
- * For each category
- * node A result = highest priority result
- * if any pointers in A intersect with any in B
- * For each intersection
- * C = copy of node that A points to
- * remove intersection from A pointer
- * add a pointer to A that points to C for the intersection
- * Merge C and node that B points to
- * Compact the pointers in A and B
- * if move flag
- * If B has only one reference
- * Move B pointers to A
- * else
- * Copy B pointers to A
- */
-static int
-acl_merge(struct acl_build_context *context,
- struct rte_acl_node *node_a, struct rte_acl_node *node_b,
- int move, int a_subset, int level)
-{
- uint32_t n, m, ptrs_a, ptrs_b;
- uint32_t min_add_a, min_add_b;
- int intersect_type;
- int node_intersect_type;
- int b_full, next_move, rc;
- struct rte_acl_bitset intersect_values;
- struct rte_acl_bitset intersect_ptr;
-
- min_add_a = 0;
- min_add_b = 0;
- intersect_type = 0;
- node_intersect_type = 0;
-
- if (level == 0)
- a_subset = 1;
-
- /*
- * Resolve match priorities
- */
- if (node_a->match_flag != 0 || node_b->match_flag != 0) {
-
- if (node_a->match_flag == 0 || node_b->match_flag == 0)
- RTE_LOG(ERR, ACL, "Not both matches\n");
-
- if (node_b->match_flag < node_a->match_flag)
- RTE_LOG(ERR, ACL, "Not same match\n");
-
- for (n = 0; n < context->cfg.num_categories; n++) {
- if (node_a->mrt->priority[n] <
- node_b->mrt->priority[n]) {
- node_a->mrt->priority[n] =
- node_b->mrt->priority[n];
- node_a->mrt->results[n] =
- node_b->mrt->results[n];
- }
- }
- }
-
- /*
- * If the two node transitions intersect then merge the transitions.
- * Check intersection for entire node (all pointers)
- */
- node_intersect_type = acl_intersect_type(&node_a->values,
- &node_b->values,
- &intersect_values);
-
- if (node_intersect_type & ACL_INTERSECT) {
-
- b_full = acl_full(node_b);
-
- min_add_b = node_b->min_add;
- node_b->min_add = node_b->num_ptrs;
- ptrs_b = node_b->num_ptrs;
-
- min_add_a = node_a->min_add;
- node_a->min_add = node_a->num_ptrs;
- ptrs_a = node_a->num_ptrs;
-
- for (n = 0; n < ptrs_a; n++) {
- for (m = 0; m < ptrs_b; m++) {
-
- if (node_a->ptrs[n].ptr == NULL ||
- node_b->ptrs[m].ptr == NULL ||
- node_a->ptrs[n].ptr ==
- node_b->ptrs[m].ptr)
- continue;
-
- intersect_type = acl_intersect_type(
- &node_a->ptrs[n].values,
- &node_b->ptrs[m].values,
- &intersect_ptr);
-
- /* If this node is not a 'match' node */
- if ((intersect_type & ACL_INTERSECT) &&
- (context->cfg.num_categories != 1 ||
- !(node_a->ptrs[n].ptr->match_flag))) {
-
- /*
- * next merge is a 'move' pointer,
- * if this one is and B is a
- * subset of the intersection.
- */
- next_move = move &&
- (intersect_type &
- ACL_INTERSECT_B) == 0;
-
- if (a_subset && b_full) {
- rc = acl_merge(context,
- node_a->ptrs[n].ptr,
- node_b->ptrs[m].ptr,
- next_move,
- 1, level + 1);
- if (rc != 0)
- return rc;
- } else {
- rc = acl_merge_intersect(
- context, node_a, n,
- node_b, m, next_move,
- level, &intersect_ptr);
- if (rc != 0)
- return rc;
- }
- }
- }
- }
- }
-
- /* Compact pointers */
- node_a->min_add = min_add_a;
- acl_compact_node_ptrs(node_a);
- node_b->min_add = min_add_b;
- acl_compact_node_ptrs(node_b);
-
- /*
- * Either COPY or MOVE pointers from B to A
- */
- acl_intersect(&node_a->values, &node_b->values, &intersect_values);
-
- if (move && node_b->ref_count == 1) {
- for (m = 0; m < node_b->num_ptrs; m++) {
- if (node_b->ptrs[m].ptr != NULL &&
- acl_move_ptr(context, node_a, node_b, m,
- &intersect_values) < 0)
- return -1;
- }
- } else {
- for (m = 0; m < node_b->num_ptrs; m++) {
- if (node_b->ptrs[m].ptr != NULL &&
- acl_copy_ptr(context, node_a, node_b, m,
- &intersect_values) < 0)
- return -1;
- }
- }
-
- /*
- * Free node if its empty (no longer used)
- */
- if (acl_empty(node_b))
- acl_free_node(context, node_b);
- return 0;
-}
-
static int
acl_resolve_leaf(struct acl_build_context *context,
struct rte_acl_node *node_a,
--
1.8.5.3
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCH 7/8] ACL: fix remove ambiguity between rules at UT
2015-06-03 23:10 [dpdk-dev] [PATCH 0/8] ACL: various fixes and cleanups Konstantin Ananyev
` (5 preceding siblings ...)
2015-06-03 23:10 ` [dpdk-dev] [PATCH 6/8] ACL: cleanup remove unused code from acl_bld.c Konstantin Ananyev
@ 2015-06-03 23:10 ` Konstantin Ananyev
2015-06-03 23:10 ` [dpdk-dev] [PATCH 8/8] ACL: add new test-cases into UT Konstantin Ananyev
2015-06-04 9:27 ` [dpdk-dev] [PATCH 0/8] ACL: various fixes and cleanups Thomas Monjalon
8 siblings, 0 replies; 21+ messages in thread
From: Konstantin Ananyev @ 2015-06-03 23:10 UTC (permalink / raw)
To: dev
Some test rules had equal priorityi for the same category.
That can causes an ambiguity in build trie and test results.
Specify different priority value for each rule from the same category.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
app/test/test_acl.h | 52 ++++++++++++++++++++++++++--------------------------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/app/test/test_acl.h b/app/test/test_acl.h
index 4af457d..4e8ff34 100644
--- a/app/test/test_acl.h
+++ b/app/test/test_acl.h
@@ -105,7 +105,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets traveling to 192.168.0.0/16 */
{
.data = {.userdata = 1, .category_mask = ACL_ALLOW_MASK,
- .priority = 2},
+ .priority = 230},
.dst_addr = IPv4(192,168,0,0),
.dst_mask_len = 16,
.src_port_low = 0,
@@ -116,7 +116,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets traveling to 192.168.1.0/24 */
{
.data = {.userdata = 2, .category_mask = ACL_ALLOW_MASK,
- .priority = 3},
+ .priority = 330},
.dst_addr = IPv4(192,168,1,0),
.dst_mask_len = 24,
.src_port_low = 0,
@@ -127,7 +127,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets traveling to 192.168.1.50 */
{
.data = {.userdata = 3, .category_mask = ACL_DENY_MASK,
- .priority = 2},
+ .priority = 230},
.dst_addr = IPv4(192,168,1,50),
.dst_mask_len = 32,
.src_port_low = 0,
@@ -140,7 +140,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets traveling from 10.0.0.0/8 */
{
.data = {.userdata = 4, .category_mask = ACL_ALLOW_MASK,
- .priority = 2},
+ .priority = 240},
.src_addr = IPv4(10,0,0,0),
.src_mask_len = 8,
.src_port_low = 0,
@@ -151,7 +151,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets traveling from 10.1.1.0/24 */
{
.data = {.userdata = 5, .category_mask = ACL_ALLOW_MASK,
- .priority = 3},
+ .priority = 340},
.src_addr = IPv4(10,1,1,0),
.src_mask_len = 24,
.src_port_low = 0,
@@ -162,7 +162,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets traveling from 10.1.1.1 */
{
.data = {.userdata = 6, .category_mask = ACL_DENY_MASK,
- .priority = 2},
+ .priority = 240},
.src_addr = IPv4(10,1,1,1),
.src_mask_len = 32,
.src_port_low = 0,
@@ -175,7 +175,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets with lower 7 bytes of VLAN tag equal to 0x64 */
{
.data = {.userdata = 7, .category_mask = ACL_ALLOW_MASK,
- .priority = 2},
+ .priority = 260},
.vlan = 0x64,
.vlan_mask = 0x7f,
.src_port_low = 0,
@@ -186,7 +186,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets with VLAN tags that have 0x5 in them */
{
.data = {.userdata = 8, .category_mask = ACL_ALLOW_MASK,
- .priority = 2},
+ .priority = 260},
.vlan = 0x5,
.vlan_mask = 0x5,
.src_port_low = 0,
@@ -197,7 +197,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets with VLAN tag 5 */
{
.data = {.userdata = 9, .category_mask = ACL_DENY_MASK,
- .priority = 3},
+ .priority = 360},
.vlan = 0x5,
.vlan_mask = 0xffff,
.src_port_low = 0,
@@ -210,7 +210,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets with lower 7 bytes of domain equal to 0x64 */
{
.data = {.userdata = 10, .category_mask = ACL_ALLOW_MASK,
- .priority = 2},
+ .priority = 250},
.domain = 0x64,
.domain_mask = 0x7f,
.src_port_low = 0,
@@ -221,7 +221,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets with domains that have 0x5 in them */
{
.data = {.userdata = 11, .category_mask = ACL_ALLOW_MASK,
- .priority = 3},
+ .priority = 350},
.domain = 0x5,
.domain_mask = 0x5,
.src_port_low = 0,
@@ -232,7 +232,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets with domain 5 */
{
.data = {.userdata = 12, .category_mask = ACL_DENY_MASK,
- .priority = 3},
+ .priority = 350},
.domain = 0x5,
.domain_mask = 0xffff,
.src_port_low = 0,
@@ -245,7 +245,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches everything with dst port 80 */
{
.data = {.userdata = 13, .category_mask = ACL_ALLOW_MASK,
- .priority = 3},
+ .priority = 310},
.dst_port_low = 80,
.dst_port_high = 80,
.src_port_low = 0,
@@ -254,7 +254,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches everything with dst port 22-1023 */
{
.data = {.userdata = 14, .category_mask = ACL_ALLOW_MASK,
- .priority = 2},
+ .priority = 210},
.dst_port_low = 22,
.dst_port_high = 1023,
.src_port_low = 0,
@@ -263,7 +263,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches everything with dst port 1020 */
{
.data = {.userdata = 15, .category_mask = ACL_DENY_MASK,
- .priority = 3},
+ .priority = 310},
.dst_port_low = 1020,
.dst_port_high = 1020,
.src_port_low = 0,
@@ -272,7 +272,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches everything with dst portrange 1000-2000 */
{
.data = {.userdata = 16, .category_mask = ACL_DENY_MASK,
- .priority = 2},
+ .priority = 210},
.dst_port_low = 1000,
.dst_port_high = 2000,
.src_port_low = 0,
@@ -283,7 +283,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches everything with src port 80 */
{
.data = {.userdata = 17, .category_mask = ACL_ALLOW_MASK,
- .priority = 3},
+ .priority = 320},
.src_port_low = 80,
.src_port_high = 80,
.dst_port_low = 0,
@@ -292,7 +292,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches everything with src port 22-1023 */
{
.data = {.userdata = 18, .category_mask = ACL_ALLOW_MASK,
- .priority = 2},
+ .priority = 220},
.src_port_low = 22,
.src_port_high = 1023,
.dst_port_low = 0,
@@ -301,7 +301,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches everything with src port 1020 */
{
.data = {.userdata = 19, .category_mask = ACL_DENY_MASK,
- .priority = 3},
+ .priority = 320},
.src_port_low = 1020,
.src_port_high = 1020,
.dst_port_low = 0,
@@ -310,7 +310,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches everything with src portrange 1000-2000 */
{
.data = {.userdata = 20, .category_mask = ACL_DENY_MASK,
- .priority = 2},
+ .priority = 220},
.src_port_low = 1000,
.src_port_high = 2000,
.dst_port_low = 0,
@@ -321,7 +321,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets with protocol number either 0x64 or 0xE4 */
{
.data = {.userdata = 21, .category_mask = ACL_ALLOW_MASK,
- .priority = 2},
+ .priority = 270},
.proto = 0x64,
.proto_mask = 0x7f,
.src_port_low = 0,
@@ -343,7 +343,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets with protocol 5 */
{
.data = {.userdata = 23, .category_mask = ACL_DENY_MASK,
- .priority = 3},
+ .priority = 370},
.proto = 0x5,
.proto_mask = 0xff,
.src_port_low = 0,
@@ -355,7 +355,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* rules combining various fields */
{
.data = {.userdata = 24, .category_mask = ACL_ALLOW_MASK,
- .priority = 4},
+ .priority = 400},
/** make sure that unmasked bytes don't fail! */
.dst_addr = IPv4(1,2,3,4),
.dst_mask_len = 16,
@@ -374,7 +374,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
},
{
.data = {.userdata = 25, .category_mask = ACL_DENY_MASK,
- .priority = 4},
+ .priority = 400},
.dst_addr = IPv4(5,6,7,8),
.dst_mask_len = 24,
.src_addr = IPv4(1,2,3,4),
@@ -392,7 +392,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
},
{
.data = {.userdata = 26, .category_mask = ACL_ALLOW_MASK,
- .priority = 5},
+ .priority = 500},
.dst_addr = IPv4(1,2,3,4),
.dst_mask_len = 8,
.src_addr = IPv4(5,6,7,8),
@@ -408,7 +408,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
},
{
.data = {.userdata = 27, .category_mask = ACL_DENY_MASK,
- .priority = 5},
+ .priority = 500},
.dst_addr = IPv4(5,6,7,8),
.dst_mask_len = 32,
.src_addr = IPv4(1,2,3,4),
--
1.8.5.3
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCH 8/8] ACL: add new test-cases into UT
2015-06-03 23:10 [dpdk-dev] [PATCH 0/8] ACL: various fixes and cleanups Konstantin Ananyev
` (6 preceding siblings ...)
2015-06-03 23:10 ` [dpdk-dev] [PATCH 7/8] ACL: fix remove ambiguity between rules at UT Konstantin Ananyev
@ 2015-06-03 23:10 ` Konstantin Ananyev
2015-06-04 9:27 ` [dpdk-dev] [PATCH 0/8] ACL: various fixes and cleanups Thomas Monjalon
8 siblings, 0 replies; 21+ messages in thread
From: Konstantin Ananyev @ 2015-06-03 23:10 UTC (permalink / raw)
To: dev
Add several new test cases for ACL to cover different build configurations.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
app/test/test_acl.c | 431 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 423 insertions(+), 8 deletions(-)
diff --git a/app/test/test_acl.c b/app/test/test_acl.c
index 6a032f9..3090246 100644
--- a/app/test/test_acl.c
+++ b/app/test/test_acl.c
@@ -47,6 +47,8 @@
#define LEN RTE_ACL_MAX_CATEGORIES
+RTE_ACL_RULE_DEF(acl_ipv4vlan_rule, RTE_ACL_IPV4VLAN_NUM_FIELDS);
+
struct rte_acl_param acl_param = {
.name = "acl_ctx",
.socket_id = SOCKET_ID_ANY,
@@ -62,6 +64,15 @@ struct rte_acl_ipv4vlan_rule acl_rule = {
.dst_port_high = UINT16_MAX,
};
+const uint32_t ipv4_7tuple_layout[RTE_ACL_IPV4VLAN_NUM] = {
+ offsetof(struct ipv4_7tuple, proto),
+ offsetof(struct ipv4_7tuple, vlan),
+ offsetof(struct ipv4_7tuple, ip_src),
+ offsetof(struct ipv4_7tuple, ip_dst),
+ offsetof(struct ipv4_7tuple, port_src),
+};
+
+
/* byteswap to cpu or network order */
static void
bswap_test_data(struct ipv4_7tuple *data, int len, int to_be)
@@ -195,13 +206,6 @@ test_classify_buid(struct rte_acl_ctx *acx,
const struct rte_acl_ipv4vlan_rule *rules, uint32_t num)
{
int ret;
- const uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = {
- offsetof(struct ipv4_7tuple, proto),
- offsetof(struct ipv4_7tuple, vlan),
- offsetof(struct ipv4_7tuple, ip_src),
- offsetof(struct ipv4_7tuple, ip_dst),
- offsetof(struct ipv4_7tuple, port_src),
- };
/* add rules to the context */
ret = rte_acl_ipv4vlan_add_rules(acx, rules, num);
@@ -212,7 +216,8 @@ test_classify_buid(struct rte_acl_ctx *acx,
}
/* try building the context */
- ret = rte_acl_ipv4vlan_build(acx, layout, RTE_ACL_MAX_CATEGORIES);
+ ret = rte_acl_ipv4vlan_build(acx, ipv4_7tuple_layout,
+ RTE_ACL_MAX_CATEGORIES);
if (ret != 0) {
printf("Line %i: Building ACL context failed!\n", __LINE__);
return ret;
@@ -412,6 +417,414 @@ test_build_ports_range(void)
return ret;
}
+static void
+convert_rule(const struct rte_acl_ipv4vlan_rule *ri,
+ struct acl_ipv4vlan_rule *ro)
+{
+ ro->data = ri->data;
+
+ ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].value.u8 = ri->proto;
+ ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].value.u16 = ri->vlan;
+ ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].value.u16 = ri->domain;
+ ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 = ri->src_addr;
+ ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 = ri->dst_addr;
+ ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].value.u16 = ri->src_port_low;
+ ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].value.u16 = ri->dst_port_low;
+
+ ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].mask_range.u8 = ri->proto_mask;
+ ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].mask_range.u16 = ri->vlan_mask;
+ ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].mask_range.u16 =
+ ri->domain_mask;
+ ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 =
+ ri->src_mask_len;
+ ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = ri->dst_mask_len;
+ ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].mask_range.u16 =
+ ri->src_port_high;
+ ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].mask_range.u16 =
+ ri->dst_port_high;
+}
+
+/*
+ * Convert IPV4 source and destination from RTE_ACL_FIELD_TYPE_MASK to
+ * RTE_ACL_FIELD_TYPE_BITMASK.
+ */
+static void
+convert_rule_1(const struct rte_acl_ipv4vlan_rule *ri,
+ struct acl_ipv4vlan_rule *ro)
+{
+ uint32_t v;
+
+ convert_rule(ri, ro);
+ v = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32;
+ ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 =
+ RTE_ACL_MASKLEN_TO_BITMASK(v, sizeof(v));
+ v = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32;
+ ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 =
+ RTE_ACL_MASKLEN_TO_BITMASK(v, sizeof(v));
+}
+
+/*
+ * Convert IPV4 source and destination from RTE_ACL_FIELD_TYPE_MASK to
+ * RTE_ACL_FIELD_TYPE_RANGE.
+ */
+static void
+convert_rule_2(const struct rte_acl_ipv4vlan_rule *ri,
+ struct acl_ipv4vlan_rule *ro)
+{
+ uint32_t hi, lo, mask;
+
+ convert_rule(ri, ro);
+
+ mask = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32;
+ mask = RTE_ACL_MASKLEN_TO_BITMASK(mask, sizeof(mask));
+ lo = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 & mask;
+ hi = lo + ~mask;
+ ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 = lo;
+ ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 = hi;
+
+ mask = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32;
+ mask = RTE_ACL_MASKLEN_TO_BITMASK(mask, sizeof(mask));
+ lo = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 & mask;
+ hi = lo + ~mask;
+ ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 = lo;
+ ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = hi;
+}
+
+/*
+ * Convert rte_acl_ipv4vlan_rule: swap VLAN and PORTS rule fields.
+ */
+static void
+convert_rule_3(const struct rte_acl_ipv4vlan_rule *ri,
+ struct acl_ipv4vlan_rule *ro)
+{
+ struct rte_acl_field t1, t2;
+
+ convert_rule(ri, ro);
+
+ t1 = ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD];
+ t2 = ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD];
+
+ ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD] =
+ ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD];
+ ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD] =
+ ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD];
+
+ ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD] = t1;
+ ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD] = t2;
+}
+
+/*
+ * Convert rte_acl_ipv4vlan_rule: swap SRC and DST IPv4 address rules.
+ */
+static void
+convert_rule_4(const struct rte_acl_ipv4vlan_rule *ri,
+ struct acl_ipv4vlan_rule *ro)
+{
+ struct rte_acl_field t;
+
+ convert_rule(ri, ro);
+
+ t = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD];
+ ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD] =
+ ro->field[RTE_ACL_IPV4VLAN_DST_FIELD];
+
+ ro->field[RTE_ACL_IPV4VLAN_DST_FIELD] = t;
+}
+
+static void
+ipv4vlan_config(struct rte_acl_config *cfg,
+ const uint32_t layout[RTE_ACL_IPV4VLAN_NUM],
+ uint32_t num_categories)
+{
+ static const struct rte_acl_field_def
+ ipv4_defs[RTE_ACL_IPV4VLAN_NUM_FIELDS] = {
+ {
+ .type = RTE_ACL_FIELD_TYPE_BITMASK,
+ .size = sizeof(uint8_t),
+ .field_index = RTE_ACL_IPV4VLAN_PROTO_FIELD,
+ .input_index = RTE_ACL_IPV4VLAN_PROTO,
+ },
+ {
+ .type = RTE_ACL_FIELD_TYPE_BITMASK,
+ .size = sizeof(uint16_t),
+ .field_index = RTE_ACL_IPV4VLAN_VLAN1_FIELD,
+ .input_index = RTE_ACL_IPV4VLAN_VLAN,
+ },
+ {
+ .type = RTE_ACL_FIELD_TYPE_BITMASK,
+ .size = sizeof(uint16_t),
+ .field_index = RTE_ACL_IPV4VLAN_VLAN2_FIELD,
+ .input_index = RTE_ACL_IPV4VLAN_VLAN,
+ },
+ {
+ .type = RTE_ACL_FIELD_TYPE_MASK,
+ .size = sizeof(uint32_t),
+ .field_index = RTE_ACL_IPV4VLAN_SRC_FIELD,
+ .input_index = RTE_ACL_IPV4VLAN_SRC,
+ },
+ {
+ .type = RTE_ACL_FIELD_TYPE_MASK,
+ .size = sizeof(uint32_t),
+ .field_index = RTE_ACL_IPV4VLAN_DST_FIELD,
+ .input_index = RTE_ACL_IPV4VLAN_DST,
+ },
+ {
+ .type = RTE_ACL_FIELD_TYPE_RANGE,
+ .size = sizeof(uint16_t),
+ .field_index = RTE_ACL_IPV4VLAN_SRCP_FIELD,
+ .input_index = RTE_ACL_IPV4VLAN_PORTS,
+ },
+ {
+ .type = RTE_ACL_FIELD_TYPE_RANGE,
+ .size = sizeof(uint16_t),
+ .field_index = RTE_ACL_IPV4VLAN_DSTP_FIELD,
+ .input_index = RTE_ACL_IPV4VLAN_PORTS,
+ },
+ };
+
+ memcpy(&cfg->defs, ipv4_defs, sizeof(ipv4_defs));
+ cfg->num_fields = RTE_DIM(ipv4_defs);
+
+ cfg->defs[RTE_ACL_IPV4VLAN_PROTO_FIELD].offset =
+ layout[RTE_ACL_IPV4VLAN_PROTO];
+ cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].offset =
+ layout[RTE_ACL_IPV4VLAN_VLAN];
+ cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].offset =
+ layout[RTE_ACL_IPV4VLAN_VLAN] +
+ cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].size;
+ cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].offset =
+ layout[RTE_ACL_IPV4VLAN_SRC];
+ cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].offset =
+ layout[RTE_ACL_IPV4VLAN_DST];
+ cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].offset =
+ layout[RTE_ACL_IPV4VLAN_PORTS];
+ cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].offset =
+ layout[RTE_ACL_IPV4VLAN_PORTS] +
+ cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].size;
+
+ cfg->num_categories = num_categories;
+}
+
+static int
+convert_rules(struct rte_acl_ctx *acx,
+ void (*convert)(const struct rte_acl_ipv4vlan_rule *,
+ struct acl_ipv4vlan_rule *),
+ const struct rte_acl_ipv4vlan_rule *rules, uint32_t num)
+{
+ int32_t rc;
+ uint32_t i;
+ struct acl_ipv4vlan_rule r;
+
+ for (i = 0; i != num; i++) {
+ convert(rules + i, &r);
+ rc = rte_acl_add_rules(acx, (struct rte_acl_rule *)&r, 1);
+ if (rc != 0) {
+ printf("Line %i: Adding rule %u to ACL context "
+ "failed with error code: %d\n",
+ __LINE__, i, rc);
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+static void
+convert_config(struct rte_acl_config *cfg)
+{
+ ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
+}
+
+/*
+ * Convert rte_acl_ipv4vlan_rule to use RTE_ACL_FIELD_TYPE_BITMASK.
+ */
+static void
+convert_config_1(struct rte_acl_config *cfg)
+{
+ ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
+ cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].type = RTE_ACL_FIELD_TYPE_BITMASK;
+ cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = RTE_ACL_FIELD_TYPE_BITMASK;
+}
+
+/*
+ * Convert rte_acl_ipv4vlan_rule to use RTE_ACL_FIELD_TYPE_RANGE.
+ */
+static void
+convert_config_2(struct rte_acl_config *cfg)
+{
+ ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
+ cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].type = RTE_ACL_FIELD_TYPE_RANGE;
+ cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = RTE_ACL_FIELD_TYPE_RANGE;
+}
+
+/*
+ * Convert rte_acl_ipv4vlan_rule: swap VLAN and PORTS rule definitions.
+ */
+static void
+convert_config_3(struct rte_acl_config *cfg)
+{
+ struct rte_acl_field_def t1, t2;
+
+ ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
+
+ t1 = cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD];
+ t2 = cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD];
+
+ /* swap VLAN1 and SRCP rule definition. */
+ cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD] =
+ cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD];
+ cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].field_index = t1.field_index;
+ cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].input_index = t1.input_index;
+
+ /* swap VLAN2 and DSTP rule definition. */
+ cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD] =
+ cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD];
+ cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].field_index = t2.field_index;
+ cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].input_index = t2.input_index;
+
+ cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].type = t1.type;
+ cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].size = t1.size;
+ cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].offset = t1.offset;
+
+ cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].type = t2.type;
+ cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].size = t2.size;
+ cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].offset = t2.offset;
+}
+
+/*
+ * Convert rte_acl_ipv4vlan_rule: swap SRC and DST ip address rule definitions.
+ */
+static void
+convert_config_4(struct rte_acl_config *cfg)
+{
+ struct rte_acl_field_def t;
+
+ ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
+
+ t = cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD];
+
+ cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD] =
+ cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD];
+ cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].field_index = t.field_index;
+ cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].input_index = t.input_index;
+
+ cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = t.type;
+ cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].size = t.size;
+ cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].offset = t.offset;
+}
+
+
+static int
+build_convert_rules(struct rte_acl_ctx *acx,
+ void (*config)(struct rte_acl_config *),
+ size_t max_size)
+{
+ struct rte_acl_config cfg;
+
+ memset(&cfg, 0, sizeof(cfg));
+ config(&cfg);
+ cfg.max_size = max_size;
+ return rte_acl_build(acx, &cfg);
+}
+
+static int
+test_convert_rules(const char *desc,
+ void (*config)(struct rte_acl_config *),
+ void (*convert)(const struct rte_acl_ipv4vlan_rule *,
+ struct acl_ipv4vlan_rule *))
+{
+ struct rte_acl_ctx *acx;
+ int32_t rc;
+ uint32_t i;
+ static const size_t mem_sizes[] = {0, -1};
+
+ printf("running %s(%s)\n", __func__, desc);
+
+ acx = rte_acl_create(&acl_param);
+ if (acx == NULL) {
+ printf("Line %i: Error creating ACL context!\n", __LINE__);
+ return -1;
+ }
+
+ rc = convert_rules(acx, convert, acl_test_rules,
+ RTE_DIM(acl_test_rules));
+ if (rc != 0)
+ printf("Line %i: Error converting ACL rules!\n", __LINE__);
+
+ for (i = 0; rc == 0 && i != RTE_DIM(mem_sizes); i++) {
+
+ rc = build_convert_rules(acx, config, mem_sizes[i]);
+ if (rc != 0) {
+ printf("Line %i: Error @ build_convert_rules(%zu)!\n",
+ __LINE__, mem_sizes[i]);
+ break;
+ }
+
+ rc = test_classify_run(acx);
+ if (rc != 0)
+ printf("%s failed at line %i, max_size=%zu\n",
+ __func__, __LINE__, mem_sizes[i]);
+ }
+
+ rte_acl_free(acx);
+ return rc;
+}
+
+static int
+test_convert(void)
+{
+ static const struct {
+ const char *desc;
+ void (*config)(struct rte_acl_config *);
+ void (*convert)(const struct rte_acl_ipv4vlan_rule *,
+ struct acl_ipv4vlan_rule *);
+ } convert_param[] = {
+ {
+ "acl_ipv4vlan_tuple",
+ convert_config,
+ convert_rule,
+ },
+ {
+ "acl_ipv4vlan_tuple, RTE_ACL_FIELD_TYPE_BITMASK type "
+ "for IPv4",
+ convert_config_1,
+ convert_rule_1,
+ },
+ {
+ "acl_ipv4vlan_tuple, RTE_ACL_FIELD_TYPE_RANGE type "
+ "for IPv4",
+ convert_config_2,
+ convert_rule_2,
+ },
+ {
+ "acl_ipv4vlan_tuple: swap VLAN and PORTs order",
+ convert_config_3,
+ convert_rule_3,
+ },
+ {
+ "acl_ipv4vlan_tuple: swap SRC and DST IPv4 order",
+ convert_config_4,
+ convert_rule_4,
+ },
+ };
+
+ uint32_t i;
+ int32_t rc;
+
+ for (i = 0; i != RTE_DIM(convert_param); i++) {
+ rc = test_convert_rules(convert_param[i].desc,
+ convert_param[i].config,
+ convert_param[i].convert);
+ if (rc != 0) {
+ printf("%s for test-case: %s failed, error code: %d;\n",
+ __func__, convert_param[i].desc, rc);
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
/*
* Test wrong layout behavior
* This test supplies the ACL context with invalid layout, which results in
@@ -1069,6 +1482,8 @@ test_acl(void)
return -1;
if (test_build_ports_range() < 0)
return -1;
+ if (test_convert() < 0)
+ return -1;
return 0;
}
--
1.8.5.3
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH 0/8] ACL: various fixes and cleanups
2015-06-03 23:10 [dpdk-dev] [PATCH 0/8] ACL: various fixes and cleanups Konstantin Ananyev
` (7 preceding siblings ...)
2015-06-03 23:10 ` [dpdk-dev] [PATCH 8/8] ACL: add new test-cases into UT Konstantin Ananyev
@ 2015-06-04 9:27 ` Thomas Monjalon
2015-06-04 10:20 ` Ananyev, Konstantin
8 siblings, 1 reply; 21+ messages in thread
From: Thomas Monjalon @ 2015-06-04 9:27 UTC (permalink / raw)
To: Konstantin Ananyev; +Cc: dev
Hi Konstantin,
2015-06-04 00:10, Konstantin Ananyev:
> This patch-set is based on:
> [PATCHv2 0/3] ACL: Fix bug in acl_merge_trie() and add a new test-case for it to the UT.
>
> Konstantin Ananyev (8):
> ACL: fix invalid rule wildness calculation for RTE_ACL_FIELD_TYPE_BITMASK
> ACL: code cleanup - use global RTE_LEN2MASK macro
> ACL: add function to check rte_acl_build() input parameters
> ACL: fix rebuilding a trie for subset of rules
> ACL: introduce RTE_ACL_MASKLEN_TO_BITMASK macro
> ACL: cleanup remove unused code from acl_bld.c
> ACL: fix remove ambiguity between rules at UT
> ACL: add new test-cases into UT
Commit titles would be more useful if they shortly explain the goal instead
of giving some function/macro names. It should be thought as a changelog entry
and reflect behavioral change.
On a side note, the keyword ACL: should be lowercase.
In the case of fixes, adding a Fixes: line may help.
It can be generated with this command:
git log -1 --abbrev=12 --format='Fixes: %h ("%s")' <commit>
Thanks
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH 0/8] ACL: various fixes and cleanups
2015-06-04 9:27 ` [dpdk-dev] [PATCH 0/8] ACL: various fixes and cleanups Thomas Monjalon
@ 2015-06-04 10:20 ` Ananyev, Konstantin
0 siblings, 0 replies; 21+ messages in thread
From: Ananyev, Konstantin @ 2015-06-04 10:20 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
Hi Thomas,
> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> Sent: Thursday, June 04, 2015 10:27 AM
> To: Ananyev, Konstantin
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 0/8] ACL: various fixes and cleanups
>
> Hi Konstantin,
>
> 2015-06-04 00:10, Konstantin Ananyev:
> > This patch-set is based on:
> > [PATCHv2 0/3] ACL: Fix bug in acl_merge_trie() and add a new test-case for it to the UT.
> >
> > Konstantin Ananyev (8):
> > ACL: fix invalid rule wildness calculation for RTE_ACL_FIELD_TYPE_BITMASK
> > ACL: code cleanup - use global RTE_LEN2MASK macro
> > ACL: add function to check rte_acl_build() input parameters
> > ACL: fix rebuilding a trie for subset of rules
> > ACL: introduce RTE_ACL_MASKLEN_TO_BITMASK macro
> > ACL: cleanup remove unused code from acl_bld.c
> > ACL: fix remove ambiguity between rules at UT
> > ACL: add new test-cases into UT
>
> Commit titles would be more useful if they shortly explain the goal instead
> of giving some function/macro names. It should be thought as a changelog entry
> and reflect behavioral change.
There is no changes in behaviour.
Just fixes and clean-ups.
> On a side note, the keyword ACL: should be lowercase.
>
> In the case of fixes, adding a Fixes: line may help.
> It can be generated with this command:
> git log -1 --abbrev=12 --format='Fixes: %h ("%s")' <commit>
Ok, will update commit messages in v2.
Konstantin
>
> Thanks
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCHv2 0/8] acl: various fixes and cleanups
2015-06-03 23:10 ` [dpdk-dev] [PATCH 1/8] ACL: fix invalid rule wildness calculation for RTE_ACL_FIELD_TYPE_BITMASK Konstantin Ananyev
@ 2015-06-08 10:41 ` Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 1/8] acl: fix invalid rule wildness calculation for bitmask field type Konstantin Ananyev
` (8 more replies)
0 siblings, 9 replies; 21+ messages in thread
From: Konstantin Ananyev @ 2015-06-08 10:41 UTC (permalink / raw)
To: dev
Several fixes and code cleanups for the librte_acl.
New test-cases for acl UT.
Konstantin Ananyev (8):
acl: fix invalid rule wildness calculation for bitmask field type
acl: code cleanup - use global EAL macro, instead of creating a local
copy
acl: add function to check build input parameters
acl: fix avoid unneeded trie splitting for subset of rules.
acl: code dedup - introduce a new macro
acl: cleanup remove unused code from acl_bld.c
acl: fix ambiguity between ACL rules in UT.
acl: add new test-cases into UT
app/test-acl/main.c | 3 +-
app/test/test_acl.c | 431 +++++++++++++++++++++++++++++++++++++-
app/test/test_acl.h | 52 ++---
lib/librte_acl/acl_bld.c | 455 +++++++----------------------------------
lib/librte_acl/rte_acl.c | 3 +-
lib/librte_acl/rte_acl.h | 5 +-
lib/librte_acl/rte_acl_osdep.h | 2 -
7 files changed, 530 insertions(+), 421 deletions(-)
--
2.4.2
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCHv2 1/8] acl: fix invalid rule wildness calculation for bitmask field type
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 0/8] acl: various fixes and cleanups Konstantin Ananyev
@ 2015-06-08 10:41 ` Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 2/8] acl: code cleanup - use global EAL macro, instead of creating a local copy Konstantin Ananyev
` (7 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Konstantin Ananyev @ 2015-06-08 10:41 UTC (permalink / raw)
To: dev
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
lib/librte_acl/acl_bld.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/lib/librte_acl/acl_bld.c b/lib/librte_acl/acl_bld.c
index 3801843..aee6ed5 100644
--- a/lib/librte_acl/acl_bld.c
+++ b/lib/librte_acl/acl_bld.c
@@ -1362,6 +1362,9 @@ acl_calc_wildness(struct rte_acl_build_rule *head,
for (n = 0; n < config->num_fields; n++) {
double wild = 0;
+ uint64_t msk_val =
+ RTE_LEN2MASK(CHAR_BIT * config->defs[n].size,
+ typeof(msk_val));
double size = CHAR_BIT * config->defs[n].size;
int field_index = config->defs[n].field_index;
const struct rte_acl_field *fld = rule->f->field +
@@ -1369,8 +1372,8 @@ acl_calc_wildness(struct rte_acl_build_rule *head,
switch (rule->config->defs[n].type) {
case RTE_ACL_FIELD_TYPE_BITMASK:
- wild = (size - __builtin_popcount(
- fld->mask_range.u8)) /
+ wild = (size - __builtin_popcountll(
+ fld->mask_range.u64 & msk_val)) /
size;
break;
--
2.4.2
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCHv2 2/8] acl: code cleanup - use global EAL macro, instead of creating a local copy
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 0/8] acl: various fixes and cleanups Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 1/8] acl: fix invalid rule wildness calculation for bitmask field type Konstantin Ananyev
@ 2015-06-08 10:41 ` Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 3/8] acl: add function to check build input parameters Konstantin Ananyev
` (6 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Konstantin Ananyev @ 2015-06-08 10:41 UTC (permalink / raw)
To: dev
use global RTE_LEN2MASK macro, instead of LEN2MASK.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
app/test-acl/main.c | 3 ++-
lib/librte_acl/acl_bld.c | 3 ++-
lib/librte_acl/rte_acl.c | 3 ++-
lib/librte_acl/rte_acl.h | 2 +-
lib/librte_acl/rte_acl_osdep.h | 2 --
5 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/app/test-acl/main.c b/app/test-acl/main.c
index 524c43a..be3d773 100644
--- a/app/test-acl/main.c
+++ b/app/test-acl/main.c
@@ -739,7 +739,8 @@ add_cb_rules(FILE *f, struct rte_acl_ctx *ctx)
return rc;
}
- v.data.category_mask = LEN2MASK(RTE_ACL_MAX_CATEGORIES);
+ v.data.category_mask = RTE_LEN2MASK(RTE_ACL_MAX_CATEGORIES,
+ typeof(v.data.category_mask));
v.data.priority = RTE_ACL_MAX_PRIORITY - n;
v.data.userdata = n;
diff --git a/lib/librte_acl/acl_bld.c b/lib/librte_acl/acl_bld.c
index aee6ed5..ff3ba8b 100644
--- a/lib/librte_acl/acl_bld.c
+++ b/lib/librte_acl/acl_bld.c
@@ -1772,7 +1772,8 @@ acl_bld(struct acl_build_context *bcx, struct rte_acl_ctx *ctx,
bcx->pool.alignment = ACL_POOL_ALIGN;
bcx->pool.min_alloc = ACL_POOL_ALLOC_MIN;
bcx->cfg = *cfg;
- bcx->category_mask = LEN2MASK(bcx->cfg.num_categories);
+ bcx->category_mask = RTE_LEN2MASK(bcx->cfg.num_categories,
+ typeof(bcx->category_mask));
bcx->node_max = node_max;
rc = sigsetjmp(bcx->pool.fail, 0);
diff --git a/lib/librte_acl/rte_acl.c b/lib/librte_acl/rte_acl.c
index b6ddeeb..a54d531 100644
--- a/lib/librte_acl/rte_acl.c
+++ b/lib/librte_acl/rte_acl.c
@@ -271,7 +271,8 @@ acl_add_rules(struct rte_acl_ctx *ctx, const void *rules, uint32_t num)
static int
acl_check_rule(const struct rte_acl_rule_data *rd)
{
- if ((rd->category_mask & LEN2MASK(RTE_ACL_MAX_CATEGORIES)) == 0 ||
+ if ((RTE_LEN2MASK(RTE_ACL_MAX_CATEGORIES, typeof(rd->category_mask)) &
+ rd->category_mask) == 0 ||
rd->priority > RTE_ACL_MAX_PRIORITY ||
rd->priority < RTE_ACL_MIN_PRIORITY ||
rd->userdata == RTE_ACL_INVALID_USERDATA)
diff --git a/lib/librte_acl/rte_acl.h b/lib/librte_acl/rte_acl.h
index 3a93730..8d9bbe5 100644
--- a/lib/librte_acl/rte_acl.h
+++ b/lib/librte_acl/rte_acl.h
@@ -115,7 +115,7 @@ struct rte_acl_field {
enum {
RTE_ACL_TYPE_SHIFT = 29,
- RTE_ACL_MAX_INDEX = LEN2MASK(RTE_ACL_TYPE_SHIFT),
+ RTE_ACL_MAX_INDEX = RTE_LEN2MASK(RTE_ACL_TYPE_SHIFT, uint32_t),
RTE_ACL_MAX_PRIORITY = RTE_ACL_MAX_INDEX,
RTE_ACL_MIN_PRIORITY = 0,
};
diff --git a/lib/librte_acl/rte_acl_osdep.h b/lib/librte_acl/rte_acl_osdep.h
index 81fdefb..41f7e3d 100644
--- a/lib/librte_acl/rte_acl_osdep.h
+++ b/lib/librte_acl/rte_acl_osdep.h
@@ -56,8 +56,6 @@
* Common defines.
*/
-#define LEN2MASK(ln) ((uint32_t)(((uint64_t)1 << (ln)) - 1))
-
#define DIM(x) RTE_DIM(x)
#include <rte_common.h>
--
2.4.2
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCHv2 3/8] acl: add function to check build input parameters
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 0/8] acl: various fixes and cleanups Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 1/8] acl: fix invalid rule wildness calculation for bitmask field type Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 2/8] acl: code cleanup - use global EAL macro, instead of creating a local copy Konstantin Ananyev
@ 2015-06-08 10:41 ` Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 4/8] acl: fix avoid unneeded trie splitting for subset of rules Konstantin Ananyev
` (5 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Konstantin Ananyev @ 2015-06-08 10:41 UTC (permalink / raw)
To: dev
Move check for build confg parameter into a separate function.
Simplify acl_calc_wildness() function.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
lib/librte_acl/acl_bld.c | 107 ++++++++++++++++++++++++-----------------------
1 file changed, 54 insertions(+), 53 deletions(-)
diff --git a/lib/librte_acl/acl_bld.c b/lib/librte_acl/acl_bld.c
index ff3ba8b..45ee065 100644
--- a/lib/librte_acl/acl_bld.c
+++ b/lib/librte_acl/acl_bld.c
@@ -1350,7 +1350,7 @@ build_trie(struct acl_build_context *context, struct rte_acl_build_rule *head,
return trie;
}
-static int
+static void
acl_calc_wildness(struct rte_acl_build_rule *head,
const struct rte_acl_config *config)
{
@@ -1362,10 +1362,10 @@ acl_calc_wildness(struct rte_acl_build_rule *head,
for (n = 0; n < config->num_fields; n++) {
double wild = 0;
- uint64_t msk_val =
- RTE_LEN2MASK(CHAR_BIT * config->defs[n].size,
+ uint32_t bit_len = CHAR_BIT * config->defs[n].size;
+ uint64_t msk_val = RTE_LEN2MASK(bit_len,
typeof(msk_val));
- double size = CHAR_BIT * config->defs[n].size;
+ double size = bit_len;
int field_index = config->defs[n].field_index;
const struct rte_acl_field *fld = rule->f->field +
field_index;
@@ -1382,54 +1382,15 @@ acl_calc_wildness(struct rte_acl_build_rule *head,
break;
case RTE_ACL_FIELD_TYPE_RANGE:
- switch (rule->config->defs[n].size) {
- case sizeof(uint8_t):
- wild = ((double)fld->mask_range.u8 -
- fld->value.u8) / UINT8_MAX;
- break;
- case sizeof(uint16_t):
- wild = ((double)fld->mask_range.u16 -
- fld->value.u16) / UINT16_MAX;
- break;
- case sizeof(uint32_t):
- wild = ((double)fld->mask_range.u32 -
- fld->value.u32) / UINT32_MAX;
- break;
- case sizeof(uint64_t):
- wild = ((double)fld->mask_range.u64 -
- fld->value.u64) / UINT64_MAX;
- break;
- default:
- RTE_LOG(ERR, ACL,
- "%s(rule: %u) invalid %u-th "
- "field, type: %hhu, "
- "unknown size: %hhu\n",
- __func__,
- rule->f->data.userdata,
- n,
- rule->config->defs[n].type,
- rule->config->defs[n].size);
- return -EINVAL;
- }
+ wild = (fld->mask_range.u64 & msk_val) -
+ (fld->value.u64 & msk_val);
+ wild = wild / msk_val;
break;
-
- default:
- RTE_LOG(ERR, ACL,
- "%s(rule: %u) invalid %u-th "
- "field, unknown type: %hhu\n",
- __func__,
- rule->f->data.userdata,
- n,
- rule->config->defs[n].type);
- return -EINVAL;
-
}
rule->wildness[field_index] = (uint32_t)(wild * 100);
}
}
-
- return 0;
}
static void
@@ -1602,7 +1563,6 @@ static int
acl_build_tries(struct acl_build_context *context,
struct rte_acl_build_rule *head)
{
- int32_t rc;
uint32_t n, num_tries;
struct rte_acl_config *config;
struct rte_acl_build_rule *last;
@@ -1621,9 +1581,7 @@ acl_build_tries(struct acl_build_context *context,
context->tries[0].type = RTE_ACL_FULL_TRIE;
/* calc wildness of each field of each rule */
- rc = acl_calc_wildness(head, config);
- if (rc != 0)
- return rc;
+ acl_calc_wildness(head, config);
for (n = 0;; n = num_tries) {
@@ -1801,6 +1759,49 @@ acl_bld(struct acl_build_context *bcx, struct rte_acl_ctx *ctx,
return rc;
}
+/*
+ * Check that parameters for acl_build() are valid.
+ */
+static int
+acl_check_bld_param(struct rte_acl_ctx *ctx, const struct rte_acl_config *cfg)
+{
+ static const size_t field_sizes[] = {
+ sizeof(uint8_t), sizeof(uint16_t),
+ sizeof(uint32_t), sizeof(uint64_t),
+ };
+
+ uint32_t i, j;
+
+ if (ctx == NULL || cfg == NULL || cfg->num_categories == 0 ||
+ cfg->num_categories > RTE_ACL_MAX_CATEGORIES ||
+ cfg->num_fields == 0 ||
+ cfg->num_fields > RTE_ACL_MAX_FIELDS)
+ return -EINVAL;
+
+ for (i = 0; i != cfg->num_fields; i++) {
+ if (cfg->defs[i].type > RTE_ACL_FIELD_TYPE_BITMASK) {
+ RTE_LOG(ERR, ACL,
+ "ACL context: %s, invalid type: %hhu for %u-th field\n",
+ ctx->name, cfg->defs[i].type, i);
+ return -EINVAL;
+ }
+ for (j = 0;
+ j != RTE_DIM(field_sizes) &&
+ cfg->defs[i].size != field_sizes[j];
+ j++)
+ ;
+
+ if (j == RTE_DIM(field_sizes)) {
+ RTE_LOG(ERR, ACL,
+ "ACL context: %s, invalid size: %hhu for %u-th field\n",
+ ctx->name, cfg->defs[i].size, i);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
int
rte_acl_build(struct rte_acl_ctx *ctx, const struct rte_acl_config *cfg)
{
@@ -1809,9 +1810,9 @@ rte_acl_build(struct rte_acl_ctx *ctx, const struct rte_acl_config *cfg)
size_t max_size;
struct acl_build_context bcx;
- if (ctx == NULL || cfg == NULL || cfg->num_categories == 0 ||
- cfg->num_categories > RTE_ACL_MAX_CATEGORIES)
- return -EINVAL;
+ rc = acl_check_bld_param(ctx, cfg);
+ if (rc != 0)
+ return rc;
acl_build_reset(ctx);
--
2.4.2
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCHv2 4/8] acl: fix avoid unneeded trie splitting for subset of rules.
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 0/8] acl: various fixes and cleanups Konstantin Ananyev
` (2 preceding siblings ...)
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 3/8] acl: add function to check build input parameters Konstantin Ananyev
@ 2015-06-08 10:41 ` Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 5/8] acl: code dedup - introduce a new macro Konstantin Ananyev
` (4 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Konstantin Ananyev @ 2015-06-08 10:41 UTC (permalink / raw)
To: dev
When rebuilding a trie for limited rule-set,
don't try to split the rule-set even further.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
lib/librte_acl/acl_bld.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/lib/librte_acl/acl_bld.c b/lib/librte_acl/acl_bld.c
index 45ee065..d89c66a 100644
--- a/lib/librte_acl/acl_bld.c
+++ b/lib/librte_acl/acl_bld.c
@@ -97,6 +97,7 @@ struct acl_build_context {
struct rte_acl_build_rule *build_rules;
struct rte_acl_config cfg;
int32_t node_max;
+ int32_t cur_node_max;
uint32_t node;
uint32_t num_nodes;
uint32_t category_mask;
@@ -1337,7 +1338,7 @@ build_trie(struct acl_build_context *context, struct rte_acl_build_rule *head,
return NULL;
node_count = context->num_nodes - node_count;
- if (node_count > context->node_max) {
+ if (node_count > context->cur_node_max) {
*last = prev;
return trie;
}
@@ -1536,7 +1537,7 @@ acl_build_index(const struct rte_acl_config *config, uint32_t *data_index)
static struct rte_acl_build_rule *
build_one_trie(struct acl_build_context *context,
struct rte_acl_build_rule *rule_sets[RTE_ACL_MAX_TRIES],
- uint32_t n)
+ uint32_t n, int32_t node_max)
{
struct rte_acl_build_rule *last;
struct rte_acl_config *config;
@@ -1553,6 +1554,8 @@ build_one_trie(struct acl_build_context *context,
context->data_indexes[n]);
context->tries[n].data_index = context->data_indexes[n];
+ context->cur_node_max = node_max;
+
context->bld_tries[n].trie = build_trie(context, rule_sets[n],
&last, &context->tries[n].count);
@@ -1587,7 +1590,7 @@ acl_build_tries(struct acl_build_context *context,
num_tries = n + 1;
- last = build_one_trie(context, rule_sets, n);
+ last = build_one_trie(context, rule_sets, n, context->node_max);
if (context->bld_tries[n].trie == NULL) {
RTE_LOG(ERR, ACL, "Build of %u-th trie failed\n", n);
return -ENOMEM;
@@ -1618,8 +1621,11 @@ acl_build_tries(struct acl_build_context *context,
head = head->next)
head->config = config;
- /* Rebuild the trie for the reduced rule-set. */
- last = build_one_trie(context, rule_sets, n);
+ /*
+ * Rebuild the trie for the reduced rule-set.
+ * Don't try to split it any further.
+ */
+ last = build_one_trie(context, rule_sets, n, INT32_MAX);
if (context->bld_tries[n].trie == NULL || last != NULL) {
RTE_LOG(ERR, ACL, "Build of %u-th trie failed\n", n);
return -ENOMEM;
--
2.4.2
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCHv2 5/8] acl: code dedup - introduce a new macro
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 0/8] acl: various fixes and cleanups Konstantin Ananyev
` (3 preceding siblings ...)
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 4/8] acl: fix avoid unneeded trie splitting for subset of rules Konstantin Ananyev
@ 2015-06-08 10:41 ` Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 6/8] acl: cleanup remove unused code from acl_bld.c Konstantin Ananyev
` (3 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Konstantin Ananyev @ 2015-06-08 10:41 UTC (permalink / raw)
To: dev
Introduce new RTE_ACL_MASKLEN_TO_BITMASK macro, that will be used
in several places inside librte_acl and it's UT.
Simplify and cleanup build_trie() code a bit.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
lib/librte_acl/acl_bld.c | 16 +++-------------
lib/librte_acl/rte_acl.h | 3 +++
2 files changed, 6 insertions(+), 13 deletions(-)
diff --git a/lib/librte_acl/acl_bld.c b/lib/librte_acl/acl_bld.c
index d89c66a..4d8a62f 100644
--- a/lib/librte_acl/acl_bld.c
+++ b/lib/librte_acl/acl_bld.c
@@ -1262,19 +1262,9 @@ build_trie(struct acl_build_context *context, struct rte_acl_build_rule *head,
* all higher bits.
*/
uint64_t mask;
-
- if (fld->mask_range.u32 == 0) {
- mask = 0;
-
- /*
- * arithmetic right shift for the length of
- * the mask less the msb.
- */
- } else {
- mask = -1 <<
- (rule->config->defs[n].size *
- CHAR_BIT - fld->mask_range.u32);
- }
+ mask = RTE_ACL_MASKLEN_TO_BITMASK(
+ fld->mask_range.u32,
+ rule->config->defs[n].size);
/* gen a mini-trie for this field */
merge = acl_gen_mask_trie(context,
diff --git a/lib/librte_acl/rte_acl.h b/lib/librte_acl/rte_acl.h
index 8d9bbe5..bd8f892 100644
--- a/lib/librte_acl/rte_acl.h
+++ b/lib/librte_acl/rte_acl.h
@@ -122,6 +122,9 @@ enum {
#define RTE_ACL_INVALID_USERDATA 0
+#define RTE_ACL_MASKLEN_TO_BITMASK(v, s) \
+((v) == 0 ? (v) : (typeof(v))((uint64_t)-1 << ((s) * CHAR_BIT - (v))))
+
/**
* Miscellaneous data for ACL rule.
*/
--
2.4.2
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCHv2 6/8] acl: cleanup remove unused code from acl_bld.c
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 0/8] acl: various fixes and cleanups Konstantin Ananyev
` (4 preceding siblings ...)
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 5/8] acl: code dedup - introduce a new macro Konstantin Ananyev
@ 2015-06-08 10:41 ` Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 7/8] acl: fix ambiguity between ACL rules in UT Konstantin Ananyev
` (2 subsequent siblings)
8 siblings, 0 replies; 21+ messages in thread
From: Konstantin Ananyev @ 2015-06-08 10:41 UTC (permalink / raw)
To: dev
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
lib/librte_acl/acl_bld.c | 310 -----------------------------------------------
1 file changed, 310 deletions(-)
diff --git a/lib/librte_acl/acl_bld.c b/lib/librte_acl/acl_bld.c
index 4d8a62f..e6f4530 100644
--- a/lib/librte_acl/acl_bld.c
+++ b/lib/librte_acl/acl_bld.c
@@ -120,10 +120,6 @@ static int acl_merge_trie(struct acl_build_context *context,
struct rte_acl_node *node_a, struct rte_acl_node *node_b,
uint32_t level, struct rte_acl_node **node_c);
-static int acl_merge(struct acl_build_context *context,
- struct rte_acl_node *node_a, struct rte_acl_node *node_b,
- int move, int a_subset, int level);
-
static void
acl_deref_ptr(struct acl_build_context *context,
struct rte_acl_node *node, int index);
@@ -415,58 +411,6 @@ acl_intersect_type(const struct rte_acl_bitset *a_bits,
}
/*
- * Check if all bits in the bitset are on
- */
-static int
-acl_full(struct rte_acl_node *node)
-{
- uint32_t n;
- bits_t all_bits = -1;
-
- for (n = 0; n < RTE_ACL_BIT_SET_SIZE; n++)
- all_bits &= node->values.bits[n];
- return all_bits == -1;
-}
-
-/*
- * Check if all bits in the bitset are off
- */
-static int
-acl_empty(struct rte_acl_node *node)
-{
- uint32_t n;
-
- if (node->ref_count == 0) {
- for (n = 0; n < RTE_ACL_BIT_SET_SIZE; n++) {
- if (0 != node->values.bits[n])
- return 0;
- }
- return 1;
- } else {
- return 0;
- }
-}
-
-/*
- * Compute intersection of A and B
- * return 1 if there is an intersection else 0.
- */
-static int
-acl_intersect(struct rte_acl_bitset *a_bits,
- struct rte_acl_bitset *b_bits,
- struct rte_acl_bitset *intersect)
-{
- uint32_t n;
- bits_t all_bits = 0;
-
- for (n = 0; n < RTE_ACL_BIT_SET_SIZE; n++) {
- intersect->bits[n] = a_bits->bits[n] & b_bits->bits[n];
- all_bits |= intersect->bits[n];
- }
- return all_bits != 0;
-}
-
-/*
* Duplicate a node
*/
static struct rte_acl_node *
@@ -534,63 +478,6 @@ acl_deref_ptr(struct acl_build_context *context,
}
/*
- * Exclude bitset from a node pointer
- * returns 0 if poiter was deref'd
- * 1 otherwise.
- */
-static int
-acl_exclude_ptr(struct acl_build_context *context,
- struct rte_acl_node *node,
- int index,
- struct rte_acl_bitset *b_bits)
-{
- int retval = 1;
-
- /*
- * remove bitset from node pointer and deref
- * if the bitset becomes empty.
- */
- if (!acl_exclude(&node->ptrs[index].values,
- &node->ptrs[index].values,
- b_bits)) {
- acl_deref_ptr(context, node, index);
- node->ptrs[index].ptr = NULL;
- retval = 0;
- }
-
- /* exclude bits from the composite bits for the node */
- acl_exclude(&node->values, &node->values, b_bits);
- return retval;
-}
-
-/*
- * Remove a bitset from src ptr and move remaining ptr to dst
- */
-static int
-acl_move_ptr(struct acl_build_context *context,
- struct rte_acl_node *dst,
- struct rte_acl_node *src,
- int index,
- struct rte_acl_bitset *b_bits)
-{
- int rc;
-
- if (b_bits != NULL)
- if (!acl_exclude_ptr(context, src, index, b_bits))
- return 0;
-
- /* add src pointer to dst node */
- rc = acl_add_ptr(context, dst, src->ptrs[index].ptr,
- &src->ptrs[index].values);
- if (rc < 0)
- return rc;
-
- /* remove ptr from src */
- acl_exclude_ptr(context, src, index, &src->ptrs[index].values);
- return 1;
-}
-
-/*
* acl_exclude rte_acl_bitset from src and copy remaining pointer to dst
*/
static int
@@ -650,203 +537,6 @@ acl_compact_node_ptrs(struct rte_acl_node *node_a)
}
}
-/*
- * acl_merge helper routine.
- */
-static int
-acl_merge_intersect(struct acl_build_context *context,
- struct rte_acl_node *node_a, uint32_t idx_a,
- struct rte_acl_node *node_b, uint32_t idx_b,
- int next_move, int level,
- struct rte_acl_bitset *intersect_ptr)
-{
- struct rte_acl_node *node_c;
-
- /* Duplicate A for intersection */
- node_c = acl_dup_node(context, node_a->ptrs[idx_a].ptr);
-
- /* Remove intersection from A */
- acl_exclude_ptr(context, node_a, idx_a, intersect_ptr);
-
- /*
- * Added link from A to C for all transitions
- * in the intersection
- */
- if (acl_add_ptr(context, node_a, node_c, intersect_ptr) < 0)
- return -1;
-
- /* merge B->node into C */
- return acl_merge(context, node_c, node_b->ptrs[idx_b].ptr, next_move,
- 0, level + 1);
-}
-
-
-/*
- * Merge the children of nodes A and B together.
- *
- * if match node
- * For each category
- * node A result = highest priority result
- * if any pointers in A intersect with any in B
- * For each intersection
- * C = copy of node that A points to
- * remove intersection from A pointer
- * add a pointer to A that points to C for the intersection
- * Merge C and node that B points to
- * Compact the pointers in A and B
- * if move flag
- * If B has only one reference
- * Move B pointers to A
- * else
- * Copy B pointers to A
- */
-static int
-acl_merge(struct acl_build_context *context,
- struct rte_acl_node *node_a, struct rte_acl_node *node_b,
- int move, int a_subset, int level)
-{
- uint32_t n, m, ptrs_a, ptrs_b;
- uint32_t min_add_a, min_add_b;
- int intersect_type;
- int node_intersect_type;
- int b_full, next_move, rc;
- struct rte_acl_bitset intersect_values;
- struct rte_acl_bitset intersect_ptr;
-
- min_add_a = 0;
- min_add_b = 0;
- intersect_type = 0;
- node_intersect_type = 0;
-
- if (level == 0)
- a_subset = 1;
-
- /*
- * Resolve match priorities
- */
- if (node_a->match_flag != 0 || node_b->match_flag != 0) {
-
- if (node_a->match_flag == 0 || node_b->match_flag == 0)
- RTE_LOG(ERR, ACL, "Not both matches\n");
-
- if (node_b->match_flag < node_a->match_flag)
- RTE_LOG(ERR, ACL, "Not same match\n");
-
- for (n = 0; n < context->cfg.num_categories; n++) {
- if (node_a->mrt->priority[n] <
- node_b->mrt->priority[n]) {
- node_a->mrt->priority[n] =
- node_b->mrt->priority[n];
- node_a->mrt->results[n] =
- node_b->mrt->results[n];
- }
- }
- }
-
- /*
- * If the two node transitions intersect then merge the transitions.
- * Check intersection for entire node (all pointers)
- */
- node_intersect_type = acl_intersect_type(&node_a->values,
- &node_b->values,
- &intersect_values);
-
- if (node_intersect_type & ACL_INTERSECT) {
-
- b_full = acl_full(node_b);
-
- min_add_b = node_b->min_add;
- node_b->min_add = node_b->num_ptrs;
- ptrs_b = node_b->num_ptrs;
-
- min_add_a = node_a->min_add;
- node_a->min_add = node_a->num_ptrs;
- ptrs_a = node_a->num_ptrs;
-
- for (n = 0; n < ptrs_a; n++) {
- for (m = 0; m < ptrs_b; m++) {
-
- if (node_a->ptrs[n].ptr == NULL ||
- node_b->ptrs[m].ptr == NULL ||
- node_a->ptrs[n].ptr ==
- node_b->ptrs[m].ptr)
- continue;
-
- intersect_type = acl_intersect_type(
- &node_a->ptrs[n].values,
- &node_b->ptrs[m].values,
- &intersect_ptr);
-
- /* If this node is not a 'match' node */
- if ((intersect_type & ACL_INTERSECT) &&
- (context->cfg.num_categories != 1 ||
- !(node_a->ptrs[n].ptr->match_flag))) {
-
- /*
- * next merge is a 'move' pointer,
- * if this one is and B is a
- * subset of the intersection.
- */
- next_move = move &&
- (intersect_type &
- ACL_INTERSECT_B) == 0;
-
- if (a_subset && b_full) {
- rc = acl_merge(context,
- node_a->ptrs[n].ptr,
- node_b->ptrs[m].ptr,
- next_move,
- 1, level + 1);
- if (rc != 0)
- return rc;
- } else {
- rc = acl_merge_intersect(
- context, node_a, n,
- node_b, m, next_move,
- level, &intersect_ptr);
- if (rc != 0)
- return rc;
- }
- }
- }
- }
- }
-
- /* Compact pointers */
- node_a->min_add = min_add_a;
- acl_compact_node_ptrs(node_a);
- node_b->min_add = min_add_b;
- acl_compact_node_ptrs(node_b);
-
- /*
- * Either COPY or MOVE pointers from B to A
- */
- acl_intersect(&node_a->values, &node_b->values, &intersect_values);
-
- if (move && node_b->ref_count == 1) {
- for (m = 0; m < node_b->num_ptrs; m++) {
- if (node_b->ptrs[m].ptr != NULL &&
- acl_move_ptr(context, node_a, node_b, m,
- &intersect_values) < 0)
- return -1;
- }
- } else {
- for (m = 0; m < node_b->num_ptrs; m++) {
- if (node_b->ptrs[m].ptr != NULL &&
- acl_copy_ptr(context, node_a, node_b, m,
- &intersect_values) < 0)
- return -1;
- }
- }
-
- /*
- * Free node if its empty (no longer used)
- */
- if (acl_empty(node_b))
- acl_free_node(context, node_b);
- return 0;
-}
-
static int
acl_resolve_leaf(struct acl_build_context *context,
struct rte_acl_node *node_a,
--
2.4.2
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCHv2 7/8] acl: fix ambiguity between ACL rules in UT.
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 0/8] acl: various fixes and cleanups Konstantin Ananyev
` (5 preceding siblings ...)
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 6/8] acl: cleanup remove unused code from acl_bld.c Konstantin Ananyev
@ 2015-06-08 10:41 ` Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 8/8] acl: add new test-cases into UT Konstantin Ananyev
2015-06-18 16:14 ` [dpdk-dev] [PATCHv2 0/8] acl: various fixes and cleanups Thomas Monjalon
8 siblings, 0 replies; 21+ messages in thread
From: Konstantin Ananyev @ 2015-06-08 10:41 UTC (permalink / raw)
To: dev
Some test rules had equal priority for the same category.
That can cause an ambiguity in build trie and test results.
Specify different priority value for each rule from the same category.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
app/test/test_acl.h | 52 ++++++++++++++++++++++++++--------------------------
1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/app/test/test_acl.h b/app/test/test_acl.h
index 4af457d..4e8ff34 100644
--- a/app/test/test_acl.h
+++ b/app/test/test_acl.h
@@ -105,7 +105,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets traveling to 192.168.0.0/16 */
{
.data = {.userdata = 1, .category_mask = ACL_ALLOW_MASK,
- .priority = 2},
+ .priority = 230},
.dst_addr = IPv4(192,168,0,0),
.dst_mask_len = 16,
.src_port_low = 0,
@@ -116,7 +116,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets traveling to 192.168.1.0/24 */
{
.data = {.userdata = 2, .category_mask = ACL_ALLOW_MASK,
- .priority = 3},
+ .priority = 330},
.dst_addr = IPv4(192,168,1,0),
.dst_mask_len = 24,
.src_port_low = 0,
@@ -127,7 +127,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets traveling to 192.168.1.50 */
{
.data = {.userdata = 3, .category_mask = ACL_DENY_MASK,
- .priority = 2},
+ .priority = 230},
.dst_addr = IPv4(192,168,1,50),
.dst_mask_len = 32,
.src_port_low = 0,
@@ -140,7 +140,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets traveling from 10.0.0.0/8 */
{
.data = {.userdata = 4, .category_mask = ACL_ALLOW_MASK,
- .priority = 2},
+ .priority = 240},
.src_addr = IPv4(10,0,0,0),
.src_mask_len = 8,
.src_port_low = 0,
@@ -151,7 +151,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets traveling from 10.1.1.0/24 */
{
.data = {.userdata = 5, .category_mask = ACL_ALLOW_MASK,
- .priority = 3},
+ .priority = 340},
.src_addr = IPv4(10,1,1,0),
.src_mask_len = 24,
.src_port_low = 0,
@@ -162,7 +162,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets traveling from 10.1.1.1 */
{
.data = {.userdata = 6, .category_mask = ACL_DENY_MASK,
- .priority = 2},
+ .priority = 240},
.src_addr = IPv4(10,1,1,1),
.src_mask_len = 32,
.src_port_low = 0,
@@ -175,7 +175,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets with lower 7 bytes of VLAN tag equal to 0x64 */
{
.data = {.userdata = 7, .category_mask = ACL_ALLOW_MASK,
- .priority = 2},
+ .priority = 260},
.vlan = 0x64,
.vlan_mask = 0x7f,
.src_port_low = 0,
@@ -186,7 +186,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets with VLAN tags that have 0x5 in them */
{
.data = {.userdata = 8, .category_mask = ACL_ALLOW_MASK,
- .priority = 2},
+ .priority = 260},
.vlan = 0x5,
.vlan_mask = 0x5,
.src_port_low = 0,
@@ -197,7 +197,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets with VLAN tag 5 */
{
.data = {.userdata = 9, .category_mask = ACL_DENY_MASK,
- .priority = 3},
+ .priority = 360},
.vlan = 0x5,
.vlan_mask = 0xffff,
.src_port_low = 0,
@@ -210,7 +210,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets with lower 7 bytes of domain equal to 0x64 */
{
.data = {.userdata = 10, .category_mask = ACL_ALLOW_MASK,
- .priority = 2},
+ .priority = 250},
.domain = 0x64,
.domain_mask = 0x7f,
.src_port_low = 0,
@@ -221,7 +221,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets with domains that have 0x5 in them */
{
.data = {.userdata = 11, .category_mask = ACL_ALLOW_MASK,
- .priority = 3},
+ .priority = 350},
.domain = 0x5,
.domain_mask = 0x5,
.src_port_low = 0,
@@ -232,7 +232,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets with domain 5 */
{
.data = {.userdata = 12, .category_mask = ACL_DENY_MASK,
- .priority = 3},
+ .priority = 350},
.domain = 0x5,
.domain_mask = 0xffff,
.src_port_low = 0,
@@ -245,7 +245,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches everything with dst port 80 */
{
.data = {.userdata = 13, .category_mask = ACL_ALLOW_MASK,
- .priority = 3},
+ .priority = 310},
.dst_port_low = 80,
.dst_port_high = 80,
.src_port_low = 0,
@@ -254,7 +254,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches everything with dst port 22-1023 */
{
.data = {.userdata = 14, .category_mask = ACL_ALLOW_MASK,
- .priority = 2},
+ .priority = 210},
.dst_port_low = 22,
.dst_port_high = 1023,
.src_port_low = 0,
@@ -263,7 +263,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches everything with dst port 1020 */
{
.data = {.userdata = 15, .category_mask = ACL_DENY_MASK,
- .priority = 3},
+ .priority = 310},
.dst_port_low = 1020,
.dst_port_high = 1020,
.src_port_low = 0,
@@ -272,7 +272,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches everything with dst portrange 1000-2000 */
{
.data = {.userdata = 16, .category_mask = ACL_DENY_MASK,
- .priority = 2},
+ .priority = 210},
.dst_port_low = 1000,
.dst_port_high = 2000,
.src_port_low = 0,
@@ -283,7 +283,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches everything with src port 80 */
{
.data = {.userdata = 17, .category_mask = ACL_ALLOW_MASK,
- .priority = 3},
+ .priority = 320},
.src_port_low = 80,
.src_port_high = 80,
.dst_port_low = 0,
@@ -292,7 +292,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches everything with src port 22-1023 */
{
.data = {.userdata = 18, .category_mask = ACL_ALLOW_MASK,
- .priority = 2},
+ .priority = 220},
.src_port_low = 22,
.src_port_high = 1023,
.dst_port_low = 0,
@@ -301,7 +301,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches everything with src port 1020 */
{
.data = {.userdata = 19, .category_mask = ACL_DENY_MASK,
- .priority = 3},
+ .priority = 320},
.src_port_low = 1020,
.src_port_high = 1020,
.dst_port_low = 0,
@@ -310,7 +310,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches everything with src portrange 1000-2000 */
{
.data = {.userdata = 20, .category_mask = ACL_DENY_MASK,
- .priority = 2},
+ .priority = 220},
.src_port_low = 1000,
.src_port_high = 2000,
.dst_port_low = 0,
@@ -321,7 +321,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets with protocol number either 0x64 or 0xE4 */
{
.data = {.userdata = 21, .category_mask = ACL_ALLOW_MASK,
- .priority = 2},
+ .priority = 270},
.proto = 0x64,
.proto_mask = 0x7f,
.src_port_low = 0,
@@ -343,7 +343,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* matches all packets with protocol 5 */
{
.data = {.userdata = 23, .category_mask = ACL_DENY_MASK,
- .priority = 3},
+ .priority = 370},
.proto = 0x5,
.proto_mask = 0xff,
.src_port_low = 0,
@@ -355,7 +355,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
/* rules combining various fields */
{
.data = {.userdata = 24, .category_mask = ACL_ALLOW_MASK,
- .priority = 4},
+ .priority = 400},
/** make sure that unmasked bytes don't fail! */
.dst_addr = IPv4(1,2,3,4),
.dst_mask_len = 16,
@@ -374,7 +374,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
},
{
.data = {.userdata = 25, .category_mask = ACL_DENY_MASK,
- .priority = 4},
+ .priority = 400},
.dst_addr = IPv4(5,6,7,8),
.dst_mask_len = 24,
.src_addr = IPv4(1,2,3,4),
@@ -392,7 +392,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
},
{
.data = {.userdata = 26, .category_mask = ACL_ALLOW_MASK,
- .priority = 5},
+ .priority = 500},
.dst_addr = IPv4(1,2,3,4),
.dst_mask_len = 8,
.src_addr = IPv4(5,6,7,8),
@@ -408,7 +408,7 @@ struct rte_acl_ipv4vlan_rule acl_test_rules[] = {
},
{
.data = {.userdata = 27, .category_mask = ACL_DENY_MASK,
- .priority = 5},
+ .priority = 500},
.dst_addr = IPv4(5,6,7,8),
.dst_mask_len = 32,
.src_addr = IPv4(1,2,3,4),
--
2.4.2
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCHv2 8/8] acl: add new test-cases into UT
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 0/8] acl: various fixes and cleanups Konstantin Ananyev
` (6 preceding siblings ...)
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 7/8] acl: fix ambiguity between ACL rules in UT Konstantin Ananyev
@ 2015-06-08 10:41 ` Konstantin Ananyev
2015-06-18 16:14 ` [dpdk-dev] [PATCHv2 0/8] acl: various fixes and cleanups Thomas Monjalon
8 siblings, 0 replies; 21+ messages in thread
From: Konstantin Ananyev @ 2015-06-08 10:41 UTC (permalink / raw)
To: dev
Add several new test cases for ACL to cover different build configurations.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
app/test/test_acl.c | 431 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 423 insertions(+), 8 deletions(-)
diff --git a/app/test/test_acl.c b/app/test/test_acl.c
index 6a032f9..b4a107d 100644
--- a/app/test/test_acl.c
+++ b/app/test/test_acl.c
@@ -47,6 +47,8 @@
#define LEN RTE_ACL_MAX_CATEGORIES
+RTE_ACL_RULE_DEF(acl_ipv4vlan_rule, RTE_ACL_IPV4VLAN_NUM_FIELDS);
+
struct rte_acl_param acl_param = {
.name = "acl_ctx",
.socket_id = SOCKET_ID_ANY,
@@ -62,6 +64,15 @@ struct rte_acl_ipv4vlan_rule acl_rule = {
.dst_port_high = UINT16_MAX,
};
+const uint32_t ipv4_7tuple_layout[RTE_ACL_IPV4VLAN_NUM] = {
+ offsetof(struct ipv4_7tuple, proto),
+ offsetof(struct ipv4_7tuple, vlan),
+ offsetof(struct ipv4_7tuple, ip_src),
+ offsetof(struct ipv4_7tuple, ip_dst),
+ offsetof(struct ipv4_7tuple, port_src),
+};
+
+
/* byteswap to cpu or network order */
static void
bswap_test_data(struct ipv4_7tuple *data, int len, int to_be)
@@ -195,13 +206,6 @@ test_classify_buid(struct rte_acl_ctx *acx,
const struct rte_acl_ipv4vlan_rule *rules, uint32_t num)
{
int ret;
- const uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = {
- offsetof(struct ipv4_7tuple, proto),
- offsetof(struct ipv4_7tuple, vlan),
- offsetof(struct ipv4_7tuple, ip_src),
- offsetof(struct ipv4_7tuple, ip_dst),
- offsetof(struct ipv4_7tuple, port_src),
- };
/* add rules to the context */
ret = rte_acl_ipv4vlan_add_rules(acx, rules, num);
@@ -212,7 +216,8 @@ test_classify_buid(struct rte_acl_ctx *acx,
}
/* try building the context */
- ret = rte_acl_ipv4vlan_build(acx, layout, RTE_ACL_MAX_CATEGORIES);
+ ret = rte_acl_ipv4vlan_build(acx, ipv4_7tuple_layout,
+ RTE_ACL_MAX_CATEGORIES);
if (ret != 0) {
printf("Line %i: Building ACL context failed!\n", __LINE__);
return ret;
@@ -412,6 +417,414 @@ test_build_ports_range(void)
return ret;
}
+static void
+convert_rule(const struct rte_acl_ipv4vlan_rule *ri,
+ struct acl_ipv4vlan_rule *ro)
+{
+ ro->data = ri->data;
+
+ ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].value.u8 = ri->proto;
+ ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].value.u16 = ri->vlan;
+ ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].value.u16 = ri->domain;
+ ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 = ri->src_addr;
+ ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 = ri->dst_addr;
+ ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].value.u16 = ri->src_port_low;
+ ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].value.u16 = ri->dst_port_low;
+
+ ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].mask_range.u8 = ri->proto_mask;
+ ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].mask_range.u16 = ri->vlan_mask;
+ ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].mask_range.u16 =
+ ri->domain_mask;
+ ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 =
+ ri->src_mask_len;
+ ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = ri->dst_mask_len;
+ ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].mask_range.u16 =
+ ri->src_port_high;
+ ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].mask_range.u16 =
+ ri->dst_port_high;
+}
+
+/*
+ * Convert IPV4 source and destination from RTE_ACL_FIELD_TYPE_MASK to
+ * RTE_ACL_FIELD_TYPE_BITMASK.
+ */
+static void
+convert_rule_1(const struct rte_acl_ipv4vlan_rule *ri,
+ struct acl_ipv4vlan_rule *ro)
+{
+ uint32_t v;
+
+ convert_rule(ri, ro);
+ v = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32;
+ ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 =
+ RTE_ACL_MASKLEN_TO_BITMASK(v, sizeof(v));
+ v = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32;
+ ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 =
+ RTE_ACL_MASKLEN_TO_BITMASK(v, sizeof(v));
+}
+
+/*
+ * Convert IPV4 source and destination from RTE_ACL_FIELD_TYPE_MASK to
+ * RTE_ACL_FIELD_TYPE_RANGE.
+ */
+static void
+convert_rule_2(const struct rte_acl_ipv4vlan_rule *ri,
+ struct acl_ipv4vlan_rule *ro)
+{
+ uint32_t hi, lo, mask;
+
+ convert_rule(ri, ro);
+
+ mask = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32;
+ mask = RTE_ACL_MASKLEN_TO_BITMASK(mask, sizeof(mask));
+ lo = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 & mask;
+ hi = lo + ~mask;
+ ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 = lo;
+ ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 = hi;
+
+ mask = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32;
+ mask = RTE_ACL_MASKLEN_TO_BITMASK(mask, sizeof(mask));
+ lo = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 & mask;
+ hi = lo + ~mask;
+ ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 = lo;
+ ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = hi;
+}
+
+/*
+ * Convert rte_acl_ipv4vlan_rule: swap VLAN and PORTS rule fields.
+ */
+static void
+convert_rule_3(const struct rte_acl_ipv4vlan_rule *ri,
+ struct acl_ipv4vlan_rule *ro)
+{
+ struct rte_acl_field t1, t2;
+
+ convert_rule(ri, ro);
+
+ t1 = ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD];
+ t2 = ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD];
+
+ ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD] =
+ ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD];
+ ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD] =
+ ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD];
+
+ ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD] = t1;
+ ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD] = t2;
+}
+
+/*
+ * Convert rte_acl_ipv4vlan_rule: swap SRC and DST IPv4 address rules.
+ */
+static void
+convert_rule_4(const struct rte_acl_ipv4vlan_rule *ri,
+ struct acl_ipv4vlan_rule *ro)
+{
+ struct rte_acl_field t;
+
+ convert_rule(ri, ro);
+
+ t = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD];
+ ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD] =
+ ro->field[RTE_ACL_IPV4VLAN_DST_FIELD];
+
+ ro->field[RTE_ACL_IPV4VLAN_DST_FIELD] = t;
+}
+
+static void
+ipv4vlan_config(struct rte_acl_config *cfg,
+ const uint32_t layout[RTE_ACL_IPV4VLAN_NUM],
+ uint32_t num_categories)
+{
+ static const struct rte_acl_field_def
+ ipv4_defs[RTE_ACL_IPV4VLAN_NUM_FIELDS] = {
+ {
+ .type = RTE_ACL_FIELD_TYPE_BITMASK,
+ .size = sizeof(uint8_t),
+ .field_index = RTE_ACL_IPV4VLAN_PROTO_FIELD,
+ .input_index = RTE_ACL_IPV4VLAN_PROTO,
+ },
+ {
+ .type = RTE_ACL_FIELD_TYPE_BITMASK,
+ .size = sizeof(uint16_t),
+ .field_index = RTE_ACL_IPV4VLAN_VLAN1_FIELD,
+ .input_index = RTE_ACL_IPV4VLAN_VLAN,
+ },
+ {
+ .type = RTE_ACL_FIELD_TYPE_BITMASK,
+ .size = sizeof(uint16_t),
+ .field_index = RTE_ACL_IPV4VLAN_VLAN2_FIELD,
+ .input_index = RTE_ACL_IPV4VLAN_VLAN,
+ },
+ {
+ .type = RTE_ACL_FIELD_TYPE_MASK,
+ .size = sizeof(uint32_t),
+ .field_index = RTE_ACL_IPV4VLAN_SRC_FIELD,
+ .input_index = RTE_ACL_IPV4VLAN_SRC,
+ },
+ {
+ .type = RTE_ACL_FIELD_TYPE_MASK,
+ .size = sizeof(uint32_t),
+ .field_index = RTE_ACL_IPV4VLAN_DST_FIELD,
+ .input_index = RTE_ACL_IPV4VLAN_DST,
+ },
+ {
+ .type = RTE_ACL_FIELD_TYPE_RANGE,
+ .size = sizeof(uint16_t),
+ .field_index = RTE_ACL_IPV4VLAN_SRCP_FIELD,
+ .input_index = RTE_ACL_IPV4VLAN_PORTS,
+ },
+ {
+ .type = RTE_ACL_FIELD_TYPE_RANGE,
+ .size = sizeof(uint16_t),
+ .field_index = RTE_ACL_IPV4VLAN_DSTP_FIELD,
+ .input_index = RTE_ACL_IPV4VLAN_PORTS,
+ },
+ };
+
+ memcpy(&cfg->defs, ipv4_defs, sizeof(ipv4_defs));
+ cfg->num_fields = RTE_DIM(ipv4_defs);
+
+ cfg->defs[RTE_ACL_IPV4VLAN_PROTO_FIELD].offset =
+ layout[RTE_ACL_IPV4VLAN_PROTO];
+ cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].offset =
+ layout[RTE_ACL_IPV4VLAN_VLAN];
+ cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].offset =
+ layout[RTE_ACL_IPV4VLAN_VLAN] +
+ cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].size;
+ cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].offset =
+ layout[RTE_ACL_IPV4VLAN_SRC];
+ cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].offset =
+ layout[RTE_ACL_IPV4VLAN_DST];
+ cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].offset =
+ layout[RTE_ACL_IPV4VLAN_PORTS];
+ cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].offset =
+ layout[RTE_ACL_IPV4VLAN_PORTS] +
+ cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].size;
+
+ cfg->num_categories = num_categories;
+}
+
+static int
+convert_rules(struct rte_acl_ctx *acx,
+ void (*convert)(const struct rte_acl_ipv4vlan_rule *,
+ struct acl_ipv4vlan_rule *),
+ const struct rte_acl_ipv4vlan_rule *rules, uint32_t num)
+{
+ int32_t rc;
+ uint32_t i;
+ struct acl_ipv4vlan_rule r;
+
+ for (i = 0; i != num; i++) {
+ convert(rules + i, &r);
+ rc = rte_acl_add_rules(acx, (struct rte_acl_rule *)&r, 1);
+ if (rc != 0) {
+ printf("Line %i: Adding rule %u to ACL context "
+ "failed with error code: %d\n",
+ __LINE__, i, rc);
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+static void
+convert_config(struct rte_acl_config *cfg)
+{
+ ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
+}
+
+/*
+ * Convert rte_acl_ipv4vlan_rule to use RTE_ACL_FIELD_TYPE_BITMASK.
+ */
+static void
+convert_config_1(struct rte_acl_config *cfg)
+{
+ ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
+ cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].type = RTE_ACL_FIELD_TYPE_BITMASK;
+ cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = RTE_ACL_FIELD_TYPE_BITMASK;
+}
+
+/*
+ * Convert rte_acl_ipv4vlan_rule to use RTE_ACL_FIELD_TYPE_RANGE.
+ */
+static void
+convert_config_2(struct rte_acl_config *cfg)
+{
+ ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
+ cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].type = RTE_ACL_FIELD_TYPE_RANGE;
+ cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = RTE_ACL_FIELD_TYPE_RANGE;
+}
+
+/*
+ * Convert rte_acl_ipv4vlan_rule: swap VLAN and PORTS rule definitions.
+ */
+static void
+convert_config_3(struct rte_acl_config *cfg)
+{
+ struct rte_acl_field_def t1, t2;
+
+ ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
+
+ t1 = cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD];
+ t2 = cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD];
+
+ /* swap VLAN1 and SRCP rule definition. */
+ cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD] =
+ cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD];
+ cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].field_index = t1.field_index;
+ cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].input_index = t1.input_index;
+
+ /* swap VLAN2 and DSTP rule definition. */
+ cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD] =
+ cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD];
+ cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].field_index = t2.field_index;
+ cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].input_index = t2.input_index;
+
+ cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].type = t1.type;
+ cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].size = t1.size;
+ cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].offset = t1.offset;
+
+ cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].type = t2.type;
+ cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].size = t2.size;
+ cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].offset = t2.offset;
+}
+
+/*
+ * Convert rte_acl_ipv4vlan_rule: swap SRC and DST ip address rule definitions.
+ */
+static void
+convert_config_4(struct rte_acl_config *cfg)
+{
+ struct rte_acl_field_def t;
+
+ ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
+
+ t = cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD];
+
+ cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD] =
+ cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD];
+ cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].field_index = t.field_index;
+ cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].input_index = t.input_index;
+
+ cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = t.type;
+ cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].size = t.size;
+ cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].offset = t.offset;
+}
+
+
+static int
+build_convert_rules(struct rte_acl_ctx *acx,
+ void (*config)(struct rte_acl_config *),
+ size_t max_size)
+{
+ struct rte_acl_config cfg;
+
+ memset(&cfg, 0, sizeof(cfg));
+ config(&cfg);
+ cfg.max_size = max_size;
+ return rte_acl_build(acx, &cfg);
+}
+
+static int
+test_convert_rules(const char *desc,
+ void (*config)(struct rte_acl_config *),
+ void (*convert)(const struct rte_acl_ipv4vlan_rule *,
+ struct acl_ipv4vlan_rule *))
+{
+ struct rte_acl_ctx *acx;
+ int32_t rc;
+ uint32_t i;
+ static const size_t mem_sizes[] = {0, -1};
+
+ printf("running %s(%s)\n", __func__, desc);
+
+ acx = rte_acl_create(&acl_param);
+ if (acx == NULL) {
+ printf("Line %i: Error creating ACL context!\n", __LINE__);
+ return -1;
+ }
+
+ rc = convert_rules(acx, convert, acl_test_rules,
+ RTE_DIM(acl_test_rules));
+ if (rc != 0)
+ printf("Line %i: Error converting ACL rules!\n", __LINE__);
+
+ for (i = 0; rc == 0 && i != RTE_DIM(mem_sizes); i++) {
+
+ rc = build_convert_rules(acx, config, mem_sizes[i]);
+ if (rc != 0) {
+ printf("Line %i: Error @ build_convert_rules(%zu)!\n",
+ __LINE__, mem_sizes[i]);
+ break;
+ }
+
+ rc = test_classify_run(acx);
+ if (rc != 0)
+ printf("%s failed at line %i, max_size=%zu\n",
+ __func__, __LINE__, mem_sizes[i]);
+ }
+
+ rte_acl_free(acx);
+ return rc;
+}
+
+static int
+test_convert(void)
+{
+ static const struct {
+ const char *desc;
+ void (*config)(struct rte_acl_config *);
+ void (*convert)(const struct rte_acl_ipv4vlan_rule *,
+ struct acl_ipv4vlan_rule *);
+ } convert_param[] = {
+ {
+ "acl_ipv4vlan_tuple",
+ convert_config,
+ convert_rule,
+ },
+ {
+ "acl_ipv4vlan_tuple, RTE_ACL_FIELD_TYPE_BITMASK type "
+ "for IPv4",
+ convert_config_1,
+ convert_rule_1,
+ },
+ {
+ "acl_ipv4vlan_tuple, RTE_ACL_FIELD_TYPE_RANGE type "
+ "for IPv4",
+ convert_config_2,
+ convert_rule_2,
+ },
+ {
+ "acl_ipv4vlan_tuple: swap VLAN and PORTs order",
+ convert_config_3,
+ convert_rule_3,
+ },
+ {
+ "acl_ipv4vlan_tuple: swap SRC and DST IPv4 order",
+ convert_config_4,
+ convert_rule_4,
+ },
+ };
+
+ uint32_t i;
+ int32_t rc;
+
+ for (i = 0; i != RTE_DIM(convert_param); i++) {
+ rc = test_convert_rules(convert_param[i].desc,
+ convert_param[i].config,
+ convert_param[i].convert);
+ if (rc != 0) {
+ printf("%s for test-case: %s failed, error code: %d;\n",
+ __func__, convert_param[i].desc, rc);
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
/*
* Test wrong layout behavior
* This test supplies the ACL context with invalid layout, which results in
@@ -1069,6 +1482,8 @@ test_acl(void)
return -1;
if (test_build_ports_range() < 0)
return -1;
+ if (test_convert() < 0)
+ return -1;
return 0;
}
--
2.4.2
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCHv2 0/8] acl: various fixes and cleanups
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 0/8] acl: various fixes and cleanups Konstantin Ananyev
` (7 preceding siblings ...)
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 8/8] acl: add new test-cases into UT Konstantin Ananyev
@ 2015-06-18 16:14 ` Thomas Monjalon
8 siblings, 0 replies; 21+ messages in thread
From: Thomas Monjalon @ 2015-06-18 16:14 UTC (permalink / raw)
To: Konstantin Ananyev; +Cc: dev
2015-06-08 11:41, Konstantin Ananyev:
> Several fixes and code cleanups for the librte_acl.
> New test-cases for acl UT.
>
> Konstantin Ananyev (8):
> acl: fix invalid rule wildness calculation for bitmask field type
> acl: code cleanup - use global EAL macro, instead of creating a local
> copy
> acl: add function to check build input parameters
> acl: fix avoid unneeded trie splitting for subset of rules.
> acl: code dedup - introduce a new macro
> acl: cleanup remove unused code from acl_bld.c
> acl: fix ambiguity between ACL rules in UT.
> acl: add new test-cases into UT
Applied, thanks
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2015-06-18 16:15 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-03 23:10 [dpdk-dev] [PATCH 0/8] ACL: various fixes and cleanups Konstantin Ananyev
2015-06-03 23:10 ` [dpdk-dev] [PATCH 1/8] ACL: fix invalid rule wildness calculation for RTE_ACL_FIELD_TYPE_BITMASK Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 0/8] acl: various fixes and cleanups Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 1/8] acl: fix invalid rule wildness calculation for bitmask field type Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 2/8] acl: code cleanup - use global EAL macro, instead of creating a local copy Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 3/8] acl: add function to check build input parameters Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 4/8] acl: fix avoid unneeded trie splitting for subset of rules Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 5/8] acl: code dedup - introduce a new macro Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 6/8] acl: cleanup remove unused code from acl_bld.c Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 7/8] acl: fix ambiguity between ACL rules in UT Konstantin Ananyev
2015-06-08 10:41 ` [dpdk-dev] [PATCHv2 8/8] acl: add new test-cases into UT Konstantin Ananyev
2015-06-18 16:14 ` [dpdk-dev] [PATCHv2 0/8] acl: various fixes and cleanups Thomas Monjalon
2015-06-03 23:10 ` [dpdk-dev] [PATCH 2/8] ACL: code cleanup - use global RTE_LEN2MASK macro Konstantin Ananyev
2015-06-03 23:10 ` [dpdk-dev] [PATCH 3/8] ACL: add function to check rte_acl_build() input parameters Konstantin Ananyev
2015-06-03 23:10 ` [dpdk-dev] [PATCH 4/8] ACL: fix rebuilding a trie for subset of rules Konstantin Ananyev
2015-06-03 23:10 ` [dpdk-dev] [PATCH 5/8] ACL: introduce RTE_ACL_MASKLEN_TO_BITMASK macro Konstantin Ananyev
2015-06-03 23:10 ` [dpdk-dev] [PATCH 6/8] ACL: cleanup remove unused code from acl_bld.c Konstantin Ananyev
2015-06-03 23:10 ` [dpdk-dev] [PATCH 7/8] ACL: fix remove ambiguity between rules at UT Konstantin Ananyev
2015-06-03 23:10 ` [dpdk-dev] [PATCH 8/8] ACL: add new test-cases into UT Konstantin Ananyev
2015-06-04 9:27 ` [dpdk-dev] [PATCH 0/8] ACL: various fixes and cleanups Thomas Monjalon
2015-06-04 10:20 ` Ananyev, Konstantin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).