diff --git a/ripd/rip_cli.c b/ripd/rip_cli.c index a4d306a4d250..d4366d018667 100644 --- a/ripd/rip_cli.c +++ b/ripd/rip_cli.c @@ -1128,46 +1128,59 @@ DEFPY_YANG (clear_ip_rip, return ret; } -DEFUN (rip_distribute_list, - rip_distribute_list_cmd, - "distribute-list [prefix] ACCESSLIST4_NAME [WORD]", - "Filter networks in routing updates\n" - "Specify a prefix\n" - "Access-list name\n" - "Filter incoming routing updates\n" - "Filter outgoing routing updates\n" - "Interface name\n") +DEFPY_YANG( + rip_distribute_list, rip_distribute_list_cmd, + "distribute-list [prefix]$prefix ACCESSLIST4_NAME$name $dir [WORD$ifname]", + "Filter networks in routing updates\n" + "Specify a prefix list\n" + "access-list or prefix-list name\n" + "Filter incoming routing updates\n" + "Filter outgoing routing updates\n" + "Interface name\n") { - const char *ifname = NULL; - int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0; - - if (argv[argc - 1]->type == VARIABLE_TKN) - ifname = argv[argc - 1]->arg; + char xpath[XPATH_MAXLEN]; - return distribute_list_parser(NULL, prefix, true, argv[2 + prefix]->text, - argv[1 + prefix]->arg, ifname); + snprintf(xpath, sizeof(xpath), + "./distribute-list[interface='%s']/%s/%s-list", + ifname ? ifname : "", dir, prefix ? "prefix" : "access"); + /* nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); */ + nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, name); + return nb_cli_apply_changes(vty, NULL); } -DEFUN (rip_no_distribute_list, - rip_no_distribute_list_cmd, - "no distribute-list [prefix] ACCESSLIST4_NAME [WORD]", - NO_STR - "Filter networks in routing updates\n" - "Specify a prefix\n" - "Access-list name\n" - "Filter incoming routing updates\n" - "Filter outgoing routing updates\n" - "Interface name\n") -{ - const char *ifname = NULL; - int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0; - - if (argv[argc - 1]->type == VARIABLE_TKN) - ifname = argv[argc - 1]->arg; +DEFPY_YANG(no_rip_distribute_list, + no_rip_distribute_list_cmd, + "no distribute-list [prefix]$prefix [ACCESSLIST4_NAME$name] $dir [WORD$ifname]", + NO_STR + "Filter networks in routing updates\n" + "Specify a prefix list\n" + "access-list or prefix-list name\n" + "Filter incoming routing updates\n" + "Filter outgoing routing updates\n" + "Interface name\n") +{ + const struct lyd_node *value_node; + char xpath[XPATH_MAXLEN]; - return distribute_list_no_parser(NULL, vty, prefix, true, - argv[3 + prefix]->text, - argv[2 + prefix]->arg, ifname); + snprintf(xpath, sizeof(xpath), + "./distribute-list[interface='%s']/%s/%s-list", + ifname ? ifname : "", dir, prefix ? "prefix" : "access"); + /* + * See if the user has specified specific list so check it exists. + * + * NOTE: Other FRR CLI commands do not do this sort of verification and + * there may be an official decision not to. + */ + if (name) { + value_node = yang_dnode_getf(vty->candidate_config->dnode, "%s/%s", + VTY_CURR_XPATH, xpath); + if (!value_node || strcmp(name, lyd_get_value(value_node))) { + vty_out(vty, "distribute list doesn't exist\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); } void rip_cli_init(void) @@ -1176,7 +1189,7 @@ void rip_cli_init(void) install_element(CONFIG_NODE, &no_router_rip_cmd); install_element(RIP_NODE, &rip_distribute_list_cmd); - install_element(RIP_NODE, &rip_no_distribute_list_cmd); + install_element(RIP_NODE, &no_rip_distribute_list_cmd); install_element(RIP_NODE, &rip_allow_ecmp_cmd); install_element(RIP_NODE, &no_rip_allow_ecmp_cmd); diff --git a/ripd/rip_nb.c b/ripd/rip_nb.c index d11f1e1d34fe..7167be124a74 100644 --- a/ripd/rip_nb.c +++ b/ripd/rip_nb.c @@ -6,11 +6,12 @@ #include -#include "northbound.h" +#include "distribute.h" +#include "if_rmap.h" #include "libfrr.h" +#include "northbound.h" #include "ripd/rip_nb.h" -#include "lib/if_rmap.h" /* clang-format off */ const struct frr_yang_module_info frr_ripd_info = { @@ -143,6 +144,45 @@ const struct frr_yang_module_info frr_ripd_info = { .destroy = ripd_instance_non_passive_interface_destroy, }, }, + { + .xpath = "/frr-ripd:ripd/instance/distribute-list", + .cbs = { + .create = ripd_instance_distribute_list_create, + .destroy = group_distribute_list_destroy, + } + }, + { + .xpath = "/frr-ripd:ripd/instance/distribute-list/in/access-list", + .cbs = { + .modify = group_distribute_list_ipv4_modify, + .destroy = group_distribute_list_ipv4_destroy, + .cli_show = group_distribute_list_ipv4_cli_show, + } + }, + { + .xpath = "/frr-ripd:ripd/instance/distribute-list/out/access-list", + .cbs = { + .modify = group_distribute_list_ipv4_modify, + .destroy = group_distribute_list_ipv4_destroy, + .cli_show = group_distribute_list_ipv4_cli_show, + } + }, + { + .xpath = "/frr-ripd:ripd/instance/distribute-list/in/prefix-list", + .cbs = { + .modify = group_distribute_list_ipv4_modify, + .destroy = group_distribute_list_ipv4_destroy, + .cli_show = group_distribute_list_ipv4_cli_show, + } + }, + { + .xpath = "/frr-ripd:ripd/instance/distribute-list/out/prefix-list", + .cbs = { + .modify = group_distribute_list_ipv4_modify, + .destroy = group_distribute_list_ipv4_destroy, + .cli_show = group_distribute_list_ipv4_cli_show, + } + }, { .xpath = "/frr-ripd:ripd/instance/redistribute", .cbs = { diff --git a/ripd/rip_nb.h b/ripd/rip_nb.h index 9929e0952b6f..811fee55ec25 100644 --- a/ripd/rip_nb.h +++ b/ripd/rip_nb.h @@ -7,6 +7,8 @@ #ifndef _FRR_RIP_NB_H_ #define _FRR_RIP_NB_H_ +#include "northbound.h" + extern const struct frr_yang_module_info frr_ripd_info; /* Mandatory callbacks. */ @@ -45,6 +47,8 @@ int ripd_instance_passive_interface_destroy(struct nb_cb_destroy_args *args); int ripd_instance_non_passive_interface_create(struct nb_cb_create_args *args); int ripd_instance_non_passive_interface_destroy( struct nb_cb_destroy_args *args); +int ripd_instance_distribute_list_create(struct nb_cb_create_args *args); +int ripd_instance_distribute_list_destroy(struct nb_cb_destroy_args *args); int ripd_instance_redistribute_create(struct nb_cb_create_args *args); int ripd_instance_redistribute_destroy(struct nb_cb_destroy_args *args); int ripd_instance_redistribute_route_map_modify(struct nb_cb_modify_args *args); diff --git a/ripd/rip_nb_config.c b/ripd/rip_nb_config.c index 8b9cc922ad12..fb7533789b5f 100644 --- a/ripd/rip_nb_config.c +++ b/ripd/rip_nb_config.c @@ -548,6 +548,23 @@ int ripd_instance_non_passive_interface_destroy(struct nb_cb_destroy_args *args) return rip_passive_nondefault_unset(rip, ifname); } + +/* + * XPath: /frr-ripd:ripd/instance/distribute-list + */ +int ripd_instance_distribute_list_create(struct nb_cb_create_args *args) +{ + struct rip *rip; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + rip = nb_running_get_entry(args->dnode, NULL, true); + group_distribute_list_create_helper(args, rip->distribute_ctx); + + return NB_OK; +} + /* * XPath: /frr-ripd:ripd/instance/redistribute */ diff --git a/ripd/ripd.c b/ripd/ripd.c index d5df16c3a976..a744e081d19c 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -3271,9 +3271,6 @@ static int config_write_rip(struct vty *vty) nb_cli_show_dnode_cmds(vty, dnode, false); - /* Distribute configuration. */ - config_write_distribute(vty, rip->distribute_ctx); - vty_out(vty, "exit\n"); write = 1; diff --git a/yang/frr-ripd.yang b/yang/frr-ripd.yang index 756e70b29256..d65ee489633f 100644 --- a/yang/frr-ripd.yang +++ b/yang/frr-ripd.yang @@ -16,6 +16,9 @@ module frr-ripd { import frr-bfdd { prefix frr-bfdd; } + import frr-filter { + prefix frr-filter; + } import frr-interface { prefix frr-interface; } @@ -258,6 +261,9 @@ module frr-ripd { "A list of interfaces where the sending of RIP packets is enabled."; } + + uses frr-filter:distribute-list-group; + list redistribute { key "protocol"; description