]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: North-bound implementation for bgp rmaps 7419/head
authorSarita Patra <saritap@vmware.com>
Fri, 30 Oct 2020 07:45:43 +0000 (00:45 -0700)
committerIgor Ryzhov <iryzhov@nfware.com>
Tue, 30 Mar 2021 19:59:30 +0000 (22:59 +0300)
This commit introduces the implementation for the north-bound
callbacks for the bgp-specific route-map match and set clauses.

Signed-off-by: NaveenThanikachalam <nthanikachal@vmware.com>
Signed-off-by: Sarita Patra <saritap@vmware.com>
bgpd/bgp_main.c
bgpd/bgp_routemap.c
bgpd/bgp_routemap_nb.c [new file with mode: 0644]
bgpd/bgp_routemap_nb.h [new file with mode: 0644]
bgpd/bgp_routemap_nb_config.c [new file with mode: 0644]
bgpd/bgp_rpki.c
bgpd/subdir.am

index 2ddafd9a0c2dafca41900eb2986cb208f61d4a7d..ea74a82cec5576ef15561eadc590d488dd47da48 100644 (file)
@@ -65,6 +65,7 @@
 #include "bgpd/bgp_nb.h"
 #include "bgpd/bgp_evpn_mh.h"
 #include "bgpd/bgp_nht.h"
+#include "bgpd/bgp_routemap_nb.h"
 
 #ifdef ENABLE_BGP_VNC
 #include "bgpd/rfapi/rfapi_backend.h"
@@ -388,6 +389,7 @@ static const struct frr_yang_module_info *const bgpd_yang_modules[] = {
        &frr_route_map_info,
        &frr_routing_info,
        &frr_vrf_info,
+       &frr_bgp_route_map_info,
 };
 
 FRR_DAEMON_INFO(bgpd, BGP, .vty_port = BGP_VTY_PORT,
index b7f3289ffcd9cb5d2806d22fe66cd0fd7608e803..a43b76da72a41679185308b97eff149aabd76645 100644 (file)
@@ -40,6 +40,7 @@
 #include "queue.h"
 #include "frrstr.h"
 #include "network.h"
+#include "lib/northbound_cli.h"
 
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_table.h"
@@ -3429,81 +3430,6 @@ static const struct route_map_rule_cmd route_set_originator_id_cmd = {
        route_set_originator_id_free,
 };
 
-/* Add bgp route map rule. */
-static int bgp_route_match_add(struct vty *vty, const char *command,
-                              const char *arg, route_map_event_t type)
-{
-       VTY_DECLVAR_CONTEXT(route_map_index, index);
-       int retval = CMD_SUCCESS;
-       enum rmap_compile_rets ret;
-
-       ret = route_map_add_match(index, command, arg, type);
-       switch (ret) {
-       case RMAP_RULE_MISSING:
-               vty_out(vty, "%% BGP Can't find rule.\n");
-               retval = CMD_WARNING_CONFIG_FAILED;
-               break;
-       case RMAP_COMPILE_ERROR:
-               vty_out(vty, "%% BGP Argument is malformed.\n");
-               retval = CMD_WARNING_CONFIG_FAILED;
-               break;
-       case RMAP_COMPILE_SUCCESS:
-               /*
-                * Intentionally doing nothing here.
-                */
-               break;
-       }
-
-       return retval;
-}
-
-/* Delete bgp route map rule. */
-static int bgp_route_match_delete(struct vty *vty, const char *command,
-                                 const char *arg, route_map_event_t type)
-{
-       VTY_DECLVAR_CONTEXT(route_map_index, index);
-       enum rmap_compile_rets ret;
-       int retval = CMD_SUCCESS;
-       char *dep_name = NULL;
-       const char *tmpstr;
-       char *rmap_name = NULL;
-
-       if (type != RMAP_EVENT_MATCH_DELETED) {
-               /* ignore the mundane, the types without any dependency */
-               if (arg == NULL) {
-                       if ((tmpstr = route_map_get_match_arg(index, command))
-                           != NULL)
-                               dep_name =
-                                       XSTRDUP(MTYPE_ROUTE_MAP_RULE, tmpstr);
-               } else {
-                       dep_name = XSTRDUP(MTYPE_ROUTE_MAP_RULE, arg);
-               }
-               rmap_name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, index->map->name);
-       }
-
-       ret = route_map_delete_match(index, command, dep_name, type);
-       switch (ret) {
-       case RMAP_RULE_MISSING:
-               vty_out(vty, "%% BGP Can't find rule.\n");
-               retval = CMD_WARNING_CONFIG_FAILED;
-               break;
-       case RMAP_COMPILE_ERROR:
-               vty_out(vty, "%% BGP Argument is malformed.\n");
-               retval = CMD_WARNING_CONFIG_FAILED;
-               break;
-       case RMAP_COMPILE_SUCCESS:
-               /*
-                * Nothing to do here
-                */
-               break;
-       }
-
-       XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
-       XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
-
-       return retval;
-}
-
 /*
  * This is the workhorse routine for processing in/out routemap
  * modifications.
@@ -3914,29 +3840,40 @@ static void bgp_route_map_event(const char *rmap_name)
        route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);
 }
 
-DEFUN (match_mac_address,
-       match_mac_address_cmd,
-       "match mac address WORD",
-       MATCH_STR
-       "mac address\n"
-       "Match address of route\n"
-       "MAC Access-list name\n")
+DEFUN_YANG (match_mac_address,
+           match_mac_address_cmd,
+           "match mac address WORD",
+           MATCH_STR
+           "mac address\n"
+           "Match address of route\n"
+           "MAC Access-list name\n")
 {
-       return bgp_route_match_add(vty, "mac address", argv[3]->arg,
-                                  RMAP_EVENT_FILTER_ADDED);
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:mac-address-list']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-match-condition/frr-bgp-route-map:list-name", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[3]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_match_mac_address,
-       no_match_mac_address_cmd,
-       "no match mac address WORD",
-       NO_STR
-       MATCH_STR
-       "mac\n"
-       "Match address of route\n"
-       "MAC acess-list name\n")
+DEFUN_YANG (no_match_mac_address,
+           no_match_mac_address_cmd,
+           "no match mac address WORD",
+           NO_STR
+           MATCH_STR
+           "mac\n"
+           "Match address of route\n"
+           "MAC acess-list name\n")
 {
-       return bgp_route_match_delete(vty, "mac address", argv[4]->arg,
-                                     RMAP_EVENT_FILTER_DELETED);
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:mac-address-list']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 /*
@@ -3963,241 +3900,377 @@ static const char *parse_evpn_rt_type(const char *num_rt_type)
        return num_rt_type;
 }
 
-DEFUN (match_evpn_route_type,
-       match_evpn_route_type_cmd,
-       "match evpn route-type <macip|2|multicast|3|prefix|5>",
-       MATCH_STR
-       EVPN_HELP_STR
-       EVPN_TYPE_HELP_STR
-       EVPN_TYPE_2_HELP_STR
-       EVPN_TYPE_2_HELP_STR
-       EVPN_TYPE_3_HELP_STR
-       EVPN_TYPE_3_HELP_STR
-       EVPN_TYPE_5_HELP_STR
-       EVPN_TYPE_5_HELP_STR)
-{
-       return bgp_route_match_add(vty, "evpn route-type",
-                                  parse_evpn_rt_type(argv[3]->arg),
-                                  RMAP_EVENT_MATCH_ADDED);
-}
-
-DEFUN (no_match_evpn_route_type,
-       no_match_evpn_route_type_cmd,
-       "no match evpn route-type <macip|2|multicast|3|prefix|5>",
-       NO_STR
-       MATCH_STR
-       EVPN_HELP_STR
-       EVPN_TYPE_HELP_STR
-       EVPN_TYPE_2_HELP_STR
-       EVPN_TYPE_2_HELP_STR
-       EVPN_TYPE_3_HELP_STR
-       EVPN_TYPE_3_HELP_STR
-       EVPN_TYPE_5_HELP_STR
-       EVPN_TYPE_5_HELP_STR)
+DEFUN_YANG (match_evpn_route_type,
+           match_evpn_route_type_cmd,
+           "match evpn route-type <macip|2|multicast|3|prefix|5>",
+           MATCH_STR
+           EVPN_HELP_STR
+           EVPN_TYPE_HELP_STR
+           EVPN_TYPE_2_HELP_STR
+           EVPN_TYPE_2_HELP_STR
+           EVPN_TYPE_3_HELP_STR
+           EVPN_TYPE_3_HELP_STR
+           EVPN_TYPE_5_HELP_STR
+           EVPN_TYPE_5_HELP_STR)
 {
-       return bgp_route_match_delete(vty, "evpn route-type",
-                                     parse_evpn_rt_type(argv[4]->arg),
-                                     RMAP_EVENT_MATCH_DELETED);
-}
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:evpn-route-type']";
+       char xpath_value[XPATH_MAXLEN];
 
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-match-condition/frr-bgp-route-map:evpn-route-type",
+                xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                             parse_evpn_rt_type(argv[3]->arg));
 
-DEFUN (match_evpn_vni,
-       match_evpn_vni_cmd,
-       "match evpn vni " CMD_VNI_RANGE,
-       MATCH_STR
-       EVPN_HELP_STR
-       "Match VNI\n"
-       "VNI ID\n")
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFUN_YANG (no_match_evpn_route_type,
+           no_match_evpn_route_type_cmd,
+           "no match evpn route-type <macip|2|multicast|3|prefix|5>",
+           NO_STR
+           MATCH_STR
+           EVPN_HELP_STR
+           EVPN_TYPE_HELP_STR
+           EVPN_TYPE_2_HELP_STR
+           EVPN_TYPE_2_HELP_STR
+           EVPN_TYPE_3_HELP_STR
+           EVPN_TYPE_3_HELP_STR
+           EVPN_TYPE_5_HELP_STR
+           EVPN_TYPE_5_HELP_STR)
 {
-       return bgp_route_match_add(vty, "evpn vni", argv[3]->arg,
-                                  RMAP_EVENT_MATCH_ADDED);
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:evpn-route-type']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_match_evpn_vni,
-       no_match_evpn_vni_cmd,
-       "no match evpn vni " CMD_VNI_RANGE,
-       NO_STR
-       MATCH_STR
-       EVPN_HELP_STR
-       "Match VNI\n"
-       "VNI ID\n")
+
+DEFUN_YANG (match_evpn_vni,
+           match_evpn_vni_cmd,
+           "match evpn vni " CMD_VNI_RANGE,
+           MATCH_STR
+           EVPN_HELP_STR
+           "Match VNI\n"
+           "VNI ID\n")
+{
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:evpn-vni']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-match-condition/frr-bgp-route-map:evpn-vni", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[3]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFUN_YANG (no_match_evpn_vni,
+           no_match_evpn_vni_cmd,
+           "no match evpn vni " CMD_VNI_RANGE,
+           NO_STR
+           MATCH_STR
+           EVPN_HELP_STR
+           "Match VNI\n"
+           "VNI ID\n")
 {
-       return bgp_route_match_delete(vty, "evpn vni", argv[4]->arg,
-                                     RMAP_EVENT_MATCH_DELETED);
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:evpn-vni']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-match-condition/frr-bgp-route-map:evpn-vni", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY, argv[3]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (match_evpn_default_route,
-       match_evpn_default_route_cmd,
-       "match evpn default-route",
-       MATCH_STR
-       EVPN_HELP_STR
-       "default EVPN type-5 route\n")
+DEFUN_YANG (match_evpn_default_route,
+           match_evpn_default_route_cmd,
+           "match evpn default-route",
+           MATCH_STR
+           EVPN_HELP_STR
+           "default EVPN type-5 route\n")
 {
-       return bgp_route_match_add(vty, "evpn default-route", NULL,
-                                  RMAP_EVENT_MATCH_ADDED);
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:evpn-default-route']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-match-condition/frr-bgp-route-map:evpn-default-route",
+                xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_match_evpn_default_route,
-       no_match_evpn_default_route_cmd,
-       "no match evpn default-route",
-       NO_STR
-       MATCH_STR
-       EVPN_HELP_STR
-       "default EVPN type-5 route\n")
+DEFUN_YANG (no_match_evpn_default_route,
+           no_match_evpn_default_route_cmd,
+           "no match evpn default-route",
+           NO_STR
+           MATCH_STR
+           EVPN_HELP_STR
+           "default EVPN type-5 route\n")
 {
-       return bgp_route_match_delete(vty, "evpn default-route", NULL,
-                                     RMAP_EVENT_MATCH_DELETED);
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:evpn-default-route']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (match_evpn_rd,
-       match_evpn_rd_cmd,
-       "match evpn rd ASN:NN_OR_IP-ADDRESS:NN",
-       MATCH_STR
-       EVPN_HELP_STR
-       "Route Distinguisher\n"
-       "ASN:XX or A.B.C.D:XX\n")
+DEFUN_YANG (match_evpn_rd,
+           match_evpn_rd_cmd,
+           "match evpn rd ASN:NN_OR_IP-ADDRESS:NN",
+           MATCH_STR
+           EVPN_HELP_STR
+           "Route Distinguisher\n"
+           "ASN:XX or A.B.C.D:XX\n")
 {
-       return bgp_route_match_add(vty, "evpn rd", argv[3]->arg,
-                                  RMAP_EVENT_MATCH_ADDED);
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:evpn-rd']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(
+               xpath_value, sizeof(xpath_value),
+               "%s/rmap-match-condition/frr-bgp-route-map:route-distinguisher",
+               xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[3]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_match_evpn_rd,
-       no_match_evpn_rd_cmd,
-       "no match evpn rd ASN:NN_OR_IP-ADDRESS:NN",
-       NO_STR
-       MATCH_STR
-       EVPN_HELP_STR
-       "Route Distinguisher\n"
-       "ASN:XX or A.B.C.D:XX\n")
+DEFUN_YANG (no_match_evpn_rd,
+           no_match_evpn_rd_cmd,
+           "no match evpn rd ASN:NN_OR_IP-ADDRESS:NN",
+           NO_STR
+           MATCH_STR
+           EVPN_HELP_STR
+           "Route Distinguisher\n"
+           "ASN:XX or A.B.C.D:XX\n")
 {
-       return bgp_route_match_delete(vty, "evpn rd", argv[4]->arg,
-                                     RMAP_EVENT_MATCH_DELETED);
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:evpn-rd']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFPY(match_vrl_source_vrf,
+DEFPY_YANG(match_vrl_source_vrf,
       match_vrl_source_vrf_cmd,
       "match source-vrf NAME$vrf_name",
       MATCH_STR
       "source vrf\n"
       "The VRF name\n")
 {
-       return bgp_route_match_add(vty, "source-vrf", vrf_name,
-                                  RMAP_EVENT_MATCH_ADDED);
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:source-vrf']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-match-condition/frr-bgp-route-map:source-vrf", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, vrf_name);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFPY(no_match_vrl_source_vrf,
+DEFPY_YANG(no_match_vrl_source_vrf,
       no_match_vrl_source_vrf_cmd,
       "no match source-vrf NAME$vrf_name",
-      NO_STR
-      MATCH_STR
+      NO_STR MATCH_STR
       "source vrf\n"
       "The VRF name\n")
 {
-       return bgp_route_match_delete(vty, "source-vrf", vrf_name,
-                                     RMAP_EVENT_MATCH_DELETED);
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:source-vrf']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (match_peer,
+DEFPY_YANG (match_peer,
        match_peer_cmd,
-       "match peer <A.B.C.D|X:X::X:X|WORD>",
+       "match peer <A.B.C.D$addrv4|X:X::X:X$addrv6|WORD$intf>",
        MATCH_STR
        "Match peer address\n"
        "IP address of peer\n"
        "IPv6 address of peer\n"
        "Interface name of peer\n")
 {
-       int idx_ip = 2;
-       return bgp_route_match_add(vty, "peer", argv[idx_ip]->arg,
-                                  RMAP_EVENT_MATCH_ADDED);
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:peer']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+       if (addrv4_str) {
+               snprintf(
+                       xpath_value, sizeof(xpath_value),
+                       "%s/rmap-match-condition/frr-bgp-route-map:peer-ipv4-address",
+                       xpath);
+               nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                                     addrv4_str);
+       } else if (addrv6_str) {
+               snprintf(
+                       xpath_value, sizeof(xpath_value),
+                       "%s/rmap-match-condition/frr-bgp-route-map:peer-ipv6-address",
+                       xpath);
+               nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                                     addrv6_str);
+       } else {
+               snprintf(
+                       xpath_value, sizeof(xpath_value),
+                       "%s/rmap-match-condition/frr-bgp-route-map:peer-interface",
+                       xpath);
+               nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, intf);
+       }
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (match_peer_local,
-       match_peer_local_cmd,
-        "match peer local",
-        MATCH_STR
-        "Match peer address\n"
-        "Static or Redistributed routes\n")
+DEFUN_YANG (match_peer_local,
+           match_peer_local_cmd,
+           "match peer local",
+           MATCH_STR
+           "Match peer address\n"
+           "Static or Redistributed routes\n")
 {
-       return bgp_route_match_add(vty, "peer", "local",
-                                  RMAP_EVENT_MATCH_DELETED);
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:peer']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-match-condition/frr-bgp-route-map:peer-local", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, "true");
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_match_peer,
-       no_match_peer_cmd,
-       "no match peer [<local|A.B.C.D|X:X::X:X|WORD>]",
-       NO_STR
-       MATCH_STR
-       "Match peer address\n"
-       "Static or Redistributed routes\n"
-       "IP address of peer\n"
-       "IPv6 address of peer\n"
-       "Interface name of peer\n")
+DEFUN_YANG (no_match_peer,
+           no_match_peer_cmd,
+           "no match peer [<local|A.B.C.D|X:X::X:X|WORD>]",
+           NO_STR
+           MATCH_STR
+           "Match peer address\n"
+           "Static or Redistributed routes\n"
+           "IP address of peer\n"
+           "IPv6 address of peer\n"
+           "Interface name of peer\n")
 {
-       int idx_peer = 3;
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:peer']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
 
-       if (argc <= idx_peer)
-               return bgp_route_match_delete(vty, "peer", NULL,
-                                             RMAP_EVENT_MATCH_DELETED);
-       return bgp_route_match_delete(vty, "peer", argv[idx_peer]->arg,
-                                     RMAP_EVENT_MATCH_DELETED);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 #ifdef HAVE_SCRIPTING
-DEFUN (match_script,
-       match_script_cmd,
-       "[no] match script WORD",
-       NO_STR
-       MATCH_STR
-       "Execute script to determine match\n"
-       "The script name to run, without .lua; e.g. 'myroutemap' to run myroutemap.lua\n")
+DEFUN_YANG (match_script,
+           match_script_cmd,
+           "[no] match script WORD",
+           NO_STR
+           MATCH_STR
+           "Execute script to determine match\n"
+           "The script name to run, without .lua; e.g. 'myroutemap' to run myroutemap.lua\n")
 {
        bool no = strmatch(argv[0]->text, "no");
        int i = 0;
        argv_find(argv, argc, "WORD", &i);
        const char *script = argv[i]->arg;
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:match-script']";
+       char xpath_value[XPATH_MAXLEN];
 
        if (no) {
-               return bgp_route_match_delete(vty, "script", script,
-                                             RMAP_EVENT_FILTER_DELETED);
-       } else {
-               return bgp_route_match_add(vty, "script", script,
-                                          RMAP_EVENT_FILTER_ADDED);
+               nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+               snprintf(xpath_value, sizeof(xpath_value),
+                        "%s/rmap-match-condition/frr-bgp-route-map:script",
+                        xpath);
+               nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY,
+                                     script);
+
+               return nb_cli_apply_changes(vty, NULL);
        }
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                       "%s/rmap-match-condition/frr-bgp-route-map:script",
+                       xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                       script);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 #endif /* HAVE_SCRIPTING */
 
 /* match probability */
