]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: remove leaf-list xpath hack from northbound
authorIgor Ryzhov <iryzhov@nfware.com>
Tue, 23 Jan 2024 00:09:25 +0000 (02:09 +0200)
committerIgor Ryzhov <iryzhov@nfware.com>
Tue, 23 Jan 2024 10:33:39 +0000 (12:33 +0200)
Currently, when editing a leaf-list, `nb_candidate_edit` expects to
receive it's xpath without a predicate and the value in a separate
argument, and then creates the full xpath. This hack is complicated,
because it depends on the operation and on the caller being a backend or
not. Instead, let's require to always include the predicate in a
leaf-list xpath. Update all the usages in the code accordingly.

Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
eigrpd/eigrp_cli.c
isisd/isis_cli.c
lib/northbound.c
lib/northbound.h
lib/northbound_confd.c
lib/northbound_sysrepo.c
pimd/pim_cmd_common.c
ripd/rip_cli.c
ripngd/ripng_cli.c
vrrpd/vrrp_vty.c
zebra/interface.c

index b961cde8714a6d098f2a9d55aa57d8a4b9bbc32e..6bc024fe0dfad80d946da2e1e599644321829e1a 100644 (file)
@@ -131,12 +131,14 @@ DEFPY_YANG(
        "Suppress routing updates on an interface\n"
        "Interface to suppress on\n")
 {
+       char xpath[XPATH_MAXLEN];
+
+       snprintf(xpath, sizeof(xpath), "./passive-interface[.='%s']", ifname);
+
        if (no)
-               nb_cli_enqueue_change(vty, "./passive-interface",
-                                     NB_OP_DESTROY, ifname);
+               nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
        else
-               nb_cli_enqueue_change(vty, "./passive-interface",
-                                     NB_OP_CREATE, ifname);
+               nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
 
        return nb_cli_apply_changes(vty, NULL);
 }
@@ -354,12 +356,14 @@ DEFPY_YANG(
        "Enable routing on an IP network\n"
        "EIGRP network prefix\n")
 {
+       char xpath[XPATH_MAXLEN];
+
+       snprintf(xpath, sizeof(xpath), "./network[.='%s']", prefix_str);
+
        if (no)
-               nb_cli_enqueue_change(vty, "./network", NB_OP_DESTROY,
-                                     prefix_str);
+               nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
        else
-               nb_cli_enqueue_change(vty, "./network", NB_OP_CREATE,
-                                     prefix_str);
+               nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
 
        return nb_cli_apply_changes(vty, NULL);
 }
@@ -383,12 +387,14 @@ DEFPY_YANG(
        "Specify a neighbor router\n"
        "Neighbor address\n")
 {
+       char xpath[XPATH_MAXLEN];
+
+       snprintf(xpath, sizeof(xpath), "./neighbor[.='%s']", addr_str);
+
        if (no)
-               nb_cli_enqueue_change(vty, "./neighbor", NB_OP_DESTROY,
-                                     addr_str);
+               nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
        else
-               nb_cli_enqueue_change(vty, "./neighbor", NB_OP_CREATE,
-                                     addr_str);
+               nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
 
        return nb_cli_apply_changes(vty, NULL);
 }
@@ -658,8 +664,9 @@ DEFPY_YANG(
                 as_str);
        nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
 
-       snprintf(xpath_auth, sizeof(xpath_auth), "%s/summarize-addresses", xpath);
-       nb_cli_enqueue_change(vty, xpath_auth, NB_OP_CREATE, prefix_str);
+       snprintf(xpath_auth, sizeof(xpath_auth),
+                "%s/summarize-addresses[.='%s']", xpath, prefix_str);
+       nb_cli_enqueue_change(vty, xpath_auth, NB_OP_CREATE, NULL);
 
        return nb_cli_apply_changes(vty, NULL);
 }
@@ -681,8 +688,9 @@ DEFPY_YANG(
                 as_str);
        nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
 
-       snprintf(xpath_auth, sizeof(xpath_auth), "%s/summarize-addresses", xpath);
-       nb_cli_enqueue_change(vty, xpath_auth, NB_OP_DESTROY, prefix_str);
+       snprintf(xpath_auth, sizeof(xpath_auth),
+                "%s/summarize-addresses[.='%s']", xpath, prefix_str);
+       nb_cli_enqueue_change(vty, xpath_auth, NB_OP_DESTROY, NULL);
 
        return nb_cli_apply_changes(vty, NULL);
 }
