On Thu, Mar 10, 2022 at 2:42 PM <[email protected]> wrote:

> From: Numan Siddique <[email protected]>
>
> Presently, if the inport or outport is a peer port (of router port),
> then we skip sending the packet to conntrack by not setting the
> reg0[0]/reg0[1] bits.  But the packet still goes through the
> stages - ls_in_acl_hint, ls_in_acl and ls_in_stateful in the ingress
> pipeline and similarly ls_out_acl_hint, ls_out_acl and ls_out_stateful
> in the egress pipeline of the logical switch.
>
> In these mentioned stages, the logical flows match on the ct states
> (ct.new, ct.est etc) and this can be problematic if the packet was
> sent to conntrack and committed in the ingress pipeline.  When
> that packet enters the egress pipeline with outport set to the peer
> port,  we skip sending the packet to conntrack (which is expected)
> but ct state values carry over from the ingress state.  If the ct.new
> flag was set in the ingress pipeline, then the below flows are hit and
> the packet gets committed in the conntrack zone of the inport logical port.
>
> table=4 (ls_out_acl         ), priority=1    ,
>          match=(ip && (!ct.est || (ct.est && ct_label.blocked == 1))),
>          action=(reg0[1] = 1; next;)
> table=7 (ls_out_stateful    ), priority=100  ,
>          match=(reg0[1] == 1 && reg0[13] == 0),
>          action=(ct_commit { ct_label.blocked = 0; }; next;)
>
> With this extra commit to the same conntrack zone, sometimes the packet
> gets
> dropped or doesn't reach the destination.  It is not very clear how
> the packet gets misplaced, but avoiding this resolves the issue.
> And OVN ideally should not do this extra commit.
>
> This patch addresses this issue by adding the below logical flow
> both in ls_in_acl and ls_out_acl stage
>
> priority=2    , match=(reg0[0] == 0 && reg0[1] == 0), action=(next;)
>
> Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2060688
> Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=2062431
> Reported-by: Michael Washer <[email protected]>
> Signed-off-by: Numan Siddique <[email protected]>
>

ovn-k8s tests are failing with this patch in the github CI.

So please ignore this patch.  I'll submit v3 addressing the test failures.

Numan