-DEFUN (match_probability,
-       match_probability_cmd,
-       "match probability (0-100)",
-       MATCH_STR
-       "Match portion of routes defined by percentage value\n"
-       "Percentage of routes\n")
+DEFUN_YANG (match_probability,
+           match_probability_cmd,
+           "match probability (0-100)",
+           MATCH_STR
+           "Match portion of routes defined by percentage value\n"
+           "Percentage of routes\n")
 {
        int idx_number = 2;
-       return bgp_route_match_add(vty, "probability", argv[idx_number]->arg,
-                                  RMAP_EVENT_MATCH_ADDED);
+
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:probability']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-match-condition/frr-bgp-route-map:probability",
+                xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                             argv[idx_number]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 
-DEFUN (no_match_probability,
-       no_match_probability_cmd,
-       "no match probability [(1-99)]",
-       NO_STR
-       MATCH_STR
-       "Match portion of routes defined by percentage value\n"
-       "Percentage of routes\n")
+DEFUN_YANG (no_match_probability,
+           no_match_probability_cmd,
+           "no match probability [(1-99)]",
+           NO_STR
+           MATCH_STR
+           "Match portion of routes defined by percentage value\n"
+           "Percentage of routes\n")
 {
        int idx_number = 3;
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:probability']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
        if (argc <= idx_number)
-               return bgp_route_match_delete(vty, "probability", NULL,
-                                             RMAP_EVENT_MATCH_DELETED);
-       return bgp_route_match_delete(vty, "probability", argv[idx_number]->arg,
-                                     RMAP_EVENT_MATCH_DELETED);
+               return nb_cli_apply_changes(vty, NULL);
+
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-match-condition/frr-bgp-route-map:probability",
+                xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY,
+                             argv[idx_number]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 
-DEFUN (match_ip_route_source,
+DEFPY_YANG (match_ip_route_source,
        match_ip_route_source_cmd,
        "match ip route-source <(1-199)|(1300-2699)|WORD>",
        MATCH_STR
@@ -4207,102 +4280,134 @@ DEFUN (match_ip_route_source,
        "IP access-list number (expanded range)\n"
        "IP standard access-list name\n")
 {
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:ip-route-source']";
+       char xpath_value[XPATH_MAXLEN + 32];
        int idx_acl = 3;
-       return bgp_route_match_add(vty, "ip route-source", argv[idx_acl]->arg,
-                                  RMAP_EVENT_FILTER_ADDED);
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                       "%s/rmap-match-condition/frr-bgp-route-map:list-name",
+                       xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                             argv[idx_acl]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 
-DEFUN (no_match_ip_route_source,
-       no_match_ip_route_source_cmd,
-       "no match ip route-source [<(1-199)|(1300-2699)|WORD>]",
-       NO_STR
-       MATCH_STR
-       IP_STR
-       "Match advertising source address of route\n"
-       "IP access-list number\n"
-       "IP access-list number (expanded range)\n"
-       "IP standard access-list name\n")
+DEFUN_YANG (no_match_ip_route_source,
+           no_match_ip_route_source_cmd,
+           "no match ip route-source [<(1-199)|(1300-2699)|WORD>]",
+           NO_STR
+           MATCH_STR
+           IP_STR
+           "Match advertising source address of route\n"
+           "IP access-list number\n"
+           "IP access-list number (expanded range)\n"
+           "IP standard access-list name\n")
 {
-       int idx_number = 4;
-       if (argc <= idx_number)
-               return bgp_route_match_delete(vty, "ip route-source", NULL,
-                                             RMAP_EVENT_FILTER_DELETED);
-       return bgp_route_match_delete(vty, "ip route-source",
-                                     argv[idx_number]->arg,
-                                     RMAP_EVENT_FILTER_DELETED);
-}
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:ip-route-source']";
 
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
+}
 
-DEFUN (match_ip_route_source_prefix_list,
-       match_ip_route_source_prefix_list_cmd,
-       "match ip route-source prefix-list WORD",
-       MATCH_STR
-       IP_STR
-       "Match advertising source address of route\n"
-       "Match entries of prefix-lists\n"
-       "IP prefix-list name\n")
+DEFUN_YANG (match_ip_route_source_prefix_list,
+           match_ip_route_source_prefix_list_cmd,
+           "match ip route-source prefix-list WORD",
+           MATCH_STR
+           IP_STR
+           "Match advertising source address of route\n"
+           "Match entries of prefix-lists\n"
+           "IP prefix-list name\n")
 {
        int idx_word = 4;
-       return bgp_route_match_add(vty, "ip route-source prefix-list",
-                                  argv[idx_word]->arg, RMAP_EVENT_PLIST_ADDED);
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:ip-route-source-prefix-list']";
+       char xpath_value[XPATH_MAXLEN + 32];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-match-condition/frr-bgp-route-map:list-name", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                             argv[idx_word]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 
-DEFUN (no_match_ip_route_source_prefix_list,
-       no_match_ip_route_source_prefix_list_cmd,
-       "no match ip route-source prefix-list [WORD]",
-       NO_STR
-       MATCH_STR
-       IP_STR
-       "Match advertising source address of route\n"
-       "Match entries of prefix-lists\n"
-       "IP prefix-list name\n")
+DEFUN_YANG (no_match_ip_route_source_prefix_list,
+           no_match_ip_route_source_prefix_list_cmd,
+           "no match ip route-source prefix-list [WORD]",
+           NO_STR
+           MATCH_STR
+           IP_STR
+           "Match advertising source address of route\n"
+           "Match entries of prefix-lists\n"
+           "IP prefix-list name\n")
 {
-       int idx_word = 5;
-       if (argc <= idx_word)
-               return bgp_route_match_delete(vty,
-                                             "ip route-source prefix-list",
-                                             NULL, RMAP_EVENT_PLIST_DELETED);
-       return bgp_route_match_delete(vty, "ip route-source prefix-list",
-                                     argv[idx_word]->arg,
-                                     RMAP_EVENT_PLIST_DELETED);
-}
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:ip-route-source-prefix-list']";
 
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
+}
 
-DEFUN (match_local_pref,
-       match_local_pref_cmd,
-       "match local-preference (0-4294967295)",
-       MATCH_STR
-       "Match local-preference of route\n"
-       "Metric value\n")
+DEFUN_YANG (match_local_pref,
+           match_local_pref_cmd,
+           "match local-preference (0-4294967295)",
+           MATCH_STR
+           "Match local-preference of route\n"
+           "Metric value\n")
 {
        int idx_number = 2;
-       return bgp_route_match_add(vty, "local-preference",
-                                  argv[idx_number]->arg,
-                                  RMAP_EVENT_MATCH_ADDED);
+
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:match-local-preference']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-match-condition/frr-bgp-route-map:local-preference",
+                xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                             argv[idx_number]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 
-DEFUN (no_match_local_pref,
-       no_match_local_pref_cmd,
-       "no match local-preference [(0-4294967295)]",
-       NO_STR
-       MATCH_STR
-       "Match local preference of route\n"
-       "Local preference value\n")
+DEFUN_YANG (no_match_local_pref,
+           no_match_local_pref_cmd,
+           "no match local-preference [(0-4294967295)]",
+           NO_STR
+           MATCH_STR
+           "Match local preference of route\n"
+           "Local preference value\n")
 {
        int idx_localpref = 3;
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:match-local-preference']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
        if (argc <= idx_localpref)
-               return bgp_route_match_delete(vty, "local-preference", NULL,
-                                             RMAP_EVENT_MATCH_DELETED);
-       return bgp_route_match_delete(vty, "local-preference",
-                                     argv[idx_localpref]->arg,
-                                     RMAP_EVENT_MATCH_DELETED);
+               return nb_cli_apply_changes(vty, NULL);
+
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-match-condition/frr-bgp-route-map:local-preference",
+                xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY,
+                             argv[idx_localpref]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 
-DEFUN (match_community,
+DEFPY_YANG (match_community,
        match_community_cmd,
        "match community <(1-99)|(100-500)|WORD> [exact-match]",
        MATCH_STR
@@ -4312,478 +4417,608 @@ DEFUN (match_community,
        "Community-list name\n"
        "Do exact matching of communities\n")
 {
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:match-community']";
+       char xpath_value[XPATH_MAXLEN];
+       char xpath_match[XPATH_MAXLEN];
        int idx_comm_list = 2;
-       int ret;
-       char *argstr;
-       size_t argstr_len;
 
-       if (argc == 4) {
-               argstr_len = strlen(argv[idx_comm_list]->arg)
-                            + strlen("exact-match") + 2;
-               argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, argstr_len);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
 
-               snprintf(argstr, argstr_len, "%s exact-match",
-                        argv[idx_comm_list]->arg);
-       } else
-               argstr = argv[idx_comm_list]->arg;
-
-       ret = bgp_route_match_add(vty, "community", argstr,
-                                 RMAP_EVENT_CLIST_ADDED);
+       snprintf(
+               xpath_value, sizeof(xpath_value),
+               "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name",
+               xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[idx_comm_list]->arg);
 
-       if (argstr != argv[idx_comm_list]->arg)
-               XFREE(MTYPE_ROUTE_MAP_COMPILED, argstr);
-
-       return ret;
-}
-
-DEFUN (no_match_community,
-       no_match_community_cmd,
-       "no match community [<(1-99)|(100-500)|WORD> [exact-match]]",
-       NO_STR
-       MATCH_STR
-       "Match BGP community list\n"
-       "Community-list number (standard)\n"
-       "Community-list number (expanded)\n"
-       "Community-list name\n"
-       "Do exact matching of communities\n")
-{
-       return bgp_route_match_delete(vty, "community", NULL,
-                                     RMAP_EVENT_CLIST_DELETED);
-}
+       if (argc == 4) {
+               snprintf(
+                       xpath_match, sizeof(xpath_match),
+                       "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match",
+                       xpath);
+               nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY,
+                               "true");
+       } else {
+               snprintf(
+                       xpath_match, sizeof(xpath_match),
+                       "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match",
+                       xpath);
+               nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY,
+                               "false");
+       }
 
-DEFUN (match_lcommunity,
-       match_lcommunity_cmd,
-       "match large-community <(1-99)|(100-500)|WORD> [exact-match]",
-       MATCH_STR
-       "Match BGP large community list\n"
-       "Large Community-list number (standard)\n"
-       "Large Community-list number (expanded)\n"
-       "Large Community-list name\n"
-       "Do exact matching of communities\n")
-{
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFUN_YANG (no_match_community,
+           no_match_community_cmd,
+           "no match community [<(1-99)|(100-500)|WORD> [exact-match]]",
+           NO_STR
+           MATCH_STR
+           "Match BGP community list\n"
+           "Community-list number (standard)\n"
+           "Community-list number (expanded)\n"
+           "Community-list name\n"
+           "Do exact matching of communities\n")
+{
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:match-community']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY_YANG (match_lcommunity,
+           match_lcommunity_cmd,
+           "match large-community <(1-99)|(100-500)|WORD> [exact-match]",
+           MATCH_STR
+           "Match BGP large community list\n"
+           "Large Community-list number (standard)\n"
+           "Large Community-list number (expanded)\n"
+           "Large Community-list name\n"
+           "Do exact matching of communities\n")
+{
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:match-large-community']";
+       char xpath_value[XPATH_MAXLEN];
+       char xpath_match[XPATH_MAXLEN];
        int idx_lcomm_list = 2;
-       int ret;
-       char *argstr;
-       size_t argstr_len;
 
-       if (argc == 4) {
-               argstr_len = strlen(argv[idx_lcomm_list]->arg)
-                            + strlen("exact-match") + 2;
-               argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, argstr_len);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
 
-               snprintf(argstr, argstr_len, "%s exact-match",
-                        argv[idx_lcomm_list]->arg);
-       } else
-               argstr = argv[idx_lcomm_list]->arg;
+       snprintf(
+               xpath_value, sizeof(xpath_value),
+               "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name",
+               xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[idx_lcomm_list]->arg);
 
-       ret = bgp_route_match_add(vty, "large-community", argstr,
-                                  RMAP_EVENT_LLIST_ADDED);
-       if (argstr != argv[idx_lcomm_list]->arg)
-               XFREE(MTYPE_ROUTE_MAP_COMPILED, argstr);
+       if (argc == 4) {
+               snprintf(
+                       xpath_match, sizeof(xpath_match),
+                       "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match",
+                       xpath);
+               nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY,
+                               "true");
+       } else {
+               snprintf(
+                       xpath_match, sizeof(xpath_match),
+                       "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match",
+                       xpath);
+               nb_cli_enqueue_change(vty, xpath_match, NB_OP_MODIFY,
+                               "false");
+       }
 
-       return ret;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_match_lcommunity,
-       no_match_lcommunity_cmd,
-       "no match large-community [<(1-99)|(100-500)|WORD> [exact-match]]",
-       NO_STR
-       MATCH_STR
-       "Match BGP large community list\n"
-       "Large Community-list number (standard)\n"
-       "Large Community-list number (expanded)\n"
-       "Large Community-list name\n"
-       "Do exact matching of communities\n")
+DEFUN_YANG (no_match_lcommunity,
+           no_match_lcommunity_cmd,
+           "no match large-community [<(1-99)|(100-500)|WORD> [exact-match]]",
+           NO_STR
+           MATCH_STR
+           "Match BGP large community list\n"
+           "Large Community-list number (standard)\n"
+           "Large Community-list number (expanded)\n"
+           "Large Community-list name\n"
+           "Do exact matching of communities\n")
 {
-       return bgp_route_match_delete(vty, "large-community", NULL,
-                                     RMAP_EVENT_LLIST_DELETED);
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:match-large-community']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (match_ecommunity,
-       match_ecommunity_cmd,
-       "match extcommunity <(1-99)|(100-500)|WORD>",
-       MATCH_STR
-       "Match BGP/VPN extended community list\n"
-       "Extended community-list number (standard)\n"
-       "Extended community-list number (expanded)\n"
-       "Extended community-list name\n")
+DEFPY_YANG (match_ecommunity,
+           match_ecommunity_cmd,
+            "match extcommunity <(1-99)|(100-500)|WORD>",
+           MATCH_STR
+           "Match BGP/VPN extended community list\n"
+           "Extended community-list number (standard)\n"
+           "Extended community-list number (expanded)\n"
+           "Extended community-list name\n")
 {
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:match-extcommunity']";
+       char xpath_value[XPATH_MAXLEN];
        int idx_comm_list = 2;
-       return bgp_route_match_add(vty, "extcommunity",
-                                  argv[idx_comm_list]->arg,
-                                  RMAP_EVENT_ECLIST_ADDED);
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+       snprintf(
+               xpath_value, sizeof(xpath_value),
+               "%s/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name",
+               xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[idx_comm_list]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 
-DEFUN (no_match_ecommunity,
-       no_match_ecommunity_cmd,
-       "no match extcommunity [<(1-99)|(100-500)|WORD>]",
-       NO_STR
-       MATCH_STR
-       "Match BGP/VPN extended community list\n"
-       "Extended community-list number (standard)\n"
-       "Extended community-list number (expanded)\n"
-       "Extended community-list name\n")
+DEFUN_YANG (no_match_ecommunity,
+           no_match_ecommunity_cmd,
+           "no match extcommunity [<(1-99)|(100-500)|WORD>]",
+           NO_STR
+           MATCH_STR
+           "Match BGP/VPN extended community list\n"
+           "Extended community-list number (standard)\n"
+           "Extended community-list number (expanded)\n"
+           "Extended community-list name\n")
 {
-       return bgp_route_match_delete(vty, "extcommunity", NULL,
-                                     RMAP_EVENT_ECLIST_DELETED);
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:match-extcommunity']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 
-DEFUN (match_aspath,
-       match_aspath_cmd,
-       "match as-path WORD",
-       MATCH_STR
-       "Match BGP AS path list\n"
-       "AS path access-list name\n")
+DEFUN_YANG (match_aspath,
+           match_aspath_cmd,
+           "match as-path WORD",
+           MATCH_STR
+           "Match BGP AS path list\n"
+           "AS path access-list name\n")
 {
        int idx_word = 2;
-       return bgp_route_match_add(vty, "as-path", argv[idx_word]->arg,
-                                  RMAP_EVENT_ASLIST_ADDED);
+
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:as-path-list']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-match-condition/frr-bgp-route-map:list-name", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                             argv[idx_word]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 
-DEFUN (no_match_aspath,
-       no_match_aspath_cmd,
-       "no match as-path [WORD]",
-       NO_STR
-       MATCH_STR
-       "Match BGP AS path list\n"
-       "AS path access-list name\n")
+DEFUN_YANG (no_match_aspath,
+           no_match_aspath_cmd,
+           "no match as-path [WORD]",
+           NO_STR
+           MATCH_STR
+           "Match BGP AS path list\n"
+           "AS path access-list name\n")
 {
-       return bgp_route_match_delete(vty, "as-path", NULL,
-                                     RMAP_EVENT_ASLIST_DELETED);
-}
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:as-path-list']";
 
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
 
-DEFUN (match_origin,
-       match_origin_cmd,
-       "match origin <egp|igp|incomplete>",
-       MATCH_STR
-       "BGP origin code\n"
-       "remote EGP\n"
-       "local IGP\n"
-       "unknown heritage\n")
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFUN_YANG (match_origin,
+           match_origin_cmd,
+           "match origin <egp|igp|incomplete>",
+           MATCH_STR
+           "BGP origin code\n"
+           "remote EGP\n"
+           "local IGP\n"
+            "unknown heritage\n")
 {
        int idx_origin = 2;
+       const char *origin_type;
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:match-origin']";
+       char xpath_value[XPATH_MAXLEN];
+
        if (strncmp(argv[idx_origin]->arg, "igp", 2) == 0)
-               return bgp_route_match_add(vty, "origin", "igp",
-                                          RMAP_EVENT_MATCH_ADDED);
-       if (strncmp(argv[idx_origin]->arg, "egp", 1) == 0)
-               return bgp_route_match_add(vty, "origin", "egp",
-                                          RMAP_EVENT_MATCH_ADDED);
-       if (strncmp(argv[idx_origin]->arg, "incomplete", 2) == 0)
-               return bgp_route_match_add(vty, "origin", "incomplete",
-                                          RMAP_EVENT_MATCH_ADDED);
+               origin_type = "igp";
+       else if (strncmp(argv[idx_origin]->arg, "egp", 1) == 0)
+               origin_type = "egp";
+       else if (strncmp(argv[idx_origin]->arg, "incomplete", 2) == 0)
+               origin_type = "incomplete";
+       else {
+               vty_out(vty, "%% Invalid match origin type\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-match-condition/frr-bgp-route-map:origin", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, origin_type);
 
-       vty_out(vty, "%% Invalid match origin type\n");
-       return CMD_WARNING_CONFIG_FAILED;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 
-DEFUN (no_match_origin,
-       no_match_origin_cmd,
-       "no match origin [<egp|igp|incomplete>]",
-       NO_STR
-       MATCH_STR
-       "BGP origin code\n"
-       "remote EGP\n"
-       "local IGP\n"
-       "unknown heritage\n")
+DEFUN_YANG (no_match_origin,
+           no_match_origin_cmd,
+           "no match origin [<egp|igp|incomplete>]",
+           NO_STR
+           MATCH_STR
+           "BGP origin code\n"
+           "remote EGP\n"
+           "local IGP\n"
+           "unknown heritage\n")
 {
-       return bgp_route_match_delete(vty, "origin", NULL,
-                                     RMAP_EVENT_MATCH_DELETED);
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:match-origin']";
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (set_table_id,
-       set_table_id_cmd,
-       "set table (1-4294967295)",
-       SET_STR
-       "export route to non-main kernel table\n"
-       "Kernel routing table id\n")
+DEFUN_YANG (set_table_id,
+           set_table_id_cmd,
+           "set table (1-4294967295)",
+           SET_STR
+           "export route to non-main kernel table\n"
+           "Kernel routing table id\n")
 {
-       int idx_id = 2;
-
-       VTY_DECLVAR_CONTEXT(route_map_index, index);
-
-       return generic_set_add(vty, index, "table", argv[idx_id]->arg);
+       int idx_number = 2;
+       const char *xpath = "./set-action[action='frr-bgp-route-map:table']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:table", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                             argv[idx_number]->arg);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFUN_YANG (no_set_table_id,
+           no_set_table_id_cmd,
+           "no set table",
+           NO_STR
+           SET_STR
+           "export route to non-main kernel table\n")
+{
+       const char *xpath = "./set-action[action='frr-bgp-route-map:table']";
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFUN_YANG (set_ip_nexthop_peer,
+           set_ip_nexthop_peer_cmd,
+           "[no] set ip next-hop peer-address",
+           NO_STR
+           SET_STR
+           IP_STR
+           "Next hop address\n"
+           "Use peer address (for BGP only)\n")
+{
+       char xpath_value[XPATH_MAXLEN];
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:set-ipv4-nexthop']";
+
+       if (strmatch(argv[0]->text, "no"))
+               nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       else {
+               nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+               snprintf(xpath_value, sizeof(xpath_value),
+                        "%s/rmap-set-action/frr-bgp-route-map:ipv4-nexthop",
+                        xpath);
+               nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                                     "peer-address");
+       }
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_set_table_id,
-       no_set_table_id_cmd,
-       "no set table",
-       NO_STR
-       SET_STR
-       "export route to non-main kernel table\n")
+DEFUN_YANG (set_ip_nexthop_unchanged,
+           set_ip_nexthop_unchanged_cmd,
+           "[no] set ip next-hop unchanged",
+           NO_STR
+           SET_STR
+           IP_STR
+           "Next hop address\n"
+           "Don't modify existing Next hop address\n")
 {
-       VTY_DECLVAR_CONTEXT(route_map_index, index);
+       char xpath_value[XPATH_MAXLEN];
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:set-ipv4-nexthop']";
 
-       return generic_set_delete(vty, index, "table", NULL);
+       if (strmatch(argv[0]->text, "no"))
+               nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       else {
+               nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+               snprintf(xpath_value, sizeof(xpath_value),
+                        "%s/rmap-set-action/frr-bgp-route-map:ipv4-nexthop",
+                        xpath);
+               nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                                     "unchanged");
+       }
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (set_ip_nexthop_peer,
-       set_ip_nexthop_peer_cmd,
-       "[no] set ip next-hop peer-address",
-       NO_STR
-       SET_STR
-       IP_STR
-       "Next hop address\n"
-       "Use peer address (for BGP only)\n")
+DEFUN_YANG (set_distance,
+           set_distance_cmd,
+           "set distance (0-255)",
+           SET_STR
+           "BGP Administrative Distance to use\n"
+           "Distance value\n")
 {
-       int (*func)(struct vty *, struct route_map_index *, const char *,
-                   const char *) = strmatch(argv[0]->text, "no")
-                                           ? generic_set_delete
-                                           : generic_set_add;
+       int idx_number = 2;
+       const char *xpath = "./set-action[action='frr-bgp-route-map:distance']";
+       char xpath_value[XPATH_MAXLEN];
 
-       return func(vty, VTY_GET_CONTEXT(route_map_index), "ip next-hop",
-                   "peer-address");
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:distance", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                             argv[idx_number]->arg);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (set_ip_nexthop_unchanged,
-       set_ip_nexthop_unchanged_cmd,
-       "[no] set ip next-hop unchanged",
-       NO_STR
-       SET_STR
-       IP_STR
-       "Next hop address\n"
-       "Don't modify existing Next hop address\n")
+DEFUN_YANG (no_set_distance,
+           no_set_distance_cmd,
+           "no set distance [(0-255)]",
+           NO_STR SET_STR
+           "BGP Administrative Distance to use\n"
+           "Distance value\n")
 {
-       int (*func)(struct vty *, struct route_map_index *, const char *,
-                   const char *) = strmatch(argv[0]->text, "no")
-                                           ? generic_set_delete
-                                           : generic_set_add;
+       const char *xpath = "./set-action[action='frr-bgp-route-map:distance']";
 
-       return func(vty, VTY_GET_CONTEXT(route_map_index), "ip next-hop",
-                   "unchanged");
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (set_distance,
-       set_distance_cmd,
-       "set distance (0-255)",
-       SET_STR
-       "BGP Administrative Distance to use\n"
-       "Distance value\n")
+DEFUN_YANG (set_local_pref,
+           set_local_pref_cmd,
+           "set local-preference WORD",
+           SET_STR
+           "BGP local preference path attribute\n"
+           "Preference value (0-4294967295)\n")
 {
        int idx_number = 2;
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:set-local-preference']";
+       char xpath_value[XPATH_MAXLEN];
 
-       return generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                              "distance", argv[idx_number]->arg);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:local-pref", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                             argv[idx_number]->arg);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_set_distance,
-       no_set_distance_cmd,
-       "no set distance [(0-255)]",
-       NO_STR SET_STR
-       "BGP Administrative Distance to use\n"
-       "Distance value\n")
+DEFUN_YANG (no_set_local_pref,
+           no_set_local_pref_cmd,
+           "no set local-preference [WORD]",
+           NO_STR
+           SET_STR
+           "BGP local preference path attribute\n"
+           "Preference value (0-4294967295)\n")
 {
-       return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                 "distance", NULL);
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:set-local-preference']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (set_local_pref,
-       set_local_pref_cmd,
-       "set local-preference WORD",
-       SET_STR
-       "BGP local preference path attribute\n"
-       "Preference value (0-4294967295)\n")
+DEFUN_YANG (set_weight,
+           set_weight_cmd,
+           "set weight (0-4294967295)",
+           SET_STR
+           "BGP weight for routing table\n"
+           "Weight value\n")
 {
        int idx_number = 2;
-       return generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                              "local-preference", argv[idx_number]->arg);
-}
-
+       const char *xpath = "./set-action[action='frr-bgp-route-map:weight']";
+       char xpath_value[XPATH_MAXLEN];
 
-DEFUN (no_set_local_pref,
-       no_set_local_pref_cmd,
-       "no set local-preference [WORD]",
-       NO_STR
-       SET_STR
-       "BGP local preference path attribute\n"
-       "Preference value (0-4294967295)\n")
-{
-       int idx_localpref = 3;
-       if (argc <= idx_localpref)
-               return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                         "local-preference", NULL);
-       return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                 "local-preference", argv[idx_localpref]->arg);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:weight", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                             argv[idx_number]->arg);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-
-DEFUN (set_weight,
-       set_weight_cmd,
-       "set weight (0-4294967295)",
-       SET_STR
-       "BGP weight for routing table\n"
-       "Weight value\n")
+DEFUN_YANG (no_set_weight,
+           no_set_weight_cmd,
+           "no set weight [(0-4294967295)]",
+           NO_STR
+           SET_STR
+           "BGP weight for routing table\n"
+           "Weight value\n")
 {
-       int idx_number = 2;
-       return generic_set_add(vty, VTY_GET_CONTEXT(route_map_index), "weight",
-                              argv[idx_number]->arg);
-}
+       const char *xpath = "./set-action[action='frr-bgp-route-map:weight']";
 
-
-DEFUN (no_set_weight,
-       no_set_weight_cmd,
-       "no set weight [(0-4294967295)]",
-       NO_STR
-       SET_STR
-       "BGP weight for routing table\n"
-       "Weight value\n")
-{
-       int idx_weight = 3;
-       if (argc <= idx_weight)
-               return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                         "weight", NULL);
-       return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                 "weight", argv[idx_weight]->arg);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (set_label_index,
-       set_label_index_cmd,
-       "set label-index (0-1048560)",
-       SET_STR
-       "Label index to associate with the prefix\n"
-       "Label index value\n")
+DEFUN_YANG (set_label_index,
+           set_label_index_cmd,
+           "set label-index (0-1048560)",
+           SET_STR
+           "Label index to associate with the prefix\n"
+           "Label index value\n")
 {
        int idx_number = 2;
-       return generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                              "label-index", argv[idx_number]->arg);
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:label-index']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:label-index", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                             argv[idx_number]->arg);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_set_label_index,
-       no_set_label_index_cmd,
-       "no set label-index [(0-1048560)]",
-       NO_STR
-       SET_STR
-       "Label index to associate with the prefix\n"
-       "Label index value\n")
+DEFUN_YANG (no_set_label_index,
+           no_set_label_index_cmd,
+           "no set label-index [(0-1048560)]",
+           NO_STR
+           SET_STR
+           "Label index to associate with the prefix\n"
+           "Label index value\n")
 {
-       int idx_label_index = 3;
-       if (argc <= idx_label_index)
-               return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                         "label-index", NULL);
-       return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                 "label-index", argv[idx_label_index]->arg);
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:label-index']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (set_aspath_prepend_asn,
-       set_aspath_prepend_asn_cmd,
-       "set as-path prepend (1-4294967295)...",
-       SET_STR
-       "Transform BGP AS_PATH attribute\n"
-       "Prepend to the as-path\n"
-       "AS number\n")
+DEFUN_YANG (set_aspath_prepend_asn,
+           set_aspath_prepend_asn_cmd,
+           "set as-path prepend (1-4294967295)...",
+           SET_STR
+           "Transform BGP AS_PATH attribute\n"
+           "Prepend to the as-path\n"
+           "AS number\n")
 {
        int idx_asn = 3;
        int ret;
        char *str;
 
        str = argv_concat(argv, argc, idx_asn);
-       ret = generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                             "as-path prepend", str);
-       XFREE(MTYPE_TMP, str);
 
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:as-path-prepend']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:prepend-as-path", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, str);
+       ret = nb_cli_apply_changes(vty, NULL);
+       XFREE(MTYPE_TMP, str);
        return ret;
 }
 
-DEFUN (set_aspath_prepend_lastas,
-       set_aspath_prepend_lastas_cmd,
-       "set as-path prepend last-as (1-10)",
-       SET_STR
-       "Transform BGP AS_PATH attribute\n"
-       "Prepend to the as-path\n"
-       "Use the peer's AS-number\n"
-       "Number of times to insert\n")
+DEFUN_YANG (set_aspath_prepend_lastas,
+           set_aspath_prepend_lastas_cmd,
+           "set as-path prepend last-as (1-10)",
+           SET_STR
+           "Transform BGP AS_PATH attribute\n"
+           "Prepend to the as-path\n"
+           "Use the peer's AS-number\n"
+           "Number of times to insert\n")
 {
-       return set_aspath_prepend_asn(self, vty, argc, argv);
+       int idx_num = 4;
+
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:as-path-prepend']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:last-as", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                             argv[idx_num]->arg);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_set_aspath_prepend,
-       no_set_aspath_prepend_cmd,
-       "no set as-path prepend [(1-4294967295)]",
-       NO_STR
-       SET_STR
-       "Transform BGP AS_PATH attribute\n"
-       "Prepend to the as-path\n"
-       "AS number\n")
+DEFUN_YANG (no_set_aspath_prepend,
+           no_set_aspath_prepend_cmd,
+           "no set as-path prepend [(1-4294967295)]",
+           NO_STR
+           SET_STR
+           "Transform BGP AS_PATH attribute\n"
+           "Prepend to the as-path\n"
+           "AS number\n")
 {
-       int idx_asn = 4;
-       int ret;
-       char *str;
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:as-path-prepend']";
 
-       str = argv_concat(argv, argc, idx_asn);
-       ret = generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                "as-path prepend", str);
-       XFREE(MTYPE_TMP, str);
-       return ret;
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_set_aspath_prepend_lastas,
-       no_set_aspath_prepend_lastas_cmd,
-       "no set as-path prepend last-as [(1-10)]",
-       NO_STR
-       SET_STR
-       "Transform BGP AS_PATH attribute\n"
-       "Prepend to the as-path\n"
-       "Use the peers AS-number\n"
-       "Number of times to insert\n")
+DEFUN_YANG (no_set_aspath_prepend_lastas,
+           no_set_aspath_prepend_lastas_cmd,
+           "no set as-path prepend last-as [(1-10)]",
+           NO_STR
+           SET_STR
+           "Transform BGP AS_PATH attribute\n"
+           "Prepend to the as-path\n"
+           "Use the peers AS-number\n"
+           "Number of times to insert\n")
 {
-       return no_set_aspath_prepend(self, vty, argc, argv);
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:as-path-prepend']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (set_aspath_exclude,
-       set_aspath_exclude_cmd,
-       "set as-path exclude (1-4294967295)...",
-       SET_STR
-       "Transform BGP AS-path attribute\n"
-       "Exclude from the as-path\n"
-       "AS number\n")
+DEFUN_YANG (set_aspath_exclude,
+           set_aspath_exclude_cmd,
+           "set as-path exclude (1-4294967295)...",
+           SET_STR
+           "Transform BGP AS-path attribute\n"
+           "Exclude from the as-path\n"
+           "AS number\n")
 {
        int idx_asn = 3;
        int ret;
        char *str;
 
        str = argv_concat(argv, argc, idx_asn);
-       ret = generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                             "as-path exclude", str);
+
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:as-path-exclude']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:exclude-as-path", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, str);
+       ret = nb_cli_apply_changes(vty, NULL);
        XFREE(MTYPE_TMP, str);
        return ret;
 }
 
-DEFUN (no_set_aspath_exclude,
-       no_set_aspath_exclude_cmd,
-       "no set as-path exclude (1-4294967295)...",
-       NO_STR
-       SET_STR
-       "Transform BGP AS_PATH attribute\n"
-       "Exclude from the as-path\n"
-       "AS number\n")
+DEFUN_YANG (no_set_aspath_exclude,
+           no_set_aspath_exclude_cmd,
+           "no set as-path exclude (1-4294967295)...",
+           NO_STR
+           SET_STR
+           "Transform BGP AS_PATH attribute\n"
+           "Exclude from the as-path\n"
+           "AS number\n")
 {
-       int idx_asn = 4;
-       int ret;
-       char *str;
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:as-path-exclude']";
 
-       str = argv_concat(argv, argc, idx_asn);
-       ret = generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                "as-path exclude", str);
-       XFREE(MTYPE_TMP, str);
-       return ret;
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-ALIAS(no_set_aspath_exclude, no_set_aspath_exclude_all_cmd,
-      "no set as-path exclude",
-      NO_STR SET_STR
-      "Transform BGP AS_PATH attribute\n"
-      "Exclude from the as-path\n")
+ALIAS_YANG (no_set_aspath_exclude, no_set_aspath_exclude_all_cmd,
+            "no set as-path exclude",
+            NO_STR SET_STR
+            "Transform BGP AS_PATH attribute\n"
+            "Exclude from the as-path\n")
 
-DEFUN (set_community,
-       set_community_cmd,
-       "set community AA:NN...",
-       SET_STR
-       "BGP community attribute\n"
-       COMMUNITY_VAL_STR)
+DEFUN_YANG (set_community,
+           set_community_cmd,
+           "set community AA:NN...",
+           SET_STR
+           "BGP community attribute\n"
+           COMMUNITY_VAL_STR)
 {
        int idx_aa_nn = 2;
        int i;
@@ -4792,9 +5027,18 @@ DEFUN (set_community,
        struct buffer *b;
        struct community *com = NULL;
        char *str;
-       char *argstr;
+       char *argstr = NULL;
        int ret;
 
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:set-community']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:community-string",
+                xpath);
+
        b = buffer_new(1024);
 
        for (i = idx_aa_nn; i < argc; i++) {
@@ -4870,50 +5114,61 @@ DEFUN (set_community,
                argstr = XCALLOC(MTYPE_TMP, argstr_sz);
                strlcpy(argstr, str, argstr_sz);
                strlcat(argstr, " additive", argstr_sz);
-               ret = generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                                     "community", argstr);
-               XFREE(MTYPE_TMP, argstr);
+               nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argstr);
        } else
-               ret = generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                                     "community", str);
+               nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, str);
+
+       ret = nb_cli_apply_changes(vty, NULL);
 
