On Jul 28, Jacob Tanenbaum via dev wrote:
> Several operations on Port Groups required a full database
> recalculation.
> 
> 1. Creating a new Port Group
> 2. Deleting a Port Group
> 3. adding a port from a switch with no other ports on a port group
> 4. removing a port from a port group that is the last one from a
>    specific switch
> 
> Those four operations required a full database recalculation to ensure
> that that the lflows from the ACLs and the southbound databases were
> correctly populated. Instead reprocess only the relevant switches and
> ACLs to avoid the cost of a full recalculation. This is done by having
> the port_group_handler update the southbound database and pass the names
> of the relevant switches to the ls_stateful_acl node.
> 
> Tested using the ovn sandbox 3000 switches and 15000 ports, Creating a
> port group with one ACL and one port
> Without I-P improvements:
> 
> Time spent on processing nb_cfg 2:
>         ovn-northd delay before processing:     1ms
>         ovn-northd completion:                  132ms
> 
> With I-P improvements:
> 
> Time spent on processing nb_cfg 5:
>         ovn-northd delay before processing:     0ms
>         ovn-northd completion:                  26ms
> 
> Reported-at: https://issues.redhat.com/browse/FDP-758
> Reported-by: Dumitru Ceara <dce...@redhat.com>
> Signed-off-by: Jacob Tanenbaum <jtane...@redhat.com>

Hi Jacob,

Thanks for this patch. I think is fine, just a couple of nits inline. Fixing
them:

Acked-by: Lorenzo Bianconi <lorenzo.bianc...@redhat.com>

Regards,
Lorenzo