> ---
>
> v1 -> v2
> -------
>   * Changed the approach to solve the issue.
>
>  northd/northd.c         | 17 +++++++++++++++--
>  northd/ovn-northd.8.xml |  6 ++++++
>  tests/ovn-northd.at     |  5 +++++
>  3 files changed, 26 insertions(+), 2 deletions(-)
>
> diff --git a/northd/northd.c b/northd/northd.c
> index b264fb850b..23ab5ac260 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -6529,7 +6529,7 @@ build_acls(struct ovn_datapath *od, struct hmap
> *lflows,
>      ovn_lflow_add(lflows, od, S_SWITCH_IN_ACL_AFTER_LB, 0, "1", "next;");
>
>      if (has_stateful) {
> -        /* Ingress and Egress ACL Table (Priority 1).
> +        /* Ingress and Egress ACL Table (Priority 1 and 2).
>           *
>           * By default, traffic is allowed.  This is partially handled by
>           * the Priority 0 ACL flows added earlier, but we also need to
> @@ -6549,7 +6549,20 @@ build_acls(struct ovn_datapath *od, struct hmap
> *lflows,
>           * We need to set ct_label.blocked=0 to let the connection
> continue,
>           * which will be done by ct_commit() in the "stateful" stage.
>           * Subsequent packets will hit the flow at priority 0 that just
> -         * uses "next;". */
> +         * uses "next;".
> +         *
> +         * However, we don't want to commit if the packet was not sent to
> +         * conntrack in the first place.
> +         * Eg. if inport or outport is a router peer port. */
> +        ovn_lflow_add(lflows, od, S_SWITCH_IN_ACL, 2,
> +                      REGBIT_CONNTRACK_DEFRAG" == 0 && "
> +                      REGBIT_CONNTRACK_NAT" == 0",
> +                      "next;");
> +        ovn_lflow_add(lflows, od, S_SWITCH_OUT_ACL, 2,
> +                      REGBIT_CONNTRACK_DEFRAG" == 0 && "
> +                      REGBIT_CONNTRACK_NAT" == 0",
> +                      "next;");
> +
>          ovn_lflow_add(lflows, od, S_SWITCH_IN_ACL, 1,
>                        "ip && (!ct.est || (ct.est && ct_label.blocked ==
> 1))",
>                         REGBIT_CONNTRACK_COMMIT" = 1; next;");
> diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml
> index 4784bff041..d788efe70b 100644
> --- a/northd/ovn-northd.8.xml
> +++ b/northd/ovn-northd.8.xml
> @@ -784,6 +784,12 @@
>      </p>
>
>      <ul>
> +      <li>
> +        A priority-2 flow that advances the packet to the next stage if
> the
> +        packet was not sent to conntrack earlier, by matching on
> +        <code>reg0[0] == 0 &amp;&amp; reg0[1] == 1</code>.
> +      </li>
> +
>        <li>
>          A priority-1 flow that sets the hint to commit IP traffic to the
>          connection tracker (with action <code>reg0[1] = 1;
> next;</code>).  This
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index 60d91a7717..bfd0f2382b 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -2265,6 +2265,7 @@ AT_CHECK([ovn-sbctl lflow-list ls | grep -e
> ls_in_acl_hint -e ls_out_acl_hint -e
>    table=4 (ls_out_acl         ), priority=1    , match=(ip && (!ct.est ||
> (ct.est && ct_label.blocked == 1))), action=(reg0[[1]] = 1; next;)
>    table=4 (ls_out_acl         ), priority=1001 , match=(reg0[[7]] == 1 &&
> (ip)), action=(reg0[[1]] = 1; next;)
>    table=4 (ls_out_acl         ), priority=1001 , match=(reg0[[8]] == 1 &&
> (ip)), action=(next;)
> +  table=4 (ls_out_acl         ), priority=2    , match=(reg0[[0]] == 0 &&
> reg0[[2]] == 0), action=(next;)
>    table=4 (ls_out_acl         ), priority=34000, match=(eth.src ==
> $svc_monitor_mac), action=(next;)
>    table=4 (ls_out_acl         ), priority=65532, match=(!ct.est && ct.rel
> && !ct.new && !ct.inv && ct_label.blocked == 0), action=(next;)
>    table=4 (ls_out_acl         ), priority=65532, match=(ct.est && !ct.rel
> && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(next;)
> @@ -2282,6 +2283,7 @@ AT_CHECK([ovn-sbctl lflow-list ls | grep -e
> ls_in_acl_hint -e ls_out_acl_hint -e
>    table=9 (ls_in_acl          ), priority=1    , match=(ip && (!ct.est ||
> (ct.est && ct_label.blocked == 1))), action=(reg0[[1]] = 1; next;)
>    table=9 (ls_in_acl          ), priority=1001 , match=(reg0[[7]] == 1 &&
> (ip)), action=(reg0[[1]] = 1; next;)
>    table=9 (ls_in_acl          ), priority=1001 , match=(reg0[[8]] == 1 &&
> (ip)), action=(next;)
> +  table=9 (ls_in_acl          ), priority=2    , match=(reg0[[0]] == 0 &&
> reg0[[2]] == 0), action=(next;)
>    table=9 (ls_in_acl          ), priority=34000, match=(eth.dst ==
> $svc_monitor_mac), action=(next;)
>    table=9 (ls_in_acl          ), priority=65532, match=(!ct.est && ct.rel
> && !ct.new && !ct.inv && ct_label.blocked == 0), action=(next;)
>    table=9 (ls_in_acl          ), priority=65532, match=(ct.est && !ct.rel
> && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0),
> action=(reg0[[9]] = 0; reg0[[10]] = 0; next;)
> @@ -6328,6 +6330,7 @@ AT_CAPTURE_FILE([lsflows])
>  AT_CHECK([grep -e "ls_in_acl" lsflows | sed 's/table=../table=??/' |
> sort], [0], [dnl
>    table=??(ls_in_acl          ), priority=0    , match=(1), action=(next;)
>    table=??(ls_in_acl          ), priority=1    , match=(ip && (!ct.est ||
> (ct.est && ct_label.blocked == 1))), action=(reg0[[1]] = 1; next;)
> +  table=??(ls_in_acl          ), priority=2    , match=(reg0[[0]] == 0 &&
> reg0[[2]] == 0), action=(next;)
>    table=??(ls_in_acl          ), priority=2001 , match=(reg0[[10]] == 1
> && (ip4)), action=(ct_commit { ct_label.blocked = 1; }; /* drop */)
>    table=??(ls_in_acl          ), priority=2001 , match=(reg0[[9]] == 1 &&
> (ip4)), action=(/* drop */)
>    table=??(ls_in_acl          ), priority=2002 , match=(reg0[[7]] == 1 &&
> (ip4 && tcp)), action=(reg0[[1]] = 1; next;)
> @@ -6380,6 +6383,7 @@ AT_CAPTURE_FILE([lsflows])
>  AT_CHECK([grep -e "ls_in_acl" lsflows | sed 's/table=../table=??/' |
> sort], [0], [dnl
>    table=??(ls_in_acl          ), priority=0    , match=(1), action=(next;)
>    table=??(ls_in_acl          ), priority=1    , match=(ip && (!ct.est ||
> (ct.est && ct_label.blocked == 1))), action=(reg0[[1]] = 1; next;)
> +  table=??(ls_in_acl          ), priority=2    , match=(reg0[[0]] == 0 &&
> reg0[[2]] == 0), action=(next;)
>    table=??(ls_in_acl          ), priority=34000, match=(eth.dst ==
> $svc_monitor_mac), action=(next;)
>    table=??(ls_in_acl          ), priority=65532, match=(!ct.est && ct.rel
> && !ct.new && !ct.inv && ct_label.blocked == 0), action=(next;)
>    table=??(ls_in_acl          ), priority=65532, match=(ct.est && !ct.rel
> && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0),
> action=(reg0[[9]] = 0; reg0[[10]] = 0; next;)
> @@ -6432,6 +6436,7 @@ AT_CAPTURE_FILE([lsflows])
>  AT_CHECK([grep -e "ls_in_acl" lsflows | sed 's/table=../table=??/' |
> sort], [0], [dnl
>    table=??(ls_in_acl          ), priority=0    , match=(1), action=(next;)
>    table=??(ls_in_acl          ), priority=1    , match=(ip && (!ct.est ||
> (ct.est && ct_label.blocked == 1))), action=(reg0[[1]] = 1; next;)
> +  table=??(ls_in_acl          ), priority=2    , match=(reg0[[0]] == 0 &&
> reg0[[2]] == 0), action=(next;)
>    table=??(ls_in_acl          ), priority=2002 , match=(reg0[[7]] == 1 &&
> (ip4 && tcp)), action=(reg0[[1]] = 1; next;)
>    table=??(ls_in_acl          ), priority=2002 , match=(reg0[[8]] == 1 &&
> (ip4 && tcp)), action=(next;)
>    table=??(ls_in_acl          ), priority=2003 , match=(reg0[[7]] == 1 &&
> (ip4 && icmp)), action=(reg0[[1]] = 1; next;)
> --
> 2.34.1
>
>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to