]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib, mgmtd, zebra: cleanup of zebra conversion to mgmtd 15181/head
authorIgor Ryzhov <iryzhov@nfware.com>
Sun, 28 Jan 2024 21:23:57 +0000 (23:23 +0200)
committerIgor Ryzhov <iryzhov@nfware.com>
Sun, 28 Jan 2024 21:46:38 +0000 (23:46 +0200)
- use `apply_finish` callback when possible to avoid multiple applies per commit
- move table range working to the CLI handler
- remove unnecessary conditional compilation
- remove unnecessary boolean conversion

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
lib/northbound.h
zebra/interface.c
zebra/table_manager.c
zebra/zebra_cli.c
zebra/zebra_nb.c
zebra/zebra_nb.h
zebra/zebra_nb_config.c

index b7194ea40e85ce5bfaa1de688bb37548c0eaa2e9..2d9643e7b49bbd8d9bcb6fdb7a75a82b1aeb7733 100644 (file)
@@ -630,6 +630,7 @@ struct frr_yang_module_info {
 
        /*
         * The NULL-terminated list of supported features.
+        * Features are defined with "feature" statements in the YANG model.
         * Use ["*", NULL] to enable all features.
         * Use NULL to disable all features.
         */
index cba052dff6640a8701b1300ea2180faed123cbc4..6e33d7ec7d115f520ef937bb8c7b8c03654ad932 100644 (file)
@@ -3792,27 +3792,16 @@ void link_param_cmd_set_uint32(struct interface *ifp, uint32_t *field,
        if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
                *field = value;
                SET_PARAM(ifp->link_params, type);
-
-               /* force protocols to update LINK STATE due to parameters change
-                */
-               if (if_is_operative(ifp))
-                       zebra_interface_parameters_update(ifp);
        }
 }
 
 void link_param_cmd_set_float(struct interface *ifp, float *field,
                              uint32_t type, float value)
 {
-
        /* Update field as needed */
        if (IS_PARAM_UNSET(ifp->link_params, type) || *field != value) {
                *field = value;
                SET_PARAM(ifp->link_params, type);
-
-               /* force protocols to update LINK STATE due to parameters change
-                */
-               if (if_is_operative(ifp))
-                       zebra_interface_parameters_update(ifp);
        }
 }
 
@@ -3823,10 +3812,6 @@ void link_param_cmd_unset(struct interface *ifp, uint32_t type)
 
        /* Unset field */
        UNSET_PARAM(ifp->link_params, type);
