On Thu, May 9, 2024 at 3:36 AM Ales Musil <[email protected]> wrote:
>
> Currently the tunnel_key change for either LS/LR/LSP/LRP wasn't
> consistent. That would lead to a situations when some old would still
> be present, breaking the connection especially for already existing
> FDBs and MAC bindings.
>
> Make sure the FDB entries are up to date by removing them from DB
> when there is a tunnel_key change as those entries have only tunnel_key
> refrences (dp_key, port_key).
>
> MAC bindings have references to the datapath and port name, instead of
> removing those entries do recompute in the controller when we detect
> tunnel_key change. This can be costly at scale, however the tunnel_key
> is not expected to change constantly, in most cases it shouldn't change
> at all.
>
> Fixes: b337750e45be ("northd: Incremental processing of VIF changes in 
> 'northd' node.")
> Fixes: 425f699e2b20 ("controller: fixed potential segfault when changing 
> tunnel_key and deleting ls.")
> Reported-at: https://issues.redhat.com/browse/FDP-393
> Acked-by: Mark Michelson <[email protected]>
> Signed-off-by: Ales Musil <[email protected]>
> Signed-off-by: Numan Siddique <[email protected]>
> (cherry picked from commit ddf051cbc6af24c303bf88970750e5c5fe285400)

Thanks.  Applied both the patches to branch-24.03.

Numan

> ---
>  controller/binding.c        | 13 ++++++++--
>  controller/ovn-controller.c | 27 +++++++------------
>  northd/northd.c             |  7 +++++
>  tests/ovn.at                | 52 +++++++++++++++++++++++++++++++++++++
>  4 files changed, 79 insertions(+), 20 deletions(-)
>
> diff --git a/controller/binding.c b/controller/binding.c
> index 8ac2ce3e2..0712d7030 100644
> --- a/controller/binding.c
> +++ b/controller/binding.c
> @@ -3126,8 +3126,17 @@ delete_done:
>              update_ld_peers(pb, b_ctx_out->local_datapaths);
>          }
>
> -        handled = handle_updated_port(b_ctx_in, b_ctx_out, pb);
> -        if (!handled) {
> +        if (!handle_updated_port(b_ctx_in, b_ctx_out, pb)) {
> +            handled = false;
> +            break;
> +        }
> +
> +        if (!sbrec_port_binding_is_new(pb) &&
> +            sbrec_port_binding_is_updated(pb,
> +                                          SBREC_PORT_BINDING_COL_TUNNEL_KEY) 
> &&
> +            get_local_datapath(b_ctx_out->local_datapaths,
> +                               pb->datapath->tunnel_key)) {
> +            handled = false;
>              break;
>          }
>      }
> diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
> index a40712e53..113d3e05c 100644
> --- a/controller/ovn-controller.c
> +++ b/controller/ovn-controller.c
> @@ -1893,7 +1893,6 @@ runtime_data_sb_datapath_binding_handler(struct 
> engine_node *node OVS_UNUSED,
>              engine_get_input("SB_datapath_binding", node));
>      const struct sbrec_datapath_binding *dp;
>      struct ed_type_runtime_data *rt_data = data;
> -    struct local_datapath *ld;
>
>      SBREC_DATAPATH_BINDING_TABLE_FOR_EACH_TRACKED (dp, dp_table) {
>          if (sbrec_datapath_binding_is_deleted(dp)) {
> @@ -1901,27 +1900,19 @@ runtime_data_sb_datapath_binding_handler(struct 
> engine_node *node OVS_UNUSED,
>                                     dp->tunnel_key)) {
>                  return false;
>              }
> +
> +        }
> +
> +        if (sbrec_datapath_binding_is_updated(
> +                dp, SBREC_DATAPATH_BINDING_COL_TUNNEL_KEY) &&
> +            !sbrec_datapath_binding_is_new(dp)) {
>              /* If the tunnel key got updated, get_local_datapath will not 
> find
>               * the ld. Use get_local_datapath_no_hash which does not
>               * rely on the hash.
>               */
> -            if (sbrec_datapath_binding_is_updated(
> -                    dp, SBREC_DATAPATH_BINDING_COL_TUNNEL_KEY)) {
> -                if (get_local_datapath_no_hash(&rt_data->local_datapaths,
> -                                               dp->tunnel_key)) {
> -                    return false;
> -                }
> -            }
> -        } else if (sbrec_datapath_binding_is_updated(
> -                        dp, SBREC_DATAPATH_BINDING_COL_TUNNEL_KEY)
> -                   && !sbrec_datapath_binding_is_new(dp)) {
> -            /* If the tunnel key is updated, remove the entry (with a wrong
> -             * hash) from the map. It will be (properly) added back later.
> -             */
> -            if ((ld = get_local_datapath_no_hash(&rt_data->local_datapaths,
> -                                                 dp->tunnel_key))) {
> -                hmap_remove(&rt_data->local_datapaths, &ld->hmap_node);
> -                local_datapath_destroy(ld);
> +            if (get_local_datapath_no_hash(&rt_data->local_datapaths,
> +                                           dp->tunnel_key)) {
> +                return false;
>              }
>          }
>      }
> diff --git a/northd/northd.c b/northd/northd.c
> index 8f20c4be3..a4bd3798b 100644
> --- a/northd/northd.c
> +++ b/northd/northd.c
> @@ -4520,6 +4520,8 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn 
> *ovnsb_idl_txn,
>                  op->visited = true;
>                  continue;
>              }
> +
> +            uint32_t old_tunnel_key = op->tunnel_key;
>              if (!ls_port_reinit(op, ovnsb_idl_txn, &nd->ls_ports,
>                                  new_nbsp, NULL,
>                                  od, sb, ni->sbrec_mirror_table,
> @@ -4529,6 +4531,11 @@ ls_handle_lsp_changes(struct ovsdb_idl_txn 
> *ovnsb_idl_txn,
>                  goto fail;
>              }
>              add_op_to_northd_tracked_ports(&trk_lsps->updated, op);
> +
> +            if (old_tunnel_key != op->tunnel_key) {
> +                delete_fdb_entry(ni->sbrec_fdb_by_dp_and_port, 
> od->tunnel_key,
> +                                 old_tunnel_key);
> +            }
>          }
>          op->visited = true;
>      }
> diff --git a/tests/ovn.at b/tests/ovn.at
> index c36fadb90..a64e09bb1 100644
> --- a/tests/ovn.at
> +++ b/tests/ovn.at
> @@ -37383,6 +37383,8 @@ sim_add hv1
>  as hv1
>  check ovs-vsctl add-br br-phys
>  ovn_attach n1 br-phys 192.168.0.11
> +ovs-vsctl -- add-port br-int vif1 -- \
> +    set interface vif1 external-ids:iface-id=lsp1
>
>  check ovn-nbctl --wait=hv ls-add ls \
>            -- lsp-add ls lsp1 \
> @@ -37395,6 +37397,56 @@ check ovn-nbctl --wait=hv ls-add ls \
>                 addresses=router \
>            -- lrp-set-gateway-chassis lr-ls hv1
>
> +dp_uuid=$(fetch_column datapath _uuid external_ids:name=lr)
> +ovn-sbctl create MAC_Binding ip=192.168.1.10 datapath=$dp_uuid 
> logical_port=lr-ls mac='"00:00:00:00:00:01"'
> +
> +OVN_POPULATE_ARP
> +wait_for_ports_up
> +check ovn-nbctl --wait=hv sync
> +
> +create_fdb() {
> +    ls_key=$(fetch_column datapath tunnel_key external_ids:name=ls)
> +    lsp_key=$(fetch_column port_binding tunnel_key logical_port=lsp1)
> +
> +    ovn-sbctl create FDB mac='"00:00:00:00:00:01"' dp_key=$ls_key 
> port_key=$lsp_key
> +}
> +
> +AS_BOX([Logical switch tunnel_key change])
> +create_fdb
> +
> +check ovn-nbctl --wait=hv set Logical_Switch ls 
> other_config:requested-tnl-key=10
> +ovn-sbctl list datapath
> +CHECK_FLOWS_AFTER_RECOMPUTE([hv1], [hv1])
> +
> +check_row_count FDB 0 mac='"00:00:00:00:00:01"'
> +
> +AS_BOX([Logical switch port tunnel_key change])
> +create_fdb
> +
> +check ovn-nbctl --wait=hv set Logical_Switch_Port lsp1 
> options:requested-tnl-key=10
> +CHECK_FLOWS_AFTER_RECOMPUTE([hv1], [hv1])
> +
> +check_row_count FDB 0 mac='"00:00:00:00:00:01"'
> +
> +AS_BOX([Logical router tunnel_key change])
> +check ovn-nbctl --wait=hv set Logical_Router lr options:requested-tnl-key=20
> +CHECK_FLOWS_AFTER_RECOMPUTE([hv1], [hv1])
> +
> +check_row_count Mac_Binding 1 ip=192.168.1.10
> +AT_CHECK([ovs-ofctl dump-flows br-int table=67 | grep -c metadata=0x14], 
> [0], [dnl
> +1
> +])
> +
> +AS_BOX([Logical router port tunnel_key change])
> +check ovn-nbctl --wait=hv set Logical_Router_Port lr-ls 
> options:requested-tnl-key=20
> +CHECK_FLOWS_AFTER_RECOMPUTE([hv1], [hv1])
> +
> +check_row_count Mac_Binding 1 ip=192.168.1.10
> +AT_CHECK([ovs-ofctl dump-flows br-int table=67 | grep -c reg14=0x14], [0], 
> [dnl
> +1
> +])
> +
> +AS_BOX([Logical switch tunnel_key change, potential segfault])
>  sleep_controller hv1
>
>  check ovn-nbctl --wait=sb set Logical_Switch ls 
> other_config:requested-tnl-key=1000
> --
> 2.44.0
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to