Merge pull request #13242 from LabNConsulting/chopps/no_rip_in_lib

Convert if_rmap to use YANG northbound
This commit is contained in:
Igor Ryzhov 2023-04-12 16:06:17 +03:00 committed by GitHub
commit 4150fc5399
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 500 additions and 141 deletions

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* route-map for interface.
* Copyright (C) 1999 Kunihiro Ishiguro
* Copyright (C) 2023 LabN Consulting, L.L.C.
*/
#include <zebra.h>
@ -10,7 +11,9 @@
#include "memory.h"
#include "if.h"
#include "if_rmap.h"
#include "ripd/ripd.h"
#include "northbound_cli.h"
#include "lib/if_rmap_clippy.c"
DEFINE_MTYPE_STATIC(LIB, IF_RMAP_CTX, "Interface route map container");
DEFINE_MTYPE_STATIC(LIB, IF_RMAP_CTX_NAME,
@ -18,8 +21,6 @@ DEFINE_MTYPE_STATIC(LIB, IF_RMAP_CTX_NAME,
DEFINE_MTYPE_STATIC(LIB, IF_RMAP, "Interface route map");
DEFINE_MTYPE_STATIC(LIB, IF_RMAP_NAME, "I.f. route map name");
static struct list *if_rmap_ctx_list;
static struct if_rmap *if_rmap_new(void)
{
struct if_rmap *new;
@ -31,7 +32,9 @@ static struct if_rmap *if_rmap_new(void)
static void if_rmap_free(struct if_rmap *if_rmap)
{
XFREE(MTYPE_IF_RMAP_NAME, if_rmap->ifname);
char *no_const_ifname = (char *)if_rmap->ifname;
XFREE(MTYPE_IF_RMAP_NAME, no_const_ifname);
XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
@ -41,22 +44,16 @@ static void if_rmap_free(struct if_rmap *if_rmap)
struct if_rmap *if_rmap_lookup(struct if_rmap_ctx *ctx, const char *ifname)
{
struct if_rmap key;
struct if_rmap key = {.ifname = ifname};
struct if_rmap *if_rmap;
/* temporary copy */
key.ifname = (ifname) ? XSTRDUP(MTYPE_IF_RMAP_NAME, ifname) : NULL;
if_rmap = hash_lookup(ctx->ifrmaphash, &key);
XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
return if_rmap;
}
void if_rmap_hook_add(struct if_rmap_ctx *ctx,
void (*func)(struct if_rmap_ctx *ctx,
struct if_rmap *))
void (*func)(struct if_rmap_ctx *ctx, struct if_rmap *))
{
ctx->if_rmap_add_hook = func;
}
@ -81,16 +78,11 @@ static void *if_rmap_hash_alloc(void *arg)
static struct if_rmap *if_rmap_get(struct if_rmap_ctx *ctx, const char *ifname)
{
struct if_rmap key;
struct if_rmap key = {.ifname = ifname};
struct if_rmap *ret;
/* temporary copy */
key.ifname = (ifname) ? XSTRDUP(MTYPE_IF_RMAP_NAME, ifname) : NULL;
ret = hash_get(ctx->ifrmaphash, &key, if_rmap_hash_alloc);
XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
return ret;
}
@ -109,147 +101,171 @@ static bool if_rmap_hash_cmp(const void *arg1, const void *arg2)
return strcmp(if_rmap1->ifname, if_rmap2->ifname) == 0;
}
static struct if_rmap *if_rmap_set(struct if_rmap_ctx *ctx,
const char *ifname, enum if_rmap_type type,
const char *routemap_name)
static void if_rmap_set(struct if_rmap_ctx *ctx, const char *ifname,
enum if_rmap_type type, const char *routemap_name)
{
struct if_rmap *if_rmap;
struct if_rmap *if_rmap = if_rmap_get(ctx, ifname);
if_rmap = if_rmap_get(ctx, ifname);
if (type == IF_RMAP_IN) {
XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
if_rmap->routemap[IF_RMAP_IN] =
XSTRDUP(MTYPE_IF_RMAP_NAME, routemap_name);
}
if (type == IF_RMAP_OUT) {
XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
if_rmap->routemap[IF_RMAP_OUT] =
XSTRDUP(MTYPE_IF_RMAP_NAME, routemap_name);
}
assert(type == IF_RMAP_IN || type == IF_RMAP_OUT);
XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[type]);
if_rmap->routemap[type] = XSTRDUP(MTYPE_IF_RMAP_NAME, routemap_name);
if (ctx->if_rmap_add_hook)
(ctx->if_rmap_add_hook)(ctx, if_rmap);
return if_rmap;
}
static int if_rmap_unset(struct if_rmap_ctx *ctx,
const char *ifname, enum if_rmap_type type,
const char *routemap_name)
static void if_rmap_unset(struct if_rmap_ctx *ctx, const char *ifname,
enum if_rmap_type type)
{
struct if_rmap *if_rmap;
struct if_rmap *if_rmap = if_rmap_lookup(ctx, ifname);
if_rmap = if_rmap_lookup(ctx, ifname);
if (!if_rmap)
return 0;
return;
if (type == IF_RMAP_IN) {
if (!if_rmap->routemap[IF_RMAP_IN])
return 0;
if (strcmp(if_rmap->routemap[IF_RMAP_IN], routemap_name) != 0)
return 0;
assert(type == IF_RMAP_IN || type == IF_RMAP_OUT);
if (!if_rmap->routemap[type])
return;
XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_IN]);
}
if (type == IF_RMAP_OUT) {
if (!if_rmap->routemap[IF_RMAP_OUT])
return 0;
if (strcmp(if_rmap->routemap[IF_RMAP_OUT], routemap_name) != 0)
return 0;
XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[IF_RMAP_OUT]);
}
XFREE(MTYPE_IF_RMAP_NAME, if_rmap->routemap[type]);
if (ctx->if_rmap_delete_hook)
ctx->if_rmap_delete_hook(ctx, if_rmap);
if (if_rmap->routemap[IF_RMAP_IN] == NULL
&& if_rmap->routemap[IF_RMAP_OUT] == NULL) {
if (if_rmap->routemap[IF_RMAP_IN] == NULL &&
if_rmap->routemap[IF_RMAP_OUT] == NULL) {
hash_release(ctx->ifrmaphash, if_rmap);
if_rmap_free(if_rmap);
}
return 1;
}
DEFUN (if_rmap,
if_rmap_cmd,
"route-map RMAP_NAME <in|out> IFNAME",
"Route map set\n"
"Route map name\n"
"Route map set for input filtering\n"
"Route map set for output filtering\n"
"Route map interface name\n")
static int if_route_map_handler(struct vty *vty, bool no, const char *dir,
const char *other_dir, const char *ifname,
const char *route_map)
{
int idx_rmap_name = 1;
int idx_in_out = 2;
int idx_ifname = 3;
enum if_rmap_type type;
struct if_rmap_ctx *ctx;
enum nb_operation op = no ? NB_OP_DESTROY : NB_OP_MODIFY;
const struct lyd_node *dnode;
struct rip *rip;
char xpath[XPATH_MAXLEN];
dnode = yang_dnode_get(running_config->dnode, VTY_CURR_XPATH);
rip = nb_running_get_entry(dnode, NULL, true);
ctx = rip->if_rmap_ctx;
if (strncmp(argv[idx_in_out]->text, "in", 1) == 0)
type = IF_RMAP_IN;
else if (strncmp(argv[idx_in_out]->text, "out", 1) == 0)
type = IF_RMAP_OUT;
else {
vty_out(vty, "route-map direction must be [in|out]\n");
return CMD_WARNING_CONFIG_FAILED;
if (!no) {
snprintf(
xpath, sizeof(xpath),
"./if-route-maps/if-route-map[interface='%s']/%s-route-map",
ifname, dir);
} else {
/*
* If we are deleting the last policy for this interface,
* (i.e., no `in` or `out` policy). delete the interface list
* node instead.
*/
dnode = yang_dnode_get(vty->candidate_config->dnode,
VTY_CURR_XPATH);
if (yang_dnode_existsf(
dnode,
"./if-route-maps/if-route-map[interface='%s']/%s-route-map",
ifname, other_dir)) {
snprintf(
xpath, sizeof(xpath),
"./if-route-maps/if-route-map[interface='%s']/%s-route-map",
ifname, dir);
} else {
/* both dir will be empty so delete the list node */
snprintf(xpath, sizeof(xpath),
"./if-route-maps/if-route-map[interface='%s']",
ifname);
}
}
nb_cli_enqueue_change(vty, xpath, op, route_map);
if_rmap_set(ctx, argv[idx_ifname]->arg,
type, argv[idx_rmap_name]->arg);
return CMD_SUCCESS;
return nb_cli_apply_changes(vty, NULL);
}
DEFUN (no_if_rmap,
no_if_rmap_cmd,
"no route-map ROUTEMAP_NAME <in|out> IFNAME",
NO_STR
"Route map unset\n"
"Route map name\n"
"Route map for input filtering\n"
"Route map for output filtering\n"
"Route map interface name\n")
DEFPY_YANG(if_ipv4_route_map, if_ipv4_route_map_cmd,
"route-map ROUTE-MAP <in$in|out> IFNAME",
"Route map set\n"
"Route map name\n"
"Route map set for input filtering\n"
"Route map set for output filtering\n" INTERFACE_STR)
{
int idx_routemap_name = 2;
int idx_in_out = 3;
int idx_ifname = 4;
int ret;
enum if_rmap_type type;
struct if_rmap_ctx *ctx =
(struct if_rmap_ctx *)listnode_head(if_rmap_ctx_list);
const char *dir = in ? "in" : "out";
const char *other_dir = in ? "out" : "in";
if (strncmp(argv[idx_in_out]->arg, "i", 1) == 0)
type = IF_RMAP_IN;
else if (strncmp(argv[idx_in_out]->arg, "o", 1) == 0)
type = IF_RMAP_OUT;
else {
vty_out(vty, "route-map direction must be [in|out]\n");
return CMD_WARNING_CONFIG_FAILED;
}
return if_route_map_handler(vty, false, dir, other_dir, ifname,
route_map);
}
ret = if_rmap_unset(ctx, argv[idx_ifname]->arg, type,
argv[idx_routemap_name]->arg);
if (!ret) {
vty_out(vty, "route-map doesn't exist\n");
return CMD_WARNING_CONFIG_FAILED;
}
return CMD_SUCCESS;
DEFPY_YANG(no_if_ipv4_route_map, no_if_ipv4_route_map_cmd,
"no route-map [ROUTE-MAP] <in$in|out> IFNAME",
NO_STR
"Route map set\n"
"Route map name\n"
"Route map set for input filtering\n"
"Route map set for output filtering\n" INTERFACE_STR)
{
const char *dir = in ? "in" : "out";
const char *other_dir = in ? "out" : "in";
return if_route_map_handler(vty, true, dir, other_dir, ifname,
route_map);
}
/*
* CLI infra requires new handlers for ripngd
*/
DEFPY_YANG(if_ipv6_route_map, if_ipv6_route_map_cmd,
"route-map ROUTE-MAP <in$in|out> IFNAME",
"Route map set\n"
"Route map name\n"
"Route map set for input filtering\n"
"Route map set for output filtering\n" INTERFACE_STR)
{
const char *dir = in ? "in" : "out";
const char *other_dir = in ? "out" : "in";
return if_route_map_handler(vty, false, dir, other_dir, ifname,
route_map);
}
DEFPY_YANG(no_if_ipv6_route_map, no_if_ipv6_route_map_cmd,
"no route-map [ROUTE-MAP] <in$in|out> IFNAME",
NO_STR
"Route map set\n"
"Route map name\n"
"Route map set for input filtering\n"
"Route map set for output filtering\n" INTERFACE_STR)
{
const char *dir = in ? "in" : "out";
const char *other_dir = in ? "out" : "in";
return if_route_map_handler(vty, true, dir, other_dir, ifname,
route_map);
}
void if_rmap_yang_modify_cb(struct if_rmap_ctx *ctx,
const struct lyd_node *dnode,
enum if_rmap_type type, bool del)
{
const char *mapname = yang_dnode_get_string(dnode, NULL);
const char *ifname = yang_dnode_get_string(dnode, "../interface");
if (del)
if_rmap_unset(ctx, ifname, type);
else
if_rmap_set(ctx, ifname, type, mapname);
}
void if_rmap_yang_destroy_cb(struct if_rmap_ctx *ctx,
const struct lyd_node *dnode)
{
const char *ifname = yang_dnode_get_string(dnode, "interface");
if_rmap_unset(ctx, ifname, IF_RMAP_IN);
if_rmap_unset(ctx, ifname, IF_RMAP_OUT);
}
/* Configuration write function. */
int config_write_if_rmap(struct vty *vty,
struct if_rmap_ctx *ctx)
int config_write_if_rmap(struct vty *vty, struct if_rmap_ctx *ctx)
{
unsigned int i;
struct hash_bucket *mp;
@ -281,10 +297,8 @@ int config_write_if_rmap(struct vty *vty,
void if_rmap_ctx_delete(struct if_rmap_ctx *ctx)
{
listnode_delete(if_rmap_ctx_list, ctx);
hash_clean_and_free(&ctx->ifrmaphash, (void (*)(void *))if_rmap_free);
if (ctx->name)
XFREE(MTYPE_IF_RMAP_CTX_NAME, ctx->name);
XFREE(MTYPE_IF_RMAP_CTX_NAME, ctx->name);
XFREE(MTYPE_IF_RMAP_CTX, ctx);
}
@ -296,27 +310,23 @@ struct if_rmap_ctx *if_rmap_ctx_create(const char *name)
ctx = XCALLOC(MTYPE_IF_RMAP_CTX, sizeof(struct if_rmap_ctx));
ctx->name = XSTRDUP(MTYPE_IF_RMAP_CTX_NAME, name);
ctx->ifrmaphash = hash_create_size(4, if_rmap_hash_make, if_rmap_hash_cmp,
"Interface Route-Map Hash");
if (!if_rmap_ctx_list)
if_rmap_ctx_list = list_new();
listnode_add(if_rmap_ctx_list, ctx);
ctx->ifrmaphash =
hash_create_size(4, if_rmap_hash_make, if_rmap_hash_cmp,
"Interface Route-Map Hash");
return ctx;
}
void if_rmap_init(int node)
{
if (node == RIPNG_NODE) {
} else if (node == RIP_NODE) {
install_element(RIP_NODE, &if_rmap_cmd);
install_element(RIP_NODE, &no_if_rmap_cmd);
if (node == RIP_NODE) {
install_element(RIP_NODE, &if_ipv4_route_map_cmd);
install_element(RIP_NODE, &no_if_ipv4_route_map_cmd);
} else if (node == RIPNG_NODE) {
install_element(RIPNG_NODE, &if_ipv6_route_map_cmd);
install_element(RIPNG_NODE, &no_if_ipv6_route_map_cmd);
}
if_rmap_ctx_list = list_new();
}
void if_rmap_terminate(void)
{
if (!if_rmap_ctx_list)
return;
list_delete(&if_rmap_ctx_list);
}

View file

@ -6,15 +6,20 @@
#ifndef _ZEBRA_IF_RMAP_H
#define _ZEBRA_IF_RMAP_H
#include "typesafe.h"
#ifdef __cplusplus
extern "C" {
#endif
struct lyd_node;
struct vty;
enum if_rmap_type { IF_RMAP_IN, IF_RMAP_OUT, IF_RMAP_MAX };
struct if_rmap {
/* Name of the interface. */
char *ifname;
const char *ifname;
char *routemap[IF_RMAP_MAX];
};
@ -45,6 +50,11 @@ void if_rmap_hook_delete(struct if_rmap_ctx *ctx,
struct if_rmap *));
extern struct if_rmap *if_rmap_lookup(struct if_rmap_ctx *ctx,
const char *ifname);
extern void if_rmap_yang_modify_cb(struct if_rmap_ctx *ctx,
const struct lyd_node *dnode,
enum if_rmap_type type, bool del);
extern void if_rmap_yang_destroy_cb(struct if_rmap_ctx *ctx,
const struct lyd_node *dnode);
extern int config_write_if_rmap(struct vty *, struct if_rmap_ctx *ctx);
#ifdef __cplusplus

View file

@ -174,6 +174,7 @@ clippy_scan += \
lib/affinitymap_cli.c \
lib/if.c \
lib/filter_cli.c \
lib/if_rmap.c \
lib/log_vty.c \
lib/nexthop_group.c \
lib/northbound_cli.c \

View file

@ -165,6 +165,27 @@ const struct frr_yang_module_info frr_ripd_info = {
.modify = ripd_instance_redistribute_metric_modify,
},
},
{
.xpath = "/frr-ripd:ripd/instance/if-route-maps/if-route-map",
.cbs = {
.create = ripd_instance_if_route_maps_if_route_map_create,
.destroy = ripd_instance_if_route_maps_if_route_map_destroy,
}
},
{
.xpath = "/frr-ripd:ripd/instance/if-route-maps/if-route-map/in-route-map",
.cbs = {
.modify = ripd_instance_if_route_maps_if_route_map_in_route_map_modify,
.destroy = ripd_instance_if_route_maps_if_route_map_in_route_map_destroy,
}
},
{
.xpath = "/frr-ripd:ripd/instance/if-route-maps/if-route-map/out-route-map",
.cbs = {
.modify = ripd_instance_if_route_maps_if_route_map_out_route_map_modify,
.destroy = ripd_instance_if_route_maps_if_route_map_out_route_map_destroy,
}
},
{
.xpath = "/frr-ripd:ripd/instance/static-route",
.cbs = {

View file

@ -52,6 +52,18 @@ int ripd_instance_redistribute_route_map_destroy(
struct nb_cb_destroy_args *args);
int ripd_instance_redistribute_metric_modify(struct nb_cb_modify_args *args);
int ripd_instance_redistribute_metric_destroy(struct nb_cb_destroy_args *args);
int ripd_instance_if_route_maps_if_route_map_create(
struct nb_cb_create_args *args);
int ripd_instance_if_route_maps_if_route_map_destroy(
struct nb_cb_destroy_args *args);
int ripd_instance_if_route_maps_if_route_map_in_route_map_modify(
struct nb_cb_modify_args *args);
int ripd_instance_if_route_maps_if_route_map_in_route_map_destroy(
struct nb_cb_destroy_args *args);
int ripd_instance_if_route_maps_if_route_map_out_route_map_modify(
struct nb_cb_modify_args *args);
int ripd_instance_if_route_maps_if_route_map_out_route_map_destroy(
struct nb_cb_destroy_args *args);
int ripd_instance_static_route_create(struct nb_cb_create_args *args);
int ripd_instance_static_route_destroy(struct nb_cb_destroy_args *args);
int ripd_instance_timers_flush_interval_modify(struct nb_cb_modify_args *args);

View file

@ -3,6 +3,7 @@
* Copyright (C) 1997, 1998, 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
* Copyright (C) 2018 NetDEF, Inc.
* Renato Westphal
* Copyright (C) 2023 LabN Consulting, L.L.C.
*/
#include <zebra.h>
@ -13,6 +14,7 @@
#include "prefix.h"
#include "table.h"
#include "command.h"
#include "if_rmap.h"
#include "routemap.h"
#include "northbound.h"
#include "libfrr.h"
@ -680,6 +682,94 @@ int ripd_instance_redistribute_metric_destroy(struct nb_cb_destroy_args *args)
return NB_OK;
}
/*
* XPath: /frr-ripd:ripd/instance/if-route-maps/if-route-map
*/
int ripd_instance_if_route_maps_if_route_map_create(
struct nb_cb_create_args *args)
{
/* if_rmap is created when first routemap is added */
return NB_OK;
}
int ripd_instance_if_route_maps_if_route_map_destroy(
struct nb_cb_destroy_args *args)
{
struct rip *rip;
if (args->event != NB_EV_APPLY)
return NB_OK;
/*
* YANG will prune edit deletes up to the most general deleted node so
* we need to handle deleting any existing state underneath and not
* count on those more specific callbacks being called individually.
*/
rip = nb_running_get_entry(args->dnode, NULL, true);
if_rmap_yang_destroy_cb(rip->if_rmap_ctx, args->dnode);
return NB_OK;
}
static void if_route_map_modify(const struct lyd_node *dnode,
enum if_rmap_type type, bool delete)
{
struct rip *rip = nb_running_get_entry(dnode, NULL, true);
if_rmap_yang_modify_cb(rip->if_rmap_ctx, dnode, type, delete);
}
/*
* XPath: /frr-ripd:ripd/instance/if-route-maps/if-route-map/in-route-map
*/
int ripd_instance_if_route_maps_if_route_map_in_route_map_modify(
struct nb_cb_modify_args *args)
{
if (args->event != NB_EV_APPLY)
return NB_OK;
if_route_map_modify(args->dnode, IF_RMAP_IN, false);
return NB_OK;
}
int ripd_instance_if_route_maps_if_route_map_in_route_map_destroy(
struct nb_cb_destroy_args *args)
{
if (args->event != NB_EV_APPLY)
return NB_OK;
if_route_map_modify(args->dnode, IF_RMAP_IN, true);
return NB_OK;
}
/*
* XPath: /frr-ripd:ripd/instance/if-route-maps/if-route-map/out-route-map
*/
int ripd_instance_if_route_maps_if_route_map_out_route_map_modify(
struct nb_cb_modify_args *args)
{
if (args->event != NB_EV_APPLY)
return NB_OK;
if_route_map_modify(args->dnode, IF_RMAP_OUT, false);
return NB_OK;
}
int ripd_instance_if_route_maps_if_route_map_out_route_map_destroy(
struct nb_cb_destroy_args *args)
{
if (args->event != NB_EV_APPLY)
return NB_OK;
if_route_map_modify(args->dnode, IF_RMAP_OUT, true);
return NB_OK;
}
/*
* XPath: /frr-ripd:ripd/instance/static-route
*/

View file

@ -114,6 +114,27 @@ const struct frr_yang_module_info frr_ripngd_info = {
.modify = ripngd_instance_redistribute_metric_modify,
},
},
{
.xpath = "/frr-ripngd:ripngd/instance/if-route-maps/if-route-map",
.cbs = {
.create = ripngd_instance_if_route_maps_if_route_map_create,
.destroy = ripngd_instance_if_route_maps_if_route_map_destroy,
}
},
{
.xpath = "/frr-ripngd:ripngd/instance/if-route-maps/if-route-map/in-route-map",
.cbs = {
.modify = ripngd_instance_if_route_maps_if_route_map_in_route_map_modify,
.destroy = ripngd_instance_if_route_maps_if_route_map_in_route_map_destroy,
}
},
{
.xpath = "/frr-ripngd:ripngd/instance/if-route-maps/if-route-map/out-route-map",
.cbs = {
.modify = ripngd_instance_if_route_maps_if_route_map_out_route_map_modify,
.destroy = ripngd_instance_if_route_maps_if_route_map_out_route_map_destroy,
}
},
{
.xpath = "/frr-ripngd:ripngd/instance/static-route",
.cbs = {

View file

@ -39,6 +39,18 @@ int ripngd_instance_redistribute_route_map_destroy(
int ripngd_instance_redistribute_metric_modify(struct nb_cb_modify_args *args);
int ripngd_instance_redistribute_metric_destroy(
struct nb_cb_destroy_args *args);
int ripngd_instance_if_route_maps_if_route_map_create(
struct nb_cb_create_args *args);
int ripngd_instance_if_route_maps_if_route_map_destroy(
struct nb_cb_destroy_args *args);
int ripngd_instance_if_route_maps_if_route_map_in_route_map_modify(
struct nb_cb_modify_args *args);
int ripngd_instance_if_route_maps_if_route_map_in_route_map_destroy(
struct nb_cb_destroy_args *args);
int ripngd_instance_if_route_maps_if_route_map_out_route_map_modify(
struct nb_cb_modify_args *args);
int ripngd_instance_if_route_maps_if_route_map_out_route_map_destroy(
struct nb_cb_destroy_args *args);
int ripngd_instance_static_route_create(struct nb_cb_create_args *args);
int ripngd_instance_static_route_destroy(struct nb_cb_destroy_args *args);
int ripngd_instance_aggregate_address_create(struct nb_cb_create_args *args);

View file

@ -3,6 +3,7 @@
* Copyright (C) 1998 Kunihiro Ishiguro
* Copyright (C) 2018 NetDEF, Inc.
* Renato Westphal
* Copyright (C) 2023 LabN Consulting, L.L.C.
*/
#include <zebra.h>
@ -13,6 +14,7 @@
#include "prefix.h"
#include "table.h"
#include "command.h"
#include "if_rmap.h"
#include "routemap.h"
#include "agg_table.h"
#include "northbound.h"
@ -502,6 +504,93 @@ int ripngd_instance_redistribute_metric_destroy(struct nb_cb_destroy_args *args)
return NB_OK;
}
/*
* XPath: /frr-ripngd:ripngd/instance/if-route-maps/if-route-map
*/
int ripngd_instance_if_route_maps_if_route_map_create(
struct nb_cb_create_args *args)
{
/* if_rmap is created when first routemap is added */
return NB_OK;
}
int ripngd_instance_if_route_maps_if_route_map_destroy(
struct nb_cb_destroy_args *args)
{
struct ripng *ripng;
if (args->event != NB_EV_APPLY)
return NB_OK;
/*
* YANG will prune edit deletes up to the most general deleted node so
* we need to handle deleting any existing state underneath and not
* count on those more specific callbacks being called individually.
*/
ripng = nb_running_get_entry(args->dnode, NULL, true);
if_rmap_yang_destroy_cb(ripng->if_rmap_ctx, args->dnode);
return NB_OK;
}
static void if_route_map_modify(const struct lyd_node *dnode,
enum if_rmap_type type, bool delete)
{
struct ripng *ripng = nb_running_get_entry(dnode, NULL, true);
if_rmap_yang_modify_cb(ripng->if_rmap_ctx, dnode, type, delete);
}
/*
* XPath: /frr-ripng:ripng/instance/if-route-maps/if-route-map/in-route-map
*/
int ripngd_instance_if_route_maps_if_route_map_in_route_map_modify(
struct nb_cb_modify_args *args)
{
if (args->event != NB_EV_APPLY)
return NB_OK;
if_route_map_modify(args->dnode, IF_RMAP_IN, false);
return NB_OK;
}
int ripngd_instance_if_route_maps_if_route_map_in_route_map_destroy(
struct nb_cb_destroy_args *args)
{
if (args->event != NB_EV_APPLY)
return NB_OK;
if_route_map_modify(args->dnode, IF_RMAP_IN, true);
return NB_OK;
}
/*
* XPath: /frr-ripngd:ripngd/instance/if-route-maps/if-route-map/out-route-map
*/
int ripngd_instance_if_route_maps_if_route_map_out_route_map_modify(
struct nb_cb_modify_args *args)
{
if (args->event != NB_EV_APPLY)
return NB_OK;
if_route_map_modify(args->dnode, IF_RMAP_OUT, false);
return NB_OK;
}
int ripngd_instance_if_route_maps_if_route_map_out_route_map_destroy(
struct nb_cb_destroy_args *args)
{
if (args->event != NB_EV_APPLY)
return NB_OK;
if_route_map_modify(args->dnode, IF_RMAP_OUT, true);
return NB_OK;
}
/*
* XPath: /frr-ripngd:ripngd/instance/static-route
*/

80
yang/frr-if-rmap.yang Normal file
View file

@ -0,0 +1,80 @@
// SPDX-License-Identifier: BSD-2-Clause
module frr-if-rmap {
yang-version 1.1;
namespace "http://frrouting.org/yang/frr-if-rmap";
prefix frr-if-map;
import frr-interface {
prefix frr-interface;
}
import frr-route-map {
prefix frr-route-map;
}
organization
"FRRouting";
contact
"FRR Users List: <mailto:frog@lists.frrouting.org>
FRR Development List: <mailto:dev@lists.frrouting.org>";
description
"This module defines route map settings
Copyright 2023 LabN Consulting L.L.C
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.";
revision 2023-04-09 {
description
"Initial revision";
reference "FRRouting";
}
grouping if-route-maps-group {
description "Grouping for interface route maps";
container if-route-maps {
description "Collection of interface route-maps";
list if-route-map {
must "in-route-map or out-route-map";
key "interface";
description "Collection of route-maps for an interface";
leaf "interface" {
type frr-interface:interface-ref;
description "The interface the route maps are associated with";
}
leaf "in-route-map" {
type frr-route-map:route-map-name;
description "Name of the ingress route map";
}
leaf "out-route-map" {
type frr-route-map:route-map-name;
description "Name of the egress route map";
}
}
}
}
}

View file

@ -10,6 +10,9 @@ module frr-ripd {
import ietf-yang-types {
prefix yang;
}
import frr-if-rmap {
prefix frr-if-rmap;
}
import frr-interface {
prefix frr-interface;
}
@ -282,6 +285,9 @@ module frr-ripd {
is 0.";
}
}
uses frr-if-rmap:if-route-maps-group;
leaf-list static-route {
type inet:ipv4-prefix;
description

View file

@ -10,6 +10,9 @@ module frr-ripngd {
import ietf-yang-types {
prefix yang;
}
import frr-if-rmap {
prefix frr-if-rmap;
}
import frr-interface {
prefix frr-interface;
}
@ -196,6 +199,9 @@ module frr-ripngd {
is 0.";
}
}
uses frr-if-rmap:if-route-maps-group;
leaf-list static-route {
type inet:ipv6-prefix;
description

View file

@ -24,6 +24,7 @@ dist_yangmodels_DATA += yang/frr-filter.yang
dist_yangmodels_DATA += yang/frr-module-translator.yang
dist_yangmodels_DATA += yang/frr-nexthop.yang
dist_yangmodels_DATA += yang/frr-test-module.yang
dist_yangmodels_DATA += yang/frr-if-rmap.yang
dist_yangmodels_DATA += yang/frr-interface.yang
dist_yangmodels_DATA += yang/frr-route-map.yang
dist_yangmodels_DATA += yang/frr-zebra-route-map.yang