lib: add northbound support to distribute-list code.

Signed-off-by: Christian Hopps <chopps@labn.net>
This commit is contained in:
Christian Hopps 2024-01-21 13:12:39 +00:00
parent dc8f136064
commit eba64f79cc
3 changed files with 221 additions and 7 deletions

View File

@ -274,7 +274,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 +444,126 @@ 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)
{
/* The code currently doesn't require this as it uses a global */
/* 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 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;
/* The code currently doesn't require this as it uses a global */
/* 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(NULL, prefix, ipv4,
dir_node->schema->name,
lyd_get_value(dnode),
lyd_get_value(intf_key));
else
distribute_list_parser(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" {
@ -74,6 +75,36 @@ extern int distribute_list_parser(bool prefix, bool v4, const char *dir,
extern int distribute_list_no_parser(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

@ -10,6 +10,9 @@ module frr-filter {
import ietf-yang-types {
prefix yang;
}
import frr-interface {
prefix frr-interface;
}
organization "FRRouting";
contact
@ -79,6 +82,65 @@ module frr-filter {
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";
}
}
}
}
/*
* Configuration data.
*/
@ -91,12 +153,12 @@ module frr-filter {
leaf type {
type enumeration {
enum ipv4 {
value 0;
description "Internet Protocol address version 4";
}
enum ipv6 {
value 1;
description "Internet Protocol address version 6";
value 0;
description "Internet Protocol address version 4";
}
enum ipv6 {
value 1;
description "Internet Protocol address version 6";
}
enum mac {
value 2;