Re: [ovs-dev] [PATCH v6 1/1] ofproto-dpif-trace: Improve conjunctive match tracing.

2023-11-16 Thread Ilya Maximets
On 11/15/23 10:47, Nobuhiro MIKI wrote:
> A conjunctive flow consists of two or more multiple flows with
> conjunction actions. When input to the ofproto/trace command
> matches a conjunctive flow, it outputs flows of all dimensions.
> 
> Acked-by: Simon Horman 
> Signed-off-by: Nobuhiro MIKI 
> ---
> v6:
> * Support multiple tables with resubmit action
> v5:
> * Support tunnel metadata
> v4:
> * Fix conj_id matching
> * Fix priority matching
> * Add a new test
> v3:
> * Remove struct flow changes.
> * Use struct 'cls_rule' instead of struct 'flow'.
> * Add priority and id conditionals for 'soft' arrays.
> * Use 'minimask' in struct 'cls_rule' as mask.
> * Use hmapx instead of ovs_list to store conj flows.
> * Passe 'conj_flows' as an argument only when tracing.
> v2:
> * Reimplemented v1 with a safer and cleaner approach,
>   since v1 was a messy implementation that rewrote const variables.
> ---
>  lib/classifier.c | 51 ---
>  lib/classifier.h |  4 +-
>  lib/ovs-router.c |  5 +-
>  lib/tnl-ports.c  |  6 +--
>  ofproto/ofproto-dpif-xlate.c | 67 +---
>  ofproto/ofproto-dpif.c   | 25 ++---
>  ofproto/ofproto-dpif.h   |  3 +-
>  tests/classifier.at  | 99 
>  tests/test-classifier.c  |  8 +--
>  9 files changed, 238 insertions(+), 30 deletions(-)

Thanks for the update and the added tests!

This version looks good to me and works fine in all the tested cases.
Applied.

Best regards, Ilya Maximets.
___
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev


[ovs-dev] [PATCH v6 1/1] ofproto-dpif-trace: Improve conjunctive match tracing.

2023-11-15 Thread Nobuhiro MIKI
A conjunctive flow consists of two or more multiple flows with
conjunction actions. When input to the ofproto/trace command
matches a conjunctive flow, it outputs flows of all dimensions.

Acked-by: Simon Horman 
Signed-off-by: Nobuhiro MIKI 
---
v6:
* Support multiple tables with resubmit action
v5:
* Support tunnel metadata
v4:
* Fix conj_id matching
* Fix priority matching
* Add a new test
v3:
* Remove struct flow changes.
* Use struct 'cls_rule' instead of struct 'flow'.
* Add priority and id conditionals for 'soft' arrays.
* Use 'minimask' in struct 'cls_rule' as mask.
* Use hmapx instead of ovs_list to store conj flows.
* Passe 'conj_flows' as an argument only when tracing.
v2:
* Reimplemented v1 with a safer and cleaner approach,
  since v1 was a messy implementation that rewrote const variables.
---
 lib/classifier.c | 51 ---
 lib/classifier.h |  4 +-
 lib/ovs-router.c |  5 +-
 lib/tnl-ports.c  |  6 +--
 ofproto/ofproto-dpif-xlate.c | 67 +---
 ofproto/ofproto-dpif.c   | 25 ++---
 ofproto/ofproto-dpif.h   |  3 +-
 tests/classifier.at  | 99 
 tests/test-classifier.c  |  8 +--
 9 files changed, 238 insertions(+), 30 deletions(-)

diff --git a/lib/classifier.c b/lib/classifier.c
index 18dbfc83ad44..0729bd190243 100644
--- a/lib/classifier.c
+++ b/lib/classifier.c
@@ -853,6 +853,32 @@ trie_ctx_init(struct trie_ctx *ctx, const struct cls_trie 
*trie)
 ctx->lookup_done = false;
 }
 
+static void
+insert_conj_flows(struct hmapx *conj_flows, uint32_t id, int priority,
+  struct cls_conjunction_set **soft, size_t n_soft)
+{
+struct cls_conjunction_set *conj_set;
+
+if (!conj_flows) {
+return;
+}
+
+for (size_t i = 0; i < n_soft; i++) {
+conj_set = soft[i];
+
+if (conj_set->priority != priority) {
+continue;
+}
+
+for (size_t j = 0; j < conj_set->n; j++) {
+if (conj_set->conj[j].id == id) {
+hmapx_add(conj_flows, (void *) (conj_set->match->cls_rule));
+break;
+}
+}
+}
+}
+
 struct conjunctive_match {
 struct hmap_node hmap_node;
 uint32_t id;
@@ -933,11 +959,15 @@ free_conjunctive_matches(struct hmap *matches,
  * recursion within this function itself.
  *
  * 'flow' is non-const to allow for temporary modifications during the lookup.
- * Any changes are restored before returning. */
+ * Any changes are restored before returning.
+ *
+ * 'conj_flows' is an optional parameter.  If it is non-null, the matching
+ * conjunctive flows are inserted. */
 static const struct cls_rule *
 classifier_lookup__(const struct classifier *cls, ovs_version_t version,
 struct flow *flow, struct flow_wildcards *wc,
-bool allow_conjunctive_matches)
+bool allow_conjunctive_matches,
+struct hmapx *conj_flows)
 {
 struct trie_ctx trie_ctx[CLS_MAX_TRIES];
 const struct cls_match *match;
@@ -1097,10 +1127,15 @@ classifier_lookup__(const struct classifier *cls, 
ovs_version_t version,
 const struct cls_rule *rule;
 
 flow->conj_id = id;
-rule = classifier_lookup__(cls, version, flow, wc, false);
+rule = classifier_lookup__(cls, version, flow, wc, false,
+   NULL);
 flow->conj_id = saved_conj_id;
 
 if (rule) {
+if (allow_conjunctive_matches) {
+insert_conj_flows(conj_flows, id, soft_pri, soft,
+  n_soft);
+}
 free_conjunctive_matches(,
  cm_stubs, ARRAY_SIZE(cm_stubs));
 if (soft != soft_stub) {
@@ -1161,12 +1196,16 @@ classifier_lookup__(const struct classifier *cls, 
ovs_version_t version,
  * flow_wildcards_init_catchall()).
  *
  * 'flow' is non-const to allow for temporary modifications during the lookup.
- * Any changes are restored before returning. */
+ * Any changes are restored before returning.
+ *
+ * 'conj_flows' is an optional parameter.  If it is non-null, the matching
+ * conjunctive flows are inserted. */
 const struct cls_rule *
 classifier_lookup(const struct classifier *cls, ovs_version_t version,
-  struct flow *flow, struct flow_wildcards *wc)
+  struct flow *flow, struct flow_wildcards *wc,
+  struct hmapx *conj_flows)
 {
-return classifier_lookup__(cls, version, flow, wc, true);
+return classifier_lookup__(cls, version, flow, wc, true, conj_flows);
 }
 
 /* Finds and returns a rule in 'cls' with exactly the same priority and
diff --git a/lib/classifier.h b/lib/classifier.h
index f646a8f7429b..f55a2cba998e 100644
--- a/lib/classifier.h
+++