On Tue, Oct 6, 2026 at 1:56 PM Mark Michelson via dev <
[email protected]> wrote:

> en-route-policies already had a handler for logical router changes.
> However, the choices were either to a) indicate no change occurred, or
> b) recompute.
>
> With this change, we can now incrementally handle logical router
> policy changes. Adding a new policy, deleting a policy, or updating a
> policy are handled incrementally.
>
> Signed-off-by: Mark Michelson <[email protected]>
> ---
>  northd/en-route-policies.c | 304 ++++++++++++++++++++++++++++++++-----
>  northd/en-route-policies.h |  28 ++++
>  northd/inc-proc-northd.c   |   2 +-
>  tests/ovn-northd.at        |  91 +++++++++--
>  4 files changed, 374 insertions(+), 51 deletions(-)
>
> diff --git a/northd/en-route-policies.c b/northd/en-route-policies.c
> index 69187ca26..4227a78dd 100644
> --- a/northd/en-route-policies.c
> +++ b/northd/en-route-policies.c
> @@ -329,11 +329,66 @@ build_route_policies(struct ovn_datapath *od,
>      }
>  }
>
> +static void
> +route_policies_tracking_data_init(struct route_policies_tracking_data
> *trk)
> +{
> +    *trk = (struct route_policies_tracking_data) {
> +        .has_tracked = false,
> +        .has_tracked_policies = false,
> +        .new_policies = HMAPX_INITIALIZER(&trk->new_policies),
> +        .deleted_policies = HMAPX_INITIALIZER(&trk->deleted_policies),
> +        .has_tracked_bfd = false,
> +        .new_bfd = HMAPX_INITIALIZER(&trk->new_bfd),
> +        .deleted_bfd = HMAPX_INITIALIZER(&trk->deleted_bfd),
> +    };
> +}
> +
> +static void
> +route_policies_tracking_data_add_new_dp_policies(
> +    struct route_policies_tracking_data *trk,
> +    struct datapath_route_policies *dp_rp)
> +{
> +    hmapx_add(&trk->new_policies, dp_rp);
> +    trk->has_tracked_policies = true;
> +    trk->has_tracked = true;
> +}
> +
> +static void
> +route_policies_tracking_data_add_deleted_dp_policies(
> +    struct route_policies_tracking_data *trk,
> +    struct datapath_route_policies *dp_rp)
> +{
> +    hmapx_add(&trk->deleted_policies, dp_rp);
> +    trk->has_tracked_policies = true;
> +    trk->has_tracked = true;
> +}
> +
> +static void
> +route_policies_tracking_data_add_new_bfd(
> +    struct route_policies_tracking_data *trk,
> +    struct datapath_bfd_active_connections *dp_bfd)
> +{
> +    hmapx_add(&trk->new_bfd, dp_bfd);
> +    trk->has_tracked_bfd = true;
> +    trk->has_tracked = true;
> +}
> +
> +static void
> +route_policies_tracking_data_add_deleted_bfd(
> +    struct route_policies_tracking_data *trk,
> +    struct datapath_bfd_active_connections *dp_bfd)
> +{
> +    hmapx_add(&trk->deleted_bfd, dp_bfd);
> +    trk->has_tracked_bfd = true;
> +    trk->has_tracked = true;
> +}
> +
>  static void
>  route_policies_init(struct route_policies_data *data)
>  {
>      sparse_array_init(&data->dp_route_policies, 0);
>      sparse_array_init(&data->dp_bfd_active_connections, 0);
> +    route_policies_tracking_data_init(&data->trk);
>  }
>
>  static struct datapath_route_policies *
> @@ -387,6 +442,26 @@ dp_bfd_active_connections_destroy(
>      free(dp_bfd);
>  }
>
> +static void
> +route_policies_tracking_data_destroy(struct route_policies_tracking_data
> *trk)
> +{
> +    hmapx_destroy(&trk->new_policies);
> +    hmapx_destroy(&trk->new_bfd);
> +
> +    struct hmapx_node *node;
> +    HMAPX_FOR_EACH_SAFE (node, &trk->deleted_policies) {
> +        struct datapath_route_policies *dp_rp = node->data;
> +        datapath_route_policies_destroy(dp_rp);
> +        hmapx_delete(&trk->deleted_policies, node);
> +    }
> +
> +    HMAPX_FOR_EACH_SAFE (node, &trk->deleted_bfd) {
> +        struct datapath_bfd_active_connections *dp_bfd = node->data;
> +        dp_bfd_active_connections_destroy(dp_bfd);
> +        hmapx_delete(&trk->deleted_bfd, node);
> +    }
> +}
> +
>  static void
>  route_policies_destroy(struct route_policies_data *data)
>  {
> @@ -401,6 +476,43 @@ route_policies_destroy(struct route_policies_data
> *data)
>          dp_bfd_active_connections_destroy(dp_bfd);
>      }
>      sparse_array_destroy(&data->dp_bfd_active_connections);
> +
> +    route_policies_tracking_data_destroy(&data->trk);
> +}
> +
> +static void
> +build_datapath_route_policies(
> +    struct ovn_datapath *od,
> +    struct route_policies_data *rp_data,
> +    struct datapath_route_policies **p_dp_rp,
> +    struct datapath_bfd_active_connections **p_dp_bfd)
> +{
> +    *p_dp_rp = NULL;
> +    *p_dp_bfd = NULL;
> +    struct datapath_route_policies *dp_rp =
> datapath_route_policies_alloc(od);
> +    struct datapath_bfd_active_connections *dp_bfd =
> +        dp_bfd_active_connections_alloc();
> +
> +    build_route_policies(od, &dp_rp->route_policies,
> +                         &dp_bfd->active_connections,
> +                         &dp_rp->chain_ids,
> +                         &dp_rp->ecmp_group_ids);
> +
> +    if (hmap_is_empty(&dp_rp->route_policies)) {
> +        datapath_route_policies_destroy(dp_rp);
> +    } else {
> +        sparse_array_add_at(&rp_data->dp_route_policies, dp_rp,
> +                            od->sdp->index);
> +        *p_dp_rp = dp_rp;
> +    }
> +
> +    if (uuidset_is_empty(&dp_bfd->active_connections)) {
> +        dp_bfd_active_connections_destroy(dp_bfd);
> +    } else {
> +        sparse_array_add_at(&rp_data->dp_bfd_active_connections, dp_bfd,
> +                            od->sdp->index);
> +        *p_dp_bfd = dp_bfd;
> +    }
>  }
>
>  enum engine_node_state
> @@ -414,29 +526,10 @@ en_route_policies_run(struct engine_node *node, void
> *data)
>
>      struct ovn_datapath *od;
>      HMAP_FOR_EACH (od, key_node, &northd_data->lr_datapaths.datapaths) {
> -        struct datapath_route_policies *dp_rp =
> -            datapath_route_policies_alloc(od);
> -        struct datapath_bfd_active_connections *dp_bfd =
> -            dp_bfd_active_connections_alloc();
> -        build_route_policies(od, &dp_rp->route_policies,
> -                             &dp_bfd->active_connections,
> -                             &dp_rp->chain_ids,
> -                             &dp_rp->ecmp_group_ids);
> -
> -        if (hmap_is_empty(&dp_rp->route_policies)) {
> -            datapath_route_policies_destroy(dp_rp);
> -        } else {
> -            sparse_array_add_at(&route_policies_data->dp_route_policies,
> dp_rp,
> -                                od->sdp->index);
> -        }
> -
> -        if (uuidset_is_empty(&dp_bfd->active_connections)) {
> -            dp_bfd_active_connections_destroy(dp_bfd);
> -        } else {
> -            sparse_array_add_at(
> -                &route_policies_data->dp_bfd_active_connections, dp_bfd,
> -                od->sdp->index);
> -        }
> +        struct datapath_route_policies *dp_rp;
> +        struct datapath_bfd_active_connections *dp_bfd;
> +        build_datapath_route_policies(od, route_policies_data, &dp_rp,
> +                                      &dp_bfd);
>      }
>
>      return EN_UPDATED;
> @@ -479,12 +572,33 @@ route_policies_northd_change_handler(struct
> engine_node *node,
>      return EN_HANDLED_UNCHANGED;
>  }
>
> +static bool
> +logical_router_policies_updated(const struct nbrec_logical_router *lr)
> +{
> +    if (nbrec_logical_router_is_updated(lr,
> +
> NBREC_LOGICAL_ROUTER_COL_POLICIES)) {
> +        return true;
> +    }
> +    for (size_t i = 0; i < lr->n_policies; i++) {
> +        const struct nbrec_logical_router_policy *rule = lr->policies[i];
> +        if (nbrec_logical_router_policy_row_get_seqno(
> +                rule, OVSDB_IDL_CHANGE_MODIFY) > 0) {
> +            return true;
> +        }
> +    }
> +
> +    return false;
> +}
> +
>  enum engine_input_handler_result
>  route_policies_datapath_synced_logical_router_handler(struct engine_node
> *node,
> -                                                      void *data
> OVS_UNUSED)
> +                                                      void *data)
>  {
>

nit: you did not remove the OVS_UNUSED from the prototype
in northd/en-route-policies.h


>      const struct ovn_synced_logical_router_map *synced_lrs =
>          engine_get_input_data("datapath_synced_logical_router", node);
> +    const struct northd_data *northd_data =
> +        engine_get_input_data("northd", node);
> +    struct route_policies_data *rp_data = data;
>
>      if (hmapx_is_empty(&synced_lrs->new) &&
>          hmapx_is_empty(&synced_lrs->updated) &&
> @@ -492,34 +606,156 @@
> route_policies_datapath_synced_logical_router_handler(struct engine_node
> *node,
>          return EN_UNHANDLED;
>      }
>
> +    enum engine_input_handler_result result = EN_HANDLED_UNCHANGED;
>      struct hmapx_node *lr_node;
>      HMAPX_FOR_EACH (lr_node, &synced_lrs->deleted) {
>          const struct ovn_synced_logical_router *lr = lr_node->data;
> -        if (lr->nb->n_policies > 0) {
> -            return EN_UNHANDLED;
> +        struct datapath_route_policies *dp_rp =
> +            sparse_array_remove(&rp_data->dp_route_policies,
> lr->sdp->index);
> +        if (dp_rp) {
> +
> route_policies_tracking_data_add_deleted_dp_policies(&rp_data->trk,
> +                                                                 dp_rp);
> +            result = EN_HANDLED_UPDATED;
> +        }
> +        struct datapath_bfd_active_connections *dp_bfd =
> +            sparse_array_remove(&rp_data->dp_bfd_active_connections,
> +                                lr->sdp->index);
> +        if (dp_bfd) {
> +            route_policies_tracking_data_add_deleted_bfd(&rp_data->trk,
> +                                                         dp_bfd);
> +            result = EN_HANDLED_UPDATED;
>          }
>      }
>
>      HMAPX_FOR_EACH (lr_node, &synced_lrs->new) {
>          const struct ovn_synced_logical_router *lr = lr_node->data;
> -        if (lr->nb->n_policies > 0) {
> +        if (lr->nb->n_policies == 0) {
> +            continue;
> +        }
> +        struct datapath_route_policies *dp_rp =
> +            sparse_array_get(&rp_data->dp_route_policies, lr->sdp->index);
> +        struct datapath_bfd_active_connections *dp_bfd =
> +            sparse_array_get(&rp_data->dp_bfd_active_connections,
> +                             lr->sdp->index);
> +        if (dp_rp || dp_bfd) {
> +            /* This should never happen since the router is new, but just
> +             * in case, let's fall back to a recompute.
> +             */
>              return EN_UNHANDLED;
>          }
> +        struct ovn_datapath *od =
> +            ovn_datapaths_find_by_index(&northd_data->lr_datapaths,
> +                                        lr->sdp->index);
> +        if (!od) {
> +            return EN_UNHANDLED;
> +        }
> +        struct datapath_route_policies *rebuilt_dp_rp;
> +        struct datapath_bfd_active_connections *rebuilt_dp_bfd;
> +        build_datapath_route_policies(od, rp_data, &rebuilt_dp_rp,
> +                                      &rebuilt_dp_bfd);
> +        if (rebuilt_dp_rp) {
> +
> route_policies_tracking_data_add_new_dp_policies(&rp_data->trk,
> +
>  rebuilt_dp_rp);
> +            result = EN_HANDLED_UPDATED;
> +        }
> +        if (rebuilt_dp_bfd) {
> +            route_policies_tracking_data_add_new_bfd(&rp_data->trk,
> +                                                     rebuilt_dp_bfd);
> +            result = EN_HANDLED_UPDATED;
> +        }
>      }
>
>      HMAPX_FOR_EACH (lr_node, &synced_lrs->updated) {
>          const struct ovn_synced_logical_router *lr = lr_node->data;
> -        if (nbrec_logical_router_is_updated(
> -                lr->nb, NBREC_LOGICAL_ROUTER_COL_POLICIES)) {
> +
> +        if (!logical_router_policies_updated(lr->nb)) {
> +            continue;
> +        }
> +        struct ovn_datapath *od =
> +            ovn_datapaths_find_by_index(&northd_data->lr_datapaths,
> +                                        lr->sdp->index);
> +        if (!od) {
>              return EN_UNHANDLED;
>          }
> -        for (size_t i = 0; i < lr->nb->n_policies; i++) {
> -            if
> (nbrec_logical_router_policy_row_get_seqno(lr->nb->policies[i],
> -                                    OVSDB_IDL_CHANGE_MODIFY) > 0) {
> -                return EN_UNHANDLED;
> +        struct datapath_route_policies *dp_rp =
> +            sparse_array_remove(&rp_data->dp_route_policies,
> lr->sdp->index);
> +        struct datapath_bfd_active_connections *dp_bfd =
> +            sparse_array_remove(&rp_data->dp_bfd_active_connections,
> +                                lr->sdp->index);
> +        if (dp_bfd) {
> +            /* Mark the old BFD active connections as deleted. We're going
> +             * to build new ones later.
> +             */
> +            route_policies_tracking_data_add_deleted_bfd(&rp_data->trk,
> +                                                         dp_bfd);
> +            result = EN_HANDLED_UPDATED;
> +        }
> +        if (!dp_rp) {
> +            /* This updated router had no policies, but now does.
> Therefore
> +             * the policies should be treated as new.
> +             */
> +            struct datapath_route_policies *rebuilt_dp_rp;
> +            struct datapath_bfd_active_connections *rebuilt_dp_bfd;
> +            build_datapath_route_policies(od, rp_data, &rebuilt_dp_rp,
> +                                          &rebuilt_dp_bfd);
> +            if (rebuilt_dp_rp) {
> +                route_policies_tracking_data_add_new_dp_policies(
> +                    &rp_data->trk, rebuilt_dp_rp);
> +                result = EN_HANDLED_UPDATED;
> +            }
> +            if (rebuilt_dp_bfd) {
> +                route_policies_tracking_data_add_new_bfd(&rp_data->trk,
> +                                                         rebuilt_dp_bfd);
> +                result = EN_HANDLED_UPDATED;
>              }
> +            continue;
> +        }
> +
> +        /* This updated router had policies and they are updated. We'll
> +         * mark the existing policies as deleted and then rebuild the
> +         * policies for this datapath and mark them as new.
> +         */
> +
> route_policies_tracking_data_add_deleted_dp_policies(&rp_data->trk,
> +                                                             dp_rp);
> +        result = EN_HANDLED_UPDATED;
> +        struct datapath_route_policies *rebuilt_dp_rp;
> +        struct datapath_bfd_active_connections *rebuilt_dp_bfd;
> +        build_datapath_route_policies(od, rp_data, &rebuilt_dp_rp,
> +                                      &rebuilt_dp_bfd);
> +        if (rebuilt_dp_rp) {
> +
> route_policies_tracking_data_add_new_dp_policies(&rp_data->trk,
> +
>  rebuilt_dp_rp);
> +        }
> +        if (rebuilt_dp_bfd) {
> +            route_policies_tracking_data_add_new_bfd(&rp_data->trk,
> +                                                     rebuilt_dp_bfd);
>          }
>      }
>
> -    return EN_HANDLED_UNCHANGED;
> +    return result;
> +}
> +
> +void
> +en_route_policies_clear_tracked_data(void *data)
> +{
> +    struct route_policies_data *rp_data = data;
> +
> +    rp_data->trk.has_tracked = false;
> +    rp_data->trk.has_tracked_bfd = false;
> +    rp_data->trk.has_tracked_policies = false;
> +    hmapx_clear(&rp_data->trk.new_policies);
> +    hmapx_clear(&rp_data->trk.new_bfd);
> +
> +    struct hmapx_node *node;
> +    HMAPX_FOR_EACH_SAFE (node, &rp_data->trk.deleted_policies) {
> +        struct datapath_route_policies *dp_rp = node->data;
> +        datapath_route_policies_destroy(dp_rp);
> +        hmapx_delete(&rp_data->trk.deleted_policies, node);
> +    }
> +
> +    HMAPX_FOR_EACH_SAFE (node, &rp_data->trk.deleted_bfd) {
> +        struct datapath_bfd_active_connections *dp_bfd = node->data;
> +        dp_bfd_active_connections_destroy(dp_bfd);
> +        hmapx_delete(&rp_data->trk.deleted_bfd, node);
> +    }
>  }
> diff --git a/northd/en-route-policies.h b/northd/en-route-policies.h
> index 3dd42c41d..e176cc3a0 100644
> --- a/northd/en-route-policies.h
> +++ b/northd/en-route-policies.h
> @@ -26,6 +26,7 @@
>  #include "uuidset.h"
>  #include "sparse-array.h"
>  #include "simap.h"
> +#include "hmapx.h"
>
>  /* Each instance of this represents a nexthop for a router
>   * policy with "reroute" action. The fields are used for
> @@ -64,11 +65,37 @@ struct datapath_bfd_active_connections {
>      struct uuidset active_connections;
>  };
>
> +struct route_policies_tracking_data {
> +    /* Indicates that some data was incrementally
> +     * processed by the en-route-policies node.
> +     */
> +    bool has_tracked;
> +
> +    /* Indicates that routing policies were incrementally
> +     * processed by the en-route-policies node.
> +     */
> +    bool has_tracked_policies;
> +    /* These contain struct datapath_route_policies. */
> +    struct hmapx new_policies;
> +    struct hmapx deleted_policies;
> +
> +    /* Indicates that BFD connections were incrementally
> +     * processed by the en-route-policies node.
> +     */
> +    bool has_tracked_bfd;
> +    /* These contain struct datapath_bfd_active_connections. */
> +    struct hmapx new_bfd;
> +    struct hmapx deleted_bfd;
> +};
>


Are all these fields necessary? Cheking the rest of the series I don't
think anyone reads new_bfd, deleted_bfd, and has_tracked_bfd.


> +
>  /* Global route policy data exported by en-route-policies. */
>  struct route_policies_data {
>      /* Each entry is a struct datapath_route_policies pointer */
>      struct sparse_array dp_route_policies;
>      struct sparse_array dp_bfd_active_connections;
> +
> +    /* Tracking data. */
> +    struct route_policies_tracking_data trk;
>  };
>
>  void en_route_policies_cleanup(void *data);
> @@ -82,5 +109,6 @@ enum engine_node_state en_route_policies_run(struct
> engine_node *node,
>                                               void *data);
>  void *en_route_policies_init(struct engine_node *node OVS_UNUSED,
>                               struct engine_arg *arg OVS_UNUSED);
> +void en_route_policies_clear_tracked_data(void *data);
>
>  #endif /* EN_ROUTE_POLICIES_H */
> diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c
> index 7e92f7fec..0fde77032 100644
> --- a/northd/inc-proc-northd.c
> +++ b/northd/inc-proc-northd.c
> @@ -180,7 +180,7 @@ static ENGINE_NODE(lb_data, CLEAR_TRACKED_DATA);
>  static ENGINE_NODE(lr_nat, CLEAR_TRACKED_DATA);
>  static ENGINE_NODE(lr_stateful, CLEAR_TRACKED_DATA);
>  static ENGINE_NODE(ls_stateful, CLEAR_TRACKED_DATA);
> -static ENGINE_NODE(route_policies);
> +static ENGINE_NODE(route_policies, CLEAR_TRACKED_DATA);
>  static ENGINE_NODE(routes, CLEAR_TRACKED_DATA);
>  static ENGINE_NODE(bfd_sync, SB_WRITE);
>  static ENGINE_NODE(ecmp_nexthop, SB_WRITE);
> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
> index 81e571d36..e11ebc6d5 100644
> --- a/tests/ovn-northd.at
> +++ b/tests/ovn-northd.at
> @@ -4689,10 +4689,7 @@ bfd_route_policy_uuid=$(fetch_column nb:bfd _uuid
> logical_port=r0-sw8)
>  AT_CHECK([ovn-nbctl list logical_router_policy | grep -q
> $bfd_route_policy_uuid])
>
>  check_engine_stats northd norecompute incremental
> -# route_policies was able to compute when the static route was
> -# added earlier, but has to recompute as a result of the policy
> -# being added.
> -check_engine_stats route_policies recompute compute
> +check_engine_stats route_policies norecompute compute
>  check_engine_stats lflow recompute nocompute
>  check_engine_stats northd_output norecompute compute
>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
> @@ -4706,11 +4703,8 @@ wait_column down bfd status dst_ip=192.168.9.3
>  wait_column down bfd status dst_ip=192.168.9.4
>
>  check_engine_stats northd norecompute compute
> -# In this case, though, the only operation that happened since
> -# clearing incremental stats is that a policy was added. In this
> -# case, route_policies has recomputed but has not computed.
> -check_engine_stats route_policies recompute nocompute
> -check_engine_stats lflow recompute nocompute
> +check_engine_stats route_policies norecompute compute
> +check_engine_stats lflow recompute compute
>  check_engine_stats northd_output norecompute compute
>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
>  check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
> @@ -24633,7 +24627,7 @@ check ovn-nbctl --wait=sb lrp-add lr0 lr0-p1
> 00:00:00:00:ff:01 10.0.0.1/24
>
>  # Create router Policy
>  check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
> -check ovn-nbctl --wait=sb lr-policy-add lr0  10 "ip4.src == 10.0.0.3"
> reroute 172.168.0.101,172.168.0.102
> +check ovn-nbctl --wait=sb lr-policy-add lr0 100 "ip4.src == 100.0.0.0/24"
> reroute 10.0.0.50
>  # northd should be able to handle a policy change without needing to
>  # recompute.
>  check_engine_stats northd norecompute compute
> @@ -24660,9 +24654,7 @@ check_engine_stats sync_from_sb norecompute
> nocompute
>  # compute because it computes on all northbound logical datapath
>  # changes.
>  check_engine_stats sync_to_sb_lb norecompute compute
> -# route_policies recomputes on a logical router policy change, so
> -# its dependent nodes should also recompute.
> -check_engine_stats route_policies recompute nocompute
> +check_engine_stats route_policies norecompute compute
>  check_engine_stats bfd_sync recompute nocompute
>  check_engine_stats lflow recompute nocompute
>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
> @@ -24690,13 +24682,13 @@ check_engine_stats port_group norecompute
> nocompute
>  check_engine_stats sync_to_sb_pb norecompute nocompute
>  check_engine_stats sync_from_sb norecompute nocompute
>  check_engine_stats sync_to_sb_lb norecompute compute
> -check_engine_stats route_policies recompute nocompute
> +check_engine_stats route_policies norecompute compute
>  check_engine_stats bfd_sync recompute nocompute
>  check_engine_stats lflow recompute nocompute
>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
>
>  check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
> -check ovn-nbctl --wait=sb lr-policy-del lr0  10 "ip4.src == 10.0.0.3"
> +check ovn-nbctl --wait=sb lr-policy-del lr0
>
>  # All engine nodes should have the same result as when we added the
>  # policy.
> @@ -24716,7 +24708,74 @@ check_engine_stats port_group norecompute
> nocompute
>  check_engine_stats sync_to_sb_pb norecompute nocompute
>  check_engine_stats sync_from_sb norecompute nocompute
>  check_engine_stats sync_to_sb_lb norecompute compute
> -check_engine_stats route_policies recompute nocompute
> +check_engine_stats route_policies norecompute compute
> +check_engine_stats bfd_sync recompute nocompute
> +check_engine_stats lflow recompute nocompute
> +CHECK_NO_CHANGE_AFTER_RECOMPUTE
> +
> +# From this point on, operations we perform may result in
> +# ovn-northd exporting tracked data, which makes some of its dependent
> +# nodes compute/recompute. Since this test is mainly focused
> +# on en-route-policies, we'll stop checking the giant list of
> +# nodes from this point on.
> +
> +# Add a logical router with a policy on it in the same
> +# transaction.
> +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
> +check ovn-nbctl lr-add lr1 \
> +    -- lr-policy-add lr1 100 "1" allow
> +check ovn-nbctl --wait=sb sync
> +
> +check_engine_stats northd norecompute compute
> +check_engine_stats route_policies norecompute compute
> +check_engine_stats bfd_sync recompute nocompute
> +check_engine_stats lflow recompute nocompute
> +CHECK_NO_CHANGE_AFTER_RECOMPUTE
> +
> +# Invalidate the policy by changing it to a jump policy but not
> +# setting the jump_chain.
> +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
> +policy_uuid=$(fetch_column nb:Logical_Router_Policy _uuid action=allow)
> +check ovn-nbctl set Logical_Router_Policy $policy_uuid action=jump
> +
> +check_engine_stats northd norecompute compute
> +check_engine_stats route_policies norecompute compute
> +check_engine_stats bfd_sync recompute nocompute
> +check_engine_stats lflow recompute nocompute
> +CHECK_NO_CHANGE_AFTER_RECOMPUTE
> +
> +# Un-invalidate the policy by changing it back to an allow policy.
> +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
> +check ovn-nbctl set Logical_Router_Policy $policy_uuid action=allow
> +
> +check_engine_stats northd norecompute compute
> +check_engine_stats route_policies norecompute compute
> +check_engine_stats bfd_sync recompute nocompute
> +check_engine_stats lflow recompute nocompute
> +CHECK_NO_CHANGE_AFTER_RECOMPUTE
> +
> +# Add a new logical router with an invalid policy in the same transaction
> +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
> +check ovn-nbctl lr-add lr2 \
> +    -- lr-policy-add lr2 100 "1" jump fakechain
> +check ovn-nbctl --wait=sb sync
> +
> +check_engine_stats northd norecompute compute
> +check_engine_stats route_policies norecompute compute
> +# Since the added policy was invalid, route_policies will
> +# compute but report no change. bfd_sync and lflow will react to
> +# the northd change and will compute as a result.
> +check_engine_stats bfd_sync norecompute compute
> +check_engine_stats lflow norecompute compute
> +CHECK_NO_CHANGE_AFTER_RECOMPUTE
> +
> +# Delete the logical router that has policies on it.
> +# This should also not require a recompute in route_policies
> +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
> +check ovn-nbctl --wait=sb lr-del lr1
> +
> +check_engine_stats northd norecompute compute
> +check_engine_stats route_policies norecompute compute
>  check_engine_stats bfd_sync recompute nocompute
>  check_engine_stats lflow recompute nocompute
>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
> --
> 2.55.0
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev


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

Reply via email to