mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-28 15:36:25 +00:00
lib: convert if_rmap to YANG northbound
- nice correspondence between new YANG grouping and shared library code. - fixes bug with RIPNG use, certainly didn't work before. - removes rip header from shared library code - still has uses RIP_NODE/RIPNG_NODE as required by CLI foo. Signed-off-by: Christian Hopps <chopps@labn.net>
This commit is contained in:
parent
2eb4471114
commit
efa2ca6ef0
275
lib/if_rmap.c
275
lib/if_rmap.c
@ -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,16 +44,11 @@ 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;
|
||||
}
|
||||
|
||||
@ -80,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;
|
||||
}
|
||||
|
||||
@ -108,58 +101,32 @@ 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);
|
||||
@ -169,80 +136,131 @@ static int if_rmap_unset(struct if_rmap_ctx *ctx,
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@ -279,10 +297,8 @@ int config_write_if_rmap(struct vty *vty, struct if_rmap_ctx *ctx)
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -297,25 +313,20 @@ struct if_rmap_ctx *if_rmap_ctx_create(const char *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);
|
||||
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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
80
yang/frr-if-rmap.yang
Normal file
80
yang/frr-if-rmap.yang
Normal 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";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user