On Thu, Oct 15, 2026 at 4:37 PM Jacob Tanenbaum <[email protected]> wrote:
>
>
>
> On Tue, Oct 6, 2026 at 1:51 PM Mark Michelson via dev 
> <[email protected]> wrote:
>>
>> With this change, en-lflow will now incrementally process logical router
>> policy changes.
>>
>> The lflow_ref is scoped to the datapath on which logical router policies
>> are attached. In the case that any logical router policies are added or
>> deleted on an existing logical router all of the policies on that
>> logical router will have their logical flows rebuilt and resynced.
>
>
> router policy processing. The only change that
>   outport_key = out_port->nbrp->name at en-route-policies.c:296) and          
>                            │    actually makes a difference is if the logical 
> router ports change, and
>   a string copy (src_addr, en-route-policies.c:298). They never hold          
>                            │    there are "reroute" policies installed on the 
> log
>
>
>>
>>
>> Signed-off-by: Mark Michelson <[email protected]>
>> ---
>>  northd/en-lflow.c                | 33 ++++++++++++++++++++++++++++++++
>>  northd/en-lflow.h                |  2 ++
>>  northd/inc-proc-northd.c         |  3 ++-
>>  northd/northd.c                  | 30 +++++++++++++++++++++++++++++
>>  northd/northd.h                  |  6 ++++++
>>  tests/ovn-inc-proc-graph-dump.at |  2 +-
>>  tests/ovn-northd.at              | 20 +++++++++++--------
>>  7 files changed, 86 insertions(+), 10 deletions(-)
>>
>> diff --git a/northd/en-lflow.c b/northd/en-lflow.c
>> index b5204a8f2..1bf8da227 100644
>> --- a/northd/en-lflow.c
>> +++ b/northd/en-lflow.c
>> @@ -311,6 +311,39 @@ lflow_ic_learned_svc_mons_handler(struct engine_node 
>> *node,
>>      return EN_HANDLED_UPDATED;
>>  }
>>
>> +enum engine_input_handler_result
>> +lflow_route_policies_handler(struct engine_node *node,
>> +                             void *data)
>> +{
>> +    struct route_policies_data *rp_data =
>> +        engine_get_input_data("route_policies", node);
>> +
>> +    if (!rp_data->trk.has_tracked) {
>> +        return EN_UNHANDLED;
>> +    }
>> +
>> +    if (!rp_data->trk.has_tracked_policies) {
>> +        /* en-route-policies computed incrementally, but there
>> +         * were no changes to any of the policies. Therefore,
>> +         * there is no need for en-lflow to take action.
>> +         */
>> +        return EN_HANDLED_UNCHANGED;
>> +    }
>> +
>> +    struct lflow_data *lflow_data = data;
>> +
>> +    struct lflow_input lflow_input;
>> +    lflow_get_input_data(node, &lflow_input);
>> +
>> +    if (!lflow_handle_route_policies_changes(
>> +            rp_data, &lflow_input, lflow_data->lflow_table,
>> +            &lflow_data->trk_data.dirty_lflow_refs)) {
>> +        return EN_UNHANDLED;
>> +    }
>> +
>> +    return EN_HANDLED_UPDATED;
>> +}
>> +
>>  void *en_lflow_init(struct engine_node *node OVS_UNUSED,
>>                       struct engine_arg *arg OVS_UNUSED)
>>  {
>> diff --git a/northd/en-lflow.h b/northd/en-lflow.h
>> index fd3f2427f..26dd5c9e9 100644
>> --- a/northd/en-lflow.h
>> +++ b/northd/en-lflow.h
>> @@ -38,4 +38,6 @@ enum engine_input_handler_result
>>  lflow_group_ecmp_route_change_handler(struct engine_node *node, void *data);
>>  enum engine_input_handler_result
>>  lflow_ic_learned_svc_mons_handler(struct engine_node *node, void *data);
>> +enum engine_input_handler_result
>> +lflow_route_policies_handler(struct engine_node *node, void *data);
>>  #endif /* EN_LFLOW_H */
>> diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c
>> index 0fde77032..603590697 100644
>> --- a/northd/inc-proc-northd.c
>> +++ b/northd/inc-proc-northd.c
>> @@ -400,7 +400,8 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
>>      engine_add_input(&en_lflow, &en_sync_meters, NULL);
>>      engine_add_input(&en_lflow, &en_sb_multicast_group, NULL);
>>      engine_add_input(&en_lflow, &en_bfd_sync, NULL);
>> -    engine_add_input(&en_lflow, &en_route_policies, NULL);
>> +    engine_add_input(&en_lflow, &en_route_policies,
>> +                     lflow_route_policies_handler);
>>      /* Route changes are propagated to en_lflow through the 
>> en_group_ecmp_route
>>       * input.  Any change to en_routes also triggers en_group_ecmp_route 
>> (via
>>       * group_ecmp_route_routes_change_handler), which then triggers 
>> en_lflow.
>> diff --git a/northd/northd.c b/northd/northd.c
>> index 3fa84963d..996eb2747 100644
>> --- a/northd/northd.c
>> +++ b/northd/northd.c
>> @@ -21067,6 +21067,36 @@ lflow_handle_ls_stateful_changes(struct 
>> ls_stateful_tracked_data *trk_data,
>>      }
>>  }
>>
>> +bool
>> +lflow_handle_route_policies_changes(struct route_policies_data *rp_data,
>> +                                    struct lflow_input *lflow_input,
>> +                                    struct lflow_table *lflows,
>> +                                    struct hmapx *dirty_lflow_refs)
>> +{
>> +    struct hmapx_node *hmapx_node;
>> +    struct datapath_route_policies *dp_rp;
>> +    HMAPX_FOR_EACH (hmapx_node, &rp_data->trk.deleted_policies) {
>> +        dp_rp = hmapx_node->data;
>> +        lflow_ref_unlink_lflows(dp_rp->lflow_ref, lflows);
>> +        hmapx_add(dirty_lflow_refs, dp_rp->lflow_ref);
>> +    }
>> +
>> +    HMAPX_FOR_EACH (hmapx_node, &rp_data->trk.new_policies) {
>> +        dp_rp = hmapx_node->data;
>> +        struct ovn_datapath *od =
>> +            sparse_array_get(&lflow_input->lr_datapaths->dps, 
>> dp_rp->dp_index);
>> +        if (!od) {
>> +            return false;
>> +        }
>
>
> Is the "if (!od)" check required? new_policy entries are produced by 
> en_route_policies  from od->sdp->index which is the same index used to put 
> datapaths in lr_datapaths
> and the full-recompute loop does not check for datapath existence.

I think this is just me being overly defensive. I'll switch this to an
ovs_assert() instead.

>
>
>
>
>>
>> +        lflow_ref_unlink_lflows(dp_rp->lflow_ref, lflows);
>> +        build_ingress_policy_flows_for_lrouter(
>> +            od, lflows, &dp_rp->route_policies, dp_rp->lflow_ref);
>> +        hmapx_add(dirty_lflow_refs, dp_rp->lflow_ref);
>> +    }
>> +
>> +    return true;
>> +}
>> +
>>  static bool
>>  mirror_needs_update(const struct nbrec_mirror *nb_mirror,
>>                      const struct sbrec_mirror *sb_mirror)
>> diff --git a/northd/northd.h b/northd/northd.h
>> index fb7d3e44e..a8985b603 100644
>> --- a/northd/northd.h
>> +++ b/northd/northd.h
>> @@ -1017,6 +1017,12 @@ bool northd_handle_lb_data_changes(struct 
>> tracked_lb_data *,
>>  void bfd_table_sync(struct ovsdb_idl_txn *,
>>                      const struct hmap *, struct hmap *,
>>                      struct sset *);
>> +struct route_policies_data;
>> +bool lflow_handle_route_policies_changes(struct route_policies_data 
>> *rp_data,
>> +                                         struct lflow_input *lflow_input,
>> +                                         struct lflow_table *lflows,
>> +                                         struct hmapx *dirty_lflow_refs);
>> +
>>  void build_bfd_map(const struct nbrec_bfd_table *,
>>                     const struct sbrec_bfd_table *, struct hmap *,
>>                     const struct uuidset *);
>> diff --git a/tests/ovn-inc-proc-graph-dump.at 
>> b/tests/ovn-inc-proc-graph-dump.at
>> index 5686e0208..8cd199b11 100644
>> --- a/tests/ovn-inc-proc-graph-dump.at
>> +++ b/tests/ovn-inc-proc-graph-dump.at
>> @@ -183,7 +183,7 @@ digraph "Incremental-Processing-Engine" {
>>         sync_meters -> lflow [[label=""]];
>>         SB_multicast_group -> lflow [[label=""]];
>>         bfd_sync -> lflow [[label=""]];
>> -       route_policies -> lflow [[label=""]];
>> +       route_policies -> lflow [[label="lflow_route_policies_handler"]];
>>         routes -> lflow [[label="engine_noop_handler"]];
>>         group_ecmp_route -> lflow 
>> [[label="lflow_group_ecmp_route_change_handler"]];
>>         global_config -> lflow [[label="node_global_config_handler"]];
>> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
>> index e11ebc6d5..ffc387aa5 100644
>> --- a/tests/ovn-northd.at
>> +++ b/tests/ovn-northd.at
>> @@ -4690,7 +4690,11 @@ AT_CHECK([ovn-nbctl list logical_router_policy | grep 
>> -q $bfd_route_policy_uuid]
>>
>>  check_engine_stats northd norecompute incremental
>>  check_engine_stats route_policies norecompute compute
>> -check_engine_stats lflow recompute nocompute
>> +# The BFD changes trigger a recompute of en-lflow, since en-routes cannot
>> +# incrementally handle BFD changes. However, en-lflow is able to 
>> incrementally
>> +# handle the added logical router policy. This is why we see both recompute
>> +# and compute true for en-lflow.
>> +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
>> @@ -24656,7 +24660,7 @@ check_engine_stats sync_from_sb norecompute nocompute
>>  check_engine_stats sync_to_sb_lb norecompute compute
>>  check_engine_stats route_policies norecompute compute
>>  check_engine_stats bfd_sync recompute nocompute
>> -check_engine_stats lflow recompute nocompute
>> +check_engine_stats lflow norecompute compute
>>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
>>
>>  # Change router Policy to use explicit output port.
>> @@ -24684,7 +24688,7 @@ check_engine_stats sync_from_sb norecompute nocompute
>>  check_engine_stats sync_to_sb_lb norecompute compute
>>  check_engine_stats route_policies norecompute compute
>>  check_engine_stats bfd_sync recompute nocompute
>> -check_engine_stats lflow recompute nocompute
>> +check_engine_stats lflow norecompute compute
>>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
>>
>>  check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats
>> @@ -24710,7 +24714,7 @@ check_engine_stats sync_from_sb norecompute nocompute
>>  check_engine_stats sync_to_sb_lb norecompute compute
>>  check_engine_stats route_policies norecompute compute
>>  check_engine_stats bfd_sync recompute nocompute
>> -check_engine_stats lflow recompute nocompute
>> +check_engine_stats lflow norecompute compute
>>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
>>
>>  # From this point on, operations we perform may result in
>> @@ -24729,7 +24733,7 @@ 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_engine_stats lflow norecompute compute
>>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
>>
>>  # Invalidate the policy by changing it to a jump policy but not
>> @@ -24741,7 +24745,7 @@ 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_engine_stats lflow norecompute compute
>>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
>>
>>  # Un-invalidate the policy by changing it back to an allow policy.
>> @@ -24751,7 +24755,7 @@ 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_engine_stats lflow norecompute compute
>>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
>>
>>  # Add a new logical router with an invalid policy in the same transaction
>> @@ -24777,7 +24781,7 @@ 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_engine_stats lflow norecompute compute
>>  CHECK_NO_CHANGE_AFTER_RECOMPUTE
>>
>>  OVN_CLEANUP_NORTHD
>> --
>> 2.55.0
>>
>> _______________________________________________
>> dev mailing list
>> [email protected]
>> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>>
>
>
> Thanks,
> Jacob Tanenbaum

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

Reply via email to