frr/lib/filter_nb.c
Rafael Zalamena 664ae7953a lib: filter remove unused variable
Remove variable that is not being used.

Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
2020-06-05 16:42:16 -03:00

1287 lines
29 KiB
C

/*
* FRR filter northbound implementation.
*
* Copyright (C) 2019 Network Device Education Foundation, Inc. ("NetDEF")
* Rafael Zalamena
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*/
#include "zebra.h"
#include "lib/northbound.h"
#include "lib/prefix.h"
#include "lib/filter.h"
#include "lib/plist.h"
#include "lib/plist_int.h"
/* Helper function. */
static in_addr_t
ipv4_network_addr(in_addr_t hostaddr, int masklen)
{
struct in_addr mask;
masklen2ip(masklen, &mask);
return hostaddr & mask.s_addr;
}
static enum nb_error
prefix_list_length_validate(const struct lyd_node *dnode)
{
int type = yang_dnode_get_enum(dnode, "../../type");
const char *xpath_le = NULL, *xpath_ge = NULL;
struct prefix p;
uint8_t le, ge;
if (type == YPLT_IPV4) {
yang_dnode_get_prefix(&p, dnode, "../ipv4-prefix");
xpath_le = "../ipv4-prefix-length-lesser-or-equal";
xpath_ge = "../ipv4-prefix-length-greater-or-equal";
} else {
yang_dnode_get_prefix(&p, dnode, "../ipv6-prefix");
xpath_le = "../ipv6-prefix-length-lesser-or-equal";
xpath_ge = "../ipv6-prefix-length-greater-or-equal";
}
/*
* Check rule:
* prefix length <= le.
*/
if (yang_dnode_exists(dnode, xpath_le)) {
le = yang_dnode_get_uint8(dnode, xpath_le);
if (p.prefixlen > le)
goto log_and_fail;
}
/*
* Check rule:
* prefix length < ge.
*/
if (yang_dnode_exists(dnode, xpath_ge)) {
ge = yang_dnode_get_uint8(dnode, xpath_ge);
if (p.prefixlen >= ge)
goto log_and_fail;
}
/*
* Check rule:
* ge <= le.
*/
if (yang_dnode_exists(dnode, xpath_le) &&
yang_dnode_exists(dnode, xpath_ge)) {
le = yang_dnode_get_uint8(dnode, xpath_le);
ge = yang_dnode_get_uint8(dnode, xpath_ge);
if (ge > le)
goto log_and_fail;
}
return NB_OK;
log_and_fail:
zlog_info("prefix-list: invalid prefix range for %pFX: "
"Make sure that mask length < ge <= le", &p);
return NB_ERR_VALIDATION;
}
/**
* Sets prefix list entry to blank value.
*
* \param[out] ple prefix list entry to modify.
*/
static void prefix_list_entry_set_empty(struct prefix_list_entry *ple)
{
ple->any = false;
memset(&ple->prefix, 0, sizeof(ple->prefix));
ple->ge = 0;
ple->le = 0;
}
/*
* XPath: /frr-filter:lib/access-list-legacy
*/
static int lib_access_list_legacy_create(struct nb_cb_create_args *args)
{
struct access_list *acl;
const char *acl_name;
if (args->event != NB_EV_APPLY)
return NB_OK;
acl_name = yang_dnode_get_string(args->dnode, "./number");
acl = access_list_get(AFI_IP, acl_name);
nb_running_set_entry(args->dnode, acl);
return NB_OK;
}
static int lib_access_list_legacy_destroy(struct nb_cb_destroy_args *args)
{
struct access_master *am;
struct access_list *acl;
if (args->event != NB_EV_APPLY)
return NB_OK;
acl = nb_running_unset_entry(args->dnode);
am = acl->master;
if (am->delete_hook)
am->delete_hook(acl);
access_list_delete(acl);
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list-legacy/remark
*/
static int lib_access_list_legacy_remark_modify(struct nb_cb_modify_args *args)
{
struct access_list *acl;
const char *remark;
if (args->event != NB_EV_APPLY)
return NB_OK;
acl = nb_running_get_entry(args->dnode, NULL, true);
if (acl->remark)
XFREE(MTYPE_TMP, acl->remark);
remark = yang_dnode_get_string(args->dnode, NULL);
acl->remark = XSTRDUP(MTYPE_TMP, remark);
return NB_OK;
}
static int
lib_access_list_legacy_remark_destroy(struct nb_cb_destroy_args *args)
{
struct access_list *acl;
if (args->event != NB_EV_APPLY)
return NB_OK;
acl = nb_running_get_entry(args->dnode, NULL, true);
if (acl->remark)
XFREE(MTYPE_TMP, acl->remark);
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list-legacy/entry
*/
static int lib_access_list_legacy_entry_create(struct nb_cb_create_args *args)
{
struct filter_cisco *fc;
struct access_list *acl;
struct filter *f;
uint32_t aclno;
/* TODO: validate `filter_lookup_cisco` returns NULL. */
if (args->event != NB_EV_APPLY)
return NB_OK;
aclno = yang_dnode_get_uint16(args->dnode, "../number");
f = filter_new();
f->cisco = 1;
f->seq = yang_dnode_get_uint32(args->dnode, "./sequence");
fc = &f->u.cfilter;
if ((aclno >= 1 && aclno <= 99) || (aclno >= 1300 && aclno <= 1999))
fc->extended = 0;
else
fc->extended = 1;
acl = nb_running_get_entry(args->dnode, NULL, true);
f->acl = acl;
access_list_filter_add(acl, f);
nb_running_set_entry(args->dnode, f);
return NB_OK;
}
static int lib_access_list_legacy_entry_destroy(struct nb_cb_destroy_args *args)
{
struct access_list *acl;
struct filter *f;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_unset_entry(args->dnode);
acl = f->acl;
access_list_filter_delete(acl, f);
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list-legacy/entry/action
*/
static int
lib_access_list_legacy_entry_action_modify(struct nb_cb_modify_args *args)
{
const char *filter_type;
struct filter *f;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
filter_type = yang_dnode_get_string(args->dnode, NULL);
if (strcmp(filter_type, "permit") == 0)
f->type = FILTER_PERMIT;
else
f->type = FILTER_DENY;
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list-legacy/entry/host
*/
static int
lib_access_list_legacy_entry_host_modify(struct nb_cb_modify_args *args)
{
struct filter_cisco *fc;
struct filter *f;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
fc = &f->u.cfilter;
yang_dnode_get_ipv4(&fc->addr, args->dnode, NULL);
fc->addr_mask.s_addr = INADDR_ANY;
return NB_OK;
}
static int
lib_access_list_legacy_entry_host_destroy(struct nb_cb_destroy_args *args)
{
struct filter_cisco *fc;
struct filter *f;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
fc = &f->u.cfilter;
fc->addr.s_addr = INADDR_ANY;
fc->addr_mask.s_addr = INADDR_NONE;
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list-legacy/entry/network
*/
static int
lib_access_list_legacy_entry_network_modify(struct nb_cb_modify_args *args)
{
struct filter_cisco *fc;
struct filter *f;
struct prefix p;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
fc = &f->u.cfilter;
yang_dnode_get_prefix(&p, args->dnode, NULL);
fc->addr.s_addr = ipv4_network_addr(p.u.prefix4.s_addr, p.prefixlen);
masklen2ip(p.prefixlen, &fc->addr_mask);
return NB_OK;
}
static int
lib_access_list_legacy_entry_network_destroy(struct nb_cb_destroy_args *args)
{
struct filter_cisco *fc;
struct filter *f;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
fc = &f->u.cfilter;
fc->addr.s_addr = INADDR_ANY;
fc->addr_mask.s_addr = INADDR_NONE;
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list-legacy/entry/any
*/
static int
lib_access_list_legacy_entry_any_create(struct nb_cb_create_args *args)
{
struct filter_cisco *fc;
struct filter *f;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
fc = &f->u.cfilter;
fc->addr.s_addr = INADDR_ANY;
fc->addr_mask.s_addr = INADDR_NONE;
return NB_OK;
}
static int
lib_access_list_legacy_entry_any_destroy(struct nb_cb_destroy_args *args)
{
struct filter_cisco *fc;
struct filter *f;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
fc = &f->u.cfilter;
fc->addr.s_addr = INADDR_ANY;
fc->addr_mask.s_addr = INADDR_NONE;
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list-legacy/entry/destination-host
*/
static int lib_access_list_legacy_entry_destination_host_modify(
struct nb_cb_modify_args *args)
{
struct filter_cisco *fc;
struct filter *f;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
fc = &f->u.cfilter;
yang_dnode_get_ipv4(&fc->mask, args->dnode, NULL);
fc->mask_mask.s_addr = INADDR_ANY;
return NB_OK;
}
static int lib_access_list_legacy_entry_destination_host_destroy(
struct nb_cb_destroy_args *args)
{
struct filter_cisco *fc;
struct filter *f;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
fc = &f->u.cfilter;
fc->mask.s_addr = INADDR_ANY;
fc->mask_mask.s_addr = INADDR_NONE;
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list-legacy/entry/destination-network
*/
static int lib_access_list_legacy_entry_destination_network_modify(
struct nb_cb_modify_args *args)
{
struct filter_cisco *fc;
struct filter *f;
struct prefix p;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
fc = &f->u.cfilter;
yang_dnode_get_prefix(&p, args->dnode, NULL);
fc->mask.s_addr = ipv4_network_addr(p.u.prefix4.s_addr, p.prefixlen);
masklen2ip(p.prefixlen, &fc->mask_mask);
return NB_OK;
}
static int lib_access_list_legacy_entry_destination_network_destroy(
struct nb_cb_destroy_args *args)
{
struct filter_cisco *fc;
struct filter *f;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
fc = &f->u.cfilter;
fc->mask.s_addr = INADDR_ANY;
fc->mask_mask.s_addr = INADDR_NONE;
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list-legacy/entry/destination-any
*/
static int lib_access_list_legacy_entry_destination_any_create(
struct nb_cb_create_args *args)
{
struct filter_cisco *fc;
struct filter *f;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
fc = &f->u.cfilter;
fc->mask.s_addr = INADDR_ANY;
fc->mask_mask.s_addr = INADDR_NONE;
return NB_OK;
}
static int lib_access_list_legacy_entry_destination_any_destroy(
struct nb_cb_destroy_args *args)
{
struct filter_cisco *fc;
struct filter *f;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
fc = &f->u.cfilter;
fc->mask.s_addr = INADDR_ANY;
fc->mask_mask.s_addr = INADDR_NONE;
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list
*/
static int lib_access_list_create(struct nb_cb_create_args *args)
{
struct access_list *acl = NULL;
const char *acl_name;
int type;
if (args->event != NB_EV_APPLY)
return NB_OK;
type = yang_dnode_get_enum(args->dnode, "./type");
acl_name = yang_dnode_get_string(args->dnode, "./name");
switch (type) {
case YALT_IPV4:
acl = access_list_get(AFI_IP, acl_name);
break;
case YALT_IPV6:
acl = access_list_get(AFI_IP6, acl_name);
break;
case YALT_MAC:
acl = access_list_get(AFI_L2VPN, acl_name);
break;
}
nb_running_set_entry(args->dnode, acl);
return NB_OK;
}
static int lib_access_list_destroy(struct nb_cb_destroy_args *args)
{
struct access_master *am;
struct access_list *acl;
if (args->event != NB_EV_APPLY)
return NB_OK;
acl = nb_running_unset_entry(args->dnode);
am = acl->master;
if (am->delete_hook)
am->delete_hook(acl);
access_list_delete(acl);
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list/entry
*/
static int lib_access_list_entry_create(struct nb_cb_create_args *args)
{
struct access_list *acl;
struct filter *f;
/* TODO: validate `filter_lookup_zebra` returns NULL. */
if (args->event != NB_EV_APPLY)
return NB_OK;
f = filter_new();
f->seq = yang_dnode_get_uint32(args->dnode, "./sequence");
acl = nb_running_get_entry(args->dnode, NULL, true);
f->acl = acl;
access_list_filter_add(acl, f);
nb_running_set_entry(args->dnode, f);
return NB_OK;
}
static int lib_access_list_entry_destroy(struct nb_cb_destroy_args *args)
{
struct access_list *acl;
struct filter *f;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_unset_entry(args->dnode);
acl = f->acl;
access_list_filter_delete(acl, f);
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list/entry/ipv4-prefix
*/
static int
lib_access_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args *args)
{
struct filter_zebra *fz;
struct filter *f;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
fz = &f->u.zfilter;
yang_dnode_get_prefix(&fz->prefix, args->dnode, NULL);
return NB_OK;
}
static int
lib_access_list_entry_ipv4_prefix_destroy(struct nb_cb_destroy_args *args)
{
struct filter_zebra *fz;
struct filter *f;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
fz = &f->u.zfilter;
memset(&fz->prefix, 0, sizeof(fz->prefix));
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list/entry/ipv4-exact-match
*/
static int
lib_access_list_entry_ipv4_exact_match_modify(struct nb_cb_modify_args *args)
{
struct filter_zebra *fz;
struct filter *f;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
fz = &f->u.zfilter;
fz->exact = yang_dnode_get_bool(args->dnode, NULL);
return NB_OK;
}
static int
lib_access_list_entry_ipv4_exact_match_destroy(struct nb_cb_destroy_args *args)
{
struct filter_zebra *fz;
struct filter *f;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
fz = &f->u.zfilter;
fz->exact = 0;
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list/entry/any
*/
static int lib_access_list_entry_any_create(struct nb_cb_create_args *args)
{
struct filter_zebra *fz;
struct filter *f;
int type;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
fz = &f->u.zfilter;
memset(&fz->prefix, 0, sizeof(fz->prefix));
type = yang_dnode_get_enum(args->dnode, "../../type");
switch (type) {
case YALT_IPV4:
fz->prefix.family = AF_INET;
break;
case YALT_IPV6:
fz->prefix.family = AF_INET6;
break;
case YALT_MAC:
fz->prefix.family = AF_ETHERNET;
break;
}
return NB_OK;
}
static int lib_access_list_entry_any_destroy(struct nb_cb_destroy_args *args)
{
struct filter_zebra *fz;
struct filter *f;
if (args->event != NB_EV_APPLY)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
fz = &f->u.zfilter;
fz->prefix.family = 0;
return NB_OK;
}
/*
* XPath: /frr-filter:lib/prefix-list
*/
static int lib_prefix_list_create(struct nb_cb_create_args *args)
{
struct prefix_list *pl = NULL;
const char *name;
int type;
if (args->event != NB_EV_APPLY)
return NB_OK;
type = yang_dnode_get_enum(args->dnode, "./type");
name = yang_dnode_get_string(args->dnode, "./name");
switch (type) {
case 0: /* ipv4 */
pl = prefix_list_get(AFI_IP, 0, name);
break;
case 1: /* ipv6 */
pl = prefix_list_get(AFI_IP6, 0, name);
break;
}
nb_running_set_entry(args->dnode, pl);
return NB_OK;
}
static int lib_prefix_list_destroy(struct nb_cb_destroy_args *args)
{
struct prefix_list *pl;
if (args->event != NB_EV_APPLY)
return NB_OK;
pl = nb_running_unset_entry(args->dnode);
prefix_list_delete(pl);
return NB_OK;
}
/*
* XPath: /frr-filter:lib/prefix-list/remark
*/
static int lib_prefix_list_remark_modify(struct nb_cb_modify_args *args)
{
struct prefix_list *pl;
const char *remark;
if (args->event != NB_EV_APPLY)
return NB_OK;
pl = nb_running_get_entry(args->dnode, NULL, true);
if (pl->desc)
XFREE(MTYPE_TMP, pl->desc);
remark = yang_dnode_get_string(args->dnode, NULL);
pl->desc = XSTRDUP(MTYPE_TMP, remark);
return NB_OK;
}
static int lib_prefix_list_remark_destroy(struct nb_cb_destroy_args *args)
{
struct prefix_list *pl;
if (args->event != NB_EV_APPLY)
return NB_OK;
pl = nb_running_get_entry(args->dnode, NULL, true);
if (pl->desc)
XFREE(MTYPE_TMP, pl->desc);
return NB_OK;
}
/*
* XPath: /frr-filter:lib/prefix-list/entry
*/
static int lib_prefix_list_entry_create(struct nb_cb_create_args *args)
{
struct prefix_list_entry *ple;
struct prefix_list *pl;
if (args->event != NB_EV_APPLY)
return NB_OK;
pl = nb_running_get_entry(args->dnode, NULL, true);
ple = prefix_list_entry_new();
ple->pl = pl;
ple->seq = yang_dnode_get_uint32(args->dnode, "./sequence");
prefix_list_entry_set_empty(ple);
nb_running_set_entry(args->dnode, ple);
return NB_OK;
}
static int lib_prefix_list_entry_destroy(struct nb_cb_destroy_args *args)
{
struct prefix_list_entry *ple;
if (args->event != NB_EV_APPLY)
return NB_OK;
ple = nb_running_unset_entry(args->dnode);
if (ple->installed)
prefix_list_entry_delete2(ple);
else
prefix_list_entry_free(ple);
return NB_OK;
}
/*
* XPath: /frr-filter:lib/prefix-list/entry/action
*/
static int lib_prefix_list_entry_action_modify(struct nb_cb_modify_args *args)
{
struct prefix_list_entry *ple;
int action_type;
if (args->event != NB_EV_APPLY)
return NB_OK;
ple = nb_running_get_entry(args->dnode, NULL, true);
/* Start prefix entry update procedure. */
prefix_list_entry_update_start(ple);
action_type = yang_dnode_get_enum(args->dnode, NULL);
if (action_type == YPLA_PERMIT)
ple->type = PREFIX_PERMIT;
else
ple->type = PREFIX_DENY;
/* Finish prefix entry update procedure. */
prefix_list_entry_update_finish(ple);
return NB_OK;
}
/*
* XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix
*/
static int
lib_prefix_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args *args)
{
struct prefix_list_entry *ple;
struct prefix p;
if (args->event == NB_EV_VALIDATE) {
/*
* TODO: validate prefix_entry_dup_check() passes.
*
* This needs to be implemented using YANG lyd_node
* navigation, because the `priv` data structures are not
* available at `NB_EV_VALIDATE` phase. An easier
* alternative would be mark `ipvx-prefix` as unique
* (see RFC 7950, Section 7.8.3. The list "unique" Statement).
*/
return NB_OK;
}
if (args->event != NB_EV_APPLY)
return NB_OK;
ple = nb_running_get_entry(args->dnode, NULL, true);
/* Start prefix entry update procedure. */
prefix_list_entry_update_start(ple);
yang_dnode_get_prefix(&ple->prefix, args->dnode, NULL);
/* Apply mask and correct original address if necessary. */
prefix_copy(&p, &ple->prefix);
apply_mask(&p);
if (!prefix_same(&ple->prefix, &p)) {
zlog_info("%s: bad network %pFX correcting it to %pFX",
__func__, &ple->prefix, &p);
prefix_copy(&ple->prefix, &p);
}
/* Finish prefix entry update procedure. */
prefix_list_entry_update_finish(ple);
return NB_OK;
}
static int
lib_prefix_list_entry_ipv4_prefix_destroy(struct nb_cb_destroy_args *args)
{
struct prefix_list_entry *ple;
if (args->event != NB_EV_APPLY)
return NB_OK;
ple = nb_running_get_entry(args->dnode, NULL, true);
/* Start prefix entry update procedure. */
prefix_list_entry_update_start(ple);
memset(&ple->prefix, 0, sizeof(ple->prefix));
/* Finish prefix entry update procedure. */
prefix_list_entry_update_finish(ple);
return NB_OK;
}
/*
* XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix-length-greater-or-equal
*/
static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify(
struct nb_cb_modify_args *args)
{
struct prefix_list_entry *ple;
if (args->event == NB_EV_VALIDATE &&
prefix_list_length_validate(args->dnode) != NB_OK)
return NB_ERR_VALIDATION;
if (args->event != NB_EV_APPLY)
return NB_OK;
ple = nb_running_get_entry(args->dnode, NULL, true);
/* Start prefix entry update procedure. */
prefix_list_entry_update_start(ple);
ple->ge = yang_dnode_get_uint8(args->dnode, NULL);
/* Finish prefix entry update procedure. */
prefix_list_entry_update_finish(ple);
return NB_OK;
}
static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy(
struct nb_cb_destroy_args *args)
{
struct prefix_list_entry *ple;
if (args->event != NB_EV_APPLY)
return NB_OK;
ple = nb_running_get_entry(args->dnode, NULL, true);
/* Start prefix entry update procedure. */
prefix_list_entry_update_start(ple);
ple->ge = 0;
/* Finish prefix entry update procedure. */
prefix_list_entry_update_finish(ple);
return NB_OK;
}
/*
* XPath: /frr-filter:lib/prefix-list/entry/ipv4-prefix-length-lesser-or-equal
*/
static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify(
struct nb_cb_modify_args *args)
{
struct prefix_list_entry *ple;
if (args->event == NB_EV_VALIDATE &&
prefix_list_length_validate(args->dnode) != NB_OK)
return NB_ERR_VALIDATION;
if (args->event != NB_EV_APPLY)
return NB_OK;
ple = nb_running_get_entry(args->dnode, NULL, true);
/* Start prefix entry update procedure. */
prefix_list_entry_update_start(ple);
ple->le = yang_dnode_get_uint8(args->dnode, NULL);
/* Finish prefix entry update procedure. */
prefix_list_entry_update_finish(ple);
return NB_OK;
}
static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy(
struct nb_cb_destroy_args *args)
{
struct prefix_list_entry *ple;
if (args->event != NB_EV_APPLY)
return NB_OK;
ple = nb_running_get_entry(args->dnode, NULL, true);
/* Start prefix entry update procedure. */
prefix_list_entry_update_start(ple);
ple->le = 0;
/* Finish prefix entry update procedure. */
prefix_list_entry_update_finish(ple);
return NB_OK;
}
/*
* XPath: /frr-filter:lib/prefix-list/entry/any
*/
static int lib_prefix_list_entry_any_create(struct nb_cb_create_args *args)
{
struct prefix_list_entry *ple;
int type;
if (args->event != NB_EV_APPLY)
return NB_OK;
ple = nb_running_get_entry(args->dnode, NULL, true);
/* Start prefix entry update procedure. */
prefix_list_entry_update_start(ple);
ple->any = true;
/* Fill prefix struct from scratch. */
memset(&ple->prefix, 0, sizeof(ple->prefix));
type = yang_dnode_get_enum(args->dnode, "../../type");
switch (type) {
case YPLT_IPV4:
ple->prefix.family = AF_INET;
ple->ge = 0;
ple->le = IPV4_MAX_BITLEN;
break;
case YPLT_IPV6:
ple->prefix.family = AF_INET6;
ple->ge = 0;
ple->le = IPV6_MAX_BITLEN;
break;
}
/* Finish prefix entry update procedure. */
prefix_list_entry_update_finish(ple);
return NB_OK;
}
static int lib_prefix_list_entry_any_destroy(struct nb_cb_destroy_args *args)
{
struct prefix_list_entry *ple;
if (args->event != NB_EV_APPLY)
return NB_OK;
ple = nb_running_get_entry(args->dnode, NULL, true);
/* Start prefix entry update procedure. */
prefix_list_entry_update_start(ple);
prefix_list_entry_set_empty(ple);
/* Finish prefix entry update procedure. */
prefix_list_entry_update_finish(ple);
return NB_OK;
}
/* clang-format off */
const struct frr_yang_module_info frr_filter_info = {
.name = "frr-filter",
.nodes = {
{
.xpath = "/frr-filter:lib/access-list-legacy",
.cbs = {
.create = lib_access_list_legacy_create,
.destroy = lib_access_list_legacy_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list-legacy/remark",
.cbs = {
.modify = lib_access_list_legacy_remark_modify,
.destroy = lib_access_list_legacy_remark_destroy,
.cli_show = access_list_legacy_remark_show,
}
},
{
.xpath = "/frr-filter:lib/access-list-legacy/entry",
.cbs = {
.create = lib_access_list_legacy_entry_create,
.destroy = lib_access_list_legacy_entry_destroy,
.cli_show = access_list_legacy_show,
}
},
{
.xpath = "/frr-filter:lib/access-list-legacy/entry/action",
.cbs = {
.modify = lib_access_list_legacy_entry_action_modify,
}
},
{
.xpath = "/frr-filter:lib/access-list-legacy/entry/host",
.cbs = {
.modify = lib_access_list_legacy_entry_host_modify,
.destroy = lib_access_list_legacy_entry_host_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list-legacy/entry/network",
.cbs = {
.modify = lib_access_list_legacy_entry_network_modify,
.destroy = lib_access_list_legacy_entry_network_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list-legacy/entry/any",
.cbs = {
.create = lib_access_list_legacy_entry_any_create,
.destroy = lib_access_list_legacy_entry_any_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list-legacy/entry/destination-host",
.cbs = {
.modify = lib_access_list_legacy_entry_destination_host_modify,
.destroy = lib_access_list_legacy_entry_destination_host_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list-legacy/entry/destination-network",
.cbs = {
.modify = lib_access_list_legacy_entry_destination_network_modify,
.destroy = lib_access_list_legacy_entry_destination_network_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list-legacy/entry/destination-any",
.cbs = {
.create = lib_access_list_legacy_entry_destination_any_create,
.destroy = lib_access_list_legacy_entry_destination_any_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list",
.cbs = {
.create = lib_access_list_create,
.destroy = lib_access_list_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list/remark",
.cbs = {
.modify = lib_access_list_legacy_remark_modify,
.destroy = lib_access_list_legacy_remark_destroy,
.cli_show = access_list_remark_show,
}
},
{
.xpath = "/frr-filter:lib/access-list/entry",
.cbs = {
.create = lib_access_list_entry_create,
.destroy = lib_access_list_entry_destroy,
.cli_show = access_list_show,
}
},
{
.xpath = "/frr-filter:lib/access-list/entry/action",
.cbs = {
.modify = lib_access_list_legacy_entry_action_modify,
}
},
{
.xpath = "/frr-filter:lib/access-list/entry/ipv4-prefix",
.cbs = {
.modify = lib_access_list_entry_ipv4_prefix_modify,
.destroy = lib_access_list_entry_ipv4_prefix_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list/entry/ipv4-exact-match",
.cbs = {
.modify = lib_access_list_entry_ipv4_exact_match_modify,
.destroy = lib_access_list_entry_ipv4_exact_match_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list/entry/ipv6-prefix",
.cbs = {
.modify = lib_access_list_entry_ipv4_prefix_modify,
.destroy = lib_access_list_entry_ipv4_prefix_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list/entry/ipv6-exact-match",
.cbs = {
.modify = lib_access_list_entry_ipv4_exact_match_modify,
.destroy = lib_access_list_entry_ipv4_exact_match_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list/entry/mac",
.cbs = {
.modify = lib_access_list_entry_ipv4_prefix_modify,
.destroy = lib_access_list_entry_ipv4_prefix_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list/entry/any",
.cbs = {
.create = lib_access_list_entry_any_create,
.destroy = lib_access_list_entry_any_destroy,
}
},
{
.xpath = "/frr-filter:lib/prefix-list",
.cbs = {
.create = lib_prefix_list_create,
.destroy = lib_prefix_list_destroy,
}
},
{
.xpath = "/frr-filter:lib/prefix-list/remark",
.cbs = {
.modify = lib_prefix_list_remark_modify,
.destroy = lib_prefix_list_remark_destroy,
.cli_show = prefix_list_remark_show,
}
},
{
.xpath = "/frr-filter:lib/prefix-list/entry",
.cbs = {
.create = lib_prefix_list_entry_create,
.destroy = lib_prefix_list_entry_destroy,
.cli_show = prefix_list_show,
}
},
{
.xpath = "/frr-filter:lib/prefix-list/entry/action",
.cbs = {
.modify = lib_prefix_list_entry_action_modify,
}
},
{
.xpath = "/frr-filter:lib/prefix-list/entry/ipv4-prefix",
.cbs = {
.modify = lib_prefix_list_entry_ipv4_prefix_modify,
.destroy = lib_prefix_list_entry_ipv4_prefix_destroy,
}
},
{
.xpath = "/frr-filter:lib/prefix-list/entry/ipv4-prefix-length-greater-or-equal",
.cbs = {
.modify = lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify,
.destroy = lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy,
}
},
{
.xpath = "/frr-filter:lib/prefix-list/entry/ipv4-prefix-length-lesser-or-equal",
.cbs = {
.modify = lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify,
.destroy = lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy,
}
},
{
.xpath = "/frr-filter:lib/prefix-list/entry/ipv6-prefix",
.cbs = {
.modify = lib_prefix_list_entry_ipv4_prefix_modify,
.destroy = lib_prefix_list_entry_ipv4_prefix_destroy,
}
},
{
.xpath = "/frr-filter:lib/prefix-list/entry/ipv6-prefix-length-greater-or-equal",
.cbs = {
.modify = lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify,
.destroy = lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy,
}
},
{
.xpath = "/frr-filter:lib/prefix-list/entry/ipv6-prefix-length-lesser-or-equal",
.cbs = {
.modify = lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify,
.destroy = lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy,
}
},
{
.xpath = "/frr-filter:lib/prefix-list/entry/any",
.cbs = {
.create = lib_prefix_list_entry_any_create,
.destroy = lib_prefix_list_entry_any_destroy,
}
},
{
.xpath = NULL,
},
}
};