+       if (argstr)
+               XFREE(MTYPE_TMP, argstr);
        community_free(&com);
 
        return ret;
 }
 
-DEFUN (set_community_none,
-       set_community_none_cmd,
-       "set community none",
-       SET_STR
-       "BGP community attribute\n"
-       "No community attribute\n")
+DEFUN_YANG (set_community_none,
+           set_community_none_cmd,
+           "set community none",
+           SET_STR
+           "BGP community attribute\n"
+           "No community attribute\n")
 {
-       return generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                              "community", "none");
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:set-community']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:community-none", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, "true");
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_set_community,
-       no_set_community_cmd,
-       "no set community AA:NN...",
-       NO_STR
-       SET_STR
-       "BGP community attribute\n"
-       COMMUNITY_VAL_STR)
+DEFUN_YANG (no_set_community,
+           no_set_community_cmd,
+           "no set community AA:NN...",
+           NO_STR
+           SET_STR
+           "BGP community attribute\n"
+           COMMUNITY_VAL_STR)
 {
-       return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                 "community", NULL);
-}
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:set-community']";
 
-ALIAS (no_set_community,
-       no_set_community_short_cmd,
-       "no set community",
-       NO_STR
-       SET_STR
-       "BGP community attribute\n")
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
+}
 
+ALIAS_YANG (no_set_community,
+            no_set_community_short_cmd,
+            "no set community",
+            NO_STR
+            SET_STR
+            "BGP community attribute\n")
 