index bcc9456d2c00fdcdb49d53452e36e2b28e37b733..2b19cbba849de147b2d41ee9e41ff691d37ee121 100644 (file)
@@ -300,8 +300,12 @@ DEFPY_YANG(net, net_cmd, "[no] net WORD",
       "A Network Entity Title for this process (OSI only)\n"
       "XX.XXXX. ... .XXX.XX  Network entity title (NET)\n")
 {
-       nb_cli_enqueue_change(vty, "./area-address",
-                             no ? NB_OP_DESTROY : NB_OP_CREATE, net);
+       char xpath[XPATH_MAXLEN];
+
+       snprintf(xpath, XPATH_MAXLEN, "./area-address[.='%s']", net);
+
+       nb_cli_enqueue_change(vty, xpath, no ? NB_OP_DESTROY : NB_OP_CREATE,
+                             NULL);
 
        return nb_cli_apply_changes(vty, NULL);
 }
@@ -3054,12 +3058,16 @@ void cli_show_ip_isis_circ_type(struct vty *vty, const struct lyd_node *dnode,
 }
 
 static int ag_change(struct vty *vty, int argc, struct cmd_token **argv,
-                    const char *xpath, bool no, int start_idx)
+                    const char *xpath_base, bool no, int start_idx)
 {
-       for (int i = start_idx; i < argc; i++)
+       char xpath[XPATH_MAXLEN];
+
+       for (int i = start_idx; i < argc; i++) {
+               snprintf(xpath, XPATH_MAXLEN, "%s[.='%s']", xpath_base,
+                        argv[i]->arg);
                nb_cli_enqueue_change(vty, xpath,
-                                     no ? NB_OP_DESTROY : NB_OP_CREATE,
-                                     argv[i]->arg);
+                                     no ? NB_OP_DESTROY : NB_OP_CREATE, NULL);
+       }
        return nb_cli_apply_changes(vty, NULL);
 }
 
