Merge pull request #15194 from idryzhov/dist-list-fixes

distribute-list fixes and improvements
This commit is contained in:
Christian Hopps 2024-01-22 20:44:01 -05:00 committed by GitHub
commit 296cda5bc1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 388 additions and 99 deletions

View File

@ -696,9 +696,8 @@ DEFPY (babel_set_smoothing_half_life,
DEFUN (babel_distribute_list,
babel_distribute_list_cmd,
"distribute-list [prefix] ACCESSLIST4_NAME <in|out> [WORD]",
"distribute-list ACCESSLIST4_NAME <in|out> [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"
@ -710,16 +709,26 @@ DEFUN (babel_distribute_list,
if (argv[argc - 1]->type == VARIABLE_TKN)
ifname = argv[argc - 1]->arg;
return distribute_list_parser(NULL, prefix, true, argv[2 + prefix]->text,
return distribute_list_parser(babel_routing_process->distribute_ctx,
prefix, true, argv[2 + prefix]->text,
argv[1 + prefix]->arg, ifname);
}
ALIAS (babel_distribute_list,
babel_distribute_list_prefix_cmd,
"distribute-list prefix PREFIXLIST4_NAME <in|out> [WORD]",
"Filter networks in routing updates\n"
"Specify a prefix list\n"
"Prefix-list name\n"
"Filter incoming routing updates\n"
"Filter outgoing routing updates\n"
"Interface name\n")
DEFUN (babel_no_distribute_list,
babel_no_distribute_list_cmd,
"no distribute-list [prefix] ACCESSLIST4_NAME <in|out> [WORD]",
"no distribute-list ACCESSLIST4_NAME <in|out> [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"
@ -731,17 +740,28 @@ DEFUN (babel_no_distribute_list,
if (argv[argc - 1]->type == VARIABLE_TKN)
ifname = argv[argc - 1]->arg;
return distribute_list_no_parser(NULL, vty, prefix, true,
return distribute_list_no_parser(babel_routing_process->distribute_ctx,
vty, prefix, true,
argv[3 + prefix]->text,
argv[2 + prefix]->arg, ifname);
}
ALIAS (babel_no_distribute_list,
babel_no_distribute_list_prefix_cmd,
"no distribute-list prefix PREFIXLIST4_NAME <in|out> [WORD]",
NO_STR
"Filter networks in routing updates\n"
"Specify a prefix list\n"
"Prefix-list name\n"
"Filter incoming routing updates\n"
"Filter outgoing routing updates\n"
"Interface name\n")
DEFUN (babel_ipv6_distribute_list,
babel_ipv6_distribute_list_cmd,
"ipv6 distribute-list [prefix] ACCESSLIST6_NAME <in|out> [WORD]",
"ipv6 distribute-list ACCESSLIST6_NAME <in|out> [WORD]",
"IPv6\n"
"Filter networks in routing updates\n"
"Specify a prefix\n"
"Access-list name\n"
"Filter incoming routing updates\n"
"Filter outgoing routing updates\n"
@ -753,18 +773,28 @@ DEFUN (babel_ipv6_distribute_list,
if (argv[argc - 1]->type == VARIABLE_TKN)
ifname = argv[argc - 1]->arg;
return distribute_list_parser(NULL, prefix, false,
argv[3 + prefix]->text,
return distribute_list_parser(babel_routing_process->distribute_ctx,
prefix, false, argv[3 + prefix]->text,
argv[2 + prefix]->arg, ifname);
}
ALIAS (babel_ipv6_distribute_list,
babel_ipv6_distribute_list_prefix_cmd,
"ipv6 distribute-list prefix PREFIXLIST6_NAME <in|out> [WORD]",
"IPv6\n"
"Filter networks in routing updates\n"
"Specify a prefix list\n"
"Prefix-list name\n"
"Filter incoming routing updates\n"
"Filter outgoing routing updates\n"
"Interface name\n")
DEFUN (babel_no_ipv6_distribute_list,
babel_no_ipv6_distribute_list_cmd,
"no ipv6 distribute-list [prefix] ACCESSLIST6_NAME <in|out> [WORD]",
"no ipv6 distribute-list ACCESSLIST6_NAME <in|out> [WORD]",
NO_STR
"IPv6\n"
"Filter networks in routing updates\n"
"Specify a prefix\n"
"Access-list name\n"
"Filter incoming routing updates\n"
"Filter outgoing routing updates\n"
@ -776,11 +806,24 @@ DEFUN (babel_no_ipv6_distribute_list,
if (argv[argc - 1]->type == VARIABLE_TKN)
ifname = argv[argc - 1]->arg;
return distribute_list_no_parser(NULL, vty, prefix, false,
return distribute_list_no_parser(babel_routing_process->distribute_ctx,
vty, prefix, false,
argv[4 + prefix]->text,
argv[3 + prefix]->arg, ifname);
}
ALIAS (babel_no_ipv6_distribute_list,
babel_no_ipv6_distribute_list_prefix_cmd,
"no ipv6 distribute-list prefix PREFIXLIST6_NAME <in|out> [WORD]",
NO_STR
"IPv6\n"
"Filter networks in routing updates\n"
"Specify a prefix list\n"
"Prefix-list name\n"
"Filter incoming routing updates\n"
"Filter outgoing routing updates\n"
"Interface name\n")
void
babeld_quagga_init(void)
{
@ -798,9 +841,13 @@ babeld_quagga_init(void)
install_element(BABEL_NODE, &babel_set_smoothing_half_life_cmd);
install_element(BABEL_NODE, &babel_distribute_list_cmd);
install_element(BABEL_NODE, &babel_distribute_list_prefix_cmd);
install_element(BABEL_NODE, &babel_no_distribute_list_cmd);
install_element(BABEL_NODE, &babel_no_distribute_list_prefix_cmd);
install_element(BABEL_NODE, &babel_ipv6_distribute_list_cmd);
install_element(BABEL_NODE, &babel_ipv6_distribute_list_prefix_cmd);
install_element(BABEL_NODE, &babel_no_ipv6_distribute_list_cmd);
install_element(BABEL_NODE, &babel_no_ipv6_distribute_list_prefix_cmd);
vrf_cmd_init(NULL);

View File

@ -401,6 +401,117 @@ void eigrp_cli_show_neighbor(struct vty *vty, const struct lyd_node *dnode,
vty_out(vty, " neighbor %s\n", prefix);
}
/*
* XPath: /frr-eigrpd:eigrpd/instance/distribute-list
*/
DEFPY_YANG (eigrp_distribute_list,
eigrp_distribute_list_cmd,
"distribute-list ACCESSLIST4_NAME$name <in|out>$dir [WORD$ifname]",
"Filter networks in routing updates\n"
"Access-list name\n"
"Filter incoming routing updates\n"
"Filter outgoing routing updates\n"
"Interface name\n")
{
char xpath[XPATH_MAXLEN];
snprintf(xpath, sizeof(xpath),
"./distribute-list[interface='%s']/%s/access-list",
ifname ? ifname : "", dir);
/* 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);
}
DEFPY_YANG (eigrp_distribute_list_prefix,
eigrp_distribute_list_prefix_cmd,
"distribute-list prefix PREFIXLIST4_NAME$name <in|out>$dir [WORD$ifname]",
"Filter networks in routing updates\n"
"Specify a prefix list\n"
"Prefix-list name\n"
"Filter incoming routing updates\n"
"Filter outgoing routing updates\n"
"Interface name\n")
{
char xpath[XPATH_MAXLEN];
snprintf(xpath, sizeof(xpath),
"./distribute-list[interface='%s']/%s/prefix-list",
ifname ? ifname : "", dir);
/* 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);
}
DEFPY_YANG (eigrp_no_distribute_list,
eigrp_no_distribute_list_cmd,
"no distribute-list [ACCESSLIST4_NAME$name] <in|out>$dir [WORD$ifname]",
NO_STR
"Filter networks in routing updates\n"
"Access-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];
snprintf(xpath, sizeof(xpath),
"./distribute-list[interface='%s']/%s/access-list",
ifname ? ifname : "", dir);
/*
* 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);
}
DEFPY_YANG (eigrp_no_distribute_list_prefix,
eigrp_no_distribute_list_prefix_cmd,
"no distribute-list prefix [PREFIXLIST4_NAME$name] <in|out>$dir [WORD$ifname]",
NO_STR
"Filter networks in routing updates\n"
"Specify a prefix list\n"
"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];
snprintf(xpath, sizeof(xpath),
"./distribute-list[interface='%s']/%s/prefix-list",
ifname ? ifname : "", dir);
/*
* 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);
}
/*
* XPath: /frr-eigrpd:eigrpd/instance/redistribute
* XPath: /frr-eigrpd:eigrpd/instance/redistribute/route-map
@ -875,6 +986,10 @@ eigrp_cli_init(void)
install_element(EIGRP_NODE, &no_eigrp_metric_weights_cmd);
install_element(EIGRP_NODE, &eigrp_network_cmd);
install_element(EIGRP_NODE, &eigrp_neighbor_cmd);
install_element(EIGRP_NODE, &eigrp_distribute_list_cmd);
install_element(EIGRP_NODE, &eigrp_distribute_list_prefix_cmd);
install_element(EIGRP_NODE, &eigrp_no_distribute_list_cmd);
install_element(EIGRP_NODE, &eigrp_no_distribute_list_prefix_cmd);
install_element(EIGRP_NODE, &eigrp_redistribute_source_metric_cmd);
vrf_cmd_init(NULL);

View File

@ -14,6 +14,7 @@
#include "lib/table.h"
#include "lib/vrf.h"
#include "lib/zclient.h"
#include "lib/distribute.h"
#include "eigrp_structs.h"
#include "eigrpd.h"
@ -701,6 +702,22 @@ static int eigrpd_instance_neighbor_destroy(struct nb_cb_destroy_args *args)
return NB_OK;
}
/*
* XPath: /frr-eigrpd:eigrpd/instance/distribute-list
*/
static int eigrpd_instance_distribute_list_create(struct nb_cb_create_args *args)
{
struct eigrp *eigrp;
if (args->event != NB_EV_APPLY)
return NB_OK;
eigrp = nb_running_get_entry(args->dnode, NULL, true);
group_distribute_list_create_helper(args, eigrp->distribute_ctx);
return NB_OK;
}
/*
* XPath: /frr-eigrpd:eigrpd/instance/redistribute
*/
@ -1402,6 +1419,45 @@ const struct frr_yang_module_info frr_eigrpd_info = {
.cli_show = eigrp_cli_show_neighbor,
}
},
{
.xpath = "/frr-eigrpd:eigrpd/instance/distribute-list",
.cbs = {
.create = eigrpd_instance_distribute_list_create,
.destroy = group_distribute_list_destroy,
}
},
{
.xpath = "/frr-eigrpd:eigrpd/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-eigrpd:eigrpd/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-eigrpd:eigrpd/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-eigrpd:eigrpd/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-eigrpd:eigrpd/instance/redistribute",
.cbs = {

View File

@ -1107,49 +1107,6 @@ ALIAS(no_set_tag, no_set_tag_val_cmd, "no set tag (0-65535)", NO_STR SET_STR
"Tag value for routing protocol\n"
"Tag value\n")
DEFUN (eigrp_distribute_list,
eigrp_distribute_list_cmd,
"distribute-list [prefix] ACCESSLIST_NAME <in|out> [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")
{
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;
return distribute_list_parser(NULL, prefix, true, argv[2 + prefix]->text,
argv[1 + prefix]->arg, ifname);
}
DEFUN (eigrp_no_distribute_list,
eigrp_no_distribute_list_cmd,
"no distribute-list [prefix] ACCESSLIST_NAME <in|out> [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;
return distribute_list_no_parser(NULL, vty, prefix, true,
argv[3 + prefix]->text,
argv[2 + prefix]->arg, ifname);
}
/* Route-map init */
void eigrp_route_map_init(void)
{
@ -1158,9 +1115,6 @@ void eigrp_route_map_init(void)
route_map_add_hook(eigrp_route_map_update);
route_map_delete_hook(eigrp_route_map_update);
install_element(EIGRP_NODE, &eigrp_distribute_list_cmd);
install_element(EIGRP_NODE, &eigrp_no_distribute_list_cmd);
/*route_map_install_match (&route_match_metric_cmd);
route_map_install_match (&route_match_interface_cmd);*/
/*route_map_install_match (&route_match_ip_next_hop_cmd);

View File

@ -17,8 +17,6 @@ DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE, "Distribute list");
DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_IFNAME, "Dist-list ifname");
DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_NAME, "Dist-list name");
static struct list *dist_ctx_list;
static struct distribute *distribute_new(void)
{
return XCALLOC(MTYPE_DISTRIBUTE, sizeof(struct distribute));
@ -249,9 +247,6 @@ int distribute_list_parser(struct distribute_ctx *ctx, bool prefix, bool v4,
{
enum distribute_type type = distribute_direction(dir, v4);
if (!ctx)
ctx = listnode_head(dist_ctx_list);
void (*distfn)(struct distribute_ctx *, const char *,
enum distribute_type, const char *) =
prefix ? &distribute_list_prefix_set : &distribute_list_set;
@ -269,9 +264,6 @@ int distribute_list_no_parser(struct distribute_ctx *ctx, struct vty *vty,
enum distribute_type type = distribute_direction(dir, v4);
int ret;
if (!ctx)
ctx = listnode_head(dist_ctx_list);
int (*distfn)(struct distribute_ctx *, const char *,
enum distribute_type, const char *) =
prefix ? &distribute_list_prefix_unset : &distribute_list_unset;
@ -573,12 +565,6 @@ void distribute_list_delete(struct distribute_ctx **ctx)
hash_clean_and_free(&(*ctx)->disthash,
(void (*)(void *))distribute_free);
if (dist_ctx_list) {
listnode_delete(dist_ctx_list, *ctx);
if (list_isempty(dist_ctx_list))
list_delete(&dist_ctx_list);
}
XFREE(MTYPE_DISTRIBUTE_CTX, (*ctx));
}
@ -589,11 +575,9 @@ struct distribute_ctx *distribute_list_ctx_create(struct vrf *vrf)
ctx = XCALLOC(MTYPE_DISTRIBUTE_CTX, sizeof(struct distribute_ctx));
ctx->vrf = vrf;
ctx->disthash = hash_create(
distribute_hash_make,
(bool (*)(const void *, const void *))distribute_cmp, NULL);
if (!dist_ctx_list)
dist_ctx_list = list_new();
listnode_add(dist_ctx_list, ctx);
ctx->disthash =
hash_create(distribute_hash_make,
(bool (*)(const void *, const void *))distribute_cmp,
NULL);
return ctx;
}

View File

@ -1632,12 +1632,26 @@ static void plist_autocomplete(vector comps, struct cmd_token *token)
plist_autocomplete_afi(AFI_IP6, comps, token);
}
static void plist4_autocomplete(vector comps, struct cmd_token *token)
{
plist_autocomplete_afi(AFI_IP, comps, token);
}
static void plist6_autocomplete(vector comps, struct cmd_token *token)
{
plist_autocomplete_afi(AFI_IP6, comps, token);
}
static const struct cmd_variable_handler plist_var_handlers[] = {
{/* "prefix-list WORD" */
.varname = "prefix_list",
.completions = plist_autocomplete},
{.tokenname = "PREFIXLIST_NAME",
.completions = plist_autocomplete},
{.tokenname = "PREFIXLIST4_NAME",
.completions = plist4_autocomplete},
{.tokenname = "PREFIXLIST6_NAME",
.completions = plist6_autocomplete},
{.completions = NULL}};

View File

@ -1130,10 +1130,9 @@ DEFPY_YANG (clear_ip_rip,
DEFPY_YANG(
rip_distribute_list, rip_distribute_list_cmd,
"distribute-list [prefix]$prefix ACCESSLIST4_NAME$name <in|out>$dir [WORD$ifname]",
"distribute-list ACCESSLIST4_NAME$name <in|out>$dir [WORD$ifname]",
"Filter networks in routing updates\n"
"Specify a prefix list\n"
"access-list or prefix-list name\n"
"Access-list name\n"
"Filter incoming routing updates\n"
"Filter outgoing routing updates\n"
"Interface name\n")
@ -1141,8 +1140,28 @@ DEFPY_YANG(
char xpath[XPATH_MAXLEN];
snprintf(xpath, sizeof(xpath),
"./distribute-list[interface='%s']/%s/%s-list",
ifname ? ifname : "", dir, prefix ? "prefix" : "access");
"./distribute-list[interface='%s']/%s/access-list",
ifname ? ifname : "", dir);
/* 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);
}
DEFPY_YANG(
rip_distribute_list_prefix, rip_distribute_list_prefix_cmd,
"distribute-list prefix PREFIXLIST4_NAME$name <in|out>$dir [WORD$ifname]",
"Filter networks in routing updates\n"
"Specify a prefix list\n"
"Prefix-list name\n"
"Filter incoming routing updates\n"
"Filter outgoing routing updates\n"
"Interface name\n")
{
char xpath[XPATH_MAXLEN];
snprintf(xpath, sizeof(xpath),
"./distribute-list[interface='%s']/%s/prefix-list",
ifname ? ifname : "", dir);
/* 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);
@ -1150,11 +1169,10 @@ DEFPY_YANG(
DEFPY_YANG(no_rip_distribute_list,
no_rip_distribute_list_cmd,
"no distribute-list [prefix]$prefix [ACCESSLIST4_NAME$name] <in|out>$dir [WORD$ifname]",
"no distribute-list [ACCESSLIST4_NAME$name] <in|out>$dir [WORD$ifname]",
NO_STR
"Filter networks in routing updates\n"
"Specify a prefix list\n"
"access-list or prefix-list name\n"
"Access-list name\n"
"Filter incoming routing updates\n"
"Filter outgoing routing updates\n"
"Interface name\n")
@ -1163,8 +1181,43 @@ DEFPY_YANG(no_rip_distribute_list,
char xpath[XPATH_MAXLEN];
snprintf(xpath, sizeof(xpath),
"./distribute-list[interface='%s']/%s/%s-list",
ifname ? ifname : "", dir, prefix ? "prefix" : "access");
"./distribute-list[interface='%s']/%s/access-list",
ifname ? ifname : "", dir);
/*
* 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);
}
DEFPY_YANG(no_rip_distribute_list_prefix,
no_rip_distribute_list_prefix_cmd,
"no distribute-list prefix [PREFIXLIST4_NAME$name] <in|out>$dir [WORD$ifname]",
NO_STR
"Filter networks in routing updates\n"
"Specify a prefix list\n"
"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];
snprintf(xpath, sizeof(xpath),
"./distribute-list[interface='%s']/%s/prefix-list",
ifname ? ifname : "", dir);
/*
* See if the user has specified specific list so check it exists.
*
@ -1189,7 +1242,9 @@ 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_distribute_list_prefix_cmd);
install_element(RIP_NODE, &no_rip_distribute_list_cmd);
install_element(RIP_NODE, &no_rip_distribute_list_prefix_cmd);
install_element(RIP_NODE, &rip_allow_ecmp_cmd);
install_element(RIP_NODE, &no_rip_allow_ecmp_cmd);

View File

@ -518,10 +518,10 @@ DEFPY_YANG (clear_ipv6_rip,
DEFPY_YANG(
ripng_ipv6_distribute_list, ripng_ipv6_distribute_list_cmd,
"ipv6 distribute-list [prefix]$prefix ACCESSLIST4_NAME$name <in|out>$dir [WORD$ifname]",
"ipv6 distribute-list ACCESSLIST6_NAME$name <in|out>$dir [WORD$ifname]",
"IPv6\n"
"Filter networks in routing updates\n"
"Specify a prefix list\n"
"access-list or prefix-list name\n"
"Access-list name\n"
"Filter incoming routing updates\n"
"Filter outgoing routing updates\n"
"Interface name\n")
@ -529,8 +529,29 @@ DEFPY_YANG(
char xpath[XPATH_MAXLEN];
snprintf(xpath, sizeof(xpath),
"./distribute-list[interface='%s']/%s/%s-list",
ifname ? ifname : "", dir, prefix ? "prefix" : "access");
"./distribute-list[interface='%s']/%s/access-list",
ifname ? ifname : "", dir);
/* 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);
}
DEFPY_YANG(
ripng_ipv6_distribute_list_prefix, ripng_ipv6_distribute_list_prefix_cmd,
"ipv6 distribute-list prefix PREFIXLIST6_NAME$name <in|out>$dir [WORD$ifname]",
"IPv6\n"
"Filter networks in routing updates\n"
"Specify a prefix list\n"
"Prefix-list name\n"
"Filter incoming routing updates\n"
"Filter outgoing routing updates\n"
"Interface name\n")
{
char xpath[XPATH_MAXLEN];
snprintf(xpath, sizeof(xpath),
"./distribute-list[interface='%s']/%s/prefix-list",
ifname ? ifname : "", dir);
/* 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);
@ -538,11 +559,11 @@ DEFPY_YANG(
DEFPY_YANG(no_ripng_ipv6_distribute_list,
no_ripng_ipv6_distribute_list_cmd,
"no ipv6 distribute-list [prefix]$prefix [ACCESSLIST4_NAME$name] <in|out>$dir [WORD$ifname]",
"no ipv6 distribute-list [ACCESSLIST6_NAME$name] <in|out>$dir [WORD$ifname]",
NO_STR
"IPv6\n"
"Filter networks in routing updates\n"
"Specify a prefix list\n"
"access-list or prefix-list name\n"
"Access-list name\n"
"Filter incoming routing updates\n"
"Filter outgoing routing updates\n"
"Interface name\n")
@ -551,8 +572,44 @@ DEFPY_YANG(no_ripng_ipv6_distribute_list,
char xpath[XPATH_MAXLEN];
snprintf(xpath, sizeof(xpath),
"./distribute-list[interface='%s']/%s/%s-list",
ifname ? ifname : "", dir, prefix ? "prefix" : "access");
"./distribute-list[interface='%s']/%s/access-list",
ifname ? ifname : "", dir);
/*
* 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);
}
DEFPY_YANG(no_ripng_ipv6_distribute_list_prefix,
no_ripng_ipv6_distribute_list_prefix_cmd,
"no ipv6 distribute-list prefix [PREFIXLIST6_NAME$name] <in|out>$dir [WORD$ifname]",
NO_STR
"IPv6\n"
"Filter networks in routing updates\n"
"Specify a prefix list\n"
"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];
snprintf(xpath, sizeof(xpath),
"./distribute-list[interface='%s']/%s/prefix-list",
ifname ? ifname : "", dir);
/*
* See if the user has specified specific list so check it exists.
*
@ -577,7 +634,9 @@ void ripng_cli_init(void)
install_element(CONFIG_NODE, &no_router_ripng_cmd);
install_element(RIPNG_NODE, &ripng_ipv6_distribute_list_cmd);
install_element(RIPNG_NODE, &ripng_ipv6_distribute_list_prefix_cmd);
install_element(RIPNG_NODE, &no_ripng_ipv6_distribute_list_cmd);
install_element(RIPNG_NODE, &no_ripng_ipv6_distribute_list_prefix_cmd);
install_element(RIPNG_NODE, &ripng_allow_ecmp_cmd);
install_element(RIPNG_NODE, &no_ripng_allow_ecmp_cmd);

View File

@ -22,6 +22,9 @@ module frr-eigrpd {
import frr-route-types {
prefix frr-route-types;
}
import frr-filter {
prefix frr-filter;
}
organization "FRRouting";
contact
@ -224,6 +227,8 @@ module frr-eigrpd {
type inet:ipv4-address;
}
uses frr-filter:distribute-list-group;
list redistribute {
description "Redistribute routes learned from other routing protocols";