diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 2ddafd9a0c..ea74a82cec 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -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, diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index b7f3289ffc..a43b76da72 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -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 ", - 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 ", + 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); + 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)); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_match_evpn_route_type, - no_match_evpn_route_type_cmd, - "no match evpn route-type ", - 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 (no_match_evpn_route_type, + no_match_evpn_route_type_cmd, + "no match evpn route-type ", + 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_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']"; + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); } -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") +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") { - 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-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 (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 (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 ", + "match peer ", 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 []", - 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 []", + 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']"; - 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); + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + 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; + + 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); if (argc == 4) { - argstr_len = strlen(argv[idx_comm_list]->arg) - + strlen("exact-match") + 2; - argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, argstr_len); + 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"); + } - 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); - - if (argstr != argv[idx_comm_list]->arg) - XFREE(MTYPE_ROUTE_MAP_COMPILED, argstr); - - return ret; + return nb_cli_apply_changes(vty, NULL); } -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") +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") { - return bgp_route_match_delete(vty, "community", NULL, - RMAP_EVENT_CLIST_DELETED); + 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); } -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") +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; + + 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_lcomm_list]->arg); if (argc == 4) { - argstr_len = strlen(argv[idx_lcomm_list]->arg) - + strlen("exact-match") + 2; - argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, argstr_len); + 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"); + } - snprintf(argstr, argstr_len, "%s exact-match", - argv[idx_lcomm_list]->arg); - } else - argstr = 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); - - 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); + + return nb_cli_apply_changes(vty, NULL); } - -DEFUN (match_origin, - match_origin_cmd, - "match origin ", - MATCH_STR - "BGP origin code\n" - "remote EGP\n" - "local IGP\n" - "unknown heritage\n") +DEFUN_YANG (match_origin, + match_origin_cmd, + "match origin ", + 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; + } - 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); + + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_match_origin, - no_match_origin_cmd, - "no match origin []", - 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 []", + 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") -{ - int idx_id = 2; - - VTY_DECLVAR_CONTEXT(route_map_index, index); - - return generic_set_add(vty, index, "table", argv[idx_id]->arg); -} - -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") -{ - VTY_DECLVAR_CONTEXT(route_map_index, index); - - return generic_set_delete(vty, index, "table", 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") -{ - int (*func)(struct vty *, struct route_map_index *, const char *, - const char *) = strmatch(argv[0]->text, "no") - ? generic_set_delete - : generic_set_add; - - return func(vty, VTY_GET_CONTEXT(route_map_index), "ip next-hop", - "peer-address"); -} - -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") -{ - int (*func)(struct vty *, struct route_map_index *, const char *, - const char *) = strmatch(argv[0]->text, "no") - ? generic_set_delete - : generic_set_add; - - return func(vty, VTY_GET_CONTEXT(route_map_index), "ip next-hop", - "unchanged"); -} - -DEFUN (set_distance, - set_distance_cmd, - "set distance (0-255)", - SET_STR - "BGP Administrative Distance to use\n" - "Distance value\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_number = 2; + const char *xpath = "./set-action[action='frr-bgp-route-map:table']"; + 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:table", 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_table_id, + no_set_table_id_cmd, + "no set table", + NO_STR + SET_STR + "export route to non-main kernel table\n") { - return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index), - "distance", NULL); + 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 (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_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_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") +{ + 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, + "unchanged"); + } + return nb_cli_apply_changes(vty, NULL); +} + +DEFUN_YANG (set_distance, + set_distance_cmd, + "set distance (0-255)", + SET_STR + "BGP Administrative Distance to use\n" + "Distance 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:distance']"; + 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:distance", 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_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") +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 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); + const char *xpath = "./set-action[action='frr-bgp-route-map:distance']"; + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + 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 (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; - 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:set-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-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_weight, - no_set_weight_cmd, - "no set weight [(0-4294967295)]", - NO_STR - SET_STR - "BGP weight for routing table\n" - "Weight 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") { - 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); + 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_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_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), - "label-index", argv[idx_number]->arg); + const char *xpath = "./set-action[action='frr-bgp-route-map:weight']"; + 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:weight", 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_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_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:weight']"; + + 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_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; + 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_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") +{ + 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_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); - return ret; -} + const char *xpath = + "./set-action[action='frr-bgp-route-map:as-path-prepend']"; + char xpath_value[XPATH_MAXLEN]; -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") -{ - return set_aspath_prepend_asn(self, vty, argc, argv); -} - -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") -{ - int idx_asn = 4; - int ret; - char *str; - - str = argv_concat(argv, argc, idx_asn); - ret = generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index), - "as-path prepend", str); + 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 (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 (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 no_set_aspath_prepend(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 (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 (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") +{ + 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_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") +{ + 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_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']"; + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); } -ALIAS (no_set_community, - no_set_community_short_cmd, - "no set community", - NO_STR - SET_STR - "BGP community attribute\n") +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; - - str = argv_concat(argv, argc, idx_asn_nn); - ret = generic_set_add(vty, VTY_GET_CONTEXT(route_map_index), - "extcommunity rt", str); - 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") -{ - int idx_asn_nn = 3; int ret; - char *str; + 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 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_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 soo", NULL); + 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 (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") +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 (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") +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; + 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); + 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_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") { int idx_lb = 3; - int ret; - char *str; + 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]; - 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; + 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); + } + + 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 (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") +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") { - return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index), - "extcommunity bandwidth", NULL); + 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 (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") +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 (set_origin, - set_origin_cmd, - "set origin ", - SET_STR - "BGP origin code\n" - "remote EGP\n" - "local IGP\n" - "unknown heritage\n") +DEFUN_YANG (set_origin, + set_origin_cmd, + "set origin ", + SET_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 = + "./set-action[action='frr-bgp-route-map:set-origin']"; + char xpath_value[XPATH_MAXLEN]; + 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"); + 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; + } - vty_out(vty, "%% Invalid set 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); + + return nb_cli_apply_changes(vty, NULL); } - -DEFUN (no_set_origin, - no_set_origin_cmd, - "no set origin []", - NO_STR - 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 []", + NO_STR + SET_STR + "BGP origin code\n" + "remote EGP\n" + "local IGP\n" + "unknown heritage\n") { - return generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index), - "origin", NULL); + const char *xpath = + "./set-action[action='frr-bgp-route-map:set-origin']"; + + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); } - -DEFUN (set_atomic_aggregate, - set_atomic_aggregate_cmd, - "set atomic-aggregate", - SET_STR - "BGP atomic aggregate attribute\n" ) +DEFUN_YANG (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); + 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); + + 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; - } + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); - argstr_len = - strlen(argv[idx_number]->arg) + strlen(argv[idx_ipv4]->arg) + 2; - argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, argstr_len); + 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); - snprintf(argstr, argstr_len, "%s %s", argv[idx_number]->arg, - argv[idx_ipv4]->arg); + 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); - ret = generic_set_add(vty, VTY_GET_CONTEXT(route_map_index), - "aggregator as", argstr); - - XFREE(MTYPE_ROUTE_MAP_COMPILED, argstr); - - 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; + const char *xpath = + "./set-action[action='frr-bgp-route-map:aggregator']"; - 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); - - snprintf(argstr, argstr_len, "%s %s", argv[idx_asn]->arg, - argv[idx_ip]->arg); - - ret = generic_set_delete(vty, VTY_GET_CONTEXT(route_map_index), - "aggregator as", argstr); - - XFREE(MTYPE_ROUTE_MAP_COMPILED, argstr); - - return ret; + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + 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 (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") { - 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']"; + 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:ipv6-address", + xpath); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[3]->arg); + + return nb_cli_apply_changes(vty, NULL); } -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") +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 = 4; - return bgp_route_match_delete(vty, "ipv6 next-hop", argv[idx_ipv6]->arg, - RMAP_EVENT_MATCH_DELETED); + const char *xpath = + "./match-condition[condition='frr-bgp-route-map:ipv6-nexthop']"; + + 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]; - return bgp_route_match_add(vty, "ip next-hop address", - argv[idx_ipv4]->arg, RMAP_EVENT_MATCH_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:ipv4-address", + xpath); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, argv[4]->arg); + + 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 ", - 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 ", + 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 ", - 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 ", + 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 vpn next-hop ", - 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 vpn next-hop ", + 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 vpn next-hop []", - 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") +DEFUN_YANG (no_set_ipx_vpn_nexthop, + no_set_ipx_vpn_nexthop_cmd, + "no set vpn next-hop []", + 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; 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); + + return nb_cli_apply_changes(vty, NULL); } - -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") +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 index 0000000000..fc59122184 --- /dev/null +++ b/bgpd/bgp_routemap_nb.c @@ -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 index 0000000000..a15f521513 --- /dev/null +++ b/bgpd/bgp_routemap_nb.h @@ -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 index 0000000000..ec6284273e --- /dev/null +++ b/bgpd/bgp_routemap_nb_config.c @@ -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); +} diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index 3ef0137ba6..3d4902aa47 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -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 ", 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; + const char *xpath = + "./match-condition[condition='frr-bgp-route-map:rpki']"; + char xpath_value[XPATH_MAXLEN]; - 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; - } + 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 CMD_SUCCESS; + return nb_cli_apply_changes(vty, NULL); } -DEFUN (no_match_rpki, +DEFUN_YANG (no_match_rpki, no_match_rpki_cmd, "no match rpki ", 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; + const char *xpath = + "./match-condition[condition='frr-bgp-route-map:rpki']"; + char xpath_value[XPATH_MAXLEN]; - 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; - } - - 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) diff --git a/bgpd/subdir.am b/bgpd/subdir.am index 0ca43fd308..583d1cd207 100644 --- a/bgpd/subdir.am +++ b/bgpd/subdir.am @@ -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