@@ -3302,31 +3310,27 @@ DEFPY(isis_lfa_exclude_interface, isis_lfa_exclude_interface_cmd,
       "Exclude an interface from computation\n"
       "Interface name\n")
 {
+       char xpath[XPATH_MAXLEN];
+
        if (!level || strmatch(level, "level-1")) {
-               if (no) {
-                       nb_cli_enqueue_change(
-                               vty,
-                               "./frr-isisd:isis/fast-reroute/level-1/lfa/exclude-interface",
-                               NB_OP_DESTROY, ifname);
-               } else {
-                       nb_cli_enqueue_change(
-                               vty,
-                               "./frr-isisd:isis/fast-reroute/level-1/lfa/exclude-interface",
-                               NB_OP_CREATE, ifname);
-               }
+               snprintf(xpath, sizeof(xpath),
+                        "./frr-isisd:isis/fast-reroute/level-1/lfa/exclude-interface[.='%s']",
+                        ifname);
+
+               if (no)
+                       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+               else
+                       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
        }
        if (!level || strmatch(level, "level-2")) {
-               if (no) {
-                       nb_cli_enqueue_change(
-                               vty,
-                               "./frr-isisd:isis/fast-reroute/level-2/lfa/exclude-interface",
-                               NB_OP_DESTROY, ifname);
-               } else {
-                       nb_cli_enqueue_change(
-                               vty,
-                               "./frr-isisd:isis/fast-reroute/level-2/lfa/exclude-interface",
-                               NB_OP_CREATE, ifname);
-               }
+               snprintf(xpath, sizeof(xpath),
+                        "./frr-isisd:isis/fast-reroute/level-2/lfa/exclude-interface[.='%s']",
+                        ifname);
+
+               if (no)
+                       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+               else
+                       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
        }
 
        return nb_cli_apply_changes(vty, NULL);
index a831fc58b2af7fa9ba3333c016b34e8ad2aef1e4..949218332aa486925b663af84459bdb1cad47455 100644 (file)
@@ -695,35 +695,22 @@ static int dnode_create(struct nb_config *candidate, const char *xpath,
 
 int nb_candidate_edit(struct nb_config *candidate, const struct nb_node *nb_node,
                      enum nb_operation operation, const char *xpath,
-                     bool in_backend, const struct yang_data *previous,
+                     const struct yang_data *previous,
                      const struct yang_data *data)
 {
        struct lyd_node *dnode, *dep_dnode, *old_dnode;
-       char xpath_edit[XPATH_MAXLEN];
        char dep_xpath[XPATH_MAXLEN];
        struct lyd_node *parent = NULL;
        uint32_t options = 0;
        LY_ERR err;
 
-       /*
-        * Use special notation for leaf-lists (RFC 6020, section 9.13.5).
-        * if we are in a backend client this notation was already applied
-        * by mgmtd before sending to us.
-        */
-       if (!in_backend && nb_node->snode->nodetype == LYS_LEAFLIST &&
-           (operation == NB_OP_DESTROY || operation == NB_OP_DELETE))
-               snprintf(xpath_edit, sizeof(xpath_edit), "%s[.='%s']", xpath,
-                        data->value);
-       else
-               strlcpy(xpath_edit, xpath, sizeof(xpath_edit));
-
        switch (operation) {
        case NB_OP_CREATE:
        case NB_OP_MODIFY:
                options = LYD_NEW_PATH_UPDATE;
                fallthrough;
        case NB_OP_CREATE_EXCL:
-               err = dnode_create(candidate, xpath_edit, data->value, options,
+               err = dnode_create(candidate, xpath, data->value, options,
                                   &dnode);
                if (err) {
                        return err;
@@ -750,7 +737,7 @@ int nb_candidate_edit(struct nb_config *candidate, const struct nb_node *nb_node
                break;
        case NB_OP_DESTROY:
        case NB_OP_DELETE:
-               dnode = yang_dnode_get(candidate->dnode, xpath_edit);
+               dnode = yang_dnode_get(candidate->dnode, xpath);
                if (!dnode) {
                        if (operation == NB_OP_DELETE)
                                return NB_ERR;
@@ -768,12 +755,12 @@ int nb_candidate_edit(struct nb_config *candidate, const struct nb_node *nb_node
                lyd_free_tree(dnode);
                break;
        case NB_OP_REPLACE:
-               old_dnode = yang_dnode_get(candidate->dnode, xpath_edit);
+               old_dnode = yang_dnode_get(candidate->dnode, xpath);
                if (old_dnode) {
                        parent = lyd_parent(old_dnode);
                        lyd_unlink_tree(old_dnode);
                }
-               err = dnode_create(candidate, xpath_edit, data->value, options,
+               err = dnode_create(candidate, xpath, data->value, options,
                                   &dnode);
                if (!err && dnode && !old_dnode) {
                        /* create dependency if the node didn't exist */
@@ -908,8 +895,7 @@ void nb_candidate_edit_config_changes(struct nb_config *candidate_config,
                 * configuration.
                 */
                ret = nb_candidate_edit(candidate_config, nb_node,
-                                       change->operation, xpath, in_backend,
-                                       NULL, data);
+                                       change->operation, xpath, NULL, data);
                yang_data_free(data);
                if (ret != NB_OK) {
                        flog_warn(
index 0a6bc88921cf1854e167fb006bea8c72478f15fd..493e5ce703b1f44aaa513604ec9658bb193c3e17 100644 (file)
@@ -950,9 +950,6 @@ extern bool nb_is_operation_allowed(struct nb_node *nb_node,
  * xpath
  *    XPath of the configuration node being edited.
  *
- * in_backend
- *    Specify whether the changes are being applied in the backend or not.
- *
  * previous
  *    Previous value of the configuration node. Should be used only when the
  *    operation is NB_OP_MOVE, otherwise this parameter is ignored.
@@ -967,7 +964,7 @@ extern bool nb_is_operation_allowed(struct nb_node *nb_node,
 extern int nb_candidate_edit(struct nb_config *candidate,
                             const struct nb_node *nb_node,
                             enum nb_operation operation, const char *xpath,
-                            bool in_backend, const struct yang_data *previous,
+                            const struct yang_data *previous,
                             const struct yang_data *data);
 
 /*
index c866b0afb466000e606d9ed3490058bcfff8f6e7..8503d18002c7f47b95da8345b46688cf77328f95 100644 (file)
@@ -256,7 +256,7 @@ frr_confd_cdb_diff_iter(confd_hkeypath_t *kp, enum cdb_iter_op cdb_op,
        /* Edit the candidate configuration. */
        data = yang_data_new(xpath, value_str);
        ret = nb_candidate_edit(iter_args->candidate, nb_node, nb_op, xpath,
-                               false, NULL, data);
+                               NULL, data);
        yang_data_free(data);
        if (ret != NB_OK) {
                flog_warn(
index 050477af9177d0230ccf683b0a88a268ae881e6e..198d96e3811cd98e3ad9cc8425bda11b8c66d01f 100644 (file)
@@ -219,7 +219,7 @@ static int frr_sr_process_change(struct nb_config *candidate,
        sr_val_to_buff(sr_data, value_str, sizeof(value_str));
        data = yang_data_new(xpath, value_str);
 
-       ret = nb_candidate_edit(candidate, nb_node, nb_op, xpath, false, NULL, data);
+       ret = nb_candidate_edit(candidate, nb_node, nb_op, xpath, NULL, data);
        yang_data_free(data);
        if (ret != NB_OK) {
                flog_warn(
index 59addd48c0b8e5991954f9e65e8715e359c51e33..ee318d45e3d4dfef6a4a6b8687c67d8278863d05 100644 (file)
@@ -525,7 +525,9 @@ int pim_process_rp_cmd(struct vty *vty, const char *rp_str,
                       const char *group_str)
 {
        const char *vrfname;
-       char rp_group_xpath[XPATH_MAXLEN];
+       char group_xpath[XPATH_MAXLEN];
+       char rp_xpath[XPATH_MAXLEN];
+       int printed;
        int result = 0;
        struct prefix group;
        pim_addr rp_addr;
@@ -570,12 +572,18 @@ int pim_process_rp_cmd(struct vty *vty, const char *rp_str,
        if (vrfname == NULL)
                return CMD_WARNING_CONFIG_FAILED;
 
-       snprintf(rp_group_xpath, sizeof(rp_group_xpath),
-                FRR_PIM_STATIC_RP_XPATH, "frr-pim:pimd", "pim", vrfname,
-                FRR_PIM_AF_XPATH_VAL, rp_str);
-       strlcat(rp_group_xpath, "/group-list", sizeof(rp_group_xpath));
+       snprintf(rp_xpath, sizeof(rp_xpath), FRR_PIM_STATIC_RP_XPATH,
+                "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL, rp_str);
+       printed = snprintf(group_xpath, sizeof(group_xpath),
+                          "%s/group-list[.='%s']", rp_xpath, group_str);
+
+       if (printed >= (int)(sizeof(group_xpath))) {
+               vty_out(vty, "Xpath too long (%d > %u)", printed + 1,
+                       XPATH_MAXLEN);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
 
-       nb_cli_enqueue_change(vty, rp_group_xpath, NB_OP_CREATE, group_str);
+       nb_cli_enqueue_change(vty, group_xpath, NB_OP_CREATE, NULL);
 
        return nb_cli_apply_changes(vty, NULL);
 }
@@ -583,7 +591,6 @@ int pim_process_rp_cmd(struct vty *vty, const char *rp_str,
 int pim_process_no_rp_cmd(struct vty *vty, const char *rp_str,
                          const char *group_str)
 {
-       char group_list_xpath[XPATH_MAXLEN];
        char group_xpath[XPATH_MAXLEN];
        char rp_xpath[XPATH_MAXLEN];
        int printed;
@@ -596,18 +603,8 @@ int pim_process_no_rp_cmd(struct vty *vty, const char *rp_str,
 
        snprintf(rp_xpath, sizeof(rp_xpath), FRR_PIM_STATIC_RP_XPATH,
                 "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL, rp_str);
-
-       printed = snprintf(group_list_xpath, sizeof(group_list_xpath),
-                          "%s/group-list", rp_xpath);
-
-       if (printed >= (int)(sizeof(group_list_xpath))) {
-               vty_out(vty, "Xpath too long (%d > %u)", printed + 1,
-                       XPATH_MAXLEN);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       printed = snprintf(group_xpath, sizeof(group_xpath), "%s[.='%s']",
-                          group_list_xpath, group_str);
+       printed = snprintf(group_xpath, sizeof(group_xpath),
+                          "%s/group-list[.='%s']", rp_xpath, group_str);
 
        if (printed >= (int)(sizeof(group_xpath))) {
                vty_out(vty, "Xpath too long (%d > %u)", printed + 1,
@@ -624,8 +621,7 @@ int pim_process_no_rp_cmd(struct vty *vty, const char *rp_str,
        if (yang_is_last_list_dnode(group_dnode))
                nb_cli_enqueue_change(vty, rp_xpath, NB_OP_DESTROY, NULL);
        else
-               nb_cli_enqueue_change(vty, group_list_xpath, NB_OP_DESTROY,
-                                     group_str);
+               nb_cli_enqueue_change(vty, group_xpath, NB_OP_DESTROY, NULL);
 
        return nb_cli_apply_changes(vty, NULL);
 }
@@ -3407,6 +3403,8 @@ int pim_process_ssmpingd_cmd(struct vty *vty, enum nb_operation operation,
 {
        const char *vrfname;
        char ssmpingd_ip_xpath[XPATH_MAXLEN];
+       char ssmpingd_src_ip_xpath[XPATH_MAXLEN];
+       int printed;
 
        vrfname = pim_cli_get_vrf_name(vty);
        if (vrfname == NULL)
@@ -3415,10 +3413,16 @@ int pim_process_ssmpingd_cmd(struct vty *vty, enum nb_operation operation,
        snprintf(ssmpingd_ip_xpath, sizeof(ssmpingd_ip_xpath),
                 FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
                 FRR_PIM_AF_XPATH_VAL);
-       strlcat(ssmpingd_ip_xpath, "/ssm-pingd-source-ip",
-               sizeof(ssmpingd_ip_xpath));
+       printed = snprintf(ssmpingd_src_ip_xpath, sizeof(ssmpingd_src_ip_xpath),
+                          "%s/ssm-pingd-source-ip[.='%s']", ssmpingd_ip_xpath,
+                          src_str);
+       if (printed >= (int)sizeof(ssmpingd_src_ip_xpath)) {
+               vty_out(vty, "Xpath too long (%d > %u)", printed + 1,
+                       XPATH_MAXLEN);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
 
-       nb_cli_enqueue_change(vty, ssmpingd_ip_xpath, operation, src_str);
+       nb_cli_enqueue_change(vty, ssmpingd_src_ip_xpath, operation, NULL);
 
        return nb_cli_apply_changes(vty, NULL);
 }
index d4366d0186676ccb7233c2c2b0eb8e3b76c89ba7..3344ccf11fdee8192585492358589912e477d949 100644 (file)
@@ -273,8 +273,13 @@ DEFPY_YANG (rip_neighbor,
        "Specify a neighbor router\n"
        "Neighbor address\n")
 {
-       nb_cli_enqueue_change(vty, "./explicit-neighbor",
-                             no ? NB_OP_DESTROY : NB_OP_CREATE, neighbor_str);
+       char xpath[XPATH_MAXLEN];
+
+       snprintf(xpath, sizeof(xpath), "./explicit-neighbor[.='%s']",
+                neighbor_str);
+
+       nb_cli_enqueue_change(vty, xpath, no ? NB_OP_DESTROY : NB_OP_CREATE,
+                             NULL);
 
        return nb_cli_apply_changes(vty, NULL);
 }
@@ -295,8 +300,12 @@ DEFPY_YANG (rip_network_prefix,
        "Enable routing on an IP network\n"
        "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
 {
-       nb_cli_enqueue_change(vty, "./network",
-                             no ? NB_OP_DESTROY : NB_OP_CREATE, network_str);
+       char xpath[XPATH_MAXLEN];
+
+       snprintf(xpath, sizeof(xpath), "./network[.='%s']", network_str);
+
+       nb_cli_enqueue_change(vty, xpath, no ? NB_OP_DESTROY : NB_OP_CREATE,
+                             NULL);
 
        return nb_cli_apply_changes(vty, NULL);
 }
@@ -317,8 +326,12 @@ DEFPY_YANG (rip_network_if,
        "Enable routing on an IP network\n"
        "Interface name\n")
 {
-       nb_cli_enqueue_change(vty, "./interface",
-                             no ? NB_OP_DESTROY : NB_OP_CREATE, network);
+       char xpath[XPATH_MAXLEN];
+
+       snprintf(xpath, sizeof(xpath), "./interface[.='%s']", network);
+
+       nb_cli_enqueue_change(vty, xpath, no ? NB_OP_DESTROY : NB_OP_CREATE,
+                             NULL);
 
        return nb_cli_apply_changes(vty, NULL);
 }
@@ -412,17 +425,21 @@ DEFPY_YANG (rip_passive_interface,
        bool passive_default =
                yang_dnode_get_bool(vty->candidate_config->dnode, "%s%s",
                                    VTY_CURR_XPATH, "/passive-default");
+       char xpath[XPATH_MAXLEN];
+       enum nb_operation op;
 
        if (passive_default) {
-               nb_cli_enqueue_change(vty, "./non-passive-interface",
-                                     no ? NB_OP_CREATE : NB_OP_DESTROY,
-                                     ifname);
+               snprintf(xpath, sizeof(xpath),
+                        "./non-passive-interface[.='%s']", ifname);
+               op = no ? NB_OP_CREATE : NB_OP_DESTROY;
        } else {
-               nb_cli_enqueue_change(vty, "./passive-interface",
-                                     no ? NB_OP_DESTROY : NB_OP_CREATE,
-                                     ifname);
+               snprintf(xpath, sizeof(xpath), "./passive-interface[.='%s']",
+                        ifname);
+               op = no ? NB_OP_DESTROY : NB_OP_CREATE;
        }
 
+       nb_cli_enqueue_change(vty, xpath, op, NULL);
+
        return nb_cli_apply_changes(vty, NULL);
 }
 
@@ -495,8 +512,12 @@ DEFPY_YANG (rip_route,
        "RIP static route configuration\n"
        "IP prefix <network>/<length>\n")
 {
-       nb_cli_enqueue_change(vty, "./static-route",
-                             no ? NB_OP_DESTROY : NB_OP_CREATE, route_str);
+       char xpath[XPATH_MAXLEN];
+
+       snprintf(xpath, sizeof(xpath), "./static-route[.='%s']", route_str);
+
+       nb_cli_enqueue_change(vty, xpath, no ? NB_OP_DESTROY : NB_OP_CREATE,
+                             NULL);
 
        return nb_cli_apply_changes(vty, NULL);
 }
index 3212229ac6a6a527941ae2d94391c82f057feb65..ee81d0c7e589bcd7f5377136d0d62d95ac436709 100644 (file)
@@ -199,8 +199,12 @@ DEFPY_YANG (ripng_network_prefix,
        "RIPng enable on specified interface or network.\n"
        "IPv6 network\n")
 {
-       nb_cli_enqueue_change(vty, "./network",
-                             no ? NB_OP_DESTROY : NB_OP_CREATE, network_str);
+       char xpath[XPATH_MAXLEN];
+
+       snprintf(xpath, sizeof(xpath), "./network[.='%s']", network_str);
+
+       nb_cli_enqueue_change(vty, xpath, no ? NB_OP_DESTROY : NB_OP_CREATE,
+                             NULL);
 
        return nb_cli_apply_changes(vty, NULL);
 }
@@ -222,8 +226,12 @@ DEFPY_YANG (ripng_network_if,
        "RIPng enable on specified interface or network.\n"
        "Interface name\n")
 {
-       nb_cli_enqueue_change(vty, "./interface",
-                             no ? NB_OP_DESTROY : NB_OP_CREATE, network);
+       char xpath[XPATH_MAXLEN];
+
+       snprintf(xpath, sizeof(xpath), "./interface[.='%s']", network);
+
+       nb_cli_enqueue_change(vty, xpath, no ? NB_OP_DESTROY : NB_OP_CREATE,
+                             NULL);
 
        return nb_cli_apply_changes(vty, NULL);
 }
@@ -288,8 +296,12 @@ DEFPY_YANG (ripng_passive_interface,
        "Suppress routing updates on an interface\n"
        "Interface name\n")
 {
-       nb_cli_enqueue_change(vty, "./passive-interface",
-                             no ? NB_OP_DESTROY : NB_OP_CREATE, ifname);
+       char xpath[XPATH_MAXLEN];
+
+       snprintf(xpath, sizeof(xpath), "./passive-interface[.='%s']", ifname);
+
+       nb_cli_enqueue_change(vty, xpath, no ? NB_OP_DESTROY : NB_OP_CREATE,
+                             ifname);
 
        return nb_cli_apply_changes(vty, NULL);
 }
@@ -355,8 +367,12 @@ DEFPY_YANG (ripng_route,
        "Static route setup\n"
        "Set static RIPng route announcement\n")
 {
-       nb_cli_enqueue_change(vty, "./static-route",
-                             no ? NB_OP_DESTROY : NB_OP_CREATE, route_str);
+       char xpath[XPATH_MAXLEN];
+
+       snprintf(xpath, sizeof(xpath), "./static-route[.='%s']", route_str);
+
+       nb_cli_enqueue_change(vty, xpath, no ? NB_OP_DESTROY : NB_OP_CREATE,
+                             NULL);
 
        return nb_cli_apply_changes(vty, NULL);
 }
@@ -377,9 +393,13 @@ DEFPY_YANG (ripng_aggregate_address,
        "Set aggregate RIPng route announcement\n"
        "Aggregate network\n")
 {
-       nb_cli_enqueue_change(vty, "./aggregate-address",
-                             no ? NB_OP_DESTROY : NB_OP_CREATE,
-                             aggregate_address_str);
+       char xpath[XPATH_MAXLEN];
+
+       snprintf(xpath, sizeof(xpath), "./aggregate-address[.='%s']",
+                aggregate_address_str);
+
+       nb_cli_enqueue_change(vty, xpath, no ? NB_OP_DESTROY : NB_OP_CREATE,
+                             NULL);
 
        return nb_cli_apply_changes(vty, NULL);
 }
index bbdf48b326273dc463fed891805a09b35564a3a5..fd6cbc8b67406d8e5250fe3b812eba9728d01ee3 100644 (file)
@@ -200,7 +200,11 @@ DEFPY_YANG(vrrp_ip,
       VRRP_IP_STR)
 {
        int op = no ? NB_OP_DESTROY : NB_OP_CREATE;
-       nb_cli_enqueue_change(vty, "./v4/virtual-address", op, ip_str);
+       char xpath[XPATH_MAXLEN];
+
+       snprintf(xpath, sizeof(xpath), "./v4/virtual-address[.='%s']", ip_str);
+
+       nb_cli_enqueue_change(vty, xpath, op, NULL);
 
        return nb_cli_apply_changes(vty, VRRP_XPATH_ENTRY, vrid);
 }
@@ -228,7 +232,11 @@ DEFPY_YANG(vrrp_ip6,
       VRRP_IP_STR)
 {
        int op = no ? NB_OP_DESTROY : NB_OP_CREATE;
-       nb_cli_enqueue_change(vty, "./v6/virtual-address", op, ipv6_str);
+       char xpath[XPATH_MAXLEN];
+
+       snprintf(xpath, sizeof(xpath), "./v6/virtual-address[.='%s']", ipv6_str);
+
+       nb_cli_enqueue_change(vty, xpath, op, NULL);
 
        return nb_cli_apply_changes(vty, VRRP_XPATH_ENTRY, vrid);
 }
index 4c6fc8c36aee3f5ae287236971447a571442e888..9f160020a8155dceda0dfa507268d0fcf7c0d487 100644 (file)
@@ -4701,12 +4701,16 @@ DEFUN (no_link_params_use_bw,
 }
 
 static int ag_change(struct vty *vty, int argc, struct cmd_token **argv,
-                    const char *xpath, bool no, int start_idx)
+                    const char *xpath_base, bool no, int start_idx)
 {
-       for (int i = start_idx; i < argc; i++)
+       char xpath[XPATH_MAXLEN];
+
+       for (int i = start_idx; i < argc; i++) {
+               snprintf(xpath, XPATH_MAXLEN, "%s[.='%s']", xpath_base,
+                        argv[i]->arg);
                nb_cli_enqueue_change(vty, xpath,
-                                     no ? NB_OP_DESTROY : NB_OP_CREATE,
-                                     argv[i]->arg);
+                                     no ? NB_OP_DESTROY : NB_OP_CREATE, NULL);
+       }
        return nb_cli_apply_changes(vty, NULL);
 }