> 
[...]
> -/* Process a NB.Port_Group record and stores any updated ls_port_groups
> - * in updated_ls_port_groups.  Returns true if a new ls_port_group had
> - * to be created or destroyed.
> +/* Process a NB.Port_Group record updated the ls_port_group_table and the
> + * port_group_ls_table. Stores a few different updates
> + *  1. Updated ls_port_groups are stored in updated_ls_port_groups so the I-P
> + *     can update the Southbound database
> + *  2. If a port_groups switch set changes the switch is stored in
> + *     ls_port_groups_sets_changed so that later I-P nodes can recalculate
> + *     lflows.
> + *  3. If a port_group has a switch removed from it's switch set it is stored
> + *     in pruned_ls_port_group_recs so that the SB entry can be deleted.
>   */
> -static bool
> +static void
>  ls_port_group_process(struct ls_port_group_table *ls_port_groups,
>                        struct port_group_ls_table *port_group_lses,
> +                      struct hmapx *ls_port_groups_sets_changed,
>                        const struct hmap *ls_ports,
>                        const struct nbrec_port_group *nb_pg,
> -                      struct hmapx *updated_ls_port_groups)
> +                      struct hmapx *updated_ls_port_groups,
> +                      struct sset *pruned_ls_port_group_recs)
>  {
>      struct hmapx cleared_ls_port_groups =
>          HMAPX_INITIALIZER(&cleared_ls_port_groups);
> -    bool ls_pg_rec_created = false;
>  
>      struct port_group_ls_record *pg_ls =
>          port_group_ls_table_find(port_group_lses, nb_pg);
> @@ -233,6 +246,12 @@ ls_port_group_process(struct ls_port_group_table 
> *ls_port_groups,
>      }
>  
>      for (size_t i = 0; i < nb_pg->n_ports; i++) {
> +        if (nbrec_port_group_is_deleted(nb_pg)) {
> +            /* When a port group is deleted we don't need to
> +             * updated the port group as the entry will be pruned
> +             */
> +            break;
> +        }

I guess this can be moved out of the loop since it depends just on nb_pg
pointer.

>          const char *port_name = nb_pg->ports[i]->name;
>          const struct ovn_datapath *od =
>              northd_get_datapath_for_port(ls_ports, port_name);
> @@ -262,7 +281,10 @@ ls_port_group_process(struct ls_port_group_table 
> *ls_port_groups,
>              ls_port_group_record_find(ls_pg, nb_pg);
>          if (!ls_pg_rec) {
>              ls_pg_rec = ls_port_group_record_create(ls_pg, nb_pg);
> -            ls_pg_rec_created = true;
> +            if (ls_port_groups_sets_changed) {
> +                hmapx_add(ls_port_groups_sets_changed,
> +                          CONST_CAST(struct nbrec_logical_switch *, 
> od->nbs));
> +            }
>          }
>          sset_add(&ls_pg_rec->ports, port_name);
>  
> @@ -273,13 +295,18 @@ ls_port_group_process(struct ls_port_group_table 
> *ls_port_groups,
>          }
>      }
>  
> -    bool ls_pg_rec_destroyed = false;
>      struct hmapx_node *node;
>      HMAPX_FOR_EACH (node, &cleared_ls_port_groups) {
>          struct ls_port_group *ls_pg = node->data;
>  
> -        if (ls_port_group_record_prune(ls_pg)) {
> -            ls_pg_rec_destroyed = true;
> +        if (ls_port_group_record_prune(ls_pg,
> +                                       nb_pg,
> +                                       pruned_ls_port_group_recs)) {
> +            if (ls_port_groups_sets_changed) {
> +                hmapx_add(ls_port_groups_sets_changed,
> +                    CONST_CAST(struct nbrec_logical_switch *,ls_pg->nbs));
> +                hmapx_find_and_delete(&pg_ls->switches, ls_pg->nbs);
> +            }
>          }
>  
>          if (hmap_is_empty(&ls_pg->nb_pgs)) {
> @@ -287,8 +314,6 @@ ls_port_group_process(struct ls_port_group_table 
> *ls_port_groups,
>          }
>      }
>      hmapx_destroy(&cleared_ls_port_groups);
> -
> -    return ls_pg_rec_created || ls_pg_rec_destroyed;
>  }
>  
>  /* Destroys all the struct ls_port_group_record that might be associated to
> @@ -320,17 +345,27 @@ ls_port_group_record_clear(struct ls_port_group_table 
> *ls_to_port_groups,
>  }
>  
>  static bool
> -ls_port_group_record_prune(struct ls_port_group *ls_pg)
> +ls_port_group_record_prune(struct ls_port_group *ls_pg,
> +                           const struct nbrec_port_group *nb_pg,
> +                           struct sset *pruned_ls_pg_rec)
>  {
>      struct ls_port_group_record *ls_pg_rec;
>      bool records_pruned = false;
>  
> -    HMAP_FOR_EACH_SAFE (ls_pg_rec, key_node, &ls_pg->nb_pgs) {
> -        if (sset_is_empty(&ls_pg_rec->ports)) {
> -            ls_port_group_record_destroy(ls_pg, ls_pg_rec);
> -            records_pruned = true;
> +    struct ds sb_pg_name = DS_EMPTY_INITIALIZER;
> +    ls_pg_rec = ls_port_group_record_find(ls_pg, nb_pg);
> +    if (sset_is_empty(&ls_pg_rec->ports) ||
> +        nbrec_port_group_is_deleted(ls_pg_rec->nb_pg)) {
> +        if (pruned_ls_pg_rec) {
> +            get_sb_port_group_name(ls_pg_rec->nb_pg->name,
> +                                   ls_pg->sb_datapath_key,
> +                                   &sb_pg_name);
> +            sset_add(pruned_ls_pg_rec, ds_cstr(&sb_pg_name));
>          }
> +        ls_port_group_record_destroy(ls_pg, ls_pg_rec);
> +        records_pruned = true;
>      }
> +    ds_destroy(&sb_pg_name);
>      return records_pruned;
>  }
>  
> @@ -460,6 +495,10 @@ en_port_group_init(struct engine_node *node OVS_UNUSED,
>                     struct engine_arg *arg OVS_UNUSED)
>  {
>      struct port_group_data *pg_data = xmalloc(sizeof *pg_data);
> +    *pg_data = (struct port_group_data) {
> +        .ls_port_groups_sets_changed =
> +            HMAPX_INITIALIZER(&pg_data->ls_port_groups_sets_changed),
> +    };
>  
>      ls_port_group_table_init(&pg_data->ls_port_groups);
>      port_group_ls_table_init(&pg_data->port_groups_lses);
> @@ -473,6 +512,7 @@ en_port_group_cleanup(void *data_)
>  
>      ls_port_group_table_destroy(&data->ls_port_groups);
>      port_group_ls_table_destroy(&data->port_groups_lses);
> +    hmapx_destroy(&data->ls_port_groups_sets_changed);
>  }
>  
>  void
> @@ -480,7 +520,7 @@ en_port_group_clear_tracked_data(void *data_)
>  {
>      struct port_group_data *data = data_;
>  
> -    data->ls_port_groups_sets_changed = true;
> +    hmapx_clear(&data->ls_port_groups_sets_changed);
>  }
>  
>  enum engine_node_state
> @@ -514,73 +554,71 @@ port_group_nb_port_group_handler(struct engine_node 
> *node, void *data_)
>      struct port_group_input input_data = port_group_get_input_data(node);
>      const struct engine_context *eng_ctx = engine_get_context();
>      struct port_group_data *data = data_;
> -    bool success = true;
>  
>      const struct nbrec_port_group_table *nb_pg_table =
>          EN_OVSDB_GET(engine_get_input("NB_port_group", node));
>      const struct nbrec_port_group *nb_pg;
>  
> -    /* Return false if a port group is created or deleted.
> -     * Handle I-P for only updated port groups. */
> -    NBREC_PORT_GROUP_TABLE_FOR_EACH_TRACKED (nb_pg, nb_pg_table) {
> -        if (nbrec_port_group_is_new(nb_pg) ||
> -                nbrec_port_group_is_deleted(nb_pg)) {
> -            return EN_UNHANDLED;
> -        }
> -    }
> -
>      struct hmapx updated_ls_port_groups =
>          HMAPX_INITIALIZER(&updated_ls_port_groups);
>  
> +    struct sset stale_sb_port_groups = 
> SSET_INITIALIZER(&stale_sb_port_groups);
>      NBREC_PORT_GROUP_TABLE_FOR_EACH_TRACKED (nb_pg, nb_pg_table) {
> -        if (ls_port_group_process(&data->ls_port_groups,
> -                                  &data->port_groups_lses,
> -                                  input_data.ls_ports,
> -                                  nb_pg, &updated_ls_port_groups)) {
> -            success = false;
> -            break;
> +        ls_port_group_process(&data->ls_port_groups,
> +                              &data->port_groups_lses,
> +                              &data->ls_port_groups_sets_changed,
> +                              input_data.ls_ports,
> +                              nb_pg, &updated_ls_port_groups,
> +                              &stale_sb_port_groups);
> +
>          }
> -    }
>  
> -    /* If changes have been successfully processed incrementally then update
> +    /* Changes have been successfully processed incrementally now update
>       * the SB too. */
> -    if (success) {
> -        struct ovsdb_idl_index *sbrec_port_group_by_name =
> -            engine_ovsdb_node_get_index(
> -                    engine_get_input("SB_port_group", node),
> -                    "sbrec_port_group_by_name");
> -        struct ds sb_pg_name = DS_EMPTY_INITIALIZER;
> -
> -        struct hmapx_node *updated_node;
> -        HMAPX_FOR_EACH (updated_node, &updated_ls_port_groups) {
> -            const struct ls_port_group *ls_pg = updated_node->data;
> -            struct ls_port_group_record *ls_pg_rec;
> -
> -            HMAP_FOR_EACH (ls_pg_rec, key_node, &ls_pg->nb_pgs) {
> -                get_sb_port_group_name(ls_pg_rec->nb_pg->name,
> -                                        ls_pg->sb_datapath_key,
> -                                        &sb_pg_name);
> -
> -                const char *sb_pg_name_cstr = ds_cstr(&sb_pg_name);
> -                const struct sbrec_port_group *sb_pg =
> -                    sb_port_group_lookup_by_name(sbrec_port_group_by_name,
> -                                                 sb_pg_name_cstr);
> -                if (!sb_pg) {
> -                    sb_pg = create_sb_port_group(eng_ctx->ovnsb_idl_txn,
> -                                                 sb_pg_name_cstr);
> -                }
> -                struct sorted_array nb_ports =
> -                    sorted_array_from_sset(&ls_pg_rec->ports);
> -                update_sb_port_group(&nb_ports, sb_pg);
> -                sorted_array_destroy(&nb_ports);
> +    struct ovsdb_idl_index *sbrec_port_group_by_name =
> +        engine_ovsdb_node_get_index(
> +                engine_get_input("SB_port_group", node),
> +                "sbrec_port_group_by_name");
> +    struct ds sb_pg_name = DS_EMPTY_INITIALIZER;
> +
> +    struct hmapx_node *updated_node;
> +    HMAPX_FOR_EACH (updated_node, &updated_ls_port_groups) {
> +        const struct ls_port_group *ls_pg = updated_node->data;
> +        struct ls_port_group_record *ls_pg_rec;
> +
> +        HMAP_FOR_EACH (ls_pg_rec, key_node, &ls_pg->nb_pgs) {
> +            get_sb_port_group_name(ls_pg_rec->nb_pg->name,
> +                                   ls_pg->sb_datapath_key,
> +                                   &sb_pg_name);
> +
> +            const char *sb_pg_name_cstr = ds_cstr(&sb_pg_name);
> +            const struct sbrec_port_group *sb_pg =
> +                sb_port_group_lookup_by_name(sbrec_port_group_by_name,
> +                                             sb_pg_name_cstr);
> +            if (!sb_pg) {
> +                sb_pg = create_sb_port_group(eng_ctx->ovnsb_idl_txn,
> +                                             sb_pg_name_cstr);
>              }
> +            struct sorted_array nb_ports =
> +                sorted_array_from_sset(&ls_pg_rec->ports);
> +            update_sb_port_group(&nb_ports, sb_pg);
> +            sorted_array_destroy(&nb_ports);
>          }
> -        ds_destroy(&sb_pg_name);
>      }
> +    ds_destroy(&sb_pg_name);
> +
> +    const char *stale_sb_port_group_name;
> +    SSET_FOR_EACH (stale_sb_port_group_name, &stale_sb_port_groups) {
> +        const struct sbrec_port_group *sb_pg =
> +            sb_port_group_lookup_by_name(sbrec_port_group_by_name,
> +                                         stale_sb_port_group_name);
> +            sbrec_port_group_delete(sb_pg);
> +    }
> +    sset_destroy(&stale_sb_port_groups);
> +
>  
> -    data->ls_port_groups_sets_changed = !success;
>      hmapx_destroy(&updated_ls_port_groups);
> -    return success ? EN_HANDLED_UPDATED : EN_UNHANDLED;
> +    return EN_HANDLED_UPDATED;

Why are we always returning EN_HANDLED_UPDATED? I guess we should return
EN_HANDLED_UNCHANGED if no work is done.

>  }
>  
>  static void
> diff --git a/northd/en-port-group.h b/northd/en-port-group.h
> index 8dcc950da..f07f118aa 100644
> --- a/northd/en-port-group.h
> +++ b/northd/en-port-group.h
> @@ -104,7 +104,7 @@ struct port_group_input {
>  struct port_group_data {
>      struct ls_port_group_table ls_port_groups;
>      struct port_group_ls_table port_groups_lses;
> -    bool ls_port_groups_sets_changed;
> +    struct hmapx ls_port_groups_sets_changed;
>  };
>  
>  void *en_port_group_init(struct engine_node *, struct engine_arg *);
> diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c
> index d43bfc16c..fc4ae58f8 100644
> --- a/northd/inc-proc-northd.c
> +++ b/northd/inc-proc-northd.c
> @@ -348,7 +348,7 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
>      engine_add_input(&en_lflow, &en_sampling_app, NULL);
>  
>      engine_add_input(&en_lflow, &en_northd, lflow_northd_handler);
> -    engine_add_input(&en_lflow, &en_port_group, lflow_port_group_handler);
> +    engine_add_input(&en_lflow, &en_port_group, engine_noop_handler);
>      engine_add_input(&en_lflow, &en_lr_stateful, lflow_lr_stateful_handler);
>      engine_add_input(&en_lflow, &en_ls_stateful, lflow_ls_stateful_handler);
>      engine_add_input(&en_lflow, &en_multicast_igmp,
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index 5e0747fcc..61d00e576 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -10100,27 +10100,11 @@ AS_BOX([Create new PG1 and PG2])
>  check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
>  check ovn-nbctl --wait=sb -- pg-add pg1 -- pg-add pg2
>  dnl The northd node should not recompute.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats northd], 
> [0], [dnl
> -Node: northd
> -- recompute:            0
> -- compute:              1
> -- cancel:               0
> -])
> -dnl The port_group node recomputes every time a NB port group is 
> added/deleted.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats 
> port_group], [0], [dnl
> -Node: port_group
> -- recompute:            1
> -- compute:              0
> -- cancel:               0
> -])
> -dnl The port_group node is an input for the lflow node.  Port_group
> -dnl recompute/compute triggers lflow recompute.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats lflow], 
> [0], [dnl
> -Node: lflow
> -- recompute:            1
> -- compute:              0
> -- cancel:               0
> -])
> +check_engine_stats northd norecompute compute
> +dnl The port_group node does not recompute when a NB port group is 
> added/deleted.
> +check_engine_stats port_group norecompute compute
> +dnl The Port group recompute/compute should not trigger an lflow recompute.
> +check_engine_stats lflow norecompute compute
>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
>  
>  AS_BOX([Add ACLs on PG1 and PG2])
> @@ -10137,28 +10121,15 @@ check_column "sw1.1" sb:Port_Group ports 
> name="${sw1_key}_pg1"
>  check_column "sw2.1" sb:Port_Group ports name="${sw2_key}_pg1"
>  
>  dnl The northd node should not recompute.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats northd], 
> [0], [dnl
> -Node: northd
> -- recompute:            0
> -- compute:              1
> -- cancel:               0
> -])
> -dnl The port_group node recomputes also every time a port from a new switch
> -dnl is added to the group.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats 
> port_group], [0], [dnl
> -Node: port_group
> -- recompute:            1
> -- compute:              0
> -- cancel:               0
> -])
> -dnl The port_group node is an input for the lflow node.  Port_group
> -dnl recompute/compute triggers lflow recompute.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats lflow], 
> [0], [dnl
> -Node: lflow
> -- recompute:            1
> -- compute:              0
> -- cancel:               0
> -])
> +check_engine_stats northd norecompute compute
> +dnl The port_group node does not recompute when a new switch is added to the
> +dnl group
> +check_engine_stats port_group norecompute compute
> +dnl The port_group node is an input for the ls_statful node.  Port_group
> +dnl should not trigger a recompute.
> +check_engine_stats ls_stateful norecompute compute
> +dnl Port_Group compute/recompute should not trigger an lflow recompute.
> +check_engine_stats lflow norecompute compute
>  dnl Expect ACL1 on sw1 and sw2
>  check_acl_lflows 1 0 1 0
>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
> @@ -10173,29 +10144,16 @@ check_column "sw1.2" sb:Port_Group ports 
> name="${sw1_key}_pg2"
>  check_column "sw2.2" sb:Port_Group ports name="${sw2_key}_pg2"
>  
>  dnl The northd node should not recompute.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats northd], 
> [0], [dnl
> -Node: northd
> -- recompute:            0
> -- compute:              1
> -- cancel:               0
> -])
> -dnl The port_group node recomputes also every time a port from a new switch
> +check_engine_stats northd norecompute compute
> +dnl The port_group node should not recompute when a  port from a new switch
>  dnl is added to the group.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats 
> port_group], [0], [dnl
> -Node: port_group
> -- recompute:            1
> -- compute:              0
> -- cancel:               0
> -])
> -dnl The port_group node is an input for the lflow node.  Port_group
> -dnl recompute/compute triggers lflow recompute (for ACLs).
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats lflow], 
> [0], [dnl
> -Node: lflow
> -- recompute:            1
> -- compute:              0
> -- cancel:               0
> -])
> -dnl Expect both ACLs on sw1 and sw2
> +check_engine_stats port_group norecompute compute
> +dnl The port_group node is an input for the ls_statful node.  Port_group
> +dnl should not trigger a recompute
> +check_engine_stats ls_stateful norecompute compute
> +dnl Port_Group compute/recompute should not trigger an lflow recompute.
> +check_engine_stats lflow norecompute compute
> +dnl Expect both ACLs on sw1 and sw2.
>  check_acl_lflows 1 1 1 1
>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
>  
> @@ -10210,29 +10168,11 @@ check_column "sw1.2 sw1.3" sb:Port_Group ports 
> name="${sw1_key}_pg2"
>  check_column "sw2.2 sw2.3" sb:Port_Group ports name="${sw2_key}_pg2"
>  
>  dnl The northd node should not recompute.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats northd], 
> [0], [dnl
> -Node: northd
> -- recompute:            0
> -- compute:              1
> -- cancel:               0
> -])
> -dnl We did not change the set of switches a pg is applied to, there should be
> -dnl no recompute.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats 
> port_group], [0], [dnl
> -Node: port_group
> -- recompute:            0
> -- compute:              1
> -- cancel:               0
> -])
> -dnl We did not change the set of switches a pg is applied to, there should be
> -dnl no recompute.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats lflow], 
> [0], [dnl
> -Node: lflow
> -- recompute:            0
> -- compute:              1
> -- cancel:               0
> -])
> -dnl Expect both ACLs on sw1 and sw2
> +check_engine_stats northd norecompute compute
> +check_engine_stats port_group norecompute compute
> +check_engine_stats ls_stateful norecompute compute
> +check_engine_stats lflow norecompute compute
> +dnl Expect both ACLs on sw1 and sw2.
>  check_acl_lflows 1 1 1 1
>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
>  
> @@ -10248,28 +10188,10 @@ check_column "sw2.2" sb:Port_Group ports 
> name="${sw2_key}_pg2"
>  
>  dnl The northd node should not recompute, it should handle nb_global update
>  dnl though, therefore "compute: 1".
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats northd], 
> [0], [dnl
> -Node: northd
> -- recompute:            0
> -- compute:              1
> -- cancel:               0
> -])
> -dnl We did not change the set of switches a pg is applied to, there should be
> -dnl no recompute.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats 
> port_group], [0], [dnl
> -Node: port_group
> -- recompute:            0
> -- compute:              1
> -- cancel:               0
> -])
> -dnl We did not change the set of switches a pg is applied to, there should be
> -dnl no recompute.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats lflow], 
> [0], [dnl
> -Node: lflow
> -- recompute:            0
> -- compute:              1
> -- cancel:               0
> -])
> +check_engine_stats northd norecompute compute
> +check_engine_stats port_group norecompute compute
> +check_engine_stats ls_stateful norecompute compute
> +check_engine_stats lflow norecompute compute
>  dnl Expect both ACLs on sw1 and sw2
>  check_acl_lflows 1 1 1 1
>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
> @@ -10280,32 +10202,19 @@ check ovn-nbctl --wait=sb pg-set-ports pg2 sw1.2
>  check_column "sw1.1" sb:Port_Group ports name="${sw1_key}_pg1"
>  check_column "sw2.1" sb:Port_Group ports name="${sw2_key}_pg1"
>  check_column "sw1.2" sb:Port_Group ports name="${sw1_key}_pg2"
> +
>  AT_CHECK([fetch_column sb:Port_Group ports name="${sw2_key}_pg2"], [0], [
>  ])
>  
>  dnl The northd node should not recompute.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats northd], 
> [0], [dnl
> -Node: northd
> -- recompute:            0
> -- compute:              1
> -- cancel:               0
> -])
> -dnl We changed the set of switches a pg is applied to, there should be
> +check_engine_stats northd norecompute compute
> +dnl We changed the set of switches a pg is applied to, this should no longer 
> require
>  dnl a recompute.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats 
> port_group], [0], [dnl
> -Node: port_group
> -- recompute:            1
> -- compute:              0
> -- cancel:               0
> -])
> -dnl We changed the set of switches a pg is applied to, there should be
> -dnl a recompute (for ACLs).
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats lflow], 
> [0], [dnl
> -Node: lflow
> -- recompute:            1
> -- compute:              0
> -- cancel:               0
> -])
> +check_engine_stats port_group norecompute compute
> +dnl There should be no recompute for ls_stateful
> +check_engine_stats ls_stateful norecompute compute
> +dnl No recompute should occur.
> +check_engine_stats lflow norecompute compute
>  dnl Expect both ACLs on sw1 and only the first one on sw2.
>  check_acl_lflows 1 1 1 0
>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
> @@ -10320,29 +10229,11 @@ check_column "sw1.2" sb:Port_Group ports 
> name="${sw1_key}_pg2"
>  AT_CHECK([fetch_column sb:Port_Group ports name="${sw2_key}_pg2"], [0], [
>  ])
>  
> -dnl The northd node should not recompute.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats northd], 
> [0], [dnl
> -Node: northd
> -- recompute:            0
> -- compute:              1
> -- cancel:               0
> -])
> -dnl We changed the set of switches a pg is applied to, there should be
> -dnl a recompute.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats 
> port_group], [0], [dnl
> -Node: port_group
> -- recompute:            1
> -- compute:              0
> -- cancel:               0
> -])
> -dnl We changed the set of switches a pg is applied to, there should be
> -dnl a recompute (for ACLs).
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats lflow], 
> [0], [dnl
> -Node: lflow
> -- recompute:            1
> -- compute:              0
> -- cancel:               0
> -])
> +check_engine_stats northd norecompute compute
> +check_engine_stats port_group norecompute compute
> +check_engine_stats ls_stateful norecompute compute
> +check_engine_stats lflow norecompute compute
> +
>  dnl Expect both ACLs on sw1 and not on sw2.
>  check_acl_lflows 1 1 0 0
>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
> @@ -10357,36 +10248,18 @@ check_column "sw2.1" sb:Port_Group ports 
> name="${sw2_key}_pg1"
>  check_column "sw1.2" sb:Port_Group ports name="${sw1_key}_pg2"
>  check_column "sw2.2" sb:Port_Group ports name="${sw2_key}_pg2"
>  
> -dnl The northd node should not recompute.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats northd], 
> [0], [dnl
> -Node: northd
> -- recompute:            0
> -- compute:              1
> -- cancel:               0
> -])
> -dnl We changed the set of switches a pg is applied to, there should be a
> -dnl recompute.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats 
> port_group], [0], [dnl
> -Node: port_group
> -- recompute:            1
> -- compute:              0
> -- cancel:               0
> -])
> -dnl We changed the set of switches a pg is applied to, there should be a
> -dnl recompute.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats lflow], 
> [0], [dnl
> -Node: lflow
> -- recompute:            1
> -- compute:              0
> -- cancel:               0
> -])
> +check_engine_stats northd norecompute compute
> +check_engine_stats port_group norecompute compute
> +check_engine_stats ls_stateful norecompute compute
> +check_engine_stats lflow norecompute compute
> +
>  dnl Expect both ACLs on sw1 and sw2
>  check_acl_lflows 1 1 1 1
>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
>  
>  AS_BOX([Remove second port from both PGs])
>  check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
> -check ovn-nbctl --wait=sb         \
> +check ovn-nbctl --wait=sb   \
>    -- pg-set-ports pg1 sw1.1 \
>    -- pg-set-ports pg2 sw1.2
>  check_column "sw1.1" sb:Port_Group ports name="${sw1_key}_pg1"
> @@ -10396,33 +10269,53 @@ check_column "sw1.2" sb:Port_Group ports 
> name="${sw1_key}_pg2"
>  AT_CHECK([fetch_column sb:Port_Group ports name="${sw2_key}_pg2"], [0], [
>  ])
>  
> -dnl The northd node should not recompute,.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats northd], 
> [0], [dnl
> -Node: northd
> -- recompute:            0
> -- compute:              1
> -- cancel:               0
> -])
> -dnl We changed the set of switches a pg is applied to, there should be a
> -dnl recompute.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats 
> port_group], [0], [dnl
> -Node: port_group
> -- recompute:            1
> -- compute:              0
> -- cancel:               0
> -])
> -dnl We changed the set of switches a pg is applied to, there should be a
> -dnl recompute.
> -AT_CHECK([as northd ovn-appctl -t ovn-northd inc-engine/show-stats lflow], 
> [0], [dnl
> -Node: lflow
> -- recompute:            1
> -- compute:              0
> -- cancel:               0
> -])
> -dnl Expect both ACLs on sw1 and no ACLs on sw2
> +check_engine_stats northd norecompute compute
> +check_engine_stats port_group norecompute compute
> +check_engine_stats ls_stateful norecompute compute
> +check_engine_stats lflow norecompute compute
> +
> +dnl Expect both ACLs sw1
>  check_acl_lflows 1 1 0 0
>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
>  
> +AS_BOX([Delete port groups PG1 and PG2])
> +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
> +check ovn-nbctl --wait=sb   \
> +    -- pg-del pg1           \
> +    -- pg-del pg2
> +
> +check_engine_stats northd norecompute compute
> +check_engine_stats port_group norecompute compute
> +check_engine_stats ls_stateful norecompute compute
> +check_engine_stats lflow norecompute compute
> +
> +dnl Expect no ACLs on sw1 and no ACLs on sw2
> +check_acl_lflows 0 0 0 0
> +CHECK_NO_CHANGE_AFTER_RECOMPUTE
> +
> +AS_BOX([Add PG1 and PG2 again setting ports and ACLs in one transaction])
> +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
> +check ovn-nbctl --wait=sb                                        \
> +    -- pg-add pg1                                                \
> +    -- pg-add pg2                                                \
> +    -- acl-add pg1 from-lport 1 eth.src==41:41:41:41:41:41 allow \
> +    -- acl-add pg2 from-lport 1 eth.src==42:42:42:42:42:42 allow \
> +    -- pg-set-ports pg1 sw1.1 sw2.1                              \
> +    -- pg-set-ports pg2 sw1.2 sw2.2
> +check_column "sw1.1" sb:Port_Group ports name="${sw1_key}_pg1"
> +check_column "sw2.1" sb:Port_Group ports name="${sw2_key}_pg1"
> +check_column "sw1.2" sb:Port_Group ports name="${sw1_key}_pg2"
> +check_column "sw2.2" sb:Port_Group ports name="${sw2_key}_pg2"
> +
> +check_engine_stats northd norecompute compute
> +check_engine_stats port_group norecompute compute
> +check_engine_stats ls_stateful norecompute compute
> +check_engine_stats lflow norecompute compute
> +
> +dnl Expect both ACLs on sw1 and sw2
> +check_acl_lflows 1 1 1 1
> +CHECK_NO_CHANGE_AFTER_RECOMPUTE
> +
>  AT_CLEANUP
>  ])
>  
> -- 
> 2.50.1
> 
> _______________________________________________
> dev mailing list
> d...@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
> 
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to