Introduce logical-flows incremental processing support for logical_switch creation/deletion.
Reported-at: https://issues.redhat.com/browse/FDP-759 Signed-off-by: Lorenzo Bianconi <[email protected]> --- northd/en-lflow.c | 13 ++-- northd/en-ls-stateful.c | 6 +- northd/en-multicast.c | 3 +- northd/lflow-mgr.c | 8 ++- northd/northd.c | 131 ++++++++++++++++++++++++++++++++-------- northd/northd.h | 8 ++- tests/ovn-northd.at | 13 +++- 7 files changed, 144 insertions(+), 38 deletions(-) diff --git a/northd/en-lflow.c b/northd/en-lflow.c index 30bf7e35c..14a211bbb 100644 --- a/northd/en-lflow.c +++ b/northd/en-lflow.c @@ -145,10 +145,6 @@ lflow_northd_handler(struct engine_node *node, return EN_UNHANDLED; } - if (northd_has_lswitches_in_tracked_data(&northd_data->trk_data)) { - return EN_UNHANDLED; - } - const struct engine_context *eng_ctx = engine_get_context(); struct lflow_data *lflow_data = data; @@ -162,6 +158,13 @@ lflow_northd_handler(struct engine_node *node, return EN_UNHANDLED; } + if (!lflow_handle_northd_ls_changes(eng_ctx->ovnsb_idl_txn, + &northd_data->trk_data.trk_switches, + &lflow_input, + lflow_data->lflow_table)) { + return EN_UNHANDLED; + } + if (!lflow_handle_northd_port_changes(eng_ctx->ovnsb_idl_txn, &northd_data->trk_data.trk_lsps, &lflow_input, @@ -214,6 +217,7 @@ lflow_ls_stateful_handler(struct engine_node *node, void *data) return EN_UNHANDLED; } + struct northd_data *northd_data = engine_get_input_data("northd", node); const struct engine_context *eng_ctx = engine_get_context(); struct lflow_data *lflow_data = data; struct lflow_input lflow_input; @@ -221,6 +225,7 @@ lflow_ls_stateful_handler(struct engine_node *node, void *data) lflow_get_input_data(node, &lflow_input); if (!lflow_handle_ls_stateful_changes(eng_ctx->ovnsb_idl_txn, &ls_sful_data->trk_data, + &northd_data->trk_data.trk_switches, &lflow_input, lflow_data->lflow_table)) { return EN_UNHANDLED; diff --git a/northd/en-ls-stateful.c b/northd/en-ls-stateful.c index a9a685504..0dea24aee 100644 --- a/northd/en-ls-stateful.c +++ b/northd/en-ls-stateful.c @@ -161,8 +161,10 @@ ls_stateful_northd_handler(struct engine_node *node, void *data_) const struct ovn_datapath *od = hmapx_node->data; if (!ls_stateful_table_find_(&data->table, od->nbs)) { - ls_stateful_record_create(&data->table, od, - input_data.ls_port_groups); + struct ls_stateful_record *ls_stateful_rec = + ls_stateful_record_create(&data->table, od, + input_data.ls_port_groups); + hmapx_add(&data->trk_data.crupdated, ls_stateful_rec); } } diff --git a/northd/en-multicast.c b/northd/en-multicast.c index f63825c8d..73f73db9b 100644 --- a/northd/en-multicast.c +++ b/northd/en-multicast.c @@ -153,7 +153,8 @@ multicast_igmp_northd_handler(struct engine_node *node, void *data OVS_UNUSED) return EN_UNHANDLED; } - if (hmapx_count(&northd_data->trk_data.trk_switches.deleted)) { + if (hmapx_count(&northd_data->trk_data.trk_switches.crupdated) || + hmapx_count(&northd_data->trk_data.trk_switches.deleted)) { return EN_UNHANDLED; } diff --git a/northd/lflow-mgr.c b/northd/lflow-mgr.c index d1fbc2196..f2eb2851c 100644 --- a/northd/lflow-mgr.c +++ b/northd/lflow-mgr.c @@ -745,6 +745,10 @@ lflow_table_add_lflow(struct lflow_table *lflow_table, hmap_insert(&lflow_ref->lflow_ref_nodes, &lrn->ref_node, hash); } + if (lrn->dpgrp_lflow) { + dynamic_bitmap_realloc(&lrn->dpgrp_bitmap, dp_bitmap_len); + } + if (!lrn->linked) { if (lrn->dpgrp_lflow) { ovs_assert(lrn->dpgrp_bitmap.capacity == dp_bitmap_len); @@ -1277,7 +1281,9 @@ ovn_sb_insert_or_update_logical_dp_group( BITMAP_FOR_EACH_1 (index, ods_size(datapaths), dpg_bitmap) { struct ovn_datapath *od = vector_get(&datapaths->dps, index, struct ovn_datapath *); - sb[n++] = od->sdp->sb_dp; + if (od) { + sb[n++] = od->sdp->sb_dp; + } } if (!dp_group) { struct uuid dpg_uuid = uuid_random(); diff --git a/northd/northd.c b/northd/northd.c index e978b66c2..8042298f1 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -5729,10 +5729,13 @@ enum mirror_filter { static void build_mirror_default_lflow(struct ovn_datapath *od, - struct lflow_table *lflows) + struct lflow_table *lflows, + struct lflow_ref *lflow_ref) { - ovn_lflow_add(lflows, od, S_SWITCH_IN_MIRROR, 0, "1", "next;", NULL); - ovn_lflow_add(lflows, od, S_SWITCH_OUT_MIRROR, 0, "1", "next;", NULL); + ovn_lflow_add(lflows, od, S_SWITCH_IN_MIRROR, 0, "1", "next;", + lflow_ref); + ovn_lflow_add(lflows, od, S_SWITCH_OUT_MIRROR, 0, "1", "next;", + lflow_ref); } static void @@ -18582,29 +18585,36 @@ build_lswitch_and_lrouter_iterate_by_ls(struct ovn_datapath *od, struct lswitch_flow_build_info *lsi) { ovs_assert(od->nbs); - build_mirror_default_lflow(od, lsi->lflows); + build_mirror_default_lflow(od, lsi->lflows, od->datapath_lflows); build_lswitch_lflows_pre_acl_and_acl(od, lsi->lflows, - lsi->meter_groups, NULL); - build_network_function(od, lsi->lflows, lsi->ls_port_groups, NULL); - build_fwd_group_lflows(od, lsi->lflows, NULL); - build_lswitch_lflows_admission_control(od, lsi->lflows, NULL); - build_lswitch_learn_fdb_od(od, lsi->lflows, NULL); - build_lswitch_arp_nd_responder_default(od, lsi->lflows, NULL); + lsi->meter_groups, + od->datapath_lflows); + build_network_function(od, lsi->lflows, lsi->ls_port_groups, + od->datapath_lflows); + build_fwd_group_lflows(od, lsi->lflows, od->datapath_lflows); + build_lswitch_lflows_admission_control(od, lsi->lflows, + od->datapath_lflows); + build_lswitch_learn_fdb_od(od, lsi->lflows, od->datapath_lflows); + build_lswitch_arp_nd_responder_default(od, lsi->lflows, + od->datapath_lflows); build_lswitch_dns_lookup_and_response(od, lsi->lflows, lsi->meter_groups, - NULL); - build_lswitch_dhcp_and_dns_defaults(od, lsi->lflows, NULL); + od->datapath_lflows); + build_lswitch_dhcp_and_dns_defaults(od, lsi->lflows, od->datapath_lflows); build_lswitch_destination_lookup_bmcast(od, lsi->lflows, &lsi->actions, - lsi->meter_groups, NULL); - build_lswitch_output_port_sec_od(od, lsi->lflows, NULL); + lsi->meter_groups, + od->datapath_lflows); + build_lswitch_output_port_sec_od(od, lsi->lflows, od->datapath_lflows); /* CT extraction flows are built with stateful flows, but default rule is * always needed */ ovn_lflow_add(lsi->lflows, od, S_SWITCH_IN_CT_EXTRACT, 0, "1", "next;", - NULL); - build_lswitch_lb_affinity_default_flows(od, lsi->lflows, NULL); + od->datapath_lflows); + build_lswitch_lb_affinity_default_flows(od, lsi->lflows, + od->datapath_lflows); if (od->has_evpn_vni) { - build_lswitch_lflows_evpn_l2_unknown(od, lsi->lflows, NULL); + build_lswitch_lflows_evpn_l2_unknown(od, lsi->lflows, + od->datapath_lflows); } else { - build_lswitch_lflows_l2_unknown(od, lsi->lflows, NULL); + build_lswitch_lflows_l2_unknown(od, lsi->lflows, od->datapath_lflows); } build_mcast_flood_lswitch(od, lsi->lflows, &lsi->actions, NULL); } @@ -19341,6 +19351,61 @@ lflow_handle_northd_lr_changes(struct ovsdb_idl_txn *ovnsb_txn, return handled; } +bool +lflow_handle_northd_ls_changes(struct ovsdb_idl_txn *ovnsb_txn, + struct tracked_dps *tracked_ls, + struct lflow_input *lflow_input, + struct lflow_table *lflows) +{ + struct hmapx_node *hmapx_node; + struct ovn_datapath *od; + + HMAPX_FOR_EACH (hmapx_node, &tracked_ls->deleted) { + od = hmapx_node->data; + if (!lflow_ref_resync_flows( + od->datapath_lflows, lflows, ovnsb_txn, + lflow_input->ls_datapaths, + lflow_input->lr_datapaths, + lflow_input->ovn_internal_version_changed, + lflow_input->sbrec_logical_flow_table, + lflow_input->sbrec_logical_dp_group_table)) { + return false; + } + } + + struct lswitch_flow_build_info lsi = { + .meter_groups = lflow_input->meter_groups, + .ls_port_groups = lflow_input->ls_port_groups, + .lflows = lflows, + .match = DS_EMPTY_INITIALIZER, + .actions = DS_EMPTY_INITIALIZER, + }; + + HMAPX_FOR_EACH (hmapx_node, &tracked_ls->crupdated) { + od = hmapx_node->data; + lflow_ref_unlink_lflows(od->datapath_lflows); + build_lswitch_and_lrouter_iterate_by_ls(od, &lsi); + } + + ds_destroy(&lsi.actions); + ds_destroy(&lsi.match); + + HMAPX_FOR_EACH (hmapx_node, &tracked_ls->crupdated) { + od = hmapx_node->data; + if (!lflow_ref_sync_lflows( + od->datapath_lflows, lflows, ovnsb_txn, + lflow_input->ls_datapaths, + lflow_input->lr_datapaths, + lflow_input->ovn_internal_version_changed, + lflow_input->sbrec_logical_flow_table, + lflow_input->sbrec_logical_dp_group_table)) { + return false; + } + } + + return true; +} + bool lflow_handle_northd_port_changes(struct ovsdb_idl_txn *ovnsb_txn, struct tracked_ovn_ports *trk_lsps, @@ -19658,6 +19723,7 @@ exit: bool lflow_handle_ls_stateful_changes(struct ovsdb_idl_txn *ovnsb_txn, struct ls_stateful_tracked_data *trk_data, + struct tracked_dps *tracked_ls, struct lflow_input *lflow_input, struct lflow_table *lflows) { @@ -19700,13 +19766,28 @@ lflow_handle_ls_stateful_changes(struct ovsdb_idl_txn *ovnsb_txn, HMAPX_FOR_EACH (hmapx_node, &trk_data->deleted) { struct ls_stateful_record *ls_stateful_rec = hmapx_node->data; - const struct ovn_datapath *od = - ovn_datapaths_find_by_index(lflow_input->ls_datapaths, - ls_stateful_rec->ls_index); - ovs_assert(od->nbs && uuid_equals(&od->nbs->header_.uuid, - &ls_stateful_rec->nbs_uuid)); - - lflow_ref_unlink_lflows(ls_stateful_rec->lflow_ref); + const struct ovn_datapath *od = NULL; + struct hmapx_node *n; + HMAPX_FOR_EACH (n, &tracked_ls->deleted) { + const struct ovn_datapath *iter = n->data; + if (iter->index == ls_stateful_rec->ls_index) { + od = iter; + break; + } + } + if (od) { + ovs_assert(od->nbs && uuid_equals(&od->nbs->header_.uuid, + &ls_stateful_rec->nbs_uuid)); + if (!lflow_ref_resync_flows( + ls_stateful_rec->lflow_ref, lflows, ovnsb_txn, + lflow_input->ls_datapaths, + lflow_input->lr_datapaths, + lflow_input->ovn_internal_version_changed, + lflow_input->sbrec_logical_flow_table, + lflow_input->sbrec_logical_dp_group_table)) { + return false; + } + } } return true; diff --git a/northd/northd.h b/northd/northd.h index 32134d36e..2af238eea 100644 --- a/northd/northd.h +++ b/northd/northd.h @@ -473,8 +473,7 @@ struct ovn_datapath { /* Map of ovn_port objects belonging to this datapath. * This map doesn't include derived ports. */ struct hmap ports; - /* Reference to the lflows belonging to this datapath currently router - * only lflows. */ + /* Reference to the lflows belonging to this datapath. */ struct lflow_ref *datapath_lflows; }; @@ -941,6 +940,10 @@ bool lflow_handle_northd_lr_changes(struct ovsdb_idl_txn *ovnsh_txn, struct tracked_dps *, struct lflow_input *, struct lflow_table *lflows); +bool lflow_handle_northd_ls_changes(struct ovsdb_idl_txn *ovnsb_txn, + struct tracked_dps *, + struct lflow_input *, + struct lflow_table *lflows); bool lflow_handle_northd_port_changes(struct ovsdb_idl_txn *ovnsb_txn, struct tracked_ovn_ports *, struct lflow_input *, @@ -955,6 +958,7 @@ bool lflow_handle_lr_stateful_changes(struct ovsdb_idl_txn *, struct lflow_table *lflows); bool lflow_handle_ls_stateful_changes(struct ovsdb_idl_txn *, struct ls_stateful_tracked_data *, + struct tracked_dps *, struct lflow_input *, struct lflow_table *lflows); bool northd_handle_sb_port_binding_changes( diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index f7ec6a33a..7f97e02f1 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -2959,6 +2959,8 @@ OVN_FOR_EACH_NORTHD_NO_HV([ AT_SETUP([check VXLAN mode disabling]) ovn_start +OVS_CTL_TIMEOUT=120 + # Create a fake chassis with vxlan encap to implicitly enable VXLAN mode. check_uuid ovn-sbctl \ --id=@e create encap chassis_name=hv1 ip="192.168.0.1" type="vxlan" \ @@ -2994,6 +2996,8 @@ OVN_FOR_EACH_NORTHD_NO_HV([ AT_SETUP([check datapath tunnel ids exhaustion]) ovn_start +OVS_CTL_TIMEOUT=120 + # Create a fake chassis with vxlan encap to lower MAX DP tunnel key to 2^12 check_uuid ovn-sbctl \ --id=@e create encap chassis_name=hv1 ip="192.168.0.1" type="vxlan" \ @@ -3057,6 +3061,8 @@ OVN_FOR_EACH_NORTHD_NO_HV([ AT_SETUP([check LS/LR single line configuration]) ovn_start +OVS_CTL_TIMEOUT=120 + cmd="" for i in {1..2048..1}; do cmd="${cmd} -- ls-add lsw-${i}" @@ -3147,11 +3153,12 @@ check_row_count sb:logical_dp_group 1 echo "$sw2_sb_uuid" >> sw_sb_uuids AT_CHECK_UNQUOTED([ovn-sbctl --bare --columns _uuid,datapaths find Logical_DP_Group dnl - | grep -A1 $ls_dpg_uuid | tail -1 | tr ' ' '\n' | sort], [0], [dnl + | tail -1 | tr ' ' '\n' | sort], [0], [dnl $(cat sw_sb_uuids | sort) ]) dnl Add two routers and check that they are in their new separate group. +ls_dpg_uuid=$(ovn-sbctl --bare --columns _uuid list Logical_DP_Group .) check ovn-nbctl --wait=sb lr-add lr0 -- lr-add lr1 lr0_sb_uuid=$(fetch_column datapath_binding _uuid external_ids:name=lr0) lr1_sb_uuid=$(fetch_column datapath_binding _uuid external_ids:name=lr1) @@ -14685,7 +14692,7 @@ check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats check ovn-nbctl --wait=sb ls-add sw0 check_engine_stats northd norecompute compute check_engine_stats ls_stateful norecompute compute -check_engine_stats lflow recompute nocompute +check_engine_stats lflow norecompute compute # For the below engine nodes, en_northd is input. So check # their engine status. @@ -14723,7 +14730,7 @@ check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats check ovn-nbctl --wait=sb ls-del sw0 check_engine_stats northd norecompute compute check_engine_stats ls_stateful norecompute compute -check_engine_stats lflow recompute nocompute +check_engine_stats lflow norecompute compute # For the below engine nodes, en_northd is input. So check # their engine status. -- 2.52.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
