(reposting, sorry, I had dropped ovs-dev from CC by accident) On 6/13/26 5:28 PM, Lucas Vargas Dias wrote: > Hi Dumitru, >
Hi Lucas, > You're right, I'm not using stale directly. > I marked it because It was used in other parts of the code. Maybe it's > useless. I'll test. > OK, we'll definitely need a new version of this patch though. > My problem is the number of openflows operations related to static > routes. So I think for my case, I'll still need the incremental > processing. But I can test with your patch. Hmm, I wonder why openflows would change that wildly when one static route is added. That shouldn't be the case, only the affected route's openflows should be added/updated/deleted. > You can include me in CC. Will do, thanks again! > > Regards, > Lucas > Regards, Dumitru > Em sex., 12 de jun. de 2026, 19:21, Dumitru Ceara <[email protected] > <mailto:[email protected]>> escreveu: > > On 6/11/26 11:06 PM, Lucas Vargas Dias wrote: > > Create a handler for static routes. It handles update, create or > > delete. > > Full recompute is triggered when update bfd column for static route. > > > > Test with 2000 static routes created in the same logical router > > and add a new one: > > Without the incremental processing: > > ovn-nbctl --print-wait-time --wait=sb lr-route-add lr1-2 > 10.0.0.1/32 <http://10.0.0.1/32> 192.168.20.2 > > Time spent on processing nb_cfg 4: > > ovn-northd delay before processing: 4ms > > ovn-northd completion: 62ms > > > > With the incremental processing: > > ovn-nbctl --print-wait-time --wait=sb lr-route-add lr1-2 > 10.0.0.1/32 <http://10.0.0.1/32> 192.168.20.2 > > Time spent on processing nb_cfg 6: > > ovn-northd delay before processing: 4ms > > ovn-northd completion: 21ms > > > > Test with 2000 static routes created in the same logical router > > and delete one: > > Without the incremental processing: > > ovn-nbctl --print-wait-time --wait=sb lr-route-del lr1-2 > 10.0.0.1/32 <http://10.0.0.1/32> 192.168.20.2 > > Time spent on processing nb_cfg 5: > > ovn-northd delay before processing: 3ms > > ovn-northd completion: 62ms > > > > With the incremental processing: > > ovn-nbctl --print-wait-time --wait=sb lr-route-del lr1-2 > 10.0.0.1/32 <http://10.0.0.1/32> 192.168.20.2 > > Time spent on processing nb_cfg 9: > > ovn-northd delay before processing: 2ms > > ovn-northd completion: 32ms > > > > Signed-off-by: Lucas Vargas Dias <[email protected]> > > --- > > Hi Lucas, > > I wanted to mention that I didn't review this new version yet but I did > spot a bunch of bad issues in the way we handle recomputations of > en_route and en_route_policies. I had initially posted: > > https://mail.openvswitch.org/pipermail/ovs-dev/2026-June/433164.html > <https://mail.openvswitch.org/pipermail/ovs-dev/2026-June/433164.html> > > but realized there's even more to gain and I am working on a v2: > https://github.com/dceara/ovn/commits/refs/heads/improve-northd- > route-recompute-v2/ <https://github.com/dceara/ovn/commits/refs/ > heads/improve-northd-route-recompute-v2/> > > In that branch I have reworked the parsed_route_hash() as well but I > think what you have in patch 1/2 might be better. > > However, in my branch, I'm removing the parsed_route "stale" field as > it's not really needed for the recompute case: > > https://github.com/dceara/ovn/commit/edab614 <https://github.com/ > dceara/ovn/commit/edab614> > > And it improves the recompute case significantly, for 1.6K routers with > a total number of 28K routes. > > Before the change: > node: routes, recompute (forced) took 5841ms > After the change: > node: routes, recompute (forced) took 177ms > > Now I'm really confused about how the "stale" field is used in your > patch. It doesn't seem to be checked anywhere. > > I'll probably apply patch 1/2 of your series to main next week and > rebase my series on top of that and post it for review too. I'll CC you > on it so we can sync up about the right way (if we still need one) to do > incremental processing for static routes. > > Regards, > Dumitru > > > northd/en-group-ecmp-route.c | 54 +++++++++++ > > northd/en-group-ecmp-route.h | 4 + > > northd/en-lflow.c | 20 ++++ > > northd/en-lflow.h | 2 + > > northd/en-northd.c | 154 ++++++++++++++++++++++++++ > +++-- > > northd/en-northd.h | 3 + > > northd/inc-proc-northd.c | 13 ++- > > northd/northd.c | 142 +++++++++++++++++++++------- > > northd/northd.h | 41 +++++++- > > tests/ovn-inc-proc-graph-dump.at <http://ovn-inc-proc-graph- > dump.at> | 6 +- > > tests/ovn-northd.at <http://ovn-northd.at> | 128 +++ > +++++++++++++++++++--- > > tests/system-ovn.at <http://system-ovn.at> | 5 +- > > 12 files changed, 514 insertions(+), 58 deletions(-) > > > > diff --git a/northd/en-group-ecmp-route.c b/northd/en-group-ecmp- > route.c > > index c4c93fd84..892ce29b7 100644 > > --- a/northd/en-group-ecmp-route.c > > +++ b/northd/en-group-ecmp-route.c > > @@ -519,3 +519,57 @@ > group_ecmp_route_learned_route_change_handler(struct engine_node > *eng_node, > > } > > return EN_HANDLED_UNCHANGED; > > } > > + > > +enum engine_input_handler_result > > +group_ecmp_static_route_change_handler(struct engine_node *eng_node, > > + void *_data) > > +{ > > + struct routes_data *routes_data > > + = engine_get_input_data("routes", eng_node); > > + struct group_ecmp_route_data *data = _data; > > + if (!routes_data->tracked) { > > + data->tracked = false; > > + return EN_UNHANDLED; > > + } > > + > > + struct parsed_route *pr; > > + struct hmapx updated_routes = HMAPX_INITIALIZER(&updated_routes); > > + > > + const struct hmapx_node *hmapx_node; > > + HMAPX_FOR_EACH (hmapx_node, > > + &routes_data- > >trk_data.trk_deleted_parsed_route) { > > + pr = hmapx_node->data; > > + if (!handle_deleted_route(data, pr, &updated_routes)) { > > + hmapx_destroy(&updated_routes); > > + return EN_UNHANDLED; > > + } > > + > > + parsed_route_free(pr); > > + } > > + > > + HMAPX_FOR_EACH (hmapx_node, > > + &routes_data- > >trk_data.trk_crupdated_parsed_route) { > > + pr = hmapx_node->data; > > + handle_added_route(data, pr, &updated_routes); > > + } > > + > > + HMAPX_FOR_EACH (hmapx_node, &updated_routes) { > > + struct group_ecmp_datapath *node = hmapx_node->data; > > + if (hmap_is_empty(&node->unique_routes) && > > + hmap_is_empty(&node->ecmp_groups)) { > > + hmapx_add(&data->trk_data.deleted_datapath_routes, node); > > + hmap_remove(&data->datapaths, &node->hmap_node); > > + } else { > > + hmapx_add(&data->trk_data.crupdated_datapath_routes, > node); > > + } > > + } > > + > > + hmapx_destroy(&updated_routes); > > + > > + if (!hmapx_is_empty(&data->trk_data.crupdated_datapath_routes) || > > + !hmapx_is_empty(&data->trk_data.deleted_datapath_routes)) { > > + data->tracked = true; > > + return EN_HANDLED_UPDATED; > > + } > > + return EN_HANDLED_UNCHANGED; > > +} > > diff --git a/northd/en-group-ecmp-route.h b/northd/en-group-ecmp- > route.h > > index d4a3248d0..246ca06bf 100644 > > --- a/northd/en-group-ecmp-route.h > > +++ b/northd/en-group-ecmp-route.h > > @@ -98,6 +98,10 @@ enum engine_input_handler_result > > group_ecmp_route_learned_route_change_handler(struct engine_node *, > > void *data); > > > > +enum engine_input_handler_result > > +group_ecmp_static_route_change_handler(struct engine_node *, > > + void *data); > > + > > struct group_ecmp_datapath *group_ecmp_datapath_lookup( > > const struct group_ecmp_route_data *data, > > const struct ovn_datapath *od); > > diff --git a/northd/en-lflow.c b/northd/en-lflow.c > > index 8cb987777..12dd9af6f 100644 > > --- a/northd/en-lflow.c > > +++ b/northd/en-lflow.c > > @@ -268,6 +268,21 @@ lflow_multicast_igmp_handler(struct > engine_node *node, void *data) > > return EN_HANDLED_UPDATED; > > } > > > > +enum engine_input_handler_result > > +lflow_group_route_change_handler(struct engine_node *node, > > + void *data OVS_UNUSED) > > +{ > > + struct routes_data *route_data = > > + engine_get_input_data("routes", node); > > + > > + /* If we do not have tracked data we need to recompute. */ > > + if (!route_data->tracked) { > > + return EN_UNHANDLED; > > + } > > + > > + return EN_HANDLED_UNCHANGED; > > +} > > + > > enum engine_input_handler_result > > lflow_group_ecmp_route_change_handler(struct engine_node *node, > > void *data OVS_UNUSED) > > @@ -317,6 +332,11 @@ lflow_group_ecmp_route_change_handler(struct > engine_node *node, > > route_node->od, lflow_data->lflow_table, > > route_node, lflow_input.bfd_ports); > > > > + build_arp_request_flows_for_lrouter(route_node->od, > > + lflow_data->lflow_table, > > + lflow_input.meter_groups, > > + route_node->lflow_ref); > > + > > bool handled = lflow_ref_sync_lflows( > > route_node->lflow_ref, lflow_data->lflow_table, > > eng_ctx->ovnsb_idl_txn, lflow_input.dps, > > diff --git a/northd/en-lflow.h b/northd/en-lflow.h > > index 99bcfda15..31ccc0925 100644 > > --- a/northd/en-lflow.h > > +++ b/northd/en-lflow.h > > @@ -29,5 +29,7 @@ lflow_multicast_igmp_handler(struct engine_node > *node, void *data); > > enum engine_input_handler_result > > lflow_group_ecmp_route_change_handler(struct engine_node *node, > void *data); > > enum engine_input_handler_result > > +lflow_group_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); > > #endif /* EN_LFLOW_H */ > > diff --git a/northd/en-northd.c b/northd/en-northd.c > > index c34818dba..9d247ffa6 100644 > > --- a/northd/en-northd.c > > +++ b/northd/en-northd.c > > @@ -207,7 +207,8 @@ northd_nb_logical_router_handler(struct > engine_node *node, > > } > > > > if (northd_has_lr_nats_in_tracked_data(&nd->trk_data) || > > - northd_has_lrouters_in_tracked_data(&nd->trk_data)) { > > + northd_has_lrouters_in_tracked_data(&nd->trk_data) || > > + northd_has_lr_route_in_tracked_data(&nd->trk_data)) { > > return EN_HANDLED_UPDATED; > > } > > > > @@ -329,7 +330,7 @@ en_route_policies_run(struct engine_node > *node, void *data) > > > > enum engine_input_handler_result > > routes_northd_change_handler(struct engine_node *node, > > - void *data OVS_UNUSED) > > + void *data OVS_UNUSED) > > { > > struct northd_data *northd_data = > engine_get_input_data("northd", node); > > if (!northd_has_tracked_data(&northd_data->trk_data)) { > > @@ -347,14 +348,148 @@ routes_northd_change_handler(struct > engine_node *node, > > * Note: When we add I-P to the created/deleted logical > routers or > > * logical router ports, we need to revisit this handler. > > * > > - * This node also accesses the static routes of the > logical router. > > - * When these static routes gets updated, en_northd > engine recomputes > > - * and so does this node. > > - * Note: When we add I-P to handle static routes > changes, we need > > - * to revisit this handler. > > */ > > return EN_HANDLED_UNCHANGED; > > } > > +enum engine_input_handler_result > > +routes_static_route_change_handler(struct engine_node *node, > > + void *data) > > +{ > > + struct routes_data *routes_data = data; > > + const struct nbrec_logical_router_static_route_table * > > + nb_lr_static_route_table = > > + > EN_OVSDB_GET(engine_get_input("NB_logical_router_static_route", node)); > > + > > + struct northd_data *northd_data = > engine_get_input_data("northd", node); > > + struct bfd_data *bfd_data = engine_get_input_data("bfd", node); > > + struct parsed_route *pr; > > + const struct nbrec_logical_router_static_route > *changed_static_route; > > + NBREC_LOGICAL_ROUTER_STATIC_ROUTE_TABLE_FOR_EACH_TRACKED ( > > + changed_static_route, > nb_lr_static_route_table) { > > + > > + bool is_deleted = > nbrec_logical_router_static_route_is_deleted( > > + > changed_static_route); > > + bool is_new = nbrec_logical_router_static_route_is_new( > > + > changed_static_route); > > + > > + > > + if (is_new && is_deleted) { > > + continue; > > + } > > + > > + if (is_new) { > > + struct ovn_datapath *od = > ovn_datapath_find_by_static_route( > > + &northd_data- > >trk_data.trk_lrs_routes, > > + &changed_static_route- > >header_.uuid); > > + if (!od) { > > + continue; > > + } > > + pr = parsed_routes_add_static(od, &northd_data->lr_ports, > > + changed_static_route, > > + &bfd_data->bfd_connections, > > + &routes_data->parsed_routes, > > + &routes_data->route_tables, > > + &routes_data- > >bfd_active_connections); > > + if (!pr) { > > + return EN_UNHANDLED; > > + } > > + hmapx_add(&routes_data- > >trk_data.trk_crupdated_parsed_route, > > + pr); > > + } > > + > > + if (is_deleted) { > > + pr = parsed_route_lookup_by_source( > > + ROUTE_SOURCE_STATIC, > > + > &changed_static_route->header_, > > + &routes_data- > >parsed_routes); > > + if (!pr) { > > + pr = > parsed_route_lookup_by_source(ROUTE_SOURCE_IC_DYNAMIC, > > + > &changed_static_route->header_, > > + &routes_data- > >parsed_routes); > > + } > > + if (pr) { > > + pr->stale = true; > > + hmapx_add(&routes_data- > >trk_data.trk_deleted_parsed_route, pr); > > + hmap_remove(&routes_data->parsed_routes, &pr- > >key_node); > > + > > + } > > + continue; > > + } > > + > > + if (!is_new && > > + (nbrec_logical_router_static_route_is_updated( > > + changed_static_route, > > + NBREC_LOGICAL_ROUTER_STATIC_ROUTE_COL_NEXTHOP) > > + || nbrec_logical_router_static_route_is_updated( > > + changed_static_route, > > + NBREC_LOGICAL_ROUTER_STATIC_ROUTE_COL_IP_PREFIX) > > + || nbrec_logical_router_static_route_is_updated( > > + changed_static_route, > > + > NBREC_LOGICAL_ROUTER_STATIC_ROUTE_COL_OUTPUT_PORT) > > + || nbrec_logical_router_static_route_is_updated( > > + changed_static_route, > > + NBREC_LOGICAL_ROUTER_STATIC_ROUTE_COL_POLICY) > > + || nbrec_logical_router_static_route_is_updated( > > + changed_static_route, > > + > NBREC_LOGICAL_ROUTER_STATIC_ROUTE_COL_ROUTE_TABLE) > > + || nbrec_logical_router_static_route_is_updated( > > + changed_static_route, > > + > NBREC_LOGICAL_ROUTER_STATIC_ROUTE_COL_SELECTION_FIELDS) > > + || nbrec_logical_router_static_route_is_updated( > > + changed_static_route, > > + > NBREC_LOGICAL_ROUTER_STATIC_ROUTE_COL_OPTIONS))) { > > + pr = parsed_route_lookup_by_source( > > + ROUTE_SOURCE_STATIC, > > + > &changed_static_route->header_, > > + &routes_data- > >parsed_routes); > > + if (!pr) { > > + pr = parsed_route_lookup_by_source( > > + > ROUTE_SOURCE_IC_DYNAMIC, > > + > &changed_static_route->header_, > > + &routes_data- > >parsed_routes); > > + } > > + > > + if (!pr || !pr->od) { > > + return EN_UNHANDLED; > > + } > > + struct parsed_route *old_pr = pr; > > + struct hmapx_node *route_node = > > + hmapx_add(&routes_data- > >trk_data.trk_deleted_parsed_route, > > + old_pr); > > + hmap_remove(&routes_data->parsed_routes, &old_pr- > >key_node); > > + pr = parsed_routes_add_static(old_pr->od, > &northd_data->lr_ports, > > + changed_static_route, > > + &bfd_data->bfd_connections, > > + &routes_data->parsed_routes, > > + &routes_data->route_tables, > > + &routes_data- > >bfd_active_connections); > > + if (!pr) { > > + hmapx_delete(&routes_data- > >trk_data.trk_deleted_parsed_route, > > + route_node); > > + return EN_UNHANDLED; > > + } > > + old_pr->stale = true; > > + > > + hmapx_add(&routes_data- > >trk_data.trk_crupdated_parsed_route, > > + pr); > > + } > > + > > + if (!is_new && nbrec_logical_router_static_route_is_updated( > > + changed_static_route, > > + NBREC_LOGICAL_ROUTER_STATIC_ROUTE_COL_BFD)) > > + { > > + return EN_UNHANDLED; > > + } > > + } > > + > > + if (!hmapx_is_empty(&routes_data- > >trk_data.trk_crupdated_parsed_route) || > > + !hmapx_is_empty(&routes_data- > >trk_data.trk_deleted_parsed_route)) { > > + routes_data->tracked = true; > > + return EN_HANDLED_UPDATED; > > + } > > + > > + return EN_HANDLED_UNCHANGED; > > +} > > > > enum engine_node_state > > en_routes_run(struct engine_node *node, void *data) > > @@ -590,6 +725,11 @@ en_routes_cleanup(void *data) > > routes_destroy(data); > > } > > > > +void > > +en_routes_clear_tracked_data(void *data) > > +{ > > + routes_clear_tracked(data); > > +} > > void > > en_bfd_cleanup(void *data) > > { > > diff --git a/northd/en-northd.h b/northd/en-northd.h > > index 7794739b9..8da8b7ceb 100644 > > --- a/northd/en-northd.h > > +++ b/northd/en-northd.h > > @@ -39,9 +39,12 @@ 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_routes_clear_tracked_data(void *data); > > void en_routes_cleanup(void *data); > > enum engine_input_handler_result > > routes_northd_change_handler(struct engine_node *node, void *data > OVS_UNUSED); > > +enum engine_input_handler_result > > +routes_static_route_change_handler(struct engine_node *node, void > *data); > > enum engine_node_state en_routes_run(struct engine_node *node, > void *data); > > void *en_bfd_init(struct engine_node *node OVS_UNUSED, > > struct engine_arg *arg OVS_UNUSED); > > diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c > > index a2b464411..1b6bdf322 100644 > > --- a/northd/inc-proc-northd.c > > +++ b/northd/inc-proc-northd.c > > @@ -75,7 +75,9 @@ static unixctl_cb_func chassis_features_list; > > NB_NODE(sampling_app) \ > > NB_NODE(network_function) \ > > NB_NODE(network_function_group) \ > > - NB_NODE(logical_switch_port_health_check) > > + NB_NODE(logical_switch_port_health_check) \ > > + NB_NODE(logical_router_static_route) > > + > > > > enum nb_engine_node { > > #define NB_NODE(NAME) NB_##NAME, > > @@ -177,7 +179,7 @@ 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(routes); > > +static ENGINE_NODE(routes, CLEAR_TRACKED_DATA); > > static ENGINE_NODE(bfd); > > static ENGINE_NODE(bfd_sync, SB_WRITE); > > static ENGINE_NODE(ecmp_nexthop, SB_WRITE); > > @@ -336,6 +338,8 @@ void inc_proc_northd_init(struct > ovsdb_idl_loop *nb, > > engine_add_input(&en_routes, &en_bfd, NULL); > > engine_add_input(&en_routes, &en_northd, > > routes_northd_change_handler); > > + engine_add_input(&en_routes, &en_nb_logical_router_static_route, > > + routes_static_route_change_handler); > > > > engine_add_input(&en_bfd_sync, &en_bfd, NULL); > > engine_add_input(&en_bfd_sync, &en_nb_bfd, NULL); > > @@ -375,7 +379,8 @@ void inc_proc_northd_init(struct > ovsdb_idl_loop *nb, > > engine_add_input(&en_learned_route_sync, &en_northd, > > learned_route_sync_northd_change_handler); > > > > - engine_add_input(&en_group_ecmp_route, &en_routes, NULL); > > + engine_add_input(&en_group_ecmp_route, &en_routes, > > + group_ecmp_static_route_change_handler); > > engine_add_input(&en_group_ecmp_route, &en_learned_route_sync, > > group_ecmp_route_learned_route_change_handler); > > > > @@ -394,7 +399,7 @@ void inc_proc_northd_init(struct > ovsdb_idl_loop *nb, > > engine_add_input(&en_lflow, &en_sb_logical_dp_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_routes, NULL); > > + engine_add_input(&en_lflow, &en_routes, > lflow_group_route_change_handler); > > /* XXX: The incremental processing only supports changes to > learned routes. > > * All other changes trigger a full recompute. */ > > engine_add_input(&en_lflow, &en_group_ecmp_route, > > diff --git a/northd/northd.c b/northd/northd.c > > index 99aaa19df..85312916c 100644 > > --- a/northd/northd.c > > +++ b/northd/northd.c > > @@ -659,6 +659,26 @@ ovn_datapath_find_by_key(struct hmap > *datapaths, uint32_t dp_key) > > return NULL; > > } > > > > +struct ovn_datapath * > > +ovn_datapath_find_by_static_route(struct hmapx *datapaths, > > + const struct uuid *route_uuid) > > +{ > > + > > + struct hmapx_node *hmapx_node; > > + HMAPX_FOR_EACH (hmapx_node, datapaths) { > > + struct ovn_datapath *od = hmapx_node->data; > > + if (od->nbr) { > > + for (int i = 0; i < od->nbr->n_static_routes; i++) { > > + struct nbrec_logical_router_static_route > *static_route = > > + od->nbr->static_routes[i]; > > + if (uuid_equals(route_uuid, &static_route- > >header_.uuid)) { > > + return od; > > + } > > + } > > + } > > + } > > + return NULL; > > +} > > struct ovn_datapath * > > ovn_datapath_from_sbrec_(const struct hmap *datapaths, > > const struct sbrec_datapath_binding *sb) > > @@ -4522,6 +4542,7 @@ destroy_northd_data_tracked_changes(struct > northd_data *nd) > > destroy_tracked_ovn_ports(&trk_changes->trk_lsps); > > destroy_tracked_lbs(&trk_changes->trk_lbs); > > hmapx_clear(&trk_changes->trk_nat_lrs); > > + hmapx_clear(&trk_changes->trk_lrs_routes); > > hmapx_clear(&trk_changes->ls_with_changed_lbs); > > hmapx_clear(&trk_changes->ls_with_changed_acls); > > hmapx_clear(&trk_changes->ls_with_changed_ipam); > > @@ -4545,6 +4566,7 @@ init_northd_tracked_data(struct northd_data *nd) > > hmapx_init(&trk_data->trk_lbs.crupdated); > > hmapx_init(&trk_data->trk_lbs.deleted); > > hmapx_init(&trk_data->trk_nat_lrs); > > + hmapx_init(&trk_data->trk_lrs_routes); > > hmapx_init(&trk_data->ls_with_changed_lbs); > > hmapx_init(&trk_data->ls_with_changed_acls); > > hmapx_init(&trk_data->ls_with_changed_ipam); > > @@ -4563,6 +4585,7 @@ destroy_northd_tracked_data(struct > northd_data *nd) > > hmapx_destroy(&trk_data->trk_lbs.crupdated); > > hmapx_destroy(&trk_data->trk_lbs.deleted); > > hmapx_destroy(&trk_data->trk_nat_lrs); > > + hmapx_destroy(&trk_data->trk_lrs_routes); > > hmapx_destroy(&trk_data->ls_with_changed_lbs); > > hmapx_destroy(&trk_data->ls_with_changed_acls); > > hmapx_destroy(&trk_data->ls_with_changed_ipam); > > @@ -5387,7 +5410,8 @@ lr_changes_can_be_handled(const struct > nbrec_logical_router *lr) > > if (nbrec_logical_router_is_updated(lr, col)) { > > if (col == NBREC_LOGICAL_ROUTER_COL_LOAD_BALANCER > > || col == > NBREC_LOGICAL_ROUTER_COL_LOAD_BALANCER_GROUP > > - || col == NBREC_LOGICAL_ROUTER_COL_NAT) { > > + || col == NBREC_LOGICAL_ROUTER_COL_NAT > > + || col == NBREC_LOGICAL_ROUTER_COL_STATIC_ROUTES) { > > continue; > > } > > return false; > > @@ -5412,12 +5436,7 @@ lr_changes_can_be_handled(const struct > nbrec_logical_router *lr) > > return false; > > } > > } > > - for (size_t i = 0; i < lr->n_static_routes; i++) { > > - if (nbrec_logical_router_static_route_row_get_seqno( > > - lr->static_routes[i], OVSDB_IDL_CHANGE_MODIFY) > 0) { > > - return false; > > - } > > - } > > + > > return true; > > } > > > > @@ -5443,6 +5462,27 @@ is_lr_nats_changed(const struct > nbrec_logical_router *nbr) { > > || is_lr_nats_seqno_changed(nbr)); > > } > > > > +static bool > > +is_lr_static_routes_seqno_changed(const struct > nbrec_logical_router *nbr) > > +{ > > + for (size_t i = 0; i < nbr->n_static_routes; i++) { > > + if (nbrec_logical_router_static_route_row_get_seqno( > > + nbr->static_routes[i], > OVSDB_IDL_CHANGE_MODIFY) > 0) { > > + return true; > > + } > > + } > > + > > + return false; > > +} > > + > > +static bool > > +is_lr_static_routes_changed(const struct nbrec_logical_router *nbr) { > > + return nbrec_logical_router_is_updated(nbr, > > + > NBREC_LOGICAL_ROUTER_COL_STATIC_ROUTES) > > + || is_lr_static_routes_seqno_changed(nbr); > > +} > > + > > + > > /* Return true if changes are handled incrementally, false otherwise. > > * > > * Note: Changes to load balancer and load balancer groups > associated with > > @@ -5514,6 +5554,22 @@ northd_handle_lr_changes(const struct > northd_input *ni, > > > > hmapx_add(&nd->trk_data.trk_nat_lrs, od); > > } > > + > > + /* Static Route was added or deleted. */ > > + if (is_lr_static_routes_changed(changed_lr)) { > > + struct ovn_datapath *od = ovn_datapath_find_( > > + &nd->lr_datapaths.datapaths, > > + &changed_lr->header_.uuid); > > + > > + if (!od) { > > + static struct vlog_rate_limit rl = > VLOG_RATE_LIMIT_INIT(1, 1); > > + VLOG_WARN_RL(&rl, "Internal error: a tracked > updated LR " > > + "doesn't exist in lr_datapaths: > "UUID_FMT, > > + UUID_ARGS(&changed_lr->header_.uuid)); > > + goto fail; > > + } > > + hmapx_add(&nd->trk_data.trk_lrs_routes, od); > > + } > > } > > > > HMAPX_FOR_EACH (node, &ni->synced_lrs->deleted) { > > @@ -5554,6 +5610,9 @@ northd_handle_lr_changes(const struct > northd_input *ni, > > if (!hmapx_is_empty(&nd->trk_data.trk_nat_lrs)) { > > nd->trk_data.type |= NORTHD_TRACKED_LR_NATS; > > } > > + if (!hmapx_is_empty(&nd->trk_data.trk_lrs_routes)) { > > + nd->trk_data.type |= NORTHD_TRACKED_LR_ROUTES; > > + } > > if (!hmapx_is_empty(&nd->trk_data.trk_routers.crupdated) || > > !hmapx_is_empty(&nd->trk_data.trk_routers.deleted)) { > > nd->trk_data.type |= NORTHD_TRACKED_ROUTERS; > > @@ -12337,7 +12396,7 @@ parsed_route_add(const struct ovn_datapath > *od, > > } > > } > > > > -static void > > +struct parsed_route * > > parsed_routes_add_static(const struct ovn_datapath *od, > > const struct hmap *lr_ports, > > const struct > nbrec_logical_router_static_route *route, > > @@ -12358,8 +12417,9 @@ parsed_routes_add_static(const struct > ovn_datapath *od, > > UUID_FMT, route->nexthop, > > UUID_ARGS(&route->header_.uuid)); > > free(nexthop); > > - return; > > + return NULL; > > } > > + > > if ((IN6_IS_ADDR_V4MAPPED(nexthop) && plen != 32) || > > (!IN6_IS_ADDR_V4MAPPED(nexthop) && plen != 128)) { > > static struct vlog_rate_limit rl = > VLOG_RATE_LIMIT_INIT(5, 1); > > @@ -12367,7 +12427,7 @@ parsed_routes_add_static(const struct > ovn_datapath *od, > > UUID_FMT, route->nexthop, > > UUID_ARGS(&route->header_.uuid)); > > free(nexthop); > > - return; > > + return NULL; > > } > > } > > > > @@ -12379,7 +12439,7 @@ parsed_routes_add_static(const struct > ovn_datapath *od, > > UUID_FMT, route->ip_prefix, > > UUID_ARGS(&route->header_.uuid)); > > free(nexthop); > > - return; > > + return NULL; > > } > > > > /* Verify that ip_prefix and nexthop are on the same network. */ > > @@ -12391,7 +12451,7 @@ parsed_routes_add_static(const struct > ovn_datapath *od, > > : IN6_IS_ADDR_V4MAPPED(&prefix), > > &lrp_addr_s, &out_port)) { > > free(nexthop); > > - return; > > + return NULL; > > } > > > > const struct nbrec_bfd *nb_bt = route->bfd; > > @@ -12401,7 +12461,7 @@ parsed_routes_add_static(const struct > ovn_datapath *od, > > nb_bt->dst_ip); > > if (!bfd_e) { > > free(nexthop); > > - return; > > + return NULL; > > } > > > > /* This static route is linked to an active bfd session. */ > > @@ -12418,10 +12478,9 @@ parsed_routes_add_static(const struct > ovn_datapath *od, > > bfd_set_status(bfd_sr, "down"); > > } > > > > - > > if (!strcmp(bfd_sr->status, "down")) { > > - free(nexthop); > > - return; > > + free(nexthop); > > + return NULL; > > } > > } > > > > @@ -12465,12 +12524,17 @@ parsed_routes_add_static(const struct > ovn_datapath *od, > > bool dynamic_routing_advertise = smap_get_bool(&route->options, > > "dynamic- > routing-advertise", > > true); > > - parsed_route_add(od, nexthop, &prefix, plen, > is_discard_route, lrp_addr_s, > > - out_port, route_table_id, is_src_route, > > - ecmp_symmetric_reply, override_connected, > > - &ecmp_selection_fields, source, > dynamic_routing_advertise, > > - &route->header_, NULL, routes); > > + struct parsed_route *pr = parsed_route_add(od, nexthop, > &prefix, plen, > > + is_discard_route, > lrp_addr_s, > > + out_port, > route_table_id, > > + is_src_route, > > + ecmp_symmetric_reply, > > + override_connected, > > + > &ecmp_selection_fields, source, > > + > dynamic_routing_advertise, > > + &route->header_, > NULL, routes); > > sset_destroy(&ecmp_selection_fields); > > + return pr; > > } > > > > static void > > @@ -16374,13 +16438,14 @@ build_lr_gateway_redirect_flows_for_nats( > > * In the common case where the Ethernet destination has been > resolved, > > * this table outputs the packet (priority 0). Otherwise, it > composes > > * and sends an ARP/IPv6 NA request (priority 100). */ > > -static void > > +void > > build_arp_request_flows_for_lrouter( > > - struct ovn_datapath *od, struct lflow_table *lflows, > > - struct ds *match, struct ds *actions, > > + const struct ovn_datapath *od, struct lflow_table *lflows, > > const struct shash *meter_groups, > > struct lflow_ref *lflow_ref) > > { > > + struct ds match = DS_EMPTY_INITIALIZER; > > + struct ds actions = DS_EMPTY_INITIALIZER; > > ovs_assert(od->nbr); > > for (int i = 0; i < od->nbr->n_static_routes; i++) { > > const struct nbrec_logical_router_static_route *route; > > @@ -16394,8 +16459,8 @@ build_arp_request_flows_for_lrouter( > > continue; > > } > > > > - ds_clear(match); > > - ds_put_format(match, "eth.dst == 00:00:00:00:00:00 && " > > + ds_clear(&match); > > + ds_put_format(&match, "eth.dst == 00:00:00:00:00:00 && " > > REGBIT_NEXTHOP_IS_IPV4" == 0 && " > > REG_NEXT_HOP_IPV6 " == %s", > > route->nexthop); > > @@ -16407,8 +16472,8 @@ build_arp_request_flows_for_lrouter( > > char sn_addr_s[INET6_ADDRSTRLEN + 1]; > > ipv6_string_mapped(sn_addr_s, &sn_addr); > > > > - ds_clear(actions); > > - ds_put_format(actions, > > + ds_clear(&actions); > > + ds_put_format(&actions, > > "nd_ns { " > > "eth.dst = "ETH_ADDR_FMT"; " > > "ip6.dst = %s; " > > @@ -16418,7 +16483,7 @@ build_arp_request_flows_for_lrouter( > > route->nexthop); > > > > ovn_lflow_add(lflows, od, S_ROUTER_IN_ARP_REQUEST, 200, > > - ds_cstr(match), ds_cstr(actions), lflow_ref, > > + ds_cstr(&match), ds_cstr(&actions), lflow_ref, > > > WITH_CTRL_METER(copp_meter_get(COPP_ND_NS_RESOLVE, > > od->nbr->copp, > > meter_groups)), > > @@ -16450,6 +16515,8 @@ build_arp_request_flows_for_lrouter( > > > meter_groups))); > > ovn_lflow_add(lflows, od, S_ROUTER_IN_ARP_REQUEST, 0, "1", > "next;", > > lflow_ref); > > + ds_destroy(&match); > > + ds_destroy(&actions); > > } > > > > static void > > @@ -19578,8 +19645,7 @@ > build_lswitch_and_lrouter_iterate_by_lr(struct ovn_datapath *od, > > build_gateway_redirect_flows_for_lrouter(od, lsi->lflows, > &lsi->match, > > &lsi->actions, > > od->datapath_lflows); > > - build_arp_request_flows_for_lrouter(od, lsi->lflows, &lsi->match, > > - &lsi->actions, > > + build_arp_request_flows_for_lrouter(od, lsi->lflows, > > lsi->meter_groups, > > od->datapath_lflows); > > build_ecmp_stateful_egr_flows_for_lrouter(od, lsi->lflows, > > @@ -21076,6 +21142,9 @@ routes_init(struct routes_data *data) > > hmap_init(&data->parsed_routes); > > simap_init(&data->route_tables); > > hmap_init(&data->bfd_active_connections); > > + data->tracked = false; > > + hmapx_init(&data->trk_data.trk_deleted_parsed_route); > > + hmapx_init(&data->trk_data.trk_crupdated_parsed_route); > > } > > > > void > > @@ -21206,6 +21275,17 @@ routes_destroy(struct routes_data *data) > > > > simap_destroy(&data->route_tables); > > __bfd_destroy(&data->bfd_active_connections); > > + data->tracked = false; > > + hmapx_destroy(&data->trk_data.trk_crupdated_parsed_route); > > + hmapx_destroy(&data->trk_data.trk_deleted_parsed_route); > > +} > > + > > +void > > +routes_clear_tracked(struct routes_data *data) > > +{ > > + data->tracked = false; > > + hmapx_clear(&data->trk_data.trk_crupdated_parsed_route); > > + hmapx_clear(&data->trk_data.trk_deleted_parsed_route); > > } > > > > void > > diff --git a/northd/northd.h b/northd/northd.h > > index 726a416e4..bda218341 100644 > > --- a/northd/northd.h > > +++ b/northd/northd.h > > @@ -110,6 +110,10 @@ ods_size(const struct ovn_datapaths *datapaths) > > struct ovn_datapath * > > ovn_datapath_find_by_key(struct hmap *datapaths, uint32_t dp_key); > > > > +struct ovn_datapath * > > +ovn_datapath_find_by_static_route(struct hmapx *, > > + const struct uuid *route_uuid); > > + > > bool od_has_lb_vip(const struct ovn_datapath *od); > > > > /* List of routing and routing-related protocols which > > @@ -159,6 +163,7 @@ enum northd_tracked_data_type { > > NORTHD_TRACKED_LS_ACLS = (1 << 4), > > NORTHD_TRACKED_SWITCHES = (1 << 5), > > NORTHD_TRACKED_ROUTERS = (1 << 6), > > + NORTHD_TRACKED_LR_ROUTES = (1 << 7), > > }; > > > > /* Track what's changed in the northd engine node. > > @@ -176,6 +181,10 @@ struct northd_tracked_data { > > * hmapx node is 'struct ovn_datapath *'. */ > > struct hmapx trk_nat_lrs; > > > > + /* Tracked logical routers whose static routes have changed. > > + * hmapx node is 'struct ovn_datapath *'. */ > > + struct hmapx trk_lrs_routes; > > + > > /* Tracked logical switches whose load balancers have changed. > > * hmapx node is 'struct ovn_datapath *'. */ > > struct hmapx ls_with_changed_lbs; > > @@ -216,10 +225,23 @@ struct route_policy { > > uint32_t jump_chain_id; > > }; > > > > +struct route_tracked_data { > > + /* Contains references to group_ecmp_route_node. Each of the > referenced > > + * datapaths contains at least one route. */ > > + struct hmapx trk_crupdated_parsed_route; > > + > > + /* Contains references to group_ecmp_route_node. Each of the > referenced > > + * datapath previously had some routes. The datapath now no > longer > > + * contains any route.*/ > > + struct hmapx trk_deleted_parsed_route; > > +}; > > + > > struct routes_data { > > struct hmap parsed_routes; /* Stores struct parsed_route. */ > > struct simap route_tables; > > struct hmap bfd_active_connections; > > + bool tracked; > > + struct route_tracked_data trk_data; > > }; > > > > struct route_policies_data { > > @@ -886,6 +908,14 @@ struct parsed_route *parsed_route_add( > > const struct ovn_port *tracked_port, > > struct hmap *routes); > > > > +struct parsed_route * parsed_routes_add_static( > > + const struct ovn_datapath *od, > > + const struct hmap *lr_ports, > > + const struct nbrec_logical_router_static_route *route, > > + const struct hmap *bfd_connections, > > + struct hmap *routes, struct simap *route_tables, > > + struct hmap *bfd_active_connections); > > + > > struct svc_monitors_map_data { > > const struct hmap *local_svc_monitors_map; > > const struct hmap *ic_learned_svc_monitors_map; > > @@ -930,7 +960,7 @@ void build_parsed_routes(const struct > ovn_datapath *, const struct hmap *, > > uint32_t get_route_table_id(struct simap *, const char *); > > void routes_init(struct routes_data *); > > void routes_destroy(struct routes_data *); > > - > > +void routes_clear_tracked(struct routes_data *); > > void bfd_init(struct bfd_data *); > > void bfd_destroy(struct bfd_data *); > > > > @@ -956,6 +986,10 @@ void build_route_data_flows_for_lrouter( > > const struct ovn_datapath *od, struct lflow_table *lflows, > > const struct group_ecmp_datapath *route_node, > > const struct sset *bfd_ports); > > +void build_arp_request_flows_for_lrouter( > > + const struct ovn_datapath *od, struct lflow_table *lflows, > > + const struct shash *meter_groups, > > + struct lflow_ref *lflow_ref); > > > > bool lflow_handle_northd_lr_changes(struct ovsdb_idl_txn *ovnsh_txn, > > struct tracked_dps *, > > @@ -1042,6 +1076,11 @@ northd_has_lr_nats_in_tracked_data(struct > northd_tracked_data *trk_nd_changes) > > { > > return trk_nd_changes->type & NORTHD_TRACKED_LR_NATS; > > } > > +static inline bool > > +northd_has_lr_route_in_tracked_data(struct northd_tracked_data > *trk_nd_changes) > > +{ > > + return trk_nd_changes->type & NORTHD_TRACKED_LR_ROUTES; > > +} > > > > static inline bool > > northd_has_ls_lbs_in_tracked_data(struct northd_tracked_data > *trk_nd_changes) > > diff --git a/tests/ovn-inc-proc-graph-dump.at <http://ovn-inc- > proc-graph-dump.at> b/tests/ovn-inc-proc-graph-dump.at <http://ovn- > inc-proc-graph-dump.at> > > index 3750339d0..50fe0d5be 100644 > > --- a/tests/ovn-inc-proc-graph-dump.at <http://ovn-inc-proc-graph- > dump.at> > > +++ b/tests/ovn-inc-proc-graph-dump.at <http://ovn-inc-proc-graph- > dump.at> > > @@ -151,9 +151,11 @@ digraph "Incremental-Processing-Engine" { > > bfd [[style=filled, shape=box, fillcolor=white, label="bfd"]]; > > NB_bfd -> bfd [[label=""]]; > > SB_bfd -> bfd [[label=""]]; > > + NB_logical_router_static_route [[style=filled, shape=box, > fillcolor=white, label="NB_logical_router_static_route"]]; > > routes [[style=filled, shape=box, fillcolor=white, > label="routes"]]; > > bfd -> routes [[label=""]]; > > northd -> routes [[label="routes_northd_change_handler"]]; > > + NB_logical_router_static_route -> routes > [[label="routes_static_route_change_handler"]]; > > route_policies [[style=filled, shape=box, fillcolor=white, > label="route_policies"]]; > > bfd -> route_policies [[label=""]]; > > northd -> route_policies > [[label="route_policies_northd_change_handler"]]; > > @@ -168,7 +170,7 @@ digraph "Incremental-Processing-Engine" { > > SB_learned_route -> learned_route_sync > [[label="learned_route_sync_sb_learned_route_change_handler"]]; > > northd -> learned_route_sync > [[label="learned_route_sync_northd_change_handler"]]; > > group_ecmp_route [[style=filled, shape=box, fillcolor=white, > label="group_ecmp_route"]]; > > - routes -> group_ecmp_route [[label=""]]; > > + routes -> group_ecmp_route > [[label="group_ecmp_static_route_change_handler"]]; > > learned_route_sync -> group_ecmp_route > [[label="group_ecmp_route_learned_route_change_handler"]]; > > ls_stateful [[style=filled, shape=box, fillcolor=white, > label="ls_stateful"]]; > > northd -> ls_stateful [[label="ls_stateful_northd_handler"]]; > > @@ -186,7 +188,7 @@ digraph "Incremental-Processing-Engine" { > > SB_logical_dp_group -> lflow [[label=""]]; > > bfd_sync -> lflow [[label=""]]; > > route_policies -> lflow [[label=""]]; > > - routes -> lflow [[label=""]]; > > + routes -> lflow [[label="lflow_group_route_change_handler"]]; > > group_ecmp_route -> lflow > [[label="lflow_group_ecmp_route_change_handler"]]; > > global_config -> lflow [[label="node_global_config_handler"]]; > > sampling_app -> lflow [[label=""]]; > > diff --git a/tests/ovn-northd.at <http://ovn-northd.at> b/tests/ > ovn-northd.at <http://ovn-northd.at> > > index f87b14c9a..ed7574854 100644 > > --- a/tests/ovn-northd.at <http://ovn-northd.at> > > +++ b/tests/ovn-northd.at <http://ovn-northd.at> > > @@ -4383,7 +4383,7 @@ check ovn-nbctl --bfd=$uuid lr-route-add r0 > 100.0.0.0/8 <http://100.0.0.0/8> 192.168.1.2 > > wait_column down bfd status logical_port=r0-sw1 > > AT_CHECK([ovn-nbctl lr-route-list r0 | grep 192.168.1.2 | grep -q > bfd], [0], [], [ignore]) > > > > -check_engine_stats northd recompute nocompute > > +check_engine_stats northd norecompute compute > > check_engine_stats bfd recompute nocompute > > check_engine_stats routes recompute nocompute > > check_engine_stats lflow recompute nocompute > > @@ -4399,7 +4399,7 @@ check ovn-nbctl --bfd lr-route-add r0 > 240.0.0.0/8 <http://240.0.0.0/8> 192.168.5.2 r0-sw5 > > wait_column down bfd status logical_port=r0-sw5 > > AT_CHECK([ovn-nbctl lr-route-list r0 | grep 192.168.5.2 | grep -q > bfd], [0], [], [ignore]) > > > > -check_engine_stats northd recompute nocompute > > +check_engine_stats northd norecompute compute > > check_engine_stats bfd recompute nocompute > > check_engine_stats routes recompute nocompute > > check_engine_stats lflow recompute nocompute > > @@ -4411,7 +4411,7 @@ check ovn-nbctl --bfd --policy=src-ip lr- > route-add r0 192.168.6.1/32 <http://192.168.6.1/32> 192.168.10. > > wait_column down bfd status logical_port=r0-sw6 > > AT_CHECK([ovn-nbctl lr-route-list r0 | grep 192.168.6.1 | grep -q > bfd], [0], [], [ignore]) > > > > -check_engine_stats northd recompute nocompute > > +check_engine_stats northd norecompute compute > > check_engine_stats bfd recompute nocompute > > check_engine_stats route_policies recompute nocompute > > check_engine_stats lflow recompute nocompute > > @@ -4446,10 +4446,10 @@ wait_column down bfd status > logical_port=r0-sw8 > > 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 recompute nocompute > > +check_engine_stats northd recompute incremental > > check_engine_stats bfd recompute nocompute > > -check_engine_stats routes recompute nocompute > > -check_engine_stats lflow recompute nocompute > > +check_engine_stats routes recompute incremental > > +check_engine_stats lflow recompute incremental > > check_engine_stats northd_output norecompute compute > > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > > @@ -16818,12 +16818,12 @@ CHECK_NO_CHANGE_AFTER_RECOMPUTE > > > > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > > check ovn-nbctl --wait=sb lr-route-add lr0 192.168.0.0/24 > <http://192.168.0.0/24> 10.0.0.10 > > -check_engine_compute northd recompute > > -check_engine_compute routes recompute > > +check_engine_compute northd incremental > > +check_engine_compute routes incremental > > check_engine_compute advertised_route_sync recompute > > -check_engine_compute learned_route_sync recompute > > -check_engine_compute group_ecmp_route recompute > > -check_engine_compute lflow recompute > > +check_engine_compute learned_route_sync incremental > > +check_engine_compute group_ecmp_route incremental > > +check_engine_compute lflow incremental > > CHECK_NO_CHANGE_AFTER_RECOMPUTE > > > > check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > > @@ -20933,3 +20933,109 @@ check_column "$global_svc_mon_mac" > sb:Service_Monitor src_mac port=2 > > OVN_CLEANUP_NORTHD > > AT_CLEANUP > > ]) > > + > > +OVN_FOR_EACH_NORTHD_NO_HV([ > > +AT_SETUP([Static Route incremental processing]) > > +ovn_start > > + > > +check ovn-nbctl lr-add r0 > > + > > +check ovn-nbctl --wait=sb lrp-add r0 r0-lrp1 00:00:00:00:00:01 > 192.168.1.1/24 <http://192.168.1.1/24> fe80::1/64 > > + > > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > > +check ovn-nbctl --wait=sb lr-route-add r0 10.0.0.0/24 > <http://10.0.0.0/24> 192.168.1.2 > > + > > +check_engine_compute northd incremental > > +check_engine_compute routes incremental > > +check_engine_compute group_ecmp_route incremental > > +check_engine_compute lflow incremental > > + > > +static_route_uuid=`ovn-nbctl --bare --columns _uuid find > Logical_Router_Static_Route nexthop=192.168.1.2` > > +AT_CHECK([test "$static_route_uuid" != ""]) > > + > > +sr_lflow_uuid=$(fetch_column Logical_flow _uuid match='"reg7 == 0 > && ip4.dst == 10.0.0.0/24 <http://10.0.0.0/24>"') > > +AT_CHECK([test "$sr_lflow_uuid" != ""]) > > + > > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > > +check ovn-nbctl --wait=sb set logical_router_static_route > $static_route_uuid nexthop=192.168.1.3 > > +check_engine_compute northd incremental > > +check_engine_compute routes incremental > > +check_engine_compute group_ecmp_route incremental > > +check_engine_compute lflow incremental > > +sr_lflow_uuid=$(fetch_column Logical_flow _uuid match='"reg7 == 0 > && ip4.dst == 10.0.0.0/24 <http://10.0.0.0/24>"') > > +AT_CHECK([test "$sr_lflow_uuid" != ""]) > > + > > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > > +check ovn-nbctl --wait=sb set logical_router_static_route > $static_route_uuid ip_prefix=10.0.1.0/24 <http://10.0.1.0/24> > > +check_engine_compute northd incremental > > +check_engine_compute routes incremental > > +check_engine_compute group_ecmp_route incremental > > +check_engine_compute lflow incremental > > +sr_lflow_uuid_old=$(fetch_column Logical_flow _uuid match='"reg7 > == 0 && ip4.dst == 10.0.0.0/24 <http://10.0.0.0/24>"') > > +AT_CHECK([test "$sr_lflow_uuid_old" == ""]) > > + > > +sr_lflow_uuid=$(fetch_column Logical_flow _uuid match='"reg7 == 0 > && ip4.dst == 10.0.1.0/24 <http://10.0.1.0/24>"') > > +AT_CHECK([test "$sr_lflow_uuid" != ""]) > > + > > +check ovn-nbctl --wait=sb lrp-add r0 r0-lrp2 00:00:00:00:00:02 > 192.168.1.10/24 <http://192.168.1.10/24> > > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > > +check ovn-nbctl --wait=sb set logical_router_static_route > $static_route_uuid output_port=r0-lrp2 > > +check_engine_compute northd incremental > > +check_engine_compute routes incremental > > +check_engine_compute group_ecmp_route incremental > > +check_engine_compute lflow incremental > > +sr_lflow_uuid=$(fetch_column Logical_flow _uuid match='"reg7 == 0 > && ip4.dst == 10.0.1.0/24 <http://10.0.1.0/24>"') > > +AT_CHECK([test "$sr_lflow_uuid" != ""]) > > + > > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > > +check ovn-nbctl --wait=sb set logical_router_static_route > $static_route_uuid policy=src-ip > > +check_engine_compute northd incremental > > +check_engine_compute routes incremental > > +check_engine_compute group_ecmp_route incremental > > +check_engine_compute lflow incremental > > +sr_lflow_uuid=$(fetch_column Logical_flow _uuid match='"reg7 == 0 > && ip4.src == 10.0.1.0/24 <http://10.0.1.0/24>"') > > +AT_CHECK([test "$sr_lflow_uuid" != ""]) > > + > > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > > +check ovn-nbctl --wait=sb set logical_router_static_route > $static_route_uuid policy=dst-ip > > +check ovn-nbctl --wait=sb set logical_router_static_route > $static_route_uuid selection_fields="ip_proto,ip_src,ip_dst" > > +check_engine_compute northd incremental > > +check_engine_compute routes incremental > > +check_engine_compute group_ecmp_route incremental > > +check_engine_compute lflow incremental > > +sr_lflow_uuid=$(fetch_column Logical_flow _uuid match='"reg7 == 0 > && ip4.dst == 10.0.1.0/24 <http://10.0.1.0/24>"') > > +AT_CHECK([test "$sr_lflow_uuid" != ""]) > > + > > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > > +check ovn-nbctl --wait=sb set logical_router_static_route > $static_route_uuid options:ecmp_symmetric_reply=true > > +check_engine_compute northd incremental > > +check_engine_compute routes incremental > > +check_engine_compute group_ecmp_route incremental > > +check_engine_compute lflow incremental > > +sr_lflow_uuid=$(fetch_column Logical_flow _uuid match='"reg7 == 0 > && ip4.dst == 10.0.1.0/24 <http://10.0.1.0/24>"') > > +AT_CHECK([test "$sr_lflow_uuid" != ""]) > > + > > + > > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > > +check ovn-nbctl --wait=sb set logical_router_static_route > $static_route_uuid nexthop=\"fe80::2\" > > +check_engine_compute northd incremental > > +check_engine_compute routes incremental > > +check_engine_compute group_ecmp_route incremental > > +check_engine_compute lflow incremental > > +sr_lflow_uuid=$(fetch_column Logical_flow _uuid match='"reg7 == 0 > && ip4.dst == 10.0.1.0/24 <http://10.0.1.0/24>"') > > +AT_CHECK([test "$sr_lflow_uuid" != ""]) > > +sr_lflow_uuid_nexthop_ipv6=$(fetch_column Logical_flow _uuid > match='"eth.dst == 00:00:00:00:00:00 && reg9[[9]] == 0 && xxreg0 == > fe80::2"') > > +AT_CHECK([test "$sr_lflow_uuid_nexthop_ipv6" != ""]) > > + > > +check as northd ovn-appctl -t ovn-northd inc-engine/clear-stats > > +check ovn-nbctl remove logical_router r0 static_routes > $static_route_uuid > > +check_engine_compute northd incremental > > +check_engine_compute routes incremental > > +check_engine_compute group_ecmp_route incremental > > +check_engine_compute lflow incremental > > +sr_lflow_uuid=$(fetch_column Logical_flow _uuid match='"reg7 == 0 > && ip4.src == 10.0.1.0/24 <http://10.0.1.0/24>"') > > +AT_CHECK([test "$sr_lflow_uuid" == ""]) > > + > > +OVN_CLEANUP_NORTHD > > +AT_CLEANUP > > +]) > > diff --git a/tests/system-ovn.at <http://system-ovn.at> b/tests/ > system-ovn.at <http://system-ovn.at> > > index cfcc3f197..9ff463ce0 100644 > > --- a/tests/system-ovn.at <http://system-ovn.at> > > +++ b/tests/system-ovn.at <http://system-ovn.at> > > @@ -7352,7 +7352,8 @@ wait_column "up" nb:bfd status > logical_port=rp-public > > OVS_WAIT_UNTIL([ovn-sbctl dump-flows R1 |grep lr_in_ip_routing | > grep 'ip4.dst == 100.0.0.0/8 <http://100.0.0.0/8>' |grep -q > 172.16.1.50]) > > > > # un-associate the bfd connection and the static route > > -check ovn-nbctl clear logical_router_static_route $route_uuid bfd > > +check ovn-nbctl --wait=sb clear logical_router_static_route > $route_uuid bfd > > +cat northd/ovn-northd.log > > wait_column "admin_down" nb:bfd status logical_port=rp-public > > OVS_WAIT_UNTIL([ip netns exec server bfdd-control status | grep - > qi state=Down]) > > > > @@ -7416,7 +7417,7 @@ wait_column "up" nb:bfd status > logical_port=rp-public > > OVS_WAIT_UNTIL([ovn-sbctl dump-flows R1 |grep lr_in_ip_routing | > grep 'ip4.dst == 100.0.0.0/8 <http://100.0.0.0/8>' |grep -q > 172.16.1.50]) > > check_row_count Advertised_Route 1 ip_prefix=100.0.0.0/8 > <http://100.0.0.0/8> > > > > -check ovn-nbctl clear logical_router_static_route $route_uuid bfd > > +check ovn-nbctl --wait=sb clear logical_router_static_route > $route_uuid bfd > > wait_column "admin_down" nb:bfd status logical_port=rp-public > > OVS_WAIT_UNTIL([ip netns exec server bfdd-control status | grep - > qi state=Down]) > > check ovn-nbctl destroy bfd $uuid > > > > /‘Esta mensagem é direcionada apenas para os endereços constantes no > cabeçalho inicial. Se você não está listado nos endereços constantes no > cabeçalho, pedimos-lhe que desconsidere completamente o conteúdo dessa > mensagem e cuja cópia, encaminhamento e/ou execução das ações citadas > estão imediatamente anuladas e proibidas’./ > > / //‘Apesar do Magazine Luiza tomar todas as precauções razoáveis para > assegurar que nenhum vírus esteja presente nesse e-mail, a empresa não > poderá aceitar a responsabilidade por quaisquer perdas ou danos causados > por esse e-mail ou por seus anexos’./ > _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
