diff --git a/lib/filter.c b/lib/filter.c index c9a1d683c5..e6add0462b 100644 --- a/lib/filter.c +++ b/lib/filter.c @@ -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; diff --git a/lib/filter.h b/lib/filter.h index 5a2af88c9d..f4bd62e40d 100644 --- a/lib/filter.h +++ b/lib/filter.h @@ -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 diff --git a/lib/filter_cli.c b/lib/filter_cli.c index 8bd085f05c..9baeae2d7c 100644 --- a/lib/filter_cli.c +++ b/lib/filter_cli.c @@ -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). */ diff --git a/lib/filter_nb.c b/lib/filter_nb.c index 3e22dcd148..9e46e961ae 100644 --- a/lib/filter_nb.c +++ b/lib/filter_nb.c @@ -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, } }, { diff --git a/lib/plist.c b/lib/plist.c index 98e02a5f1a..aa420da927 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -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);