-DEFUN (set_community_delete,
+DEFPY_YANG (set_community_delete,
        set_community_delete_cmd,
        "set comm-list <(1-99)|(100-500)|WORD> delete",
        SET_STR
@@ -4923,93 +5178,124 @@ DEFUN (set_community_delete,
        "Community-list name\n"
        "Delete matching communities\n")
 {
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:comm-list-delete']";
+       char xpath_value[XPATH_MAXLEN];
        int idx_comm_list = 2;
-       char *args;
 
-       args = argv_concat(argv, argc, idx_comm_list);
-       generic_set_add(vty, VTY_GET_CONTEXT(route_map_index), "comm-list",
-                       args);
-       XFREE(MTYPE_TMP, args);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:comm-list-name",
+                xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                       argv[idx_comm_list]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
 
-       return CMD_SUCCESS;
 }
 
-DEFUN (no_set_community_delete,
-       no_set_community_delete_cmd,
-       "no set comm-list [<(1-99)|(100-500)|WORD> delete]",
-       NO_STR
-       SET_STR
-       "set BGP community list (for deletion)\n"
-       "Community-list number (standard)\n"
-       "Community-list number (expanded)\n"
-       "Community-list name\n"
-       "Delete matching communities\n")
+DEFUN_YANG (no_set_community_delete,
+           no_set_community_delete_cmd,
+           "no set comm-list [<(1-99)|(100-500)|WORD> delete]",
+           NO_STR
+           SET_STR
+           "set BGP community list (for deletion)\n"
+           "Community-list number (standard)\n"
+           "Community-list number (expanded)\n"
+           "Community-list name\n"
+           "Delete matching communities\n")
 {
-       return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                 "comm-list", NULL);
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:comm-list-delete']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (set_lcommunity,
-       set_lcommunity_cmd,
-       "set large-community AA:BB:CC...",
-       SET_STR
-       "BGP large community attribute\n"
-       "Large Community number in aa:bb:cc format or additive\n")
+DEFUN_YANG (set_lcommunity,
+           set_lcommunity_cmd,
+           "set large-community AA:BB:CC...",
+           SET_STR
+           "BGP large community attribute\n"
+           "Large Community number in aa:bb:cc format or additive\n")
 {
-       int ret;
        char *str;
+       int ret;
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:set-large-community']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
 
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:large-community-string",
+                xpath);
        str = argv_concat(argv, argc, 2);
-       ret = generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                             "large-community", str);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, str);
+       ret = nb_cli_apply_changes(vty, NULL);
        XFREE(MTYPE_TMP, str);
-
        return ret;
 }
 
-DEFUN (set_lcommunity_none,
-       set_lcommunity_none_cmd,
-       "set large-community none",
-       SET_STR
-       "BGP large community attribute\n"
-       "No large community attribute\n")
+DEFUN_YANG (set_lcommunity_none,
+           set_lcommunity_none_cmd,
+           "set large-community none",
+           SET_STR
+           "BGP large community attribute\n"
+           "No large community attribute\n")
 {
-       return generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                              "large-community", "none");
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:set-large-community']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:large-community-none",
+                xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, "true");
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_set_lcommunity,
-       no_set_lcommunity_cmd,
-       "no set large-community none",
-       NO_STR
-       SET_STR
-       "BGP large community attribute\n"
-       "No community attribute\n")
+DEFUN_YANG (no_set_lcommunity,
+           no_set_lcommunity_cmd,
+           "no set large-community none",
+           NO_STR
+           SET_STR
+           "BGP large community attribute\n"
+           "No community attribute\n")
 {
-       return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                 "large-community", NULL);
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:set-large-community']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_set_lcommunity1,
-       no_set_lcommunity1_cmd,
-       "no set large-community AA:BB:CC...",
-       NO_STR
-       SET_STR
-       "BGP large community attribute\n"
-       "Large community in AA:BB:CC... format or additive\n")
+DEFUN_YANG (no_set_lcommunity1,
+           no_set_lcommunity1_cmd,
+           "no set large-community AA:BB:CC...",
+           NO_STR
+           SET_STR
+           "BGP large community attribute\n"
+           "Large community in AA:BB:CC... format or additive\n")
 {
-       return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                 "large-community", NULL);
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:set-large-community']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-ALIAS (no_set_lcommunity1,
-       no_set_lcommunity1_short_cmd,
-       "no set large-community",
-       NO_STR
-       SET_STR
-       "BGP large community attribute\n")
+ALIAS_YANG (no_set_lcommunity1,
+            no_set_lcommunity1_short_cmd,
+            "no set large-community",
+            NO_STR
+            SET_STR
+            "BGP large community attribute\n")
 
-DEFUN (set_lcommunity_delete,
+DEFPY_YANG (set_lcommunity_delete,
        set_lcommunity_delete_cmd,
        "set large-comm-list <(1-99)|(100-500)|WORD> delete",
        SET_STR
@@ -5019,336 +5305,401 @@ DEFUN (set_lcommunity_delete,
        "Large Community-list name\n"
        "Delete matching large communities\n")
 {
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:large-comm-list-delete']";
+       char xpath_value[XPATH_MAXLEN];
        int idx_lcomm_list = 2;
-       char *args;
 
-       args = argv_concat(argv, argc, idx_lcomm_list);
-       generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                       "large-comm-list", args);
-       XFREE(MTYPE_TMP, args);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
 
-       return CMD_SUCCESS;
+       snprintf(xpath_value, sizeof(xpath_value),
+                       "%s/rmap-set-action/frr-bgp-route-map:comm-list-name",
+                       xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                       argv[idx_lcomm_list]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_set_lcommunity_delete,
-       no_set_lcommunity_delete_cmd,
-       "no set large-comm-list <(1-99)|(100-500)|WORD> [delete]",
-       NO_STR
-       SET_STR
-       "set BGP large community list (for deletion)\n"
-       "Large Community-list number (standard)\n"
-       "Large Communitly-list number (expanded)\n"
-       "Large Community-list name\n"
-       "Delete matching large communities\n")
+DEFUN_YANG (no_set_lcommunity_delete,
+           no_set_lcommunity_delete_cmd,
+           "no set large-comm-list <(1-99)|(100-500)|WORD> [delete]",
+           NO_STR
+           SET_STR
+           "set BGP large community list (for deletion)\n"
+           "Large Community-list number (standard)\n"
+           "Large Communitly-list number (expanded)\n"
+           "Large Community-list name\n"
+           "Delete matching large communities\n")
 {
-       return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                 "large-comm-list", NULL);
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:large-comm-list-delete']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-ALIAS (no_set_lcommunity_delete,
-       no_set_lcommunity_delete_short_cmd,
-       "no set large-comm-list",
-       NO_STR
-       SET_STR
-       "set BGP large community list (for deletion)\n")
+ALIAS_YANG (no_set_lcommunity_delete,
+            no_set_lcommunity_delete_short_cmd,
+            "no set large-comm-list",
+            NO_STR
+            SET_STR
+            "set BGP large community list (for deletion)\n")
 
-DEFUN (set_ecommunity_rt,
-       set_ecommunity_rt_cmd,
-       "set extcommunity rt ASN:NN_OR_IP-ADDRESS:NN...",
-       SET_STR
-       "BGP extended community attribute\n"
-       "Route Target extended community\n"
-       "VPN extended community\n")
+DEFUN_YANG (set_ecommunity_rt,
+           set_ecommunity_rt_cmd,
+           "set extcommunity rt ASN:NN_OR_IP-ADDRESS:NN...",
+           SET_STR
+           "BGP extended community attribute\n"
+           "Route Target extended community\n"
+           "VPN extended community\n")
 {
        int idx_asn_nn = 3;
-       int ret;
        char *str;
+       int ret;
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:set-extcommunity-rt']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
 
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:extcommunity-rt", xpath);
        str = argv_concat(argv, argc, idx_asn_nn);
-       ret = generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                             "extcommunity rt", str);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, str);
+       ret = nb_cli_apply_changes(vty, NULL);
        XFREE(MTYPE_TMP, str);
-
        return ret;
 }
 
-DEFUN (no_set_ecommunity_rt,
-       no_set_ecommunity_rt_cmd,
-       "no set extcommunity rt ASN:NN_OR_IP-ADDRESS:NN...",
-       NO_STR
-       SET_STR
-       "BGP extended community attribute\n"
-       "Route Target extended community\n"
-       "VPN extended community\n")
-{
-       return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                 "extcommunity rt", NULL);
-}
-
-ALIAS (no_set_ecommunity_rt,
-       no_set_ecommunity_rt_short_cmd,
-       "no set extcommunity rt",
-       NO_STR
-       SET_STR
-       "BGP extended community attribute\n"
-       "Route Target extended community\n")
-
-DEFUN (set_ecommunity_soo,
-       set_ecommunity_soo_cmd,
-       "set extcommunity soo ASN:NN_OR_IP-ADDRESS:NN...",
-       SET_STR
-       "BGP extended community attribute\n"
-       "Site-of-Origin extended community\n"
-       "VPN extended community\n")
+DEFUN_YANG (no_set_ecommunity_rt,
+           no_set_ecommunity_rt_cmd,
+           "no set extcommunity rt ASN:NN_OR_IP-ADDRESS:NN...",
+           NO_STR
+           SET_STR
+           "BGP extended community attribute\n"
+           "Route Target extended community\n"
+           "VPN extended community\n")
+{
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:set-extcommunity-rt']";
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+ALIAS_YANG (no_set_ecommunity_rt,
+            no_set_ecommunity_rt_short_cmd,
+            "no set extcommunity rt",
+            NO_STR
+            SET_STR
+            "BGP extended community attribute\n"
+            "Route Target extended community\n")
+
+DEFUN_YANG (set_ecommunity_soo,
+           set_ecommunity_soo_cmd,
+           "set extcommunity soo ASN:NN_OR_IP-ADDRESS:NN...",
+           SET_STR
+          "BGP extended community attribute\n"
+          "Site-of-Origin extended community\n"
+          "VPN extended community\n")
 {
        int idx_asn_nn = 3;
-       int ret;
        char *str;
+       int ret;
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:set-extcommunity-soo']";
+       char xpath_value[XPATH_MAXLEN];
 
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:extcommunity-soo",
+                xpath);
        str = argv_concat(argv, argc, idx_asn_nn);
-       ret = generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                             "extcommunity soo", str);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, str);
+       ret = nb_cli_apply_changes(vty, NULL);
        XFREE(MTYPE_TMP, str);
        return ret;
 }
 
-
-DEFUN (no_set_ecommunity_soo,
-       no_set_ecommunity_soo_cmd,
-       "no set extcommunity soo ASN:NN_OR_IP-ADDRESS:NN...",
-       NO_STR
-       SET_STR
-       "BGP extended community attribute\n"
-       "Site-of-Origin extended community\n"
-       "VPN extended community\n")
+DEFUN_YANG (no_set_ecommunity_soo,
+           no_set_ecommunity_soo_cmd,
+           "no set extcommunity soo ASN:NN_OR_IP-ADDRESS:NN...",
+           NO_STR
+           SET_STR
+           "BGP extended community attribute\n"
+           "Site-of-Origin extended community\n"
+           "VPN extended community\n")
+{
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:set-extcommunity-soo']";
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+ALIAS_YANG (no_set_ecommunity_soo,
+            no_set_ecommunity_soo_short_cmd,
+            "no set extcommunity soo",
+            NO_STR
+            SET_STR
+            "GP extended community attribute\n"
+            "Site-of-Origin extended community\n")
+
+DEFUN_YANG (set_ecommunity_lb,
+           set_ecommunity_lb_cmd,
+           "set extcommunity bandwidth <(1-25600)|cumulative|num-multipaths> [non-transitive]",
+           SET_STR
+           "BGP extended community attribute\n"
+           "Link bandwidth extended community\n"
+           "Bandwidth value in Mbps\n"
+           "Cumulative bandwidth of all multipaths (outbound-only)\n"
+           "Internally computed bandwidth based on number of multipaths (outbound-only)\n"
+           "Attribute is set as non-transitive\n")
 {
-       return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                 "extcommunity soo", NULL);
-}
-
-ALIAS (no_set_ecommunity_soo,
-       no_set_ecommunity_soo_short_cmd,
-       "no set extcommunity soo",
-       NO_STR
-       SET_STR
-       "GP extended community attribute\n"
-       "Site-of-Origin extended community\n")
+       int idx_lb = 3;
+       int idx_non_transitive = 4;
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:set-extcommunity-lb']";
+       char xpath_lb_type[XPATH_MAXLEN];
+       char xpath_bandwidth[XPATH_MAXLEN];
+       char xpath_non_transitive[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+
+       snprintf(xpath_lb_type, sizeof(xpath_lb_type),
+                "%s/rmap-set-action/frr-bgp-route-map:extcommunity-lb/lb-type",
+                xpath);
+       snprintf(xpath_bandwidth, sizeof(xpath_bandwidth),
+                "%s/rmap-set-action/frr-bgp-route-map:extcommunity-lb/bandwidth",
+                xpath);
+       snprintf(xpath_non_transitive, sizeof(xpath_non_transitive),
+                "%s/rmap-set-action/frr-bgp-route-map:extcommunity-lb/two-octet-as-specific",
+                xpath);
+
+       if ((strcmp(argv[idx_lb]->arg, "cumulative")) == 0)
+               nb_cli_enqueue_change(vty, xpath_lb_type, NB_OP_MODIFY,
+                                     "cumulative-bandwidth");
+       else if ((strcmp(argv[idx_lb]->arg, "num-multipaths")) == 0)
+               nb_cli_enqueue_change(vty, xpath_lb_type, NB_OP_MODIFY,
+                                     "computed-bandwidth");
+       else {
+               nb_cli_enqueue_change(vty, xpath_lb_type, NB_OP_MODIFY,
+                                     "explicit-bandwidth");
+               nb_cli_enqueue_change(vty, xpath_bandwidth, NB_OP_MODIFY,
+                                     argv[idx_lb]->arg);
+       }
 
-DEFUN (set_ecommunity_lb,
-       set_ecommunity_lb_cmd,
-       "set extcommunity bandwidth <(1-25600)|cumulative|num-multipaths> [non-transitive]",
-       SET_STR
-       "BGP extended community attribute\n"
-       "Link bandwidth extended community\n"
-       "Bandwidth value in Mbps\n"
-       "Cumulative bandwidth of all multipaths (outbound-only)\n"
-       "Internally computed bandwidth based on number of multipaths (outbound-only)\n"
-       "Attribute is set as non-transitive\n")
+       if (argv[idx_non_transitive])
+               nb_cli_enqueue_change(vty, xpath_non_transitive, NB_OP_MODIFY,
+                                     "true");
+       else
+               nb_cli_enqueue_change(vty, xpath_non_transitive, NB_OP_MODIFY,
+                                     "false");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFUN_YANG (no_set_ecommunity_lb,
+           no_set_ecommunity_lb_cmd,
+           "no set extcommunity bandwidth <(1-25600)|cumulative|num-multipaths> [non-transitive]",
+           NO_STR
+           SET_STR
+           "BGP extended community attribute\n"
+           "Link bandwidth extended community\n"
+           "Bandwidth value in Mbps\n"
+           "Cumulative bandwidth of all multipaths (outbound-only)\n"
+           "Internally computed bandwidth based on number of multipaths (outbound-only)\n"
+           "Attribute is set as non-transitive\n")
+{
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:set-extcommunity-lb']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+ALIAS_YANG (no_set_ecommunity_lb,
+            no_set_ecommunity_lb_short_cmd,
+            "no set extcommunity bandwidth",
+            NO_STR
+            SET_STR
+            "BGP extended community attribute\n"
+            "Link bandwidth extended community\n")
+
+DEFUN_YANG (set_origin,
+           set_origin_cmd,
+           "set origin <egp|igp|incomplete>",
+           SET_STR
+           "BGP origin code\n"
+           "remote EGP\n"
+           "local IGP\n"
+           "unknown heritage\n")
 {
-       int idx_lb = 3;
-       int ret;
-       char *str;
+       int idx_origin = 2;
+       const char *origin_type;
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:set-origin']";
+       char xpath_value[XPATH_MAXLEN];
 
-       str = argv_concat(argv, argc, idx_lb);
-       ret = generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                             "extcommunity bandwidth", str);
-       XFREE(MTYPE_TMP, str);
-       return ret;
-}
+       if (strncmp(argv[idx_origin]->arg, "igp", 2) == 0)
+               origin_type = "igp";
+       else if (strncmp(argv[idx_origin]->arg, "egp", 1) == 0)
+               origin_type = "egp";
+       else if (strncmp(argv[idx_origin]->arg, "incomplete", 2) == 0)
+               origin_type = "incomplete";
+       else {
+               vty_out(vty, "%% Invalid match origin type\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
 
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:origin", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, origin_type);
 
-DEFUN (no_set_ecommunity_lb,
-       no_set_ecommunity_lb_cmd,
-       "no set extcommunity bandwidth <(1-25600)|cumulative|num-multipaths> [non-transitive]",
-       NO_STR
-       SET_STR
-       "BGP extended community attribute\n"
-       "Link bandwidth extended community\n"
-       "Bandwidth value in Mbps\n"
-       "Cumulative bandwidth of all multipaths (outbound-only)\n"
-       "Internally computed bandwidth based on number of multipaths (outbound-only)\n"
-       "Attribute is set as non-transitive\n")
-{
-       return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                 "extcommunity bandwidth", NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-ALIAS (no_set_ecommunity_lb,
-       no_set_ecommunity_lb_short_cmd,
-       "no set extcommunity bandwidth",
-       NO_STR
-       SET_STR
-       "BGP extended community attribute\n"
-       "Link bandwidth extended community\n")
-
-DEFUN (set_origin,
-       set_origin_cmd,
-       "set origin <egp|igp|incomplete>",
-       SET_STR
-       "BGP origin code\n"
-       "remote EGP\n"
-       "local IGP\n"
-       "unknown heritage\n")
+DEFUN_YANG (no_set_origin,
+           no_set_origin_cmd,
+           "no set origin [<egp|igp|incomplete>]",
+           NO_STR
+           SET_STR
+           "BGP origin code\n"
+           "remote EGP\n"
+           "local IGP\n"
+           "unknown heritage\n")
 {
-       int idx_origin = 2;
-       if (strncmp(argv[idx_origin]->arg, "igp", 2) == 0)
-               return generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                                      "origin", "igp");
-       if (strncmp(argv[idx_origin]->arg, "egp", 1) == 0)
-               return generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                                      "origin", "egp");
-       if (strncmp(argv[idx_origin]->arg, "incomplete", 2) == 0)
-               return generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                                      "origin", "incomplete");
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:set-origin']";
 
-       vty_out(vty, "%% Invalid set origin type\n");
-       return CMD_WARNING_CONFIG_FAILED;
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-
-DEFUN (no_set_origin,
-       no_set_origin_cmd,
-       "no set origin [<egp|igp|incomplete>]",
-       NO_STR
-       SET_STR
-       "BGP origin code\n"
-       "remote EGP\n"
-       "local IGP\n"
-       "unknown heritage\n")
+DEFUN_YANG (set_atomic_aggregate,
+           set_atomic_aggregate_cmd,
+           "set atomic-aggregate",
+           SET_STR
+           "BGP atomic aggregate attribute\n" )
 {
-       return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                 "origin", NULL);
-}
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:atomic-aggregate']";
+       char xpath_value[XPATH_MAXLEN];
 
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:atomic-aggregate",
+                xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, NULL);
 
