lib: migrate filter configuration writer

Use northbound to write the configuration from now on. While here, fix
how `exact-match` configuration is being created.

Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
This commit is contained in:
Rafael Zalamena 2020-04-30 13:56:05 -03:00
parent 63895e83cb
commit 1d3c4b664d
5 changed files with 251 additions and 210 deletions

View File

@ -29,6 +29,7 @@
#include "log.h"
#include "routemap.h"
#include "libfrr.h"
#include "northbound_cli.h"
DEFINE_MTYPE_STATIC(LIB, ACCESS_LIST, "Access List")
DEFINE_MTYPE_STATIC(LIB, ACCESS_LIST_STR, "Access List Str")
@ -775,86 +776,12 @@ static void config_write_access_zebra(struct vty *vty, struct filter *mfilter)
vty_out(vty, "\n");
}
static int config_write_access(struct vty *vty, afi_t afi)
{
struct access_list *access;
struct access_master *master;
struct filter *mfilter;
int write = 0;
master = access_master_get(afi);
if (master == NULL)
return 0;
for (access = master->num.head; access; access = access->next) {
if (access->remark) {
vty_out(vty, "%saccess-list %s remark %s\n",
(afi == AFI_IP) ? ("")
: ((afi == AFI_IP6) ? ("ipv6 ")
: ("mac ")),
access->name, access->remark);
write++;
}
for (mfilter = access->head; mfilter; mfilter = mfilter->next) {
vty_out(vty, "%saccess-list %s seq %" PRId64 " %s",
(afi == AFI_IP) ? ("")
: ((afi == AFI_IP6) ? ("ipv6 ")
: ("mac ")),
access->name, mfilter->seq,
filter_type_str(mfilter));
if (mfilter->cisco)
config_write_access_cisco(vty, mfilter);
else
config_write_access_zebra(vty, mfilter);
write++;
}
}
for (access = master->str.head; access; access = access->next) {
if (access->remark) {
vty_out(vty, "%saccess-list %s remark %s\n",
(afi == AFI_IP) ? ("")
: ((afi == AFI_IP6) ? ("ipv6 ")
: ("mac ")),
access->name, access->remark);
write++;
}
for (mfilter = access->head; mfilter; mfilter = mfilter->next) {
vty_out(vty, "%saccess-list %s seq %" PRId64 " %s",
(afi == AFI_IP) ? ("")
: ((afi == AFI_IP6) ? ("ipv6 ")
: ("mac ")),
access->name, mfilter->seq,
filter_type_str(mfilter));
if (mfilter->cisco)
config_write_access_cisco(vty, mfilter);
else
config_write_access_zebra(vty, mfilter);
write++;
}
}
return write;
}
static int config_write_access_mac(struct vty *vty);
static struct cmd_node access_mac_node = {
.name = "MAC access list",
.node = ACCESS_MAC_NODE,
.prompt = "",
.config_write = config_write_access_mac,
};
static int config_write_access_mac(struct vty *vty)
{
return config_write_access(vty, AFI_L2VPN);
}
static void access_list_reset_mac(void)
{
struct access_list *access;
@ -891,17 +818,26 @@ static void access_list_init_mac(void)
}
/* Access-list node. */
static int config_write_access_ipv4(struct vty *vty);
static int config_write_access(struct vty *vty);
static struct cmd_node access_node = {
.name = "ipv4 access list",
.node = ACCESS_NODE,
.prompt = "",
.config_write = config_write_access_ipv4,
.config_write = config_write_access,
};
static int config_write_access_ipv4(struct vty *vty)
static int config_write_access(struct vty *vty)
{
return config_write_access(vty, AFI_IP);
struct lyd_node *dnode;
int written = 0;
dnode = yang_dnode_get(running_config->dnode, "/frr-filter:lib");
if (dnode) {
nb_cli_show_dnode_cmds(vty, dnode, false);
written = 1;
}
return written;
}
static void access_list_reset_ipv4(void)
@ -939,19 +875,12 @@ static void access_list_init_ipv4(void)
install_element(ENABLE_NODE, &show_ip_access_list_name_cmd);
}
static int config_write_access_ipv6(struct vty *vty);
static struct cmd_node access_ipv6_node = {
.name = "ipv6 access list",
.node = ACCESS_IPV6_NODE,
.prompt = "",
.config_write = config_write_access_ipv6,
};
static int config_write_access_ipv6(struct vty *vty)
{
return config_write_access(vty, AFI_IP6);
}
static void access_list_reset_ipv6(void)
{
struct access_list *access;

View File

@ -148,6 +148,24 @@ struct filter *filter_lookup_zebra(struct access_list *access,
extern const struct frr_yang_module_info frr_filter_info;
/* filter_cli.c */
struct lyd_node;
struct vty;
extern void access_list_legacy_show(struct vty *vty, struct lyd_node *dnode,
bool show_defaults);
extern void access_list_legacy_remark_show(struct vty *vty,
struct lyd_node *dnode,
bool show_defaults);
extern void access_list_show(struct vty *vty, struct lyd_node *dnode,
bool show_defaults);
extern void access_list_remark_show(struct vty *vty, struct lyd_node *dnode,
bool show_defaults);
extern void prefix_list_show(struct vty *vty, struct lyd_node *dnode,
bool show_defaults);
extern void prefix_list_remark_show(struct vty *vty, struct lyd_node *dnode,
bool show_defaults);
void filter_cli_init(void);
#ifdef __cplusplus

View File

@ -20,6 +20,8 @@
* 02110-1301 USA.
*/
#include "northbound.h"
#include "prefix.h"
#include "zebra.h"
#include "lib/command.h"
@ -473,6 +475,50 @@ DEFPY(
return nb_cli_apply_changes(vty, NULL);
}
void access_list_legacy_show(struct vty *vty, struct lyd_node *dnode,
bool show_defaults)
{
uint16_t number = yang_dnode_get_uint16(dnode, "../number");
bool extended;
struct prefix p;
struct in_addr mask;
vty_out(vty, "access-list %d seq %s %s", number,
yang_dnode_get_string(dnode, "./sequence"),
yang_dnode_get_string(dnode, "./action"));
extended = (number >= 100 && number <= 199)
|| (number >= 2000 && number <= 2699);
if (extended)
vty_out(vty, " ip");
if (yang_dnode_exists(dnode, "./network")) {
yang_dnode_get_prefix(&p, dnode, "./network");
masklen2ip(p.prefixlen, &mask);
vty_out(vty, " %pI4 %pI4", &p.u.prefix4, &mask);
} else if (yang_dnode_exists(dnode, "./host")) {
if (extended)
vty_out(vty, " host");
vty_out(vty, " %s", yang_dnode_get_string(dnode, "./host"));
} else if (yang_dnode_exists(dnode, "./any"))
vty_out(vty, " any");
if (extended) {
if (yang_dnode_exists(dnode, "./network")) {
yang_dnode_get_prefix(&p, dnode, "./network");
masklen2ip(p.prefixlen, &mask);
vty_out(vty, " %pI4 %pI4", &p.u.prefix4, &mask);
} else if (yang_dnode_exists(dnode, "./host"))
vty_out(vty, " host %s",
yang_dnode_get_string(dnode, "./host"));
else if (yang_dnode_exists(dnode, "./any"))
vty_out(vty, " any");
}
vty_out(vty, "\n");
}
DEFPY(
access_list_legacy_remark, access_list_legacy_remark_cmd,
"access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)>$number remark LINE...",
@ -517,6 +563,14 @@ DEFPY(
return nb_cli_apply_changes(vty, NULL);
}
void access_list_legacy_remark_show(struct vty *vty, struct lyd_node *dnode,
bool show_defaults)
{
vty_out(vty, "access-list %s remark %s\n",
yang_dnode_get_string(dnode, "../number"),
yang_dnode_get_string(dnode, NULL));
}
/*
* Zebra access lists.
*/
@ -570,12 +624,8 @@ DEFPY(
snprintf(xpath_value, sizeof(xpath_value),
"%s/ipv4-exact-match", xpath_entry);
if (exact)
nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE,
NULL);
else
nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY,
NULL);
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
exact ? "true" : "false");
} else {
snprintf(xpath_value, sizeof(xpath_value), "%s/any",
xpath_entry);
@ -753,12 +803,8 @@ DEFPY(
snprintf(xpath_value, sizeof(xpath_value),
"%s/ipv6-exact-match", xpath_entry);
if (exact)
nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE,
NULL);
else
nb_cli_enqueue_change(vty, xpath_value, NB_OP_DESTROY,
NULL);
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
exact ? "true" : "false");
} else {
snprintf(xpath_value, sizeof(xpath_value), "%s/any",
xpath_entry);
@ -1065,6 +1111,83 @@ DEFPY(
return nb_cli_apply_changes(vty, NULL);
}
void access_list_show(struct vty *vty, struct lyd_node *dnode,
bool show_defaults)
{
int type = yang_dnode_get_enum(dnode, "../type");
struct prefix p;
bool is_any;
bool is_exact = false;
char macstr[PREFIX2STR_BUFFER];
is_any = yang_dnode_exists(dnode, "./any");
switch (type) {
case 0: /* ipv4 */
if (is_any)
break;
yang_dnode_get_prefix(&p, dnode, "./ipv4-prefix");
is_exact = yang_dnode_get_bool(dnode, "./ipv4-exact-match");
break;
case 1: /* ipv6 */
vty_out(vty, "ipv6 ");
if (is_any)
break;
yang_dnode_get_prefix(&p, dnode, "./ipv6-prefix");
is_exact = yang_dnode_get_bool(dnode, "./ipv6-exact-match");
break;
case 2: /* mac */
vty_out(vty, "mac ");
if (is_any)
break;
yang_dnode_get_prefix(&p, dnode, "./mac");
break;
}
vty_out(vty, "access-list %s seq %s %s",
yang_dnode_get_string(dnode, "../name"),
yang_dnode_get_string(dnode, "./sequence"),
yang_dnode_get_string(dnode, "./action"));
if (!is_any) {
/* If type is MAC don't show '/mask'. */
if (type == 2 /* mac */) {
prefix_mac2str(&p.u.prefix_eth, macstr, sizeof(macstr));
vty_out(vty, " %s", macstr);
} else
vty_out(vty, " %pFX", &p);
} else
vty_out(vty, " any");
if (is_exact)
vty_out(vty, " exact-match");
vty_out(vty, "\n");
}
void access_list_remark_show(struct vty *vty, struct lyd_node *dnode,
bool show_defaults)
{
int type = yang_dnode_get_enum(dnode, "../type");
switch (type) {
case 0: /* ipv4 */
break;
case 1: /* ipv6 */
vty_out(vty, "ipv6 ");
break;
case 2: /* mac */
vty_out(vty, "mac ");
break;
}
vty_out(vty, "access-list %s remark %s\n",
yang_dnode_get_string(dnode, "../name"),
yang_dnode_get_string(dnode, NULL));
}
/*
* Prefix lists.
*/
@ -1477,6 +1600,84 @@ ALIAS(
ACCESS_LIST_REMARK_STR
ACCESS_LIST_REMARK_LINE_STR)
void prefix_list_show(struct vty *vty, struct lyd_node *dnode,
bool show_defaults)
{
int type = yang_dnode_get_enum(dnode, "../type");
const char *ge_str = NULL, *le_str = NULL;
bool is_any;
struct prefix p;
is_any = yang_dnode_exists(dnode, "./any");
switch (type) {
case 0: /* ipv4 */
if (!is_any)
yang_dnode_get_prefix(&p, dnode, "./ipv4-prefix");
if (yang_dnode_exists(dnode,
"./ipv4-prefix-length-greater-or-equal"))
ge_str = yang_dnode_get_string(
dnode, "./ipv4-prefix-length-greater-or-equal");
if (yang_dnode_exists(dnode,
"./ipv4-prefix-length-lesser-or-equal"))
le_str = yang_dnode_get_string(
dnode, "./ipv4-prefix-length-lesser-or-equal");
vty_out(vty, "ip ");
break;
case 1: /* ipv6 */
if (!is_any)
yang_dnode_get_prefix(&p, dnode, "ipv6-prefix");
if (yang_dnode_exists(dnode,
"./ipv6-prefix-length-greater-or-equal"))
ge_str = yang_dnode_get_string(
dnode, "./ipv6-prefix-length-greater-or-equal");
if (yang_dnode_exists(dnode,
"./ipv6-prefix-length-lesser-or-equal"))
le_str = yang_dnode_get_string(
dnode, "./ipv6-prefix-length-lesser-or-equal");
vty_out(vty, "ipv6 ");
break;
}
vty_out(vty, "prefix-list %s seq %s %s",
yang_dnode_get_string(dnode, "../name"),
yang_dnode_get_string(dnode, "./sequence"),
yang_dnode_get_string(dnode, "./action"));
if (is_any) {
vty_out(vty, " any\n");
return;
}
vty_out(vty, " %pFX", &p);
if (ge_str)
vty_out(vty, " ge %s", ge_str);
if (le_str)
vty_out(vty, " le %s", le_str);
vty_out(vty, "\n");
}
void prefix_list_remark_show(struct vty *vty, struct lyd_node *dnode,
bool show_defaults)
{
int type = yang_dnode_get_enum(dnode, "../type");
switch (type) {
case 0: /* ipv4 */
vty_out(vty, "ip ");
break;
case 1: /* ipv6 */
vty_out(vty, "ipv6 ");
break;
}
vty_out(vty, "prefix-list %s remark %s\n",
yang_dnode_get_string(dnode, "../name"),
yang_dnode_get_string(dnode, NULL));
}
void filter_cli_init(void)
{
/* access-list cisco-style (legacy). */

View File

@ -1007,6 +1007,7 @@ const struct frr_yang_module_info frr_filter_info = {
.cbs = {
.modify = lib_access_list_legacy_remark_modify,
.destroy = lib_access_list_legacy_remark_destroy,
.cli_show = access_list_legacy_remark_show,
}
},
{
@ -1014,6 +1015,7 @@ const struct frr_yang_module_info frr_filter_info = {
.cbs = {
.create = lib_access_list_legacy_entry_create,
.destroy = lib_access_list_legacy_entry_destroy,
.cli_show = access_list_legacy_show,
}
},
{
@ -1076,6 +1078,7 @@ const struct frr_yang_module_info frr_filter_info = {
.cbs = {
.modify = lib_access_list_remark_modify,
.destroy = lib_access_list_remark_destroy,
.cli_show = access_list_remark_show,
}
},
{
@ -1083,6 +1086,7 @@ const struct frr_yang_module_info frr_filter_info = {
.cbs = {
.create = lib_access_list_entry_create,
.destroy = lib_access_list_entry_destroy,
.cli_show = access_list_show,
}
},
{
@ -1145,6 +1149,7 @@ const struct frr_yang_module_info frr_filter_info = {
.cbs = {
.modify = lib_prefix_list_description_modify,
.destroy = lib_prefix_list_description_destroy,
.cli_show = prefix_list_remark_show,
}
},
{
@ -1152,6 +1157,7 @@ const struct frr_yang_module_info frr_filter_info = {
.cbs = {
.create = lib_prefix_list_entry_create,
.destroy = lib_prefix_list_entry_destroy,
.cli_show = prefix_list_show,
}
},
{

View File

@ -1252,104 +1252,6 @@ DEFPY (clear_ipv6_prefix_list,
return vty_clear_prefix_list(vty, AFI_IP6, prefix_list, prefix_str);
}
/* Configuration write function. */
static int config_write_prefix_afi(afi_t afi, struct vty *vty)
{
struct prefix_list *plist;
struct prefix_list_entry *pentry;
struct prefix_master *master;
int write = 0;
master = prefix_master_get(afi, 0);
if (master == NULL)
return 0;
if (!master->seqnum) {
vty_out(vty, "no ip%s prefix-list sequence-number\n",
afi == AFI_IP ? "" : "v6");
vty_out(vty, "!\n");
}
for (plist = master->num.head; plist; plist = plist->next) {
if (plist->desc) {
vty_out(vty, "ip%s prefix-list %s description %s\n",
afi == AFI_IP ? "" : "v6", plist->name,
plist->desc);
write++;
}
for (pentry = plist->head; pentry; pentry = pentry->next) {
vty_out(vty, "ip%s prefix-list %s ",
afi == AFI_IP ? "" : "v6", plist->name);
if (master->seqnum)
vty_out(vty, "seq %" PRId64 " ", pentry->seq);
vty_out(vty, "%s ", prefix_list_type_str(pentry));
if (pentry->any)
vty_out(vty, "any");
else {
struct prefix *p = &pentry->prefix;
char buf[BUFSIZ];
vty_out(vty, "%s/%d",
inet_ntop(p->family, p->u.val, buf,
BUFSIZ),
p->prefixlen);
if (pentry->ge)
vty_out(vty, " ge %d", pentry->ge);
if (pentry->le)
vty_out(vty, " le %d", pentry->le);
}
vty_out(vty, "\n");
write++;
}
/* vty_out (vty, "!\n"); */
}
for (plist = master->str.head; plist; plist = plist->next) {
if (plist->desc) {
vty_out(vty, "ip%s prefix-list %s description %s\n",
afi == AFI_IP ? "" : "v6", plist->name,
plist->desc);
write++;
}
for (pentry = plist->head; pentry; pentry = pentry->next) {
vty_out(vty, "ip%s prefix-list %s ",
afi == AFI_IP ? "" : "v6", plist->name);
if (master->seqnum)
vty_out(vty, "seq %" PRId64 " ", pentry->seq);
vty_out(vty, "%s", prefix_list_type_str(pentry));
if (pentry->any)
vty_out(vty, " any");
else {
struct prefix *p = &pentry->prefix;
char buf[BUFSIZ];
vty_out(vty, " %s/%d",
inet_ntop(p->family, p->u.val, buf,
BUFSIZ),
p->prefixlen);
if (pentry->ge)
vty_out(vty, " ge %d", pentry->ge);
if (pentry->le)
vty_out(vty, " le %d", pentry->le);
}
vty_out(vty, "\n");
write++;
}
}
return write;
}
struct stream *prefix_bgp_orf_entry(struct stream *s, struct prefix_list *plist,
uint8_t init_flag, uint8_t permit_flag,
uint8_t deny_flag)
@ -1545,21 +1447,13 @@ static void prefix_list_reset_afi(afi_t afi, int orf)
master->recent = NULL;
}
static int config_write_prefix_ipv4(struct vty *vty);
/* Prefix-list node. */
static struct cmd_node prefix_node = {
.name = "ipv4 prefix list",
.node = PREFIX_NODE,
.prompt = "",
.config_write = config_write_prefix_ipv4,
};
static int config_write_prefix_ipv4(struct vty *vty)
{
return config_write_prefix_afi(AFI_IP, vty);
}
static void plist_autocomplete_afi(afi_t afi, vector comps,
struct cmd_token *token)
{
@ -1603,20 +1497,13 @@ static void prefix_list_init_ipv4(void)
install_element(ENABLE_NODE, &clear_ip_prefix_list_cmd);
}
static int config_write_prefix_ipv6(struct vty *vty);
/* Prefix-list node. */
static struct cmd_node prefix_ipv6_node = {
.name = "ipv6 prefix list",
.node = PREFIX_IPV6_NODE,
.prompt = "",
.config_write = config_write_prefix_ipv6,
};
static int config_write_prefix_ipv6(struct vty *vty)
{
return config_write_prefix_afi(AFI_IP6, vty);
}
static void prefix_list_init_ipv6(void)
{
install_node(&prefix_ipv6_node);