-
-       /* force protocols to update LINK STATE due to parameters change */
-       if (if_is_operative(ifp))
-               zebra_interface_parameters_update(ifp);
 }
 
 void if_ip_address_install(struct interface *ifp, struct prefix *prefix,
index 3e540fda149e6ab545bc337ece8aae2507e445b2..8417a22114f41ae5b5cdd4fd5d0116d4cfa21a90 100644 (file)
@@ -267,14 +267,8 @@ void table_manager_disable(struct zebra_vrf *zvrf)
 void table_manager_range(bool add, struct zebra_vrf *zvrf, uint32_t start,
                         uint32_t end)
 {
-       if (add) {
-               if (zvrf->tbl_mgr &&
-                   ((zvrf->tbl_mgr->start && zvrf->tbl_mgr->start != start) ||
-                    (zvrf->tbl_mgr->end && zvrf->tbl_mgr->end != end)))
-                       zlog_info(
-                               "%% New range will be taken into account at restart");
-
+       if (add)
                table_range_add(zvrf, start, end);
-       else
+       else
                table_range_add(zvrf, 0, 0);
 }
index 1d98c27828c3f3f901c899d66edc278699377ab0..296f03ae892e6a1d73bebe542627863ea88a337c 100644 (file)
@@ -2212,7 +2212,10 @@ DEFPY_YANG (vrf_netns,
        "Attach VRF to a Namespace\n"
        "The file name in " NS_RUN_DIR ", or a full pathname\n")
 {
-       return CMD_SUCCESS;
+       vty_out(vty, "%% This command doesn't do anything.\n");
+       vty_out(vty,
+               "%% VRF is linked to a netns automatically based on its name.\n");
+       return CMD_WARNING;
 }
 
 DEFPY_YANG (ip_table_range, ip_table_range_cmd,
@@ -2224,6 +2227,41 @@ DEFPY_YANG (ip_table_range, ip_table_range_cmd,
       "End Routing Table\n")
 {
        if (!no) {
+               const struct lyd_node *start_node;
+               const struct lyd_node *end_node;
+
+               if (vty->node == CONFIG_NODE) {
+                       start_node =
+                               yang_dnode_getf(vty->candidate_config->dnode,
+                                               "/frr-vrf:lib/vrf[name='%s']/frr-zebra:zebra/netns/table-range/start",
+                                               VRF_DEFAULT_NAME);
+                       end_node =
+                               yang_dnode_getf(vty->candidate_config->dnode,
+                                               "/frr-vrf:lib/vrf[name='%s']/frr-zebra:zebra/netns/table-range/end",
+                                               VRF_DEFAULT_NAME);
+               } else {
+                       start_node =
+                               yang_dnode_getf(vty->candidate_config->dnode,
+                                               "%s/frr-zebra:zebra/netns/table-range/start",
+                                               VTY_CURR_XPATH);
+                       end_node =
+                               yang_dnode_getf(vty->candidate_config->dnode,
+                                               "%s/frr-zebra:zebra/netns/table-range/end",
+                                               VTY_CURR_XPATH);
+               }
+
+               if (start_node && end_node) {
+                       if (yang_dnode_get_uint32(start_node, NULL) !=
+                                   (uint32_t)start ||
+                           yang_dnode_get_uint32(end_node, NULL) !=
+                                   (uint32_t)end) {
+                               vty_out(vty,
+                                       "%% New range will be taken into account at restart.\n");
+                               vty_out(vty,
+                                       "%% Don't forget to save your configuration.\n");
+                       }
+               }
+
                nb_cli_enqueue_change(vty, "./frr-zebra:zebra/netns/table-range",
                                      NB_OP_CREATE, NULL);
                nb_cli_enqueue_change(vty,
@@ -2546,7 +2584,6 @@ DEFPY_YANG(
        return nb_cli_apply_changes(vty, NULL);
 }
 
-#if HAVE_BFDD == 0 || defined(HAVE_RTADV)
 const char *features[] = {
 #if HAVE_BFDD == 0
        "ptm-bfd",
@@ -2556,15 +2593,12 @@ const char *features[] = {
 #endif
        NULL
 };
-#endif
 
 /* clang-format off */
 const struct frr_yang_module_info frr_zebra_cli_info = {
        .name = "frr-zebra",
        .ignore_cfg_cbs = true,
-#if HAVE_BFDD == 0 || defined(HAVE_RTADV)
        .features = features,
-#endif
        .nodes = {
 #if HAVE_BFDD == 0
                {
index aace4289d33cb0d0f8bd67f9dd43e95e9a96a22f..7e1c43c204d7c5245bad707a4c2dfc999bd96640 100644 (file)
@@ -10,7 +10,6 @@
 #include "libfrr.h"
 #include "zebra_nb.h"
 
-#if HAVE_BFDD == 0 || defined(HAVE_RTADV)
 const char *features[] = {
 #if HAVE_BFDD == 0
        "ptm-bfd",
@@ -20,14 +19,11 @@ const char *features[] = {
 #endif
        NULL
 };
-#endif
 
 /* clang-format off */
 const struct frr_yang_module_info frr_zebra_info = {
        .name = "frr-zebra",
-#if HAVE_BFDD == 0 || defined(HAVE_RTADV)
        .features = features,
-#endif
        .nodes = {
                {
                        .xpath = "/frr-zebra:zebra/mcast-rpf-lookup",
@@ -392,6 +388,7 @@ const struct frr_yang_module_info frr_zebra_info = {
                        .cbs = {
                                .create = lib_interface_zebra_link_params_create,
                                .destroy = lib_interface_zebra_link_params_destroy,
+                               .apply_finish = lib_interface_zebra_link_params_apply_finish,
                        }
                },
                {
@@ -808,6 +805,7 @@ const struct frr_yang_module_info frr_zebra_info = {
                        .cbs = {
                                .create = lib_vrf_zebra_filter_protocol_create,
                                .destroy = lib_vrf_zebra_filter_protocol_destroy,
+                               .apply_finish = lib_vrf_zebra_filter_protocol_apply_finish,
                        }
                },
                {
@@ -821,6 +819,7 @@ const struct frr_yang_module_info frr_zebra_info = {
                        .cbs = {
                                .create = lib_vrf_zebra_filter_nht_create,
                                .destroy = lib_vrf_zebra_filter_nht_destroy,
+                               .apply_finish = lib_vrf_zebra_filter_nht_apply_finish,
                        }
                },
                {
index 2886469e9a5c48dccf5bb3785940d1740940bba8..97979ef9623bede3649fc169f074b3da1bfe2135 100644 (file)
@@ -107,6 +107,8 @@ int lib_interface_zebra_mpls_modify(struct nb_cb_modify_args *args);
 int lib_interface_zebra_mpls_destroy(struct nb_cb_destroy_args *args);
 int lib_interface_zebra_link_params_create(struct nb_cb_create_args *args);
 int lib_interface_zebra_link_params_destroy(struct nb_cb_destroy_args *args);
+void lib_interface_zebra_link_params_apply_finish(
+       struct nb_cb_apply_finish_args *args);
 int lib_interface_zebra_link_params_metric_modify(struct nb_cb_modify_args *args);
 int lib_interface_zebra_link_params_metric_destroy(
        struct nb_cb_destroy_args *args);
@@ -283,10 +285,13 @@ int lib_vrf_zebra_ipv6_router_id_modify(struct nb_cb_modify_args *args);
 int lib_vrf_zebra_ipv6_router_id_destroy(struct nb_cb_destroy_args *args);
 int lib_vrf_zebra_filter_protocol_create(struct nb_cb_create_args *args);
 int lib_vrf_zebra_filter_protocol_destroy(struct nb_cb_destroy_args *args);
+void lib_vrf_zebra_filter_protocol_apply_finish(
+       struct nb_cb_apply_finish_args *args);
 int lib_vrf_zebra_filter_protocol_route_map_modify(
        struct nb_cb_modify_args *args);
 int lib_vrf_zebra_filter_nht_create(struct nb_cb_create_args *args);
 int lib_vrf_zebra_filter_nht_destroy(struct nb_cb_destroy_args *args);
+void lib_vrf_zebra_filter_nht_apply_finish(struct nb_cb_apply_finish_args *args);
 int lib_vrf_zebra_filter_nht_route_map_modify(struct nb_cb_modify_args *args);
 int lib_vrf_zebra_resolve_via_default_modify(struct nb_cb_modify_args *args);
 int lib_vrf_zebra_resolve_via_default_destroy(struct nb_cb_destroy_args *args);
index b026f994cdf40dff39ab0a4199a173c18a21d121..f24af16a2e58a94506ab3c3e0a894cf843817f6d 100644 (file)
@@ -1326,8 +1326,11 @@ int lib_interface_zebra_link_params_create(struct nb_cb_create_args *args)
 
        ifp = nb_running_get_entry(args->dnode, NULL, true);
        if_link_params_enable(ifp);
-       if (if_is_operative(ifp))
-               zebra_interface_parameters_update(ifp);
+
+       /*
+        * The interface is updated in the apply_finish callback after all
+        * parameters are set in the corresponding callbacks.
+        */
 
        return NB_OK;
 }
@@ -1347,6 +1350,16 @@ int lib_interface_zebra_link_params_destroy(struct nb_cb_destroy_args *args)
        return NB_OK;
 }
 
+void lib_interface_zebra_link_params_apply_finish(
+       struct nb_cb_apply_finish_args *args)
+{
+       struct interface *ifp;
+
+       ifp = nb_running_get_entry(args->dnode, NULL, true);
+       if (if_is_operative(ifp))
+               zebra_interface_parameters_update(ifp);
+}
+
 /*
  * XPath: /frr-interface:lib/interface/frr-zebra:zebra/link-params/metric
  */
@@ -1736,9 +1749,6 @@ int lib_interface_zebra_legacy_admin_group_modify(
 
                admin_group_clear(&iflp->ext_admin_grp);
                UNSET_PARAM(iflp, LP_EXTEND_ADM_GRP);
-
-               if (if_is_operative(ifp))
-                       zebra_interface_parameters_update(ifp);
                break;
        }
        return NB_OK;
@@ -1761,9 +1771,6 @@ int lib_interface_zebra_legacy_admin_group_destroy(
 
                iflp->admin_grp = 0;
                UNSET_PARAM(iflp, LP_ADM_GRP);
-
-               if (if_is_operative(ifp))
-                       zebra_interface_parameters_update(ifp);
                break;
        }
        return NB_OK;
@@ -1806,9 +1813,6 @@ int lib_interface_zebra_affinity_create(struct nb_cb_create_args *args)
                                        affmap->bit_position);
                        SET_PARAM(iflp, LP_EXTEND_ADM_GRP);
                }
-
-               if (if_is_operative(ifp))
-                       zebra_interface_parameters_update(ifp);
                break;
        }
        return NB_OK;
@@ -1849,9 +1853,6 @@ int lib_interface_zebra_affinity_destroy(struct nb_cb_destroy_args *args)
                        if (admin_group_zero(&iflp->ext_admin_grp))
                                UNSET_PARAM(iflp, LP_EXTEND_ADM_GRP);
                }
-
-               if (if_is_operative(ifp))
-                       zebra_interface_parameters_update(ifp);
                break;
        }
        return NB_OK;
@@ -1911,9 +1912,6 @@ int lib_interface_zebra_affinity_mode_modify(struct nb_cb_modify_args *args)
                                SET_PARAM(iflp, LP_ADM_GRP);
                        }
                }
-
-               if (if_is_operative(ifp))
-                       zebra_interface_parameters_update(ifp);
                break;
        }
        return NB_OK;
@@ -1942,9 +1940,6 @@ int lib_interface_zebra_link_params_neighbor_create(struct nb_cb_create_args *ar
        iflp->rmt_ip = ip;
        SET_PARAM(iflp, LP_RMT_AS);
 
-       if (if_is_operative(ifp))
-               zebra_interface_parameters_update(ifp);
-
        return NB_OK;
 }
 
@@ -1964,9 +1959,6 @@ int lib_interface_zebra_link_params_neighbor_destroy(
        iflp->rmt_ip.s_addr = 0;
        UNSET_PARAM(iflp, LP_RMT_AS);
 
-       if (if_is_operative(ifp))
-               zebra_interface_parameters_update(ifp);
-
        return NB_OK;
 }
 
@@ -1990,9 +1982,6 @@ int lib_interface_zebra_link_params_neighbor_remote_as_modify(
 
        iflp->rmt_as = as;
 
-       if (if_is_operative(ifp))
-               zebra_interface_parameters_update(ifp);
-
        return NB_OK;
 }
 
@@ -2016,9 +2005,6 @@ int lib_interface_zebra_link_params_neighbor_ipv4_remote_id_modify(
 
        iflp->rmt_ip = ip;
 
-       if (if_is_operative(ifp))
-               zebra_interface_parameters_update(ifp);
-
        return NB_OK;
 }
 
@@ -2084,9 +2070,6 @@ int lib_interface_zebra_link_params_min_max_delay_create(
        iflp->max_delay = delay_max;
        SET_PARAM(iflp, LP_MM_DELAY);
 
-       if (if_is_operative(ifp))
-               zebra_interface_parameters_update(ifp);
-
        return NB_OK;
 }
 
@@ -2106,9 +2089,6 @@ int lib_interface_zebra_link_params_min_max_delay_destroy(
        iflp->max_delay = 0;
        UNSET_PARAM(iflp, LP_MM_DELAY);
 
-       if (if_is_operative(ifp))
-               zebra_interface_parameters_update(ifp);
-
        return NB_OK;
 }
 
@@ -2132,9 +2112,6 @@ int lib_interface_zebra_link_params_min_max_delay_delay_min_modify(
 
        iflp->min_delay = delay_min;
 
-       if (if_is_operative(ifp))
-               zebra_interface_parameters_update(ifp);
-
        return NB_OK;
 }
 
@@ -2158,9 +2135,6 @@ int lib_interface_zebra_link_params_min_max_delay_delay_max_modify(
 
        iflp->max_delay = delay_max;
 
-       if (if_is_operative(ifp))
-               zebra_interface_parameters_update(ifp);
-
        return NB_OK;
 }
 
@@ -2566,7 +2540,7 @@ int lib_interface_zebra_ipv6_router_advertisements_managed_flag_modify(
 
        managed_flag = yang_dnode_get_bool(args->dnode, NULL);
 
-       zif->rtadv.AdvManagedFlag = !!managed_flag;
+       zif->rtadv.AdvManagedFlag = managed_flag;
 
        return NB_OK;
 }
@@ -2589,7 +2563,7 @@ int lib_interface_zebra_ipv6_router_advertisements_other_config_flag_modify(
 
        other_config_flag = yang_dnode_get_bool(args->dnode, NULL);
 
-       zif->rtadv.AdvOtherConfigFlag = !!other_config_flag;
+       zif->rtadv.AdvOtherConfigFlag = other_config_flag;
 
        return NB_OK;
 }
@@ -2612,7 +2586,7 @@ int lib_interface_zebra_ipv6_router_advertisements_home_agent_flag_modify(
 
        home_agent_flag = yang_dnode_get_bool(args->dnode, NULL);
 
-       zif->rtadv.AdvHomeAgentFlag = !!home_agent_flag;
+       zif->rtadv.AdvHomeAgentFlag = home_agent_flag;
 
        return NB_OK;
 }
@@ -2804,7 +2778,7 @@ int lib_interface_zebra_ipv6_router_advertisements_advertisement_interval_option
 
        option = yang_dnode_get_bool(args->dnode, NULL);
 
-       zif->rtadv.AdvIntervalOption = !!option;
+       zif->rtadv.AdvIntervalOption = option;
 
        return NB_OK;
 }
@@ -2927,11 +2901,11 @@ int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_create(
        ifp = nb_running_get_entry(args->dnode, NULL, true);
 
        yang_dnode_get_ipv6p(&rp.prefix, args->dnode, "prefix-spec");
-       rp.AdvOnLinkFlag = !!yang_dnode_get_bool(args->dnode, "on-link-flag");
-       rp.AdvAutonomousFlag = !!yang_dnode_get_bool(args->dnode,
-                                                    "autonomous-flag");
-       rp.AdvRouterAddressFlag = !!yang_dnode_get_bool(args->dnode,
-                                                       "router-address-flag");
+       rp.AdvOnLinkFlag = yang_dnode_get_bool(args->dnode, "on-link-flag");
+       rp.AdvAutonomousFlag = yang_dnode_get_bool(args->dnode,
+                                                  "autonomous-flag");
+       rp.AdvRouterAddressFlag = yang_dnode_get_bool(args->dnode,
+                                                     "router-address-flag");
        rp.AdvValidLifetime = yang_dnode_get_uint32(args->dnode,
                                                    "valid-lifetime");
        rp.AdvPreferredLifetime = yang_dnode_get_uint32(args->dnode,
@@ -2991,7 +2965,7 @@ int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_on_link_fl
 
        prefix = nb_running_get_entry(args->dnode, NULL, true);
 
-       prefix->AdvOnLinkFlag = !!yang_dnode_get_bool(args->dnode, NULL);
+       prefix->AdvOnLinkFlag = yang_dnode_get_bool(args->dnode, NULL);
 
        return NB_OK;
 }
@@ -3027,7 +3001,7 @@ int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_autonomous
 
        prefix = nb_running_get_entry(args->dnode, NULL, true);
 
-       prefix->AdvAutonomousFlag = !!yang_dnode_get_bool(args->dnode, NULL);
+       prefix->AdvAutonomousFlag = yang_dnode_get_bool(args->dnode, NULL);
 
        return NB_OK;
 }
@@ -3045,7 +3019,7 @@ int lib_interface_zebra_ipv6_router_advertisements_prefix_list_prefix_router_add
 
        prefix = nb_running_get_entry(args->dnode, NULL, true);
 
-       prefix->AdvRouterAddressFlag = !!yang_dnode_get_bool(args->dnode, NULL);
+       prefix->AdvRouterAddressFlag = yang_dnode_get_bool(args->dnode, NULL);
 
        return NB_OK;
 }
@@ -3326,16 +3300,9 @@ int lib_vrf_zebra_ipv6_router_id_destroy(struct nb_cb_destroy_args *args)
  */
 int lib_vrf_zebra_filter_protocol_create(struct nb_cb_create_args *args)
 {
-       struct vrf *vrf;
-       const char *afi_safi = yang_dnode_get_string(args->dnode, "afi-safi");
        const char *proto = yang_dnode_get_string(args->dnode, "protocol");
-       const char *rmap = yang_dnode_get_string(args->dnode, "route-map");
-       afi_t afi;
-       safi_t safi;
        int rtype;
 
-       yang_afi_safi_identity2value(afi_safi, &afi, &safi);
-
        if (strcasecmp(proto, "any") == 0)
                rtype = ZEBRA_ROUTE_MAX;
        else
@@ -3348,12 +3315,7 @@ int lib_vrf_zebra_filter_protocol_create(struct nb_cb_create_args *args)
                        return NB_ERR_VALIDATION;
                }
 
-       if (args->event != NB_EV_APPLY)
-               return NB_OK;
-
-       vrf = nb_running_get_entry(args->dnode, NULL, true);
-
-       ip_protocol_rm_add(vrf->info, rmap, rtype, afi, safi);
+       /* the creation finishes in the apply_finish callback */
 
        return NB_OK;
 }
@@ -3388,15 +3350,13 @@ int lib_vrf_zebra_filter_protocol_destroy(struct nb_cb_destroy_args *args)
        return NB_OK;
 }
 
-/*
- * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/filter-protocol/route-map
- */
-int lib_vrf_zebra_filter_protocol_route_map_modify(struct nb_cb_modify_args *args)
+void lib_vrf_zebra_filter_protocol_apply_finish(
+       struct nb_cb_apply_finish_args *args)
 {
        struct vrf *vrf;
-       const char *afi_safi = yang_dnode_get_string(args->dnode, "../afi-safi");
-       const char *proto = yang_dnode_get_string(args->dnode, "../protocol");
-       const char *rmap = yang_dnode_get_string(args->dnode, NULL);
+       const char *afi_safi = yang_dnode_get_string(args->dnode, "afi-safi");
+       const char *proto = yang_dnode_get_string(args->dnode, "protocol");
+       const char *rmap = yang_dnode_get_string(args->dnode, "route-map");
        afi_t afi;
        safi_t safi;
        int rtype;
@@ -3408,16 +3368,20 @@ int lib_vrf_zebra_filter_protocol_route_map_modify(struct nb_cb_modify_args *arg
        else
                rtype = proto_name2num(proto);
 
-       /* editing an existing entry, it can't be invalid */
+       /* finishing apply for a validated entry, it can't be invalid */
        assert(rtype >= 0);
 
-       if (args->event != NB_EV_APPLY)
-               return NB_OK;
-
        vrf = nb_running_get_entry(args->dnode, NULL, true);
 
        ip_protocol_rm_add(vrf->info, rmap, rtype, afi, safi);
+}
 
+/*
+ * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/filter-protocol/route-map
+ */
+int lib_vrf_zebra_filter_protocol_route_map_modify(struct nb_cb_modify_args *args)
+{
+       /* the update is done in the apply_finish callback */
        return NB_OK;
 }
 
@@ -3426,10 +3390,8 @@ int lib_vrf_zebra_filter_protocol_route_map_modify(struct nb_cb_modify_args *arg
  */
 int lib_vrf_zebra_filter_nht_create(struct nb_cb_create_args *args)
 {
-       struct vrf *vrf;
        const char *afi_safi = yang_dnode_get_string(args->dnode, "afi-safi");
        const char *proto = yang_dnode_get_string(args->dnode, "protocol");
-       const char *rmap = yang_dnode_get_string(args->dnode, "route-map");
        afi_t afi;
        safi_t safi;
        int rtype;
@@ -3454,12 +3416,7 @@ int lib_vrf_zebra_filter_nht_create(struct nb_cb_create_args *args)
                }
        }
 
-       if (args->event != NB_EV_APPLY)
-               return NB_OK;
-
-       vrf = nb_running_get_entry(args->dnode, NULL, true);
-
-       ip_nht_rm_add(vrf->info, rmap, rtype, afi);
+       /* the creation finishes in the apply_finish callback */
 
        return NB_OK;
 }
@@ -3495,15 +3452,12 @@ int lib_vrf_zebra_filter_nht_destroy(struct nb_cb_destroy_args *args)
        return NB_OK;
 }
 
-/*
- * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/filter-nht/route-map
- */
-int lib_vrf_zebra_filter_nht_route_map_modify(struct nb_cb_modify_args *args)
+void lib_vrf_zebra_filter_nht_apply_finish(struct nb_cb_apply_finish_args *args)
 {
        struct vrf *vrf;
-       const char *afi_safi = yang_dnode_get_string(args->dnode, "../afi-safi");
-       const char *proto = yang_dnode_get_string(args->dnode, "../protocol");
-       const char *rmap = yang_dnode_get_string(args->dnode, NULL);
+       const char *afi_safi = yang_dnode_get_string(args->dnode, "afi-safi");
+       const char *proto = yang_dnode_get_string(args->dnode, "protocol");
+       const char *rmap = yang_dnode_get_string(args->dnode, "route-map");
        afi_t afi;
        safi_t safi;
        int rtype;
@@ -3515,17 +3469,21 @@ int lib_vrf_zebra_filter_nht_route_map_modify(struct nb_cb_modify_args *args)
        else
                rtype = proto_name2num(proto);
 
-       /* editing an existing entry, it can't be invalid */
+       /* finishing apply for an existing entry, it can't be invalid */
        assert(rtype >= 0);
        assert(safi == SAFI_UNICAST);
 
-       if (args->event != NB_EV_APPLY)
-               return NB_OK;
-
        vrf = nb_running_get_entry(args->dnode, NULL, true);
 
        ip_nht_rm_add(vrf->info, rmap, rtype, afi);
+}
 
+/*
+ * XPath: /frr-vrf:lib/vrf/frr-zebra:zebra/filter-nht/route-map
+ */
+int lib_vrf_zebra_filter_nht_route_map_modify(struct nb_cb_modify_args *args)
+{
+       /* the update is done in the apply_finish callback */
        return NB_OK;
 }