-DEFUN (set_atomic_aggregate,
-       set_atomic_aggregate_cmd,
-       "set atomic-aggregate",
-       SET_STR
-       "BGP atomic aggregate attribute\n" )
-{
-       return generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                              "atomic-aggregate", NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_set_atomic_aggregate,
-       no_set_atomic_aggregate_cmd,
-       "no set atomic-aggregate",
-       NO_STR
-       SET_STR
-       "BGP atomic aggregate attribute\n" )
+DEFUN_YANG (no_set_atomic_aggregate,
+           no_set_atomic_aggregate_cmd,
+           "no set atomic-aggregate",
+           NO_STR
+           SET_STR
+           "BGP atomic aggregate attribute\n" )
 {
-       return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                 "atomic-aggregate", NULL);
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:atomic-aggregate']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (set_aggregator_as,
-       set_aggregator_as_cmd,
-       "set aggregator as (1-4294967295) A.B.C.D",
-       SET_STR
-       "BGP aggregator attribute\n"
-       "AS number of aggregator\n"
-       "AS number\n"
-       "IP address of aggregator\n")
+DEFUN_YANG (set_aggregator_as,
+           set_aggregator_as_cmd,
+           "set aggregator as (1-4294967295) A.B.C.D",
+           SET_STR
+           "BGP aggregator attribute\n"
+           "AS number of aggregator\n"
+           "AS number\n"
+           "IP address of aggregator\n")
 {
        int idx_number = 3;
        int idx_ipv4 = 4;
-       int ret;
-       struct in_addr address;
-       char *argstr;
-       size_t argstr_len;
+       char xpath_asn[XPATH_MAXLEN];
+       char xpath_addr[XPATH_MAXLEN];
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:aggregator']";
 
-       ret = inet_aton(argv[idx_ipv4]->arg, &address);
-       if (ret == 0) {
-               vty_out(vty, "Aggregator IP address is invalid\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       argstr_len =
-               strlen(argv[idx_number]->arg) + strlen(argv[idx_ipv4]->arg) + 2;
-       argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, argstr_len);
-
-       snprintf(argstr, argstr_len, "%s %s", argv[idx_number]->arg,
-                argv[idx_ipv4]->arg);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
 
-       ret = generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                             "aggregator as", argstr);
+       snprintf(
+               xpath_asn, sizeof(xpath_asn),
+               "%s/rmap-set-action/frr-bgp-route-map:aggregator/aggregator-asn",
+               xpath);
+       nb_cli_enqueue_change(vty, xpath_asn, NB_OP_MODIFY,
+                             argv[idx_number]->arg);
 
-       XFREE(MTYPE_ROUTE_MAP_COMPILED, argstr);
+       snprintf(
+               xpath_addr, sizeof(xpath_addr),
+               "%s/rmap-set-action/frr-bgp-route-map:aggregator/aggregator-address",
+               xpath);
+       nb_cli_enqueue_change(vty, xpath_addr, NB_OP_MODIFY,
+                             argv[idx_ipv4]->arg);
 
-       return ret;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-
-DEFUN (no_set_aggregator_as,
-       no_set_aggregator_as_cmd,
-       "no set aggregator as [(1-4294967295) A.B.C.D]",
-       NO_STR
-       SET_STR
-       "BGP aggregator attribute\n"
-       "AS number of aggregator\n"
-       "AS number\n"
-       "IP address of aggregator\n")
+DEFUN_YANG (no_set_aggregator_as,
+           no_set_aggregator_as_cmd,
+           "no set aggregator as [(1-4294967295) A.B.C.D]",
+           NO_STR
+           SET_STR
+           "BGP aggregator attribute\n"
+           "AS number of aggregator\n"
+           "AS number\n"
+           "IP address of aggregator\n")
 {
-       int idx_asn = 4;
-       int idx_ip = 5;
-       int ret;
-       struct in_addr address;
-       char *argstr;
-       size_t argstr_len;
-
-       if (argc <= idx_asn)
-               return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                         "aggregator as", NULL);
-
-       ret = inet_aton(argv[idx_ip]->arg, &address);
-       if (ret == 0) {
-               vty_out(vty, "Aggregator IP address is invalid\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       argstr_len = strlen(argv[idx_asn]->arg) + strlen(argv[idx_ip]->arg) + 2;
-       argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, argstr_len);
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:aggregator']";
 
-       snprintf(argstr, argstr_len, "%s %s", argv[idx_asn]->arg,
-                argv[idx_ip]->arg);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
+}
 
-       ret = generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                "aggregator as", argstr);
+DEFUN_YANG (match_ipv6_next_hop,
+           match_ipv6_next_hop_cmd,
+           "match ipv6 next-hop X:X::X:X",
+           MATCH_STR
+           IPV6_STR
+           "Match IPv6 next-hop address of route\n"
+           "IPv6 address of next hop\n")
+{
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:ipv6-nexthop']";
+       char xpath_value[XPATH_MAXLEN];
 
-       XFREE(MTYPE_ROUTE_MAP_COMPILED, argstr);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-match-condition/frr-bgp-route-map:ipv6-address",
+                xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[3]->arg);
 
-       return ret;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (match_ipv6_next_hop,
-       match_ipv6_next_hop_cmd,
-       "match ipv6 next-hop X:X::X:X",
-       MATCH_STR
-       IPV6_STR
-       "Match IPv6 next-hop address of route\n"
-       "IPv6 address of next hop\n")
+DEFUN_YANG (no_match_ipv6_next_hop,
+           no_match_ipv6_next_hop_cmd,
+           "no match ipv6 next-hop X:X::X:X",
+           NO_STR
+           MATCH_STR
+           IPV6_STR
+           "Match IPv6 next-hop address of route\n"
+           "IPv6 address of next hop\n")
 {
-       int idx_ipv6 = 3;
-       return bgp_route_match_add(vty, "ipv6 next-hop", argv[idx_ipv6]->arg,
-                                  RMAP_EVENT_MATCH_ADDED);
-}
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:ipv6-nexthop']";
 
-DEFUN (no_match_ipv6_next_hop,
-       no_match_ipv6_next_hop_cmd,
-       "no match ipv6 next-hop X:X::X:X",
-       NO_STR
-       MATCH_STR
-       IPV6_STR
-       "Match IPv6 next-hop address of route\n"
-       "IPv6 address of next hop\n")
-{
-       int idx_ipv6 = 4;
-       return bgp_route_match_delete(vty, "ipv6 next-hop", argv[idx_ipv6]->arg,
-                                     RMAP_EVENT_MATCH_DELETED);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFPY (match_ipv4_next_hop,
+DEFPY_YANG (match_ipv4_next_hop,
        match_ipv4_next_hop_cmd,
        "match ip next-hop address A.B.C.D",
        MATCH_STR
@@ -5357,13 +5708,20 @@ DEFPY (match_ipv4_next_hop,
        "IP address\n"
        "IP address of next-hop\n")
 {
-       int idx_ipv4 = 4;
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:ipv4-nexthop']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-match-condition/frr-bgp-route-map:ipv4-address",
+                xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[4]->arg);
 
-       return bgp_route_match_add(vty, "ip next-hop address",
-                                  argv[idx_ipv4]->arg, RMAP_EVENT_MATCH_ADDED);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFPY (no_match_ipv4_next_hop,
+DEFPY_YANG (no_match_ipv4_next_hop,
        no_match_ipv4_next_hop_cmd,
        "no match ip next-hop address [A.B.C.D]",
        NO_STR
@@ -5373,264 +5731,313 @@ DEFPY (no_match_ipv4_next_hop,
        "IP address\n"
        "IP address of next-hop\n")
 {
-       return bgp_route_match_delete(vty, "ip next-hop address", NULL,
-                                     RMAP_EVENT_MATCH_DELETED);
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:ipv4-nexthop']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (set_ipv6_nexthop_peer,
-       set_ipv6_nexthop_peer_cmd,
-       "set ipv6 next-hop peer-address",
-       SET_STR
-       IPV6_STR
-       "Next hop address\n"
-       "Use peer address (for BGP only)\n")
+DEFUN_YANG (set_ipv6_nexthop_peer,
+           set_ipv6_nexthop_peer_cmd,
+           "set ipv6 next-hop peer-address",
+           SET_STR
+           IPV6_STR
+           "Next hop address\n"
+           "Use peer address (for BGP only)\n")
 {
-       return generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                              "ipv6 next-hop peer-address", NULL);
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:ipv6-peer-address']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:preference", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, "true");
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_set_ipv6_nexthop_peer,
-       no_set_ipv6_nexthop_peer_cmd,
-       "no set ipv6 next-hop peer-address",
-       NO_STR
-       SET_STR
-       IPV6_STR
-       "IPv6 next-hop address\n"
-       "Use peer address (for BGP only)\n")
+DEFUN_YANG (no_set_ipv6_nexthop_peer,
+           no_set_ipv6_nexthop_peer_cmd,
+           "no set ipv6 next-hop peer-address",
+           NO_STR
+           SET_STR
+           IPV6_STR
+           "IPv6 next-hop address\n"
+           "Use peer address (for BGP only)\n")
 {
-       return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                 "ipv6 next-hop peer-address", NULL);
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:ipv6-peer-address']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (set_ipv6_nexthop_prefer_global,
-       set_ipv6_nexthop_prefer_global_cmd,
-       "set ipv6 next-hop prefer-global",
-       SET_STR
-       IPV6_STR
-       "IPv6 next-hop address\n"
-       "Prefer global over link-local if both exist\n")
+DEFUN_YANG (set_ipv6_nexthop_prefer_global,
+           set_ipv6_nexthop_prefer_global_cmd,
+           "set ipv6 next-hop prefer-global",
+           SET_STR
+           IPV6_STR
+           "IPv6 next-hop address\n"
+           "Prefer global over link-local if both exist\n")
 {
-       return generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                              "ipv6 next-hop prefer-global", NULL);
-       ;
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:ipv6-prefer-global']";
+       char xpath_value[XPATH_MAXLEN];
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:preference", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, "true");
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_set_ipv6_nexthop_prefer_global,
-       no_set_ipv6_nexthop_prefer_global_cmd,
-       "no set ipv6 next-hop prefer-global",
-       NO_STR
-       SET_STR
-       IPV6_STR
-       "IPv6 next-hop address\n"
-       "Prefer global over link-local if both exist\n")
+DEFUN_YANG (no_set_ipv6_nexthop_prefer_global,
+           no_set_ipv6_nexthop_prefer_global_cmd,
+           "no set ipv6 next-hop prefer-global",
+           NO_STR
+           SET_STR
+           IPV6_STR
+           "IPv6 next-hop address\n"
+           "Prefer global over link-local if both exist\n")
 {
-       return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                 "ipv6 next-hop prefer-global", NULL);
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:ipv6-prefer-global']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (set_ipv6_nexthop_global,
-       set_ipv6_nexthop_global_cmd,
-       "set ipv6 next-hop global X:X::X:X",
-       SET_STR
-       IPV6_STR
-       "IPv6 next-hop address\n"
-       "IPv6 global address\n"
-       "IPv6 address of next hop\n")
+DEFUN_YANG (set_ipv6_nexthop_global,
+           set_ipv6_nexthop_global_cmd,
+           "set ipv6 next-hop global X:X::X:X",
+           SET_STR
+           IPV6_STR
+           "IPv6 next-hop address\n"
+           "IPv6 global address\n"
+           "IPv6 address of next hop\n")
 {
        int idx_ipv6 = 4;
-       struct in6_addr addr;
-       int ret;
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:ipv6-nexthop-global']";
+       char xpath_value[XPATH_MAXLEN];
 
-       ret = inet_pton(AF_INET6, argv[idx_ipv6]->arg, &addr);
-       if (!ret) {
-               vty_out(vty, "%% Malformed nexthop address\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       if (IN6_IS_ADDR_UNSPECIFIED(&addr) || IN6_IS_ADDR_LOOPBACK(&addr)
-           || IN6_IS_ADDR_MULTICAST(&addr) || IN6_IS_ADDR_LINKLOCAL(&addr)) {
-               vty_out(vty, "%% Invalid global nexthop address\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:ipv6-address", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                             argv[idx_ipv6]->arg);
 
-       return generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                              "ipv6 next-hop global", argv[idx_ipv6]->arg);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-
-DEFUN (no_set_ipv6_nexthop_global,
-       no_set_ipv6_nexthop_global_cmd,
-       "no set ipv6 next-hop global X:X::X:X",
-       NO_STR
-       SET_STR
-       IPV6_STR
-       "IPv6 next-hop address\n"
-       "IPv6 global address\n"
-       "IPv6 address of next hop\n")
+DEFUN_YANG (no_set_ipv6_nexthop_global,
+           no_set_ipv6_nexthop_global_cmd,
+           "no set ipv6 next-hop global X:X::X:X",
+           NO_STR
+           SET_STR
+           IPV6_STR
+           "IPv6 next-hop address\n"
+           "IPv6 global address\n"
+           "IPv6 address of next hop\n")
 {
-       int idx_ipv6 = 5;
-       if (argc <= idx_ipv6)
-               return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                         "ipv6 next-hop global", NULL);
-       return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                 "ipv6 next-hop global", argv[idx_ipv6]->arg);
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:ipv6-nexthop-global']";
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 #ifdef KEEP_OLD_VPN_COMMANDS
-DEFUN (set_vpn_nexthop,
-       set_vpn_nexthop_cmd,
-       "set <vpnv4 next-hop A.B.C.D|vpnv6 next-hop X:X::X:X>",
-       SET_STR
-       "VPNv4 information\n"
-       "VPN next-hop address\n"
-       "IP address of next hop\n"
-       "VPNv6 information\n"
-       "VPN next-hop address\n"
-       "IPv6 address of next hop\n")
+DEFUN_YANG (set_vpn_nexthop,
+           set_vpn_nexthop_cmd,
+           "set <vpnv4 next-hop A.B.C.D|vpnv6 next-hop X:X::X:X>",
+           SET_STR
+           "VPNv4 information\n"
+           "VPN next-hop address\n"
+           "IP address of next hop\n"
+           "VPNv6 information\n"
+           "VPN next-hop address\n"
+           "IPv6 address of next hop\n")
 {
        int idx_ip = 3;
        afi_t afi;
        int idx = 0;
 
        if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
-               if (afi == AFI_IP)
-                       return generic_set_add(
-                               vty, VTY_GET_CONTEXT(route_map_index),
-                               "ipv4 vpn next-hop", argv[idx_ip]->arg);
-               else
-                       return generic_set_add(
-                               vty, VTY_GET_CONTEXT(route_map_index),
-                               "ipv6 vpn next-hop", argv[idx_ip]->arg);
+               if (afi == AFI_IP) {
+                       const char *xpath =
+                               "./set-action[action='frr-bgp-route-map:ipv4-vpn-address']";
+
+                       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+                       snprintf(
+                               xpath_value, sizeof(xpath_value),
+                               "%s/rmap-set-action/frr-bgp-route-map:ipv4-address",
+                               xpath);
+               } else {
+                       const char *xpath =
+                               "./set-action[action='frr-bgp-route-map:ipv6-vpn-address']";
+
+                       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+                       snprintf(
+                               xpath_value, sizeof(xpath_value),
+                               "%s/rmap-set-action/frr-bgp-route-map:ipv6-address",
+                               xpath);
+               }
+
+               nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                               argv[idx_ip]->arg);
+
+               return nb_cli_apply_changes(vty, NULL);
        }
+
        return CMD_SUCCESS;
 }
 
-DEFUN (no_set_vpn_nexthop,
-       no_set_vpn_nexthop_cmd,
-       "no set <vpnv4 next-hop A.B.C.D|vpnv6 next-hop X:X::X:X>",
-       NO_STR
-       SET_STR
-       "VPNv4 information\n"
-       "VPN next-hop address\n"
-       "IP address of next hop\n"
-       "VPNv6 information\n"
-       "VPN next-hop address\n"
-       "IPv6 address of next hop\n")
+DEFUN_YANG (no_set_vpn_nexthop,
+          no_set_vpn_nexthop_cmd,
+          "no set <vpnv4 next-hop A.B.C.D|vpnv6 next-hop X:X::X:X>",
+          NO_STR
+          SET_STR
+          "VPNv4 information\n"
+          "VPN next-hop address\n"
+          "IP address of next hop\n"
+          "VPNv6 information\n"
+          "VPN next-hop address\n"
+          "IPv6 address of next hop\n")
 {
        int idx_ip = 4;
        char *arg;
        afi_t afi;
        int idx = 0;
 
-       if (argc <= idx_ip)
-               arg = NULL;
-       else
-               arg = argv[idx_ip]->arg;
        if (argv_find_and_parse_vpnvx(argv, argc, &idx, &afi)) {
-               if (afi == AFI_IP)
-                       return generic_set_delete(
-                               vty, VTY_GET_CONTEXT(route_map_index),
-                               "ipv4 vpn next-hop", arg);
-               else
-                       return generic_set_delete(
-                               vty, VTY_GET_CONTEXT(route_map_index),
-                               "ipv6 vpn next-hop", argv[idx_ip]->arg);
+               if (afi == AFI_IP) {
+                       const char *xpath =
+                               "./set-action[action='frr-bgp-route-map:ipv4-vpn-address']";
+                       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+               } else {
+                       const char *xpath =
+                               "./set-action[action='frr-bgp-route-map:ipv6-vpn-address']";
+                       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+               }
+               return nb_cli_apply_changes(vty, NULL);
        }
        return CMD_SUCCESS;
 }
 #endif /* KEEP_OLD_VPN_COMMANDS */
 
