On Wed, May 27, 2026 at 11:36 AM Dumitru Ceara via dev <
[email protected]> wrote:

> They always are local.  Otherwise the 'from_evpn_vtep' and
> 'to_evpn_vtep' predicates always evaluate to false.
>
> The commit that introduced these predicates also added a test but that
> test was incomplete, it was only checking traffic in one direction.
> In order to expose the issue it should've sent traffic in both
> directions.  Address that too to make sure we don't regress in the
> future.
>
> Fixes: c420b6fbfdf7 ("northd: Skip conntrack for EVPN remote VTEP
> traffic.")
> Signed-off-by: Dumitru Ceara <[email protected]>
> ---
>  controller/lflow.c | 45 ++++++++++++++++++++++++++++-----------------
>  lib/ovn-util.h     |  1 +
>  tests/multinode.at | 12 +++++++++++-
>  3 files changed, 40 insertions(+), 18 deletions(-)
>
> diff --git a/controller/lflow.c b/controller/lflow.c
> index 35ed6d30b7..e431477c43 100644
> --- a/controller/lflow.c
> +++ b/controller/lflow.c
> @@ -229,6 +229,27 @@ is_chassis_resident_cb(const void *c_aux_, const char
> *port_name)
>      }
>  }
>
> +static bool
> +lport_id_is_local(const struct lflow_ctx_in *l_ctx_in,
> +                  const struct uuid *lflow_uuid,
> +                  int64_t dp_id, int64_t port_id)
> +{
> +    /* To/from EVPN VTEP logical port keys are always local. */
> +    if (OVN_IS_EVPN_KEY(port_id)) {
> +        return true;
> +    }
> +
> +    char buf[16];
> +    get_unique_lport_key(dp_id, port_id, buf, sizeof(buf));
> +
> +    if (!sset_contains(l_ctx_in->related_lport_ids, buf)) {
> +        VLOG_DBG("lflow "UUID_FMT " port %s in match is not local, skip",


nit: Extra space after UUID_FMT.


> +                 UUID_ARGS(lflow_uuid), buf);
> +        return false;
> +    }
> +    return true;
> +}
> +
>  /* Adds the logical flows from the Logical_Flow table to flow tables. */
>  static void
>  add_logical_flows(struct lflow_ctx_in *l_ctx_in,
> @@ -936,22 +957,15 @@ add_matches_to_flow_table(const struct
> sbrec_logical_flow *lflow,
>
>      struct expr_match *m;
>      HMAP_FOR_EACH (m, hmap_node, matches) {
> -        match_set_metadata(&m->match, htonll(ldp->datapath->tunnel_key));
> +        int64_t dp_id = ldp->datapath->tunnel_key;
> +        match_set_metadata(&m->match, htonll(dp_id));
>          if (ldp->is_switch) {
>              unsigned int reg_index
>                  = (ingress ? MFF_LOG_INPORT : MFF_LOG_OUTPORT) - MFF_REG0;
>              int64_t port_id = m->match.flow.regs[reg_index];
> -            if (port_id) {
> -                int64_t dp_id = ldp->datapath->tunnel_key;
> -                char buf[16];
> -                get_unique_lport_key(dp_id, port_id, buf, sizeof(buf));
> -                if (!sset_contains(l_ctx_in->related_lport_ids, buf)) {
> -                    VLOG_DBG("lflow "UUID_FMT
> -                             " port %s in match is not local, skip",
> -                             UUID_ARGS(&lflow->header_.uuid),
> -                             buf);
> -                    continue;
> -                }
> +            if (port_id && !lport_id_is_local(l_ctx_in,
> &lflow->header_.uuid,
> +                                              dp_id, port_id)) {
> +                continue;
>              }
>          }
>
> @@ -1090,11 +1104,8 @@ consider_logical_flow__(const struct
> sbrec_logical_flow *lflow,
>                       "found, skip", UUID_ARGS(&lflow->header_.uuid),
> io_port);
>              return;
>          }
> -        char buf[16];
> -        get_unique_lport_key(dp->tunnel_key, pb->tunnel_key, buf, sizeof
> buf);
> -        if (!sset_contains(l_ctx_in->related_lport_ids, buf)) {
> -            VLOG_DBG("lflow "UUID_FMT" matches inport/outport %s that's
> not "
> -                     "local, skip", UUID_ARGS(&lflow->header_.uuid),
> io_port);
> +        if (!lport_id_is_local(l_ctx_in, &lflow->header_.uuid,
> +                               dp->tunnel_key, pb->tunnel_key)) {
>              return;
>          }
>      }
> diff --git a/lib/ovn-util.h b/lib/ovn-util.h
> index 4e8cf6f521..bfca178e48 100644
> --- a/lib/ovn-util.h
> +++ b/lib/ovn-util.h
> @@ -189,6 +189,7 @@ struct ovsdb_idl_txn *run_idl_loop(struct
> ovsdb_idl_loop *idl_loop,
>  #define OVN_EVPN_KEY_FLAG 31
>  #define OVN_MIN_EVPN_KEY (1u << OVN_EVPN_KEY_FLAG)
>  #define OVN_MAX_EVPN_KEY (OVN_MAX_DP_GLOBAL_NUM | OVN_MIN_EVPN_KEY)
> +#define OVN_IS_EVPN_KEY(key) (((key) & OVN_MIN_EVPN_KEY) ==
> OVN_MIN_EVPN_KEY)
>
>  struct hmap;
>  void ovn_destroy_tnlids(struct hmap *tnlids);
> diff --git a/tests/multinode.at b/tests/multinode.at
> index d07660797c..f3f1483e65 100644
> --- a/tests/multinode.at
> +++ b/tests/multinode.at
> @@ -3837,12 +3837,17 @@ check multinode_nbctl --wait=hv \
>      -- acl-add ls from-lport 100 "ip" allow-related \
>      -- acl-add ls to-lport 100 "ip" allow-related
>
> -dnl Verify fabric-to-workload pings still work with stateful ACL.
> +dnl Verify fabric-to-workload pings still work with stateful ACL (both
> directions).
>  OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec fabric_workload ping    -W 1
> -c 1 10.0.0.11])
>  OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec fabric_workload ping -6 -W 1
> -c 1 10::11])
>  OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec fabric_workload ping    -W 1
> -c 1 10.0.0.12])
>  OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec fabric_workload ping -6 -W 1
> -c 1 10::12])
>
> +OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec w1 ping    -W 1 -c 1
> 10.0.0.41])
> +OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec w1 ping -6 -W 1 -c 1 10::41])
> +OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec w2 ping    -W 1 -c 1
> 10.0.0.42])
> +OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec w2 ping -6 -W 1 -c 1 10::42])
> +
>  dnl Also add a load balancer and verify pings still work.
>  check multinode_nbctl --wait=hv \
>      -- lb-add lb1 10.0.0.100:80 10.0.0.11:80 \
> @@ -3853,6 +3858,11 @@ OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec
> fabric_workload ping -6 -W 1 -c 1 10
>  OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec fabric_workload ping    -W 1
> -c 1 10.0.0.12])
>  OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec fabric_workload ping -6 -W 1
> -c 1 10::12])
>
> +OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec w1 ping    -W 1 -c 1
> 10.0.0.41])
> +OVS_WAIT_UNTIL([m_as ovn-gw-1 ip netns exec w1 ping -6 -W 1 -c 1 10::41])
> +OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec w2 ping    -W 1 -c 1
> 10.0.0.42])
> +OVS_WAIT_UNTIL([m_as ovn-gw-2 ip netns exec w2 ping -6 -W 1 -c 1 10::42])
> +
>  dnl Cleanup ACL and LB.
>  check multinode_nbctl --wait=hv \
>      -- acl-del ls \
> --
> 2.54.0
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
>
Thank you Dumitru,

I fixed the nit and applied this to main and 26.03.

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

Reply via email to