On 1/22/21 9:33 AM, [email protected] wrote:
From: Numan Siddique <[email protected]>

When the below ACL is added -
ovn-nbctl acl-add ls1 to-lport 3
   '(ip4.src==10.0.0.1 || ip4.src==10.0.0.2) &&
    (ip4.dst == 10.0.0.3 || ip4.dst == 10.0.0.4)' allow

ovn-controller installs the below OF flows

table=45, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.4 
actions=conjunction(2,1/2)
table=45, priority=1003,ip,metadata=0x1,nw_dst=10.0.0.3 
actions=conjunction(2,1/2)
table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.2 
actions=conjunction(2,2/2)
table=45, priority=1003,ip,metadata=0x1,nw_src=10.0.0.1 
actions=conjunction(2,2/2)
table=45, priority=1003,conj_id=2,ip,metadata=0x1 actions=resubmit(,46)

When a full recompute is triggered, ovn-controller deletes the last
OF flow with the match conj_id=2 and adds the below OF flow

table=45, priority=1003,conj_id=3,ip,metadata=0x1 actions=resubmit(,46)

For subsequent recomputes, the conj_id keeps increasing by 1.

This disrupts the traffic which matches on conjuction action flows.

This patch fixes this issue.

Fixes: 1213bc8270("ovn-controller: Cache logical flow expr matches.")
Signed-off-by: Numan Siddique <[email protected]>
---

Hi Numan,

Good catch!

  controller/lflow.c |  7 +++++++
  tests/ovn.at       | 28 ++++++++++++++++++++++++++++
  2 files changed, 35 insertions(+)

diff --git a/controller/lflow.c b/controller/lflow.c
index c02585b1e..a9420a7c4 100644
--- a/controller/lflow.c
+++ b/controller/lflow.c
@@ -754,6 +754,13 @@ add_matches_to_flow_table(const struct sbrec_logical_flow 
*lflow,
                                        &m->match, &conj, &lflow->header_.uuid);
              ofpbuf_uninit(&conj);
          }
+
+        if (m->match.wc.masks.conj_id) {
+            /* Reset the conj_id back to relative conj id. If caching is
+             * enabled, then processing of the expr match next time (due to
+             * full recompute) will result in the wrong conj_id match flow. */
+            m->match.flow.conj_id -= conj_id_ofs;
+        }

While this works I'm not sure this is the best way to fix the issue. We're now making the add_matches_to_flow_table() aware of the lflow cache.

In my opinion the problem is that the matches we cache when storing entries of type LCACHE_T_MATCHES are not fully processed.

One option to fix that is to pass the current conj_ids_ofs to expr_to_matches() to make sure the generated match objects always use the "final" conj_id.

This is quite intrusive I guess.

An alternative is to add a new step, something like:

prepare_matches(matches, conj_id_ofs)
{
    for_each m in matches:
        // adjust m conj_id
        if (m->match.wc.masks.conj_id)
            m->match.flow.conj_id += conj_id_ofs;
        for_each conj in m->conjunctions:
            conj->id += conj_id_ofs;
}

We'd also have to remove the parts that update the conj_ids in add_matches_to_flow_table():

https://github.com/ovn-org/ovn/blob/a2d043d2ee473da8e4a835730d86f16a47fb096b/controller/lflow.c#L712

and

https://github.com/ovn-org/ovn/blob/master/controller/lflow.c#L747

Then we could call prepare_matches() before add_matches_to_flow_table() if:
1. flow cache disabled.
2. if flow cache is enabled and we're caching lflow matches.

Later, when cached matches are used (from step 2 above) we don't need to change them in any way and we can just call add_matches_to_flow_table() without having to worry about offsets.

What do you think?

Thanks,
Dumitru

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to