-DEFUN (set_ipx_vpn_nexthop,
-       set_ipx_vpn_nexthop_cmd,
-       "set <ipv4|ipv6> vpn next-hop <A.B.C.D|X:X::X:X>",
-       SET_STR
-       "IPv4 information\n"
-       "IPv6 information\n"
-       "VPN information\n"
-       "VPN next-hop address\n"
-       "IP address of next hop\n"
-       "IPv6 address of next hop\n")
+DEFUN_YANG (set_ipx_vpn_nexthop,
+           set_ipx_vpn_nexthop_cmd,
+           "set <ipv4|ipv6> vpn next-hop <A.B.C.D|X:X::X:X>",
+           SET_STR
+           "IPv4 information\n"
+           "IPv6 information\n"
+           "VPN information\n"
+           "VPN next-hop address\n"
+           "IP address of next hop\n"
+           "IPv6 address of next hop\n")
 {
        int idx_ip = 4;
        afi_t afi;
        int idx = 0;
+       char xpath_value[XPATH_MAXLEN];
 
        if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
-               if (afi == AFI_IP)
-                       return generic_set_add(
-                               vty, VTY_GET_CONTEXT(route_map_index),
-                               "ipv4 vpn next-hop", argv[idx_ip]->arg);
-               else
-                       return generic_set_add(
-                               vty, VTY_GET_CONTEXT(route_map_index),
-                               "ipv6 vpn next-hop", argv[idx_ip]->arg);
+               if (afi == AFI_IP) {
+                       const char *xpath =
+                               "./set-action[action='frr-bgp-route-map:ipv4-vpn-address']";
+
+                       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+                       snprintf(
+                               xpath_value, sizeof(xpath_value),
+                               "%s/rmap-set-action/frr-bgp-route-map:ipv4-address",
+                               xpath);
+               } else {
+                       const char *xpath =
+                               "./set-action[action='frr-bgp-route-map:ipv6-vpn-address']";
+
+                       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+                       snprintf(
+                               xpath_value, sizeof(xpath_value),
+                               "%s/rmap-set-action/frr-bgp-route-map:ipv6-address",
+                               xpath);
+               }
+               nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                                     argv[idx_ip]->arg);
+               return nb_cli_apply_changes(vty, NULL);
        }
        return CMD_SUCCESS;
 }
 
-DEFUN (no_set_ipx_vpn_nexthop,
-       no_set_ipx_vpn_nexthop_cmd,
-       "no set <ipv4|ipv6> vpn next-hop [<A.B.C.D|X:X::X:X>]",
-       NO_STR
-       SET_STR
-       "IPv4 information\n"
-       "IPv6 information\n"
-       "VPN information\n"
-       "VPN next-hop address\n"
-       "IP address of next hop\n"
-       "IPv6 address of next hop\n")
-{
-       int idx_ip = 5;
-       char *arg;
+DEFUN_YANG (no_set_ipx_vpn_nexthop,
+           no_set_ipx_vpn_nexthop_cmd,
+           "no set <ipv4|ipv6> vpn next-hop [<A.B.C.D|X:X::X:X>]",
+           NO_STR
+           SET_STR
+           "IPv4 information\n"
+           "IPv6 information\n"
+           "VPN information\n"
+           "VPN next-hop address\n"
+           "IP address of next hop\n"
+           "IPv6 address of next hop\n")
+{
        afi_t afi;
        int idx = 0;
 
-       if (argc <= idx_ip)
-               arg = NULL;
-       else
-               arg = argv[idx_ip]->arg;
        if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
-               if (afi == AFI_IP)
-                       return generic_set_delete(
-                               vty, VTY_GET_CONTEXT(route_map_index),
-                               "ipv4 vpn next-hop", arg);
-               else
-                       return generic_set_delete(
-                               vty, VTY_GET_CONTEXT(route_map_index),
-                               "ipv6 vpn next-hop", arg);
+               if (afi == AFI_IP) {
+                       const char *xpath =
+                               "./set-action[action='frr-bgp-route-map:ipv4-vpn-address']";
+                       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+               } else {
+                       const char *xpath =
+                               "./set-action[action='frr-bgp-route-map:ipv6-vpn-address']";
+                       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+               }
+               return nb_cli_apply_changes(vty, NULL);
        }
        return CMD_SUCCESS;
 }
 
-DEFUN (set_originator_id,
-       set_originator_id_cmd,
-       "set originator-id A.B.C.D",
-       SET_STR
-       "BGP originator ID attribute\n"
-       "IP address of originator\n")
+DEFUN_YANG (set_originator_id,
+           set_originator_id_cmd,
+           "set originator-id A.B.C.D",
+           SET_STR
+          "BGP originator ID attribute\n"
+          "IP address of originator\n")
 {
        int idx_ipv4 = 2;
-       return generic_set_add(vty, VTY_GET_CONTEXT(route_map_index),
-                              "originator-id", argv[idx_ipv4]->arg);
-}
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:originator-id']";
+       char xpath_value[XPATH_MAXLEN];
 
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-set-action/frr-bgp-route-map:originator-id", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
+                             argv[idx_ipv4]->arg);
 
