Merge pull request #15185 from LabNConsulting/chopps/distlist

add northbound support to distribute-list code.
This commit is contained in:
Igor Ryzhov 2024-01-22 16:52:45 +02:00 committed by GitHub
commit 22d1ad786f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 543 additions and 170 deletions

View File

@ -710,7 +710,7 @@ DEFUN (babel_distribute_list,
if (argv[argc - 1]->type == VARIABLE_TKN)
ifname = argv[argc - 1]->arg;
return distribute_list_parser(prefix, true, argv[2 + prefix]->text,
return distribute_list_parser(NULL, prefix, true, argv[2 + prefix]->text,
argv[1 + prefix]->arg, ifname);
}
@ -731,7 +731,7 @@ DEFUN (babel_no_distribute_list,
if (argv[argc - 1]->type == VARIABLE_TKN)
ifname = argv[argc - 1]->arg;
return distribute_list_no_parser(vty, prefix, true,
return distribute_list_no_parser(NULL, vty, prefix, true,
argv[3 + prefix]->text,
argv[2 + prefix]->arg, ifname);
}
@ -753,7 +753,8 @@ DEFUN (babel_ipv6_distribute_list,
if (argv[argc - 1]->type == VARIABLE_TKN)
ifname = argv[argc - 1]->arg;
return distribute_list_parser(prefix, false, argv[3 + prefix]->text,
return distribute_list_parser(NULL, prefix, false,
argv[3 + prefix]->text,
argv[2 + prefix]->arg, ifname);
}
@ -775,7 +776,7 @@ DEFUN (babel_no_ipv6_distribute_list,
if (argv[argc - 1]->type == VARIABLE_TKN)
ifname = argv[argc - 1]->arg;
return distribute_list_no_parser(vty, prefix, false,
return distribute_list_no_parser(NULL, vty, prefix, false,
argv[4 + prefix]->text,
argv[3 + prefix]->arg, ifname);
}

View File

@ -1123,7 +1123,7 @@ DEFUN (eigrp_distribute_list,
if (argv[argc - 1]->type == VARIABLE_TKN)
ifname = argv[argc - 1]->arg;
return distribute_list_parser(prefix, true, argv[2 + prefix]->text,
return distribute_list_parser(NULL, prefix, true, argv[2 + prefix]->text,
argv[1 + prefix]->arg, ifname);
}
@ -1144,14 +1144,14 @@ DEFUN (eigrp_no_distribute_list,
if (argv[argc - 1]->type == VARIABLE_TKN)
ifname = argv[argc - 1]->arg;
return distribute_list_no_parser(vty, prefix, true,
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 eigrp_route_map_init(void)
{
route_map_init();
route_map_init_vty();

View File

@ -244,11 +244,13 @@ static enum distribute_type distribute_direction(const char *dir, bool v4)
__builtin_unreachable();
}
int distribute_list_parser(bool prefix, bool v4, const char *dir,
const char *list, const char *ifname)
int distribute_list_parser(struct distribute_ctx *ctx, bool prefix, bool v4,
const char *dir, const char *list, const char *ifname)
{
enum distribute_type type = distribute_direction(dir, v4);
struct distribute_ctx *ctx = listnode_head(dist_ctx_list);
if (!ctx)
ctx = listnode_head(dist_ctx_list);
void (*distfn)(struct distribute_ctx *, const char *,
enum distribute_type, const char *) =
@ -259,14 +261,17 @@ int distribute_list_parser(bool prefix, bool v4, const char *dir,
return CMD_SUCCESS;
}
int distribute_list_no_parser(struct vty *vty, bool prefix, bool v4,
const char *dir, const char *list,
const char *ifname)
int distribute_list_no_parser(struct distribute_ctx *ctx, struct vty *vty,
bool prefix, bool v4, const char *dir,
const char *list, const char *ifname)
{
enum distribute_type type = distribute_direction(dir, v4);
struct distribute_ctx *ctx = listnode_head(dist_ctx_list);
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;
@ -274,7 +279,8 @@ int distribute_list_no_parser(struct vty *vty, bool prefix, bool v4,
ret = distfn(ctx, ifname, type, list);
if (!ret) {
vty_out(vty, "distribute list doesn't exist\n");
if (vty)
vty_out(vty, "distribute list doesn't exist\n");
return CMD_WARNING_CONFIG_FAILED;
}
@ -443,6 +449,125 @@ int config_write_distribute(struct vty *vty,
return write;
}
/* ---------- */
/* Northbound */
/* ---------- */
int group_distribute_list_create_helper(
struct nb_cb_create_args *args, struct distribute_ctx *ctx)
{
nb_running_set_entry(args->dnode, ctx);
return NB_OK;
}
/*
* XPath: /frr-ripd:ripd/instance/distribute-lists/distribute-list/{in,out}/{access,prefix}-list
*/
int group_distribute_list_destroy(struct nb_cb_destroy_args *args)
{
nb_running_unset_entry(args->dnode);
return NB_OK;
}
static int distribute_list_leaf_update(const struct lyd_node *dnode,
int ip_version, bool no)
{
struct distribute_ctx *ctx;
struct lyd_node *dir_node = lyd_parent(dnode);
struct lyd_node_inner *list_node = dir_node->parent;
struct lyd_node *intf_key = list_node->child;
bool ipv4 = ip_version == 4 ? true : false;
bool prefix;
ctx = nb_running_get_entry_non_rec(&list_node->node, NULL, false);
prefix = dnode->schema->name[0] == 'p' ? true : false;
if (no)
distribute_list_no_parser(ctx, NULL, prefix, ipv4,
dir_node->schema->name,
lyd_get_value(dnode),
lyd_get_value(intf_key));
else
distribute_list_parser(ctx, prefix, ipv4,
dir_node->schema->name,
lyd_get_value(dnode),
lyd_get_value(intf_key));
return NB_OK;
}
static int distribute_list_leaf_modify(struct nb_cb_modify_args *args,
int ip_version)
{
if (args->event != NB_EV_APPLY)
return NB_OK;
return distribute_list_leaf_update(args->dnode, ip_version, false);
}
static int distribute_list_leaf_destroy(struct nb_cb_destroy_args *args,
int ip_version)
{
if (args->event != NB_EV_APPLY)
return NB_OK;
return distribute_list_leaf_update(args->dnode, ip_version, true);
}
int group_distribute_list_ipv4_modify(struct nb_cb_modify_args *args)
{
return distribute_list_leaf_modify(args, 4);
}
int group_distribute_list_ipv4_destroy(struct nb_cb_destroy_args *args)
{
return distribute_list_leaf_destroy(args, 4);
}
int group_distribute_list_ipv6_modify(struct nb_cb_modify_args *args)
{
return distribute_list_leaf_modify(args, 6);
}
int group_distribute_list_ipv6_destroy(struct nb_cb_destroy_args *args)
{
return distribute_list_leaf_destroy(args, 6);
}
static int distribute_list_leaf_cli_show(struct vty *vty,
const struct lyd_node *dnode,
int ip_version)
{
struct lyd_node *dir_node = lyd_parent(dnode);
struct lyd_node_inner *list_node = dir_node->parent;
struct lyd_node *intf_key = list_node->child;
bool ipv6 = ip_version == 6 ? true : false;
bool prefix;
prefix = dnode->schema->name[0] == 'p' ? true : false;
vty_out(vty,
" %sdistribute-list %s%s %s %s\n",
ipv6 ? "ipv6 " : "",
prefix ? "prefix " : "",
lyd_get_value(dnode),
dir_node->schema->name,
lyd_get_value(intf_key));
return NB_OK;
}
void group_distribute_list_ipv4_cli_show(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults)
{
distribute_list_leaf_cli_show(vty, dnode, 4);
}
void group_distribute_list_ipv6_cli_show(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults)
{
distribute_list_leaf_cli_show(vty, dnode, 6);
}
/* ------------- */
/* Setup/Cleanup */
/* ------------- */
void distribute_list_delete(struct distribute_ctx **ctx)
{
hash_clean_and_free(&(*ctx)->disthash,

View File

@ -9,6 +9,7 @@
#include <zebra.h>
#include "if.h"
#include "filter.h"
#include "northbound.h"
#ifdef __cplusplus
extern "C" {
@ -69,11 +70,43 @@ extern enum filter_type distribute_apply_in(struct interface *,
extern enum filter_type distribute_apply_out(struct interface *,
struct prefix *);
extern int distribute_list_parser(bool prefix, bool v4, const char *dir,
const char *list, const char *ifname);
extern int distribute_list_no_parser(struct vty *vty, bool prefix, bool v4,
extern int distribute_list_parser(struct distribute_ctx *ctx, bool prefix,
bool v4, const char *dir, const char *list,
const char *ifname);
extern int distribute_list_no_parser(struct distribute_ctx *ctx,
struct vty *vty, bool prefix, bool v4,
const char *dir, const char *list,
const char *ifname);
/*
* Northbound
*/
/*
* Define your own create callback and then call thes helper with your
* distribute list context when a list entry is created. Additionally, plug the
* destroy callback into the frr_module_yang_info struct, or call it if you have
* your own callback destroy function.
*/
extern int group_distribute_list_create_helper(struct nb_cb_create_args *args,
struct distribute_ctx *ctx);
extern int group_distribute_list_destroy(struct nb_cb_destroy_args *args);
/*
* Plug 3 of these handlers in for your distribute-list for all the northbound
* distribute_list leaf callbacks. If you need multi-protocol then use the
* grouping twice under 2 different containers.
*/
extern int group_distribute_list_ipv4_modify(struct nb_cb_modify_args *args);
extern int group_distribute_list_ipv4_destroy(struct nb_cb_destroy_args *args);
extern void group_distribute_list_ipv4_cli_show(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults);
extern int group_distribute_list_ipv6_modify(struct nb_cb_modify_args *args);
extern int group_distribute_list_ipv6_destroy(struct nb_cb_destroy_args *args);
extern void group_distribute_list_ipv6_cli_show(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults);
#ifdef __cplusplus
}
#endif

View File

@ -1128,46 +1128,59 @@ DEFPY_YANG (clear_ip_rip,
return ret;
}
DEFUN (rip_distribute_list,
rip_distribute_list_cmd,
"distribute-list [prefix] 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"
"Interface name\n")
DEFPY_YANG(
rip_distribute_list, rip_distribute_list_cmd,
"distribute-list [prefix]$prefix 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"
"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;
char xpath[XPATH_MAXLEN];
if (argv[argc - 1]->type == VARIABLE_TKN)
ifname = argv[argc - 1]->arg;
return distribute_list_parser(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 <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")
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_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 char *ifname = NULL;
int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
const struct lyd_node *value_node;
char xpath[XPATH_MAXLEN];
if (argv[argc - 1]->type == VARIABLE_TKN)
ifname = argv[argc - 1]->arg;
return distribute_list_no_parser(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);

View File

@ -6,11 +6,12 @@
#include <zebra.h>
#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 = {

View File

@ -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);

View File

@ -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
*/

View File

@ -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;

View File

@ -516,48 +516,59 @@ DEFPY_YANG (clear_ipv6_rip,
return ret;
}
DEFUN (ripng_ipv6_distribute_list,
ripng_ipv6_distribute_list_cmd,
"ipv6 distribute-list [prefix] 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"
"Interface name\n")
DEFPY_YANG(
ripng_ipv6_distribute_list, ripng_ipv6_distribute_list_cmd,
"ipv6 distribute-list [prefix]$prefix 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"
"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;
char xpath[XPATH_MAXLEN];
if (argv[argc - 1]->type == VARIABLE_TKN)
ifname = argv[argc - 1]->arg;
return distribute_list_parser(prefix, false, 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");
/* 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 (ripng_no_ipv6_distribute_list,
ripng_no_ipv6_distribute_list_cmd,
"no ipv6 distribute-list [prefix] 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"
"Interface name\n")
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_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 char *ifname = NULL;
int prefix = (argv[3]->type == WORD_TKN) ? 1 : 0;
const struct lyd_node *value_node;
char xpath[XPATH_MAXLEN];
if (argv[argc - 1]->type == VARIABLE_TKN)
ifname = argv[argc - 1]->arg;
return distribute_list_no_parser(vty, prefix, false,
argv[4 + prefix]->text,
argv[3 + 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 ripng_cli_init(void)
@ -566,7 +577,7 @@ 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_no_ipv6_distribute_list_cmd);
install_element(RIPNG_NODE, &no_ripng_ipv6_distribute_list_cmd);
install_element(RIPNG_NODE, &ripng_allow_ecmp_cmd);
install_element(RIPNG_NODE, &no_ripng_allow_ecmp_cmd);

View File

@ -6,11 +6,12 @@
#include <zebra.h>
#include "northbound.h"
#include "distribute.h"
#include "if_rmap.h"
#include "libfrr.h"
#include "northbound.h"
#include "ripngd/ripng_nb.h"
#include "lib/if_rmap.h"
/* clang-format off */
const struct frr_yang_module_info frr_ripngd_info = {
@ -92,6 +93,45 @@ const struct frr_yang_module_info frr_ripngd_info = {
.destroy = ripngd_instance_passive_interface_destroy,
},
},
{
.xpath = "/frr-ripngd:ripngd/instance/distribute-list",
.cbs = {
.create = ripngd_instance_distribute_list_create,
.destroy = group_distribute_list_destroy,
}
},
{
.xpath = "/frr-ripngd:ripngd/instance/distribute-list/in/access-list",
.cbs = {
.modify = group_distribute_list_ipv6_modify,
.destroy = group_distribute_list_ipv6_destroy,
.cli_show = group_distribute_list_ipv6_cli_show,
}
},
{
.xpath = "/frr-ripngd:ripngd/instance/distribute-list/out/access-list",
.cbs = {
.modify = group_distribute_list_ipv6_modify,
.destroy = group_distribute_list_ipv6_destroy,
.cli_show = group_distribute_list_ipv6_cli_show,
}
},
{
.xpath = "/frr-ripngd:ripngd/instance/distribute-list/in/prefix-list",
.cbs = {
.modify = group_distribute_list_ipv6_modify,
.destroy = group_distribute_list_ipv6_destroy,
.cli_show = group_distribute_list_ipv6_cli_show,
}
},
{
.xpath = "/frr-ripngd:ripngd/instance/distribute-list/out/prefix-list",
.cbs = {
.modify = group_distribute_list_ipv6_modify,
.destroy = group_distribute_list_ipv6_destroy,
.cli_show = group_distribute_list_ipv6_cli_show,
}
},
{
.xpath = "/frr-ripngd:ripngd/instance/redistribute",
.cbs = {

View File

@ -7,6 +7,8 @@
#ifndef _FRR_RIPNG_NB_H_
#define _FRR_RIPNG_NB_H_
#include "northbound.h"
extern const struct frr_yang_module_info frr_ripngd_info;
/* Mandatory callbacks. */
@ -30,6 +32,8 @@ int ripngd_instance_offset_list_access_list_modify(
int ripngd_instance_offset_list_metric_modify(struct nb_cb_modify_args *args);
int ripngd_instance_passive_interface_create(struct nb_cb_create_args *args);
int ripngd_instance_passive_interface_destroy(struct nb_cb_destroy_args *args);
int ripngd_instance_distribute_list_create(struct nb_cb_create_args *args);
int ripngd_instance_distribute_list_destroy(struct nb_cb_destroy_args *args);
int ripngd_instance_redistribute_create(struct nb_cb_create_args *args);
int ripngd_instance_redistribute_destroy(struct nb_cb_destroy_args *args);
int ripngd_instance_redistribute_route_map_modify(

View File

@ -368,6 +368,22 @@ int ripngd_instance_passive_interface_destroy(struct nb_cb_destroy_args *args)
return ripng_passive_interface_unset(ripng, ifname);
}
/*
* XPath: /frr-ripng:ripng/instance/distribute-list
*/
int ripngd_instance_distribute_list_create(struct nb_cb_create_args *args)
{
struct ripng *ripng;
if (args->event != NB_EV_APPLY)
return NB_OK;
ripng = nb_running_get_entry(args->dnode, NULL, true);
group_distribute_list_create_helper(args, ripng->distribute_ctx);
return NB_OK;
}
/*
* XPath: /frr-ripngd:ripngd/instance/redistribute
*/

View File

@ -2286,8 +2286,6 @@ static int ripng_config_write(struct vty *vty)
nb_cli_show_dnode_cmds(vty, dnode, false);
config_write_distribute(vty, ripng->distribute_ctx);
vty_out(vty, "exit\n");
write = 1;

View File

@ -10,6 +10,9 @@ module frr-filter {
import ietf-yang-types {
prefix yang;
}
import frr-interface {
prefix frr-interface;
}
organization "FRRouting";
contact
@ -45,35 +48,95 @@ module frr-filter {
revision 2019-07-04 {
description "Initial revision";
reference "FRRouting";
}
/*
* Types.
*/
typedef access-list-name {
description "Access list name formatting";
type string {
length 1..128;
}
description "Access list name formatting";
}
typedef access-list-sequence {
description "Access list sequence number";
type uint32 {
range "1..4294967295";
}
description "Access list sequence number";
}
typedef access-list-action {
description "Access list return action on match";
type enumeration {
enum deny {
description "Deny an entry";
value 0;
description "Deny an entry";
}
enum permit {
description "Accept an entry";
value 1;
description "Accept an entry";
}
}
description "Access list return action on match";
}
typedef access-list-ref {
type leafref {
path "/frr-filter:lib/frr-filter:access-list/frr-filter:name";
require-instance false;
}
description "IPv4 or IPv6 access list reference";
}
typedef prefix-list-ref {
type leafref {
path "/frr-filter:lib/frr-filter:prefix-list/frr-filter:name";
require-instance false;
}
description "IPv4 or IPv6 prefix list reference";
}
/*
* Grouping.
*/
grouping distribute-list-group {
description "Distribute list grouping";
list distribute-list {
key "interface";
description "Distribute list configuration";
leaf interface {
type union {
type frr-interface:interface-ref;
type empty;
}
description
"Interface to attach list to or empty for global.";
}
container in {
description "Inbound filter list";
leaf access-list {
type access-list-ref;
description "inbound access list";
}
leaf prefix-list {
type prefix-list-ref;
description "inbound prefix list";
}
}
container out {
description "Outbound filter list";
leaf access-list {
type access-list-ref;
description "outbound access list";
}
leaf prefix-list {
type prefix-list-ref;
description "outbound prefix list";
}
}
}
}
@ -82,77 +145,74 @@ module frr-filter {
* Configuration data.
*/
container lib {
description "Filter library";
list access-list {
key "type name";
description "Access list instance";
key "type name";
leaf type {
description "Access list content type";
type enumeration {
enum ipv4 {
description "Internet Protocol address version 4";
value 0;
}
enum ipv6 {
description "Internet Protocol address version 6";
value 1;
value 0;
description "Internet Protocol address version 4";
}
enum ipv6 {
value 1;
description "Internet Protocol address version 6";
}
enum mac {
description "Media Access Control address";
value 2;
description "Media Access Control address";
}
}
description "Access list content type";
}
leaf name {
description "Access list name";
type access-list-name;
description "Access list name";
}
leaf remark {
description "Access list remark";
type string;
description "Access list remark";
}
list entry {
description "Access list entry";
key "sequence";
description "Access list entry";
leaf sequence {
description "Access list sequence value";
type access-list-sequence;
description "Access list sequence value";
}
leaf action {
description "Access list action on match";
type access-list-action;
mandatory true;
description "Access list action on match";
}
choice value {
description "Access list value to match";
mandatory true;
description "Access list value to match";
case ipv4-prefix {
when "../type = 'ipv4'";
choice style {
description "Access list entry style selection: zebra or cisco.";
mandatory true;
description "Access list entry style selection: zebra or cisco.";
case zebra {
leaf ipv4-prefix {
description "Configure IPv4 prefix to match";
type inet:ipv4-prefix;
mandatory true;
description "Configure IPv4 prefix to match";
}
leaf ipv4-exact-match {
description "Exact match of prefix";
type boolean;
default false;
description "Exact match of prefix";
}
}
case cisco {
@ -160,19 +220,20 @@ module frr-filter {
description "Source value to match";
leaf host {
description "Host to match";
type inet:ipv4-address;
description "Host to match";
}
container network {
description "Network to match";
leaf address {
type inet:ipv4-address;
mandatory true;
description "Network address part.";
type inet:ipv4-address;
}
leaf mask {
type inet:ipv4-address;
mandatory true;
description "Network mask/wildcard part.";
type inet:ipv4-address;
}
}
leaf source-any {
@ -180,8 +241,8 @@ module frr-filter {
* Was `any`, however it conflicts with `any` leaf
* outside this choice.
*/
description "Match any";
type empty;
description "Match any";
}
}
@ -189,24 +250,25 @@ module frr-filter {
description "Destination value to match";
leaf destination-host {
description "Host to match";
type inet:ipv4-address;
description "Host to match";
}
container destination-network {
description "Destination network to match";
leaf address {
type inet:ipv4-address;
mandatory true;
description "Network address part.";
type inet:ipv4-address;
}
leaf mask {
type inet:ipv4-address;
mandatory true;
description "Network mask/wildcard part.";
type inet:ipv4-address;
}
}
leaf destination-any {
description "Match any";
type empty;
description "Match any";
}
}
}
@ -216,29 +278,29 @@ module frr-filter {
when "../type = 'ipv6'";
leaf ipv6-prefix {
description "Configure IPv6 prefix to match";
type inet:ipv6-prefix;
mandatory true;
description "Configure IPv6 prefix to match";
}
leaf ipv6-exact-match {
description "Exact match of prefix";
type boolean;
default false;
description "Exact match of prefix";
}
}
case mac {
when "../type = 'mac'";
leaf mac {
description "Configure MAC address to match";
type yang:mac-address;
description "Configure MAC address to match";
}
}
case any {
leaf any {
description "Match anything";
type empty;
description "Match anything";
}
}
}
@ -246,108 +308,104 @@ module frr-filter {
}
list prefix-list {
description "Prefix list instance";
key "type name";
description "Prefix list instance";
leaf type {
description "Prefix list type";
type enumeration {
enum ipv4 {
description "Internet Protocol address version 4";
value 0;
description "Internet Protocol address version 4";
}
enum ipv6 {
description "Internet Protocol address version 6";
value 1;
description "Internet Protocol address version 6";
}
}
description "Prefix list type";
}
leaf name {
description "Prefix list name";
type access-list-name;
description "Prefix list name";
}
leaf remark {
description "Prefix list user description";
type string;
description "Prefix list user description";
}
list entry {
description "Prefix list entry";
key "sequence";
description "Prefix list entry";
leaf sequence {
description "Prefix list sequence value";
type access-list-sequence;
description "Prefix list sequence value";
}
leaf action {
description "Prefix list action on match";
type access-list-action;
mandatory true;
description "Prefix list action on match";
}
choice value {
description "Prefix list value to match";
mandatory true;
description "Prefix list value to match";
case ipv4-prefix {
leaf ipv4-prefix {
description "Configure IPv4 prefix to match";
type inet:ipv4-prefix;
mandatory true;
description "Configure IPv4 prefix to match";
}
leaf ipv4-prefix-length-greater-or-equal {
type uint8 {
range "0..32";
}
description
"Specifies if matching prefixes with length greater than
or equal to value";
type uint8 {
range "0..32";
}
}
leaf ipv4-prefix-length-lesser-or-equal {
description
"Specifies if matching prefixes with length lesser than
or equal to value";
type uint8 {
range "0..32";
}
description
"Specifies if matching prefixes with length lesser than
or equal to value";
}
}
case ipv6-prefix {
leaf ipv6-prefix {
description "Configure IPv6 prefix to match";
type inet:ipv6-prefix;
mandatory true;
description "Configure IPv6 prefix to match";
}
leaf ipv6-prefix-length-greater-or-equal {
type uint8 {
range "0..128";
}
description
"Specifies if matching prefixes with length greater than
or equal to value";
type uint8 {
range "0..128";
}
}
leaf ipv6-prefix-length-lesser-or-equal {
description
"Specifies if matching prefixes with length lesser than
or equal to value";
type uint8 {
range "0..128";
}
description
"Specifies if matching prefixes with length lesser than
or equal to value";
}
}
case any {
leaf any {
description "Match anything";
type empty;
description "Match anything";
}
}
}

View File

@ -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
@ -380,9 +386,9 @@ module frr-ripd {
}
leaf default-bfd-profile {
type frr-bfdd:profile-ref;
description
"Use this BFD profile for all peers by default.";
type frr-bfdd:profile-ref;
}
/*
@ -691,12 +697,13 @@ module frr-ripd {
container bfd-monitoring {
presence
"Present if BFD is configured for RIP peers in this interface.";
description "Configure BFD use in RIPD";
leaf enable {
type boolean;
default false;
description
"Enable/disable BFD monitoring.";
default false;
}
leaf profile {

View File

@ -13,6 +13,9 @@ module frr-ripngd {
import frr-if-rmap {
prefix frr-if-rmap;
}
import frr-filter {
prefix frr-filter;
}
import frr-interface {
prefix frr-interface;
}
@ -63,6 +66,7 @@ module frr-ripngd {
description
"Changed interface references to use
frr-interface:interface-ref typedef";
reference "FRRouting";
}
revision 2018-11-27 {
description
@ -72,6 +76,7 @@ module frr-ripngd {
}
container ripngd {
description "ripng routing instance data";
/*
* Routing instance configuration.
*/
@ -169,15 +174,18 @@ module frr-ripngd {
"A list of interfaces where the sending of RIPng packets
is disabled.";
}
uses frr-filter:distribute-list-group;
list redistribute {
key "protocol";
description
"Redistributes routes learned from other routing protocols.";
leaf protocol {
type frr-route-types:frr-route-types-v6;
must '. != "ripng"';
description
"Routing protocol.";
must '. != "ripng"';
}
leaf route-map {
type frr-route-map:route-map-ref;
@ -330,6 +338,7 @@ module frr-ripngd {
* Per-interface configuration data
*/
augment "/frr-interface:lib/frr-interface:interface" {
description "RIPng interface augmentation.";
container ripng {
description
"RIPng interface parameters.";