-DEFUN (no_set_originator_id,
-       no_set_originator_id_cmd,
-       "no set originator-id [A.B.C.D]",
-       NO_STR
-       SET_STR
-       "BGP originator ID attribute\n"
-       "IP address of originator\n")
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFUN_YANG (no_set_originator_id,
+           no_set_originator_id_cmd,
+           "no set originator-id [A.B.C.D]",
+           NO_STR
+           SET_STR
+           "BGP originator ID attribute\n"
+           "IP address of originator\n")
 {
-       int idx = 0;
-       char *arg =
-               argv_find(argv, argc, "A.B.C.D", &idx) ? argv[idx]->arg : NULL;
+       const char *xpath =
+               "./set-action[action='frr-bgp-route-map:originator-id']";
 
-       return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index),
-                                 "originator-id", arg);
+       nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-
 /* Initialization of route map. */
 void bgp_route_map_init(void)
 {
diff --git a/bgpd/bgp_routemap_nb.c b/bgpd/bgp_routemap_nb.c
new file mode 100644 (file)
index 0000000..fc59122
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2020        Vmware
+ *                           Sarita Patra
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#include "lib/command.h"
+#include "lib/log.h"
+#include "lib/northbound.h"
+#include "lib/routemap.h"
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_routemap_nb.h"
+
+/* clang-format off */
+const struct frr_yang_module_info frr_bgp_route_map_info = {
+       .name = "frr-bgp-route-map",
+       .nodes = {
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:local-preference",
+                       .cbs = {
+                               .modify = lib_route_map_entry_match_condition_rmap_match_condition_local_preference_modify,
+                               .destroy = lib_route_map_entry_match_condition_rmap_match_condition_local_preference_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:script",
+                       .cbs = {
+                               .modify = lib_route_map_entry_match_condition_rmap_match_condition_script_modify,
+                               .destroy = lib_route_map_entry_match_condition_rmap_match_condition_script_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:origin",
+                       .cbs = {
+                               .modify = lib_route_map_entry_match_condition_rmap_match_condition_origin_modify,
+                               .destroy = lib_route_map_entry_match_condition_rmap_match_condition_origin_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:rpki",
+                       .cbs = {
+                               .modify = lib_route_map_entry_match_condition_rmap_match_condition_rpki_modify,
+                               .destroy = lib_route_map_entry_match_condition_rmap_match_condition_rpki_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:probability",
+                       .cbs = {
+                               .modify = lib_route_map_entry_match_condition_rmap_match_condition_probability_modify,
+                               .destroy = lib_route_map_entry_match_condition_rmap_match_condition_probability_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:source-vrf",
+                       .cbs = {
+                               .modify = lib_route_map_entry_match_condition_rmap_match_condition_source_vrf_modify,
+                               .destroy = lib_route_map_entry_match_condition_rmap_match_condition_source_vrf_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:peer-ipv4-address",
+                       .cbs = {
+                               .modify = lib_route_map_entry_match_condition_rmap_match_condition_peer_ipv4_address_modify,
+                               .destroy = lib_route_map_entry_match_condition_rmap_match_condition_peer_ipv4_address_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:peer-interface",
+                       .cbs = {
+                               .modify = lib_route_map_entry_match_condition_rmap_match_condition_peer_interface_modify,
+                               .destroy = lib_route_map_entry_match_condition_rmap_match_condition_peer_interface_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:peer-ipv6-address",
+                       .cbs = {
+                               .modify = lib_route_map_entry_match_condition_rmap_match_condition_peer_ipv6_address_modify,
+                               .destroy = lib_route_map_entry_match_condition_rmap_match_condition_peer_ipv6_address_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:peer-local",
+                       .cbs = {
+                               .modify = lib_route_map_entry_match_condition_rmap_match_condition_peer_local_modify,
+                               .destroy = lib_route_map_entry_match_condition_rmap_match_condition_peer_local_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:list-name",
+                       .cbs = {
+                               .modify = lib_route_map_entry_match_condition_rmap_match_condition_list_name_modify,
+                               .destroy = lib_route_map_entry_match_condition_rmap_match_condition_list_name_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:evpn-default-route",
+                       .cbs = {
+                               .create = lib_route_map_entry_match_condition_rmap_match_condition_evpn_default_route_create,
+                               .destroy = lib_route_map_entry_match_condition_rmap_match_condition_evpn_default_route_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:evpn-vni",
+                       .cbs = {
+                               .modify = lib_route_map_entry_match_condition_rmap_match_condition_evpn_vni_modify,
+                               .destroy = lib_route_map_entry_match_condition_rmap_match_condition_evpn_vni_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:evpn-route-type",
+                       .cbs = {
+                               .modify = lib_route_map_entry_match_condition_rmap_match_condition_evpn_route_type_modify,
+                               .destroy = lib_route_map_entry_match_condition_rmap_match_condition_evpn_route_type_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:route-distinguisher",
+                       .cbs = {
+                               .modify = lib_route_map_entry_match_condition_rmap_match_condition_route_distinguisher_modify,
+                               .destroy = lib_route_map_entry_match_condition_rmap_match_condition_route_distinguisher_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:comm-list",
+                       .cbs = {
+                               .apply_finish = lib_route_map_entry_match_condition_rmap_match_condition_comm_list_finish,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name",
+                       .cbs = {
+                               .modify = lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_modify,
+                               .destroy = lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match",
+                       .cbs = {
+                               .modify = lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_exact_match_modify,
+                               .destroy = lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_exact_match_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:ipv4-address",
+                       .cbs = {
+                               .modify = lib_route_map_entry_match_condition_rmap_match_condition_ipv4_address_modify,
+                               .destroy = lib_route_map_entry_match_condition_rmap_match_condition_ipv4_address_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:ipv6-address",
+                       .cbs = {
+                               .modify = lib_route_map_entry_match_condition_rmap_match_condition_ipv6_address_modify,
+                               .destroy = lib_route_map_entry_match_condition_rmap_match_condition_ipv6_address_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:distance",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_distance_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_distance_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:extcommunity-rt",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_extcommunity_rt_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_extcommunity_rt_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:extcommunity-soo",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_extcommunity_soo_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_extcommunity_soo_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:ipv4-address",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_ipv4_address_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_ipv4_address_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:ipv4-nexthop",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_ipv4_nexthop_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_ipv4_nexthop_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:ipv6-address",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_ipv6_address_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_ipv6_address_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:preference",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_preference_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_preference_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:label-index",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_label_index_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_label_index_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:local-pref",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_local_pref_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_local_pref_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:weight",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_weight_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_weight_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:origin",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_origin_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_origin_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:originator-id",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_originator_id_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_originator_id_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:table",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_table_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_table_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:atomic-aggregate",
+                       .cbs = {
+                               .create = lib_route_map_entry_set_action_rmap_set_action_atomic_aggregate_create,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_atomic_aggregate_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:prepend-as-path",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_prepend_as_path_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_prepend_as_path_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:last-as",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_last_as_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_last_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:exclude-as-path",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_exclude_as_path_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_exclude_as_path_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:community-none",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_community_none_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_community_none_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:community-string",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_community_string_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_community_string_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:large-community-none",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_large_community_none_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_large_community_none_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:large-community-string",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_large_community_string_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_large_community_string_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:aggregator",
+                       .cbs = {
+                               .apply_finish = lib_route_map_entry_set_action_rmap_set_action_aggregator_finish,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:aggregator/aggregator-asn",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_aggregator_aggregator_asn_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_aggregator_aggregator_asn_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:aggregator/aggregator-address",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_aggregator_aggregator_address_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_aggregator_aggregator_address_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:comm-list-name",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_comm_list_name_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_comm_list_name_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:extcommunity-lb",
+                       .cbs = {
+                               .apply_finish = lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_finish,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:extcommunity-lb/lb-type",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_lb_type_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_lb_type_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:extcommunity-lb/bandwidth",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_bandwidth_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_bandwidth_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:extcommunity-lb/two-octet-as-specific",
+                       .cbs = {
+                               .modify = lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_two_octet_as_specific_modify,
+                               .destroy = lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_two_octet_as_specific_destroy,
+                       }
+               },
+               {
+                       .xpath = NULL,
+               },
+       }
+};
diff --git a/bgpd/bgp_routemap_nb.h b/bgpd/bgp_routemap_nb.h
new file mode 100644 (file)
index 0000000..a15f521
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2020        Vmware
+ *                           Sarita Patra
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _FRR_BGP_ROUTEMAP_NB_H_
+#define _FRR_BGP_ROUTEMAP_NB_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const struct frr_yang_module_info frr_bgp_route_map_info;
+
+/* prototypes */
+int lib_route_map_entry_match_condition_rmap_match_condition_local_preference_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_local_preference_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_script_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_script_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_origin_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_origin_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_rpki_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_rpki_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_probability_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_probability_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_source_vrf_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_source_vrf_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_peer_ipv4_address_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_peer_ipv4_address_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_peer_interface_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_peer_interface_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_peer_ipv6_address_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_peer_ipv6_address_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_peer_local_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_peer_local_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_access_list_num_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_access_list_num_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_access_list_num_extended_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_access_list_num_extended_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_list_name_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_list_name_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_evpn_default_route_create(struct nb_cb_create_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_evpn_default_route_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_evpn_vni_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_evpn_vni_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_evpn_route_type_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_evpn_route_type_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_route_distinguisher_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_route_distinguisher_destroy(struct nb_cb_destroy_args *args);
+void lib_route_map_entry_match_condition_rmap_match_condition_comm_list_finish(struct nb_cb_apply_finish_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_exact_match_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_exact_match_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_ipv4_address_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_ipv4_address_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_ipv6_address_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_match_condition_rmap_match_condition_ipv6_address_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_distance_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_distance_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_extcommunity_rt_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_extcommunity_rt_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_extcommunity_soo_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_extcommunity_soo_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_ipv4_address_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_ipv4_address_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_ipv4_nexthop_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_ipv4_nexthop_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_ipv6_address_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_ipv6_address_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_preference_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_preference_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_label_index_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_label_index_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_local_pref_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_local_pref_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_weight_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_weight_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_origin_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_origin_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_originator_id_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_originator_id_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_table_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_table_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_atomic_aggregate_create(struct nb_cb_create_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_atomic_aggregate_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_prepend_as_path_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_prepend_as_path_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_last_as_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_last_as_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_exclude_as_path_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_exclude_as_path_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_community_none_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_community_none_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_community_string_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_community_string_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_large_community_none_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_large_community_none_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_large_community_string_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_large_community_string_destroy(struct nb_cb_destroy_args *args);
+void lib_route_map_entry_set_action_rmap_set_action_aggregator_finish(struct nb_cb_apply_finish_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_aggregator_aggregator_asn_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_aggregator_aggregator_asn_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_aggregator_aggregator_address_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_aggregator_aggregator_address_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_comm_list_num_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_comm_list_num_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_comm_list_num_extended_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_comm_list_num_extended_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_comm_list_name_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_comm_list_name_destroy(struct nb_cb_destroy_args *args);
+void lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_finish(struct nb_cb_apply_finish_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_lb_type_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_lb_type_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_bandwidth_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_bandwidth_destroy(struct nb_cb_destroy_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_two_octet_as_specific_modify(struct nb_cb_modify_args *args);
+int lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_two_octet_as_specific_destroy(struct nb_cb_destroy_args *args);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/bgpd/bgp_routemap_nb_config.c b/bgpd/bgp_routemap_nb_config.c
new file mode 100644 (file)
index 0000000..ec62842
--- /dev/null
@@ -0,0 +1,2637 @@
+/*
+ * Copyright (C) 2020        Vmware
+ *                           Sarita Patra
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "lib/command.h"
+#include "lib/log.h"
+#include "lib/northbound.h"
+#include "lib/routemap.h"
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_routemap_nb.h"
+
+/* Add bgp route map rule. */
+static int bgp_route_match_add(struct route_map_index *index,
+               const char *command, const char *arg,
+               route_map_event_t type,
+               char *errmsg, size_t errmsg_len)
+{
+       int retval = CMD_SUCCESS;
+       enum rmap_compile_rets ret;
+
+       ret = route_map_add_match(index, command, arg, type);
+       switch (ret) {
+       case RMAP_RULE_MISSING:
+               snprintf(errmsg, errmsg_len, "%% BGP Can't find rule.");
+               retval = CMD_WARNING_CONFIG_FAILED;
+               break;
+       case RMAP_COMPILE_ERROR:
+               snprintf(errmsg, errmsg_len, "%% BGP Argument is malformed.");
+               retval = CMD_WARNING_CONFIG_FAILED;
+               break;
+       case RMAP_COMPILE_SUCCESS:
+               /*
+                * Intentionally doing nothing here.
+                */
+               break;
+       }
+
+       return retval;
+}
+
+/* Delete bgp route map rule. */
+static int bgp_route_match_delete(struct route_map_index *index,
+               const char *command, const char *arg,
+               route_map_event_t type,
+               char *errmsg, size_t errmsg_len)
+{
+       enum rmap_compile_rets ret;
+       int retval = CMD_SUCCESS;
+       char *dep_name = NULL;
+       const char *tmpstr;
+       char *rmap_name = NULL;
+
+       if (type != RMAP_EVENT_MATCH_DELETED) {
+               /* ignore the mundane, the types without any dependency */
+               if (arg == NULL) {
+                       if ((tmpstr = route_map_get_match_arg(index, command))
+                                       != NULL)
+                               dep_name =
+                                       XSTRDUP(MTYPE_ROUTE_MAP_RULE, tmpstr);
+               } else {
+                       dep_name = XSTRDUP(MTYPE_ROUTE_MAP_RULE, arg);
+               }
+               rmap_name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, index->map->name);
+       }
+
+       ret = route_map_delete_match(index, command, dep_name, type);
+       switch (ret) {
+               case RMAP_RULE_MISSING:
+                       snprintf(errmsg, errmsg_len, "%% BGP Can't find rule.");
+                       retval = CMD_WARNING_CONFIG_FAILED;
+                       break;
+               case RMAP_COMPILE_ERROR:
+                       snprintf(errmsg, errmsg_len,
+                                "%% BGP Argument is malformed.");
+                       retval = CMD_WARNING_CONFIG_FAILED;
+                       break;
+               case RMAP_COMPILE_SUCCESS:
+                       /*
+                        * Nothing to do here
+                        */
+                       break;
+       }
+
+       XFREE(MTYPE_ROUTE_MAP_RULE, dep_name);
+       XFREE(MTYPE_ROUTE_MAP_NAME, rmap_name);
+
+       return retval;
+}
+
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:local-preference
+ */
+int
+lib_route_map_entry_match_condition_rmap_match_condition_local_preference_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *local_pref;
+       enum rmap_compile_rets ret;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               local_pref = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_mhook = bgp_route_match_delete;
+               rhc->rhc_rule = "local-preference";
+               rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
+
+               ret = bgp_route_match_add(rhc->rhc_rmi, "local-preference",
+                               local_pref, RMAP_EVENT_MATCH_ADDED,
+                               args->errmsg, args->errmsg_len);
+
+               if (ret != RMAP_COMPILE_SUCCESS) {
+                       rhc->rhc_mhook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+               return NB_OK;
+}
+
+int
+lib_route_map_entry_match_condition_rmap_match_condition_local_preference_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:script
+ */
+int
+lib_route_map_entry_match_condition_rmap_match_condition_script_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *script;
+       enum rmap_compile_rets ret;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               script = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_mhook = bgp_route_match_delete;
+               rhc->rhc_rule = "script";
+               rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
+
+               ret = bgp_route_match_add(rhc->rhc_rmi, "script",
+                               script, RMAP_EVENT_MATCH_ADDED,
+                               args->errmsg, args->errmsg_len);
+
+               if (ret != RMAP_COMPILE_SUCCESS) {
+                       rhc->rhc_mhook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_match_condition_rmap_match_condition_script_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:origin
+ */
+int
+lib_route_map_entry_match_condition_rmap_match_condition_origin_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *origin;
+       enum rmap_compile_rets ret;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               origin = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_mhook = bgp_route_match_delete;
+               rhc->rhc_rule = "origin";
+               rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
+
+               ret = bgp_route_match_add(rhc->rhc_rmi, "origin", origin,
+                                         RMAP_EVENT_MATCH_ADDED,
+                                         args->errmsg, args->errmsg_len);
+
+               if (ret != RMAP_COMPILE_SUCCESS) {
+                       rhc->rhc_mhook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_match_condition_rmap_match_condition_origin_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:rpki
+ */
+int
+lib_route_map_entry_match_condition_rmap_match_condition_rpki_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *rpki;
+       enum rmap_compile_rets ret;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               rpki = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_mhook = bgp_route_match_delete;
+               rhc->rhc_rule = "rpki";
+               rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
+
+               ret = bgp_route_match_add(rhc->rhc_rmi, "rpki", rpki,
+                               RMAP_EVENT_MATCH_ADDED,
+                               args->errmsg, args->errmsg_len);
+
+               if (ret != RMAP_COMPILE_SUCCESS) {
+                       rhc->rhc_mhook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_match_condition_rmap_match_condition_rpki_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:probability
+ */
+int
+lib_route_map_entry_match_condition_rmap_match_condition_probability_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *probability;
+       enum rmap_compile_rets ret;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               probability = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_mhook = bgp_route_match_delete;
+               rhc->rhc_rule = "probability";
+               rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
+
+               ret = bgp_route_match_add(rhc->rhc_rmi, "probability",
+                                         probability, RMAP_EVENT_MATCH_ADDED,
+                                         args->errmsg, args->errmsg_len);
+
+               if (ret != RMAP_COMPILE_SUCCESS) {
+                       rhc->rhc_mhook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_match_condition_rmap_match_condition_probability_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:source-vrf
+ */
+int
+lib_route_map_entry_match_condition_rmap_match_condition_source_vrf_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *vrf;
+       enum rmap_compile_rets ret;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               vrf = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_mhook = bgp_route_match_delete;
+               rhc->rhc_rule = "source-vrf";
+               rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
+
+               ret = bgp_route_match_add(rhc->rhc_rmi, "source-vrf", vrf,
+                                         RMAP_EVENT_MATCH_ADDED,
+                                         args->errmsg, args->errmsg_len);
+
+               if (ret != RMAP_COMPILE_SUCCESS) {
+                       rhc->rhc_mhook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_match_condition_rmap_match_condition_source_vrf_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:peer-ipv4-address
+ */
+int
+lib_route_map_entry_match_condition_rmap_match_condition_peer_ipv4_address_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *peer;
+       enum rmap_compile_rets ret;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               peer = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_mhook = bgp_route_match_delete;
+               rhc->rhc_rule = "peer";
+               rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
+
+               ret = bgp_route_match_add(rhc->rhc_rmi, "peer", peer,
+                                         RMAP_EVENT_MATCH_ADDED,
+                                         args->errmsg, args->errmsg_len);
+
+               if (ret != RMAP_COMPILE_SUCCESS) {
+                       rhc->rhc_mhook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_match_condition_rmap_match_condition_peer_ipv4_address_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:peer-interface
+ */
+int
+lib_route_map_entry_match_condition_rmap_match_condition_peer_interface_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *peer;
+       enum rmap_compile_rets ret;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               peer = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_mhook = bgp_route_match_delete;
+               rhc->rhc_rule = "peer";
+               rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
+
+               ret = bgp_route_match_add(rhc->rhc_rmi, "peer", peer,
+                               RMAP_EVENT_MATCH_ADDED,
+                               args->errmsg, args->errmsg_len);
+
+               if (ret != RMAP_COMPILE_SUCCESS) {
+                       rhc->rhc_mhook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_match_condition_rmap_match_condition_peer_interface_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:peer-ipv6-address
+ */
+int
+lib_route_map_entry_match_condition_rmap_match_condition_peer_ipv6_address_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *peer;
+       enum rmap_compile_rets ret;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               peer = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_mhook = bgp_route_match_delete;
+               rhc->rhc_rule = "peer";
+               rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
+
+               ret = bgp_route_match_add(rhc->rhc_rmi, "peer", peer,
+                               RMAP_EVENT_MATCH_ADDED,
+                               args->errmsg, args->errmsg_len);
+
+               if (ret != RMAP_COMPILE_SUCCESS) {
+                       rhc->rhc_mhook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_match_condition_rmap_match_condition_peer_ipv6_address_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:peer-local
+ */
+int
+lib_route_map_entry_match_condition_rmap_match_condition_peer_local_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       bool value;
+       enum rmap_compile_rets ret;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               value = yang_dnode_get_bool(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_mhook = bgp_route_match_delete;
+               rhc->rhc_rule = "peer";
+               rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
+
+               if (value) {
+                       ret = bgp_route_match_add(rhc->rhc_rmi, "peer",
+                                               "local",
+                                               RMAP_EVENT_MATCH_ADDED,
+                                               args->errmsg, args->errmsg_len);
+
+                       if (ret != RMAP_COMPILE_SUCCESS) {
+                               rhc->rhc_mhook = NULL;
+                               return NB_ERR_INCONSISTENCY;
+                       }
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_match_condition_rmap_match_condition_peer_local_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:list-name
+ */
+int
+lib_route_map_entry_match_condition_rmap_match_condition_list_name_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *list_name;
+       enum rmap_compile_rets ret = RMAP_COMPILE_SUCCESS;
+       const char *condition;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               list_name = yang_dnode_get_string(args->dnode, NULL);
+               condition = yang_dnode_get_string(args->dnode,
+                               "../../frr-route-map:condition");
+
+               if (IS_MATCH_AS_LIST(condition)) {
+                       /* Set destroy information. */
+                       rhc->rhc_mhook = bgp_route_match_delete;
+                       rhc->rhc_rule = "as-path";
+                       rhc->rhc_event = RMAP_EVENT_ASLIST_DELETED;
+
+                       ret = bgp_route_match_add(rhc->rhc_rmi, "as-path",
+                                       list_name, RMAP_EVENT_ASLIST_ADDED,
+                                       args->errmsg, args->errmsg_len);
+               } else if (IS_MATCH_MAC_LIST(condition)) {
+                       /* Set destroy information. */
+                       rhc->rhc_mhook = bgp_route_match_delete;
+                       rhc->rhc_rule = "mac address";
+                       rhc->rhc_event = RMAP_EVENT_FILTER_DELETED;
+
+                       ret = bgp_route_match_add(rhc->rhc_rmi,
+                                                 "mac address",
+                                                 list_name,
+                                                 RMAP_EVENT_FILTER_ADDED,
+                                                 args->errmsg, args->errmsg_len);
+               } else if (IS_MATCH_ROUTE_SRC(condition)) {
+                       /* Set destroy information. */
+                       rhc->rhc_mhook = bgp_route_match_delete;
+                       rhc->rhc_rule = "ip route-source";
+                       rhc->rhc_event = RMAP_EVENT_FILTER_DELETED;
+
+                       ret = bgp_route_match_add(rhc->rhc_rmi,
+                                       "ip route-source",
+                                       list_name, RMAP_EVENT_FILTER_ADDED,
+                                       args->errmsg, args->errmsg_len);
+               } else if (IS_MATCH_ROUTE_SRC_PL(condition)) {
+                       /* Set destroy information. */
+                       rhc->rhc_mhook = bgp_route_match_delete;
+                       rhc->rhc_rule = "ip route-source prefix-list";
+                       rhc->rhc_event = RMAP_EVENT_PLIST_DELETED;
+
+                       ret = bgp_route_match_add(rhc->rhc_rmi,
+                                       "ip route-source prefix-list",
+                                       list_name, RMAP_EVENT_PLIST_ADDED,
+                                       args->errmsg, args->errmsg_len);
+               }
+
+               if (ret != RMAP_COMPILE_SUCCESS) {
+                       rhc->rhc_mhook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_match_condition_rmap_match_condition_list_name_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:evpn-default-route
+ */
+int
+lib_route_map_entry_match_condition_rmap_match_condition_evpn_default_route_create(
+       struct nb_cb_create_args *args)
+{
+       struct routemap_hook_context *rhc;
+       enum rmap_compile_rets ret;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+
+               /* Set destroy information. */
+               rhc->rhc_mhook = bgp_route_match_delete;
+               rhc->rhc_rule = "evpn default-route";
+               rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
+
+               ret = bgp_route_match_add(rhc->rhc_rmi, "evpn default-route",
+                                         NULL, RMAP_EVENT_MATCH_ADDED,
+                                         args->errmsg, args->errmsg_len);
+
+               if (ret != RMAP_COMPILE_SUCCESS) {
+                       rhc->rhc_mhook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_match_condition_rmap_match_condition_evpn_default_route_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:evpn-vni
+ */
+int
+lib_route_map_entry_match_condition_rmap_match_condition_evpn_vni_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *vni;
+       enum rmap_compile_rets ret;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               vni = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_mhook = bgp_route_match_delete;
+               rhc->rhc_rule = "evpn vni";
+               rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
+
+               ret = bgp_route_match_add(rhc->rhc_rmi, "evpn vni", vni,
+                               RMAP_EVENT_MATCH_ADDED,
+                               args->errmsg, args->errmsg_len);
+
+               if (ret != RMAP_COMPILE_SUCCESS) {
+                       rhc->rhc_mhook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_match_condition_rmap_match_condition_evpn_vni_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:evpn-route-type
+ */
+int
+lib_route_map_entry_match_condition_rmap_match_condition_evpn_route_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *type;
+       enum rmap_compile_rets ret;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               type = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_mhook = bgp_route_match_delete;
+               rhc->rhc_rule = "evpn route-type";
+               rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
+
+               ret = bgp_route_match_add(rhc->rhc_rmi, "evpn route-type",
+                                         type,
+                                         RMAP_EVENT_MATCH_ADDED,
+                                         args->errmsg, args->errmsg_len);
+
+               if (ret != RMAP_COMPILE_SUCCESS) {
+                       rhc->rhc_mhook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_match_condition_rmap_match_condition_evpn_route_type_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:route-distinguisher
+ */
+int
+lib_route_map_entry_match_condition_rmap_match_condition_route_distinguisher_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *rd;
+       enum rmap_compile_rets ret;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               rd = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_mhook = bgp_route_match_delete;
+               rhc->rhc_rule = "evpn rd";
+               rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
+
+               ret = bgp_route_match_add(rhc->rhc_rmi, "evpn rd", rd,
+                               RMAP_EVENT_MATCH_ADDED,
+                               args->errmsg, args->errmsg_len);
+
+               if (ret != RMAP_COMPILE_SUCCESS) {
+                       rhc->rhc_mhook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_match_condition_rmap_match_condition_route_distinguisher_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath = /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:comm-list
+ */
+void
+lib_route_map_entry_match_condition_rmap_match_condition_comm_list_finish(
+       struct nb_cb_apply_finish_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *value;
+       bool exact_match = false;
+       char *argstr;
+       const char *condition;
+       route_map_event_t event;
+
+       /* Add configuration. */
+       rhc = nb_running_get_entry(args->dnode, NULL, true);
+       value = yang_dnode_get_string(args->dnode, "./comm-list-name");
+
+       if (yang_dnode_exists(args->dnode, "./comm-list-name-exact-match"))
+               exact_match = yang_dnode_get_bool(
+                       args->dnode, "./comm-list-name-exact-match");
+
+       if (exact_match) {
+               argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED,
+                                strlen(value) + strlen("exact-match") + 2);
+
+               snprintf(argstr, (strlen(value) + strlen("exact-match") + 2),
+                        "%s exact-match", value);
+       } else
+               argstr = (char *)value;
+
+       /* Set destroy information. */
+       rhc->rhc_mhook = bgp_route_match_delete;
+
+       condition = yang_dnode_get_string(args->dnode,
+                                         "../../frr-route-map:condition");
+       if (IS_MATCH_COMMUNITY(condition)) {
+               rhc->rhc_rule = "community";
+               event = RMAP_EVENT_CLIST_ADDED;
+               rhc->rhc_event = RMAP_EVENT_CLIST_DELETED;
+       } else if (IS_MATCH_LCOMMUNITY(condition)) {
+               rhc->rhc_rule = "large-community";
+               event = RMAP_EVENT_LLIST_ADDED;
+               rhc->rhc_event = RMAP_EVENT_LLIST_DELETED;
+       } else {
+               rhc->rhc_rule = "extcommunity";
+               event = RMAP_EVENT_ECLIST_ADDED;
+               rhc->rhc_event = RMAP_EVENT_ECLIST_DELETED;
+       }
+
+       bgp_route_match_add(rhc->rhc_rmi, rhc->rhc_rule, argstr, event,
+                           args->errmsg, args->errmsg_len);
+
+       if (argstr != value)
+               XFREE(MTYPE_ROUTE_MAP_COMPILED, argstr);
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name
+ */
+int
+lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               break;
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+
+}
+
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:comm-list/comm-list-name-exact-match
+ */
+int
+lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_exact_match_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               break;
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_match_condition_rmap_match_condition_comm_list_comm_list_name_exact_match_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:ipv4-address
+ */
+int
+lib_route_map_entry_match_condition_rmap_match_condition_ipv4_address_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *peer;
+       enum rmap_compile_rets ret;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               peer = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_mhook = bgp_route_match_delete;
+               rhc->rhc_rule = "ip next-hop address";
+               rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
+
+               ret = bgp_route_match_add(rhc->rhc_rmi, rhc->rhc_rule,
+                                         peer, RMAP_EVENT_MATCH_ADDED,
+                                         args->errmsg, args->errmsg_len);
+
+               if (ret != RMAP_COMPILE_SUCCESS) {
+                       rhc->rhc_mhook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_match_condition_rmap_match_condition_ipv4_address_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath: /frr-route-map:lib/route-map/entry/match-condition/rmap-match-condition/frr-bgp-route-map:ipv6-address
+ */
+int
+lib_route_map_entry_match_condition_rmap_match_condition_ipv6_address_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *peer;
+       enum rmap_compile_rets ret;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               peer = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_mhook = bgp_route_match_delete;
+               rhc->rhc_rule = "ipv6 next-hop";
+               rhc->rhc_event = RMAP_EVENT_MATCH_DELETED;
+
+               ret = bgp_route_match_add(rhc->rhc_rmi, rhc->rhc_rule,
+                                         peer, RMAP_EVENT_MATCH_ADDED,
+                                         args->errmsg, args->errmsg_len);
+
+               if (ret != RMAP_COMPILE_SUCCESS) {
+                       rhc->rhc_mhook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_match_condition_rmap_match_condition_ipv6_address_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:distance
+ */
+int lib_route_map_entry_set_action_rmap_set_action_distance_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *type;
+       int rv;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               type = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_rule = "distance";
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               rv = generic_set_add(rhc->rhc_rmi, "distance", type,
+                                    args->errmsg, args->errmsg_len);
+               if (rv != CMD_SUCCESS) {
+                       rhc->rhc_shook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int lib_route_map_entry_set_action_rmap_set_action_distance_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:extcommunity-rt
+ */
+int
+lib_route_map_entry_set_action_rmap_set_action_extcommunity_rt_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *type;
+       int rv;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               type = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_rule = "extcommunity rt";
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               rv = generic_set_add(rhc->rhc_rmi, "extcommunity rt", type,
+                                    args->errmsg, args->errmsg_len);
+               if (rv != CMD_SUCCESS) {
+                       rhc->rhc_shook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_set_action_rmap_set_action_extcommunity_rt_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:extcommunity-soo
+ */
+int
+lib_route_map_entry_set_action_rmap_set_action_extcommunity_soo_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *type;
+       int rv;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               type = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_rule = "extcommunity soo";
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               rv = generic_set_add(rhc->rhc_rmi, "extcommunity soo",
+                                    type,
+                                    args->errmsg, args->errmsg_len);
+               if (rv != CMD_SUCCESS) {
+                       rhc->rhc_shook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_set_action_rmap_set_action_extcommunity_soo_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_match_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:ipv4-address
+ */
+int lib_route_map_entry_set_action_rmap_set_action_ipv4_address_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *addr;
+       int rv = CMD_SUCCESS;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               addr = yang_dnode_get_string(args->dnode, NULL);
+
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+               rhc->rhc_rule = "ipv4 vpn next-hop";
+
+               rv = generic_set_add(rhc->rhc_rmi, rhc->rhc_rule, addr,
+                                    args->errmsg, args->errmsg_len);
+
+               if (rv != CMD_SUCCESS) {
+                       rhc->rhc_shook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int lib_route_map_entry_set_action_rmap_set_action_ipv4_address_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:ipv4-nexthop
+ */
+int lib_route_map_entry_set_action_rmap_set_action_ipv4_nexthop_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *type;
+       int rv;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               type = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_rule = "ip next-hop";
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               rv = generic_set_add(rhc->rhc_rmi, rhc->rhc_rule, type,
+                                   args->errmsg, args->errmsg_len);
+
+               if (rv != CMD_SUCCESS) {
+                       rhc->rhc_shook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int lib_route_map_entry_set_action_rmap_set_action_ipv4_nexthop_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:ipv6-address
+ */
+int lib_route_map_entry_set_action_rmap_set_action_ipv6_address_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *addr;
+       int rv = CMD_SUCCESS;
+       const char *action = NULL;
+       struct in6_addr i6a;
+
+       action = yang_dnode_get_string(args->dnode,
+                                      "../../frr-route-map:action");
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               if (action && IS_SET_IPV6_NH_GLOBAL(action)) {
+                       yang_dnode_get_ipv6(&i6a, args->dnode, NULL);
+                       if (IN6_IS_ADDR_UNSPECIFIED(&i6a)
+                           || IN6_IS_ADDR_LOOPBACK(&i6a)
+                           || IN6_IS_ADDR_MULTICAST(&i6a)
+                           || IN6_IS_ADDR_LINKLOCAL(&i6a))
+                               return NB_ERR_VALIDATION;
+               }
+       /* FALLTHROUGH */
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               break;
+       }
+
+       /* Add configuration. */
+       rhc = nb_running_get_entry(args->dnode, NULL, true);
+       addr = yang_dnode_get_string(args->dnode, NULL);
+
+       rhc->rhc_shook = generic_set_delete;
+       rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+       if (IS_SET_IPV6_NH_GLOBAL(action))
+               /* Set destroy information. */
+               rhc->rhc_rule = "ipv6 next-hop global";
+       else
+               rhc->rhc_rule = "ipv6 vpn next-hop";
+
+       rv = generic_set_add(rhc->rhc_rmi, rhc->rhc_rule, addr,
+                            args->errmsg, args->errmsg_len);
+
+       if (rv != CMD_SUCCESS) {
+               rhc->rhc_shook = NULL;
+               return NB_ERR_INCONSISTENCY;
+       }
+
+       return NB_OK;
+}
+
+int lib_route_map_entry_set_action_rmap_set_action_ipv6_address_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:preference
+ */
+int lib_route_map_entry_set_action_rmap_set_action_preference_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       int rv = CMD_SUCCESS;
+       const char *action = NULL;
+       bool value;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               value = yang_dnode_get_bool(args->dnode, NULL);
+
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               action = yang_dnode_get_string(args->dnode,
+                               "../../frr-route-map:action");
+
+               if (value) {
+                       if (IS_SET_IPV6_PEER_ADDR(action))
+                               /* Set destroy information. */
+                               rhc->rhc_rule = "ipv6 next-hop peer-address";
+                       else
+                               rhc->rhc_rule = "ipv6 next-hop prefer-global";
+
+                       rv = generic_set_add(rhc->rhc_rmi, rhc->rhc_rule,
+                                            NULL,
+                                            args->errmsg, args->errmsg_len);
+               }
+
+               if (rv != CMD_SUCCESS) {
+                       rhc->rhc_shook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int lib_route_map_entry_set_action_rmap_set_action_preference_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:label-index
+ */
+int lib_route_map_entry_set_action_rmap_set_action_label_index_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *type;
+       int rv;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               type = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_rule = "label-index";
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               rv = generic_set_add(rhc->rhc_rmi, "label-index", type,
+                                    args->errmsg, args->errmsg_len);
+               if (rv != CMD_SUCCESS) {
+                       rhc->rhc_shook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int lib_route_map_entry_set_action_rmap_set_action_label_index_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:local-pref
+ */
+int lib_route_map_entry_set_action_rmap_set_action_local_pref_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *type;
+       int rv;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               type = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_rule = "local-preference";
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               rv = generic_set_add(rhc->rhc_rmi, "local-preference",
+                                    type,
+                                    args->errmsg, args->errmsg_len);
+               if (rv != CMD_SUCCESS) {
+                       rhc->rhc_shook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int lib_route_map_entry_set_action_rmap_set_action_local_pref_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:weight
+ */
+int lib_route_map_entry_set_action_rmap_set_action_weight_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *type;
+       int rv;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               type = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_rule = "weight";
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               rv = generic_set_add(rhc->rhc_rmi, "weight", type,
+                                    args->errmsg, args->errmsg_len);
+               if (rv != CMD_SUCCESS) {
+                       rhc->rhc_shook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int lib_route_map_entry_set_action_rmap_set_action_weight_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:origin
+ */
+int lib_route_map_entry_set_action_rmap_set_action_origin_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *type;
+       int rv;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               type = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_rule = "origin";
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               rv = generic_set_add(rhc->rhc_rmi, "origin", type,
+                                    args->errmsg, args->errmsg_len);
+               if (rv != CMD_SUCCESS) {
+                       rhc->rhc_shook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int lib_route_map_entry_set_action_rmap_set_action_origin_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:originator-id
+ */
+int lib_route_map_entry_set_action_rmap_set_action_originator_id_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *type;
+       int rv;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               type = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_rule = "originator-id";
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               rv = generic_set_add(rhc->rhc_rmi, "originator-id", type,
+                                    args->errmsg, args->errmsg_len);
+               if (rv != CMD_SUCCESS) {
+                       rhc->rhc_shook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int lib_route_map_entry_set_action_rmap_set_action_originator_id_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:table
+ */
+int lib_route_map_entry_set_action_rmap_set_action_table_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *type;
+       int rv;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               type = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_rule = "table";
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               rv = generic_set_add(rhc->rhc_rmi, "table", type,
+                                    args->errmsg, args->errmsg_len);
+               if (rv != CMD_SUCCESS) {
+                       rhc->rhc_shook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int lib_route_map_entry_set_action_rmap_set_action_table_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:atomic-aggregate
+ */
+int
+lib_route_map_entry_set_action_rmap_set_action_atomic_aggregate_create(
+       struct nb_cb_create_args *args)
+{
+       struct routemap_hook_context *rhc;
+       int rv;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+
+               /* Set destroy information. */
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_rule = "atomic-aggregate";
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               rv = generic_set_add(rhc->rhc_rmi, rhc->rhc_rule, NULL,
+                                    args->errmsg, args->errmsg_len);
+               if (rv != CMD_SUCCESS) {
+                       rhc->rhc_shook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_set_action_rmap_set_action_atomic_aggregate_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:prepend-as-path
+ */
+int
+lib_route_map_entry_set_action_rmap_set_action_prepend_as_path_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *type;
+       int rv;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               type = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_rule = "as-path prepend";
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               rv = generic_set_add(rhc->rhc_rmi, "as-path prepend",
+                                    type,
+                                    args->errmsg, args->errmsg_len);
+               if (rv != CMD_SUCCESS) {
+                       rhc->rhc_shook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_set_action_rmap_set_action_prepend_as_path_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:last-as
+ */
+int lib_route_map_entry_set_action_rmap_set_action_last_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *value;
+       char *argstr;
+       int rv;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               value = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_rule = "as-path prepend";
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED,
+                               strlen(value) + strlen("last-as") + 2);
+
+               snprintf(argstr, (strlen(value) + strlen("last-as") + 2),
+                        "last-as %s", value);
+
+               rv = generic_set_add(rhc->rhc_rmi, "as-path prepend",
+                                    argstr,
+                                    args->errmsg, args->errmsg_len);
+               if (rv != CMD_SUCCESS) {
+                       rhc->rhc_shook = NULL;
+                       XFREE(MTYPE_ROUTE_MAP_COMPILED, argstr);
+                       return NB_ERR_INCONSISTENCY;
+               }
+
+               XFREE(MTYPE_ROUTE_MAP_COMPILED, argstr);
+       }
+
+       return NB_OK;
+}
+
+int lib_route_map_entry_set_action_rmap_set_action_last_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:exclude-as-path
+ */
+int
+lib_route_map_entry_set_action_rmap_set_action_exclude_as_path_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *type;
+       int rv;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               type = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_rule = "as-path exclude";
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               rv = generic_set_add(rhc->rhc_rmi, "as-path exclude",
+                                    type,
+                                    args->errmsg, args->errmsg_len);
+               if (rv != CMD_SUCCESS) {
+                       rhc->rhc_shook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_set_action_rmap_set_action_exclude_as_path_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:community-none
+ */
+int lib_route_map_entry_set_action_rmap_set_action_community_none_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       bool none = false;
+       int rv;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               none = yang_dnode_get_bool(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_rule = "community";
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               if (none) {
+                       rv = generic_set_add(rhc->rhc_rmi, "community",
+                                            "none",
+                                            args->errmsg, args->errmsg_len);
+                       if (rv != CMD_SUCCESS) {
+                               rhc->rhc_shook = NULL;
+                               return NB_ERR_INCONSISTENCY;
+                       }
+                       return NB_OK;
+               }
+
+               return NB_ERR_INCONSISTENCY;
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_set_action_rmap_set_action_community_none_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:community-string
+ */
+int
+lib_route_map_entry_set_action_rmap_set_action_community_string_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *type;
+       int rv;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               type = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_rule = "community";
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               rv = generic_set_add(rhc->rhc_rmi, "community", type,
+                                    args->errmsg, args->errmsg_len);
+               if (rv != CMD_SUCCESS) {
+                       rhc->rhc_shook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_set_action_rmap_set_action_community_string_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:large-community-none
+ */
+int
+lib_route_map_entry_set_action_rmap_set_action_large_community_none_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       bool none = false;
+       int rv;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               none = yang_dnode_get_bool(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_rule = "large-community";
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               if (none) {
+                       rv = generic_set_add(rhc->rhc_rmi,
+                                            "large-community",
+                                            "none",
+                                             args->errmsg, args->errmsg_len);
+                       if (rv != CMD_SUCCESS) {
+                               rhc->rhc_shook = NULL;
+                               return NB_ERR_INCONSISTENCY;
+                       }
+               return NB_OK;
+               }
+
+               return NB_ERR_INCONSISTENCY;
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_set_action_rmap_set_action_large_community_none_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:large-community-string
+ */
+int
+lib_route_map_entry_set_action_rmap_set_action_large_community_string_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *type;
+       int rv;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               type = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_shook = generic_set_delete;
+               rhc->rhc_rule = "large-community";
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               rv = generic_set_add(rhc->rhc_rmi, "large-community",
+                                    type,
+                                    args->errmsg, args->errmsg_len);
+               if (rv != CMD_SUCCESS) {
+                       rhc->rhc_shook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_set_action_rmap_set_action_large_community_string_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * xpath =
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:aggregator
+ */
+void lib_route_map_entry_set_action_rmap_set_action_aggregator_finish(
+       struct nb_cb_apply_finish_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *asn;
+       const char *addr;
+       char *argstr;
+
+       /* Add configuration. */
+       rhc = nb_running_get_entry(args->dnode, NULL, true);
+       asn = yang_dnode_get_string(args->dnode, "./aggregator-asn");
+       addr = yang_dnode_get_string(args->dnode, "./aggregator-address");
+
+       argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED,
+                        strlen(asn) + strlen(addr) + 2);
+
+       snprintf(argstr, (strlen(asn) + strlen(addr) + 2), "%s %s", asn, addr);
+
+       /* Set destroy information. */
+       rhc->rhc_shook = generic_set_delete;
+       rhc->rhc_rule = "aggregator as";
+       rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+       generic_set_add(rhc->rhc_rmi, rhc->rhc_rule, argstr,
+                       args->errmsg, args->errmsg_len);
+       XFREE(MTYPE_ROUTE_MAP_COMPILED, argstr);
+}
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:aggregator/aggregator-asn
+ */
+int
+lib_route_map_entry_set_action_rmap_set_action_aggregator_aggregator_asn_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               break;
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_set_action_rmap_set_action_aggregator_aggregator_asn_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:aggregator/aggregator-address
+ */
+int
+lib_route_map_entry_set_action_rmap_set_action_aggregator_aggregator_address_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               break;
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_set_action_rmap_set_action_aggregator_aggregator_address_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:comm-list-name
+ */
+int lib_route_map_entry_set_action_rmap_set_action_comm_list_name_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct routemap_hook_context *rhc;
+       const char *value;
+       const char *action;
+       int rv = CMD_SUCCESS;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               /* Add configuration. */
+               rhc = nb_running_get_entry(args->dnode, NULL, true);
+               value = yang_dnode_get_string(args->dnode, NULL);
+
+               /* Set destroy information. */
+               rhc->rhc_shook = generic_set_delete;
+
+               action = yang_dnode_get_string(args->dnode,
+                               "../../frr-route-map:action");
+               if (IS_SET_COMM_LIST_DEL(action))
+                       rhc->rhc_rule = "comm-list";
+               else
+                       rhc->rhc_rule = "large-comm-list";
+
+               rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+               rv = generic_set_add(rhc->rhc_rmi, rhc->rhc_rule, value,
+                                    args->errmsg, args->errmsg_len);
+
+               if (rv != CMD_SUCCESS) {
+                       rhc->rhc_shook = NULL;
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_set_action_rmap_set_action_comm_list_name_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               break;
+       case NB_EV_APPLY:
+               return lib_route_map_entry_set_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+enum e_community_lb_type {
+       EXPLICIT_BANDWIDTH,
+       CUMULATIVE_BANDWIDTH,
+       COMPUTED_BANDWIDTH
+};
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:extcommunity-lb
+ */
+void
+lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_finish(
+       struct nb_cb_apply_finish_args *args)
+{
+       struct routemap_hook_context *rhc;
+       int lb_type;
+       char str[VTY_BUFSIZ];
+       uint16_t bandwidth;
+
+       /* Add configuration. */
+       rhc = nb_running_get_entry(args->dnode, NULL, true);
+       lb_type = yang_dnode_get_enum(args->dnode, "./lb-type");
+
+       /* Set destroy information. */
+       rhc->rhc_shook = generic_set_delete;
+       rhc->rhc_rule = "extcommunity bandwidth";
+       rhc->rhc_event = RMAP_EVENT_SET_DELETED;
+
+       switch (lb_type) {
+       case EXPLICIT_BANDWIDTH:
+               bandwidth = yang_dnode_get_uint16(args->dnode, "./bandwidth");
+               snprintf(str, sizeof(str), "%d", bandwidth);
+               break;
+       case CUMULATIVE_BANDWIDTH:
+               snprintf(str, sizeof(str), "%s", "cumulative");
+               break;
+       case COMPUTED_BANDWIDTH:
+               snprintf(str, sizeof(str), "%s", "num-multipaths");
+       }
+
+       if (yang_dnode_get_bool(args->dnode, "./two-octet-as-specific"))
+               strlcat(str, " non-transitive", sizeof(str));
+
+       generic_set_add(rhc->rhc_rmi,
+                       "extcommunity bandwidth", str,
+                       args->errmsg, args->errmsg_len);
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:extcommunity-lb/lb-type
+ */
+int
+lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_lb_type_modify(
+               struct nb_cb_modify_args *args)
+{
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_lb_type_destroy(
+               struct nb_cb_destroy_args *args)
+{
+       return lib_route_map_entry_set_destroy(args);
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:extcommunity-lb/bandwidth
+ */
+int
+lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_bandwidth_modify(
+               struct nb_cb_modify_args *args)
+{
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_bandwidth_destroy(
+               struct nb_cb_destroy_args *args)
+{
+       return lib_route_map_entry_set_destroy(args);
+}
+
+/*
+ * XPath:
+ * /frr-route-map:lib/route-map/entry/set-action/rmap-set-action/frr-bgp-route-map:extcommunity-lb/two-octet-as-specific
+ */
+int
+lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_two_octet_as_specific_modify(
+       struct nb_cb_modify_args *args)
+{
+       return NB_OK;
+}
+
+int
+lib_route_map_entry_set_action_rmap_set_action_extcommunity_lb_two_octet_as_specific_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       return lib_route_map_entry_set_destroy(args);
+}
index 3ef0137ba6b27ec17d0da6479d2816a5665d3081..3d4902aa47943a2d7174fabbee96b5ca7ad40452 100644 (file)
@@ -1164,7 +1164,7 @@ DEFUN (show_rpki_prefix_table,
        return CMD_SUCCESS;
 }
 
-DEFPY(show_rpki_as_number, show_rpki_as_number_cmd,
+DEFPY (show_rpki_as_number, show_rpki_as_number_cmd,
       "show rpki as-number (1-4294967295)$by_asn",
       SHOW_STR RPKI_OUTPUT_STRING
       "Lookup by ASN in prefix table\n"
@@ -1357,7 +1357,7 @@ DEFUN (no_debug_rpki,
        return CMD_SUCCESS;
 }
 
-DEFUN (match_rpki,
+DEFUN_YANG (match_rpki,
        match_rpki_cmd,
        "match rpki <valid|invalid|notfound>",
        MATCH_STR
@@ -1366,27 +1366,19 @@ DEFUN (match_rpki,
        "Invalid prefix\n"
        "Prefix not found\n")
 {
-       VTY_DECLVAR_CONTEXT(route_map_index, index);
-       enum rmap_compile_rets ret;
-
-       ret = route_map_add_match(index, "rpki", argv[2]->arg,
-                                 RMAP_EVENT_MATCH_ADDED);
-       switch (ret) {
-       case RMAP_RULE_MISSING:
-               vty_out(vty, "%% BGP Can't find rule.\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       case RMAP_COMPILE_ERROR:
-               vty_out(vty, "%% BGP Argument is malformed.\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       case RMAP_COMPILE_SUCCESS:
-               return CMD_SUCCESS;
-               break;
-       }
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:rpki']";
+       char xpath_value[XPATH_MAXLEN];
 
-       return CMD_SUCCESS;
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       snprintf(xpath_value, sizeof(xpath_value),
+                "%s/rmap-match-condition/frr-bgp-route-map:rpki", xpath);
+       nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[2]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_match_rpki,
+DEFUN_YANG (no_match_rpki,
        no_match_rpki_cmd,
        "no match rpki <valid|invalid|notfound>",
        NO_STR
@@ -1396,26 +1388,12 @@ DEFUN (no_match_rpki,
        "Invalid prefix\n"
        "Prefix not found\n")
 {
-       VTY_DECLVAR_CONTEXT(route_map_index, index);
-       enum rmap_compile_rets ret;
-
-       ret = route_map_delete_match(index, "rpki", argv[3]->arg,
-                                    RMAP_EVENT_MATCH_DELETED);
-       switch (ret) {
-       case RMAP_RULE_MISSING:
-               vty_out(vty, "%% BGP Can't find rule.\n");
-               return CMD_WARNING_CONFIG_FAILED;
-               break;
-       case RMAP_COMPILE_ERROR:
-               vty_out(vty, "%% BGP Argument is malformed.\n");
-               return CMD_WARNING_CONFIG_FAILED;
-               break;
-       case RMAP_COMPILE_SUCCESS:
-               return CMD_SUCCESS;
-               break;
-       }
+       const char *xpath =
+               "./match-condition[condition='frr-bgp-route-map:rpki']";
+       char xpath_value[XPATH_MAXLEN];
 
-       return CMD_SUCCESS;
+       nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 static void install_cli_commands(void)
index 0ca43fd308562e2122a26ac7f49e4c5ff84b09fb..583d1cd20727c565d17a85f57db70a5edd2678ae 100644 (file)
@@ -96,6 +96,8 @@ bgpd_libbgp_a_SOURCES = \
        bgpd/bgp_regex.c \
        bgpd/bgp_route.c \
        bgpd/bgp_routemap.c \
+       bgpd/bgp_routemap_nb.c \
+       bgpd/bgp_routemap_nb_config.c \
        bgpd/bgp_script.c \
        bgpd/bgp_table.c \
        bgpd/bgp_updgrp.c \
@@ -178,6 +180,7 @@ noinst_HEADERS += \
        bgpd/bgp_regex.h \
        bgpd/bgp_rpki.h \
        bgpd/bgp_route.h \
+       bgpd/bgp_routemap_nb.h \
        bgpd/bgp_script.h \
        bgpd/bgp_table.h \
        bgpd/bgp_updgrp.h \
@@ -255,4 +258,6 @@ nodist_bgpd_bgpd_SOURCES = \
        yang/frr-bgp-bmp.yang.c \
        yang/frr-bgp-rpki.yang.c \
        yang/frr-deviations-bgp-datacenter.yang.c \
+       yang/frr-bgp-filter.yang.c \
+       yang/frr-bgp-route-map.yang.c \
        # end