lib,yang: merge cisco/zebra access list styles

Merge the cisco style access list with zebra's logic so we can mix both
types of rules while keeping the commands.

With this the cisco style limitation of having 'destination-*' only for
specific number ranges no longer exist for users of YANG/northbound (the
CLI still has this limitation).

Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
This commit is contained in:
Rafael Zalamena 2020-07-19 15:27:56 -03:00
parent 55528234ea
commit 375d157f0e
7 changed files with 480 additions and 848 deletions

View File

@ -170,11 +170,6 @@ enum yang_prefix_list_action {
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,

View File

@ -193,7 +193,8 @@ DEFPY(
* none given (backward compatibility).
*/
snprintf(xpath, sizeof(xpath),
"/frr-filter:lib/access-list-legacy[number='%s']", number_str);
"/frr-filter:lib/access-list[type='ipv4'][name='%s']",
number_str);
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
if (seq_str == NULL) {
/* Use XPath to find the next sequence number. */
@ -213,7 +214,7 @@ DEFPY(
concat_addr_mask_v4(host_str, mask_str, ipmask, sizeof(ipmask));
nb_cli_enqueue_change(vty, "./network", NB_OP_MODIFY, ipmask);
} else {
nb_cli_enqueue_change(vty, "./any", NB_OP_CREATE, NULL);
nb_cli_enqueue_change(vty, "./source-any", NB_OP_CREATE, NULL);
}
return nb_cli_apply_changes(vty, xpath_entry);
@ -244,7 +245,7 @@ DEFPY(
if (seq_str != NULL) {
snprintf(
xpath, sizeof(xpath),
"/frr-filter:lib/access-list-legacy[number='%s']/entry[sequence='%s']",
"/frr-filter:lib/access-list[type='ipv4'][name='%s']/entry[sequence='%s']",
number_str, seq_str);
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
@ -252,7 +253,8 @@ DEFPY(
/* Otherwise, to keep compatibility, we need to figure it out. */
snprintf(xpath, sizeof(xpath),
"/frr-filter:lib/access-list-legacy[number='%s']", number_str);
"/frr-filter:lib/access-list[type='ipv4'][name='%s']",
number_str);
/* Access-list must exist before entries. */
if (yang_dnode_exists(running_config->dnode, xpath) == false)
@ -308,7 +310,8 @@ DEFPY(
* none given (backward compatibility).
*/
snprintf(xpath, sizeof(xpath),
"/frr-filter:lib/access-list-legacy[number='%s']", number_str);
"/frr-filter:lib/access-list[type='ipv4'][name='%s']",
number_str);
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
if (seq_str == NULL) {
/* Use XPath to find the next sequence number. */
@ -329,7 +332,7 @@ DEFPY(
sizeof(ipmask));
nb_cli_enqueue_change(vty, "./network", NB_OP_MODIFY, ipmask);
} else {
nb_cli_enqueue_change(vty, "./any", NB_OP_CREATE, NULL);
nb_cli_enqueue_change(vty, "./source-any", NB_OP_CREATE, NULL);
}
if (dst_str != NULL && dst_mask_str == NULL) {
@ -379,7 +382,7 @@ DEFPY(
if (seq_str != NULL) {
snprintfrr(
xpath, sizeof(xpath),
"/frr-filter:lib/access-list-legacy[number='%s']/entry[sequence='%s']",
"/frr-filter:lib/access-list[type='ipv4'][name='%s']/entry[sequence='%s']",
number_str, seq_str);
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
@ -387,7 +390,8 @@ DEFPY(
/* Otherwise, to keep compatibility, we need to figure it out. */
snprintf(xpath, sizeof(xpath),
"/frr-filter:lib/access-list-legacy[number='%s']", number_str);
"/frr-filter:lib/access-list[type='ipv4'][name='%s']",
number_str);
/* Access-list must exist before entries. */
if (yang_dnode_exists(running_config->dnode, xpath) == false)
@ -429,127 +433,6 @@ DEFPY(
return nb_cli_apply_changes(vty, NULL);
}
DEFPY(
no_access_list_legacy, no_access_list_legacy_cmd,
"no access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)>$number",
NO_STR
ACCESS_LIST_STR
ACCESS_LIST_XLEG_STR)
{
char xpath[XPATH_MAXLEN];
snprintf(xpath, sizeof(xpath),
"/frr-filter:lib/access-list-legacy[number='%s']", number_str);
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
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, "./destination-network")) {
yang_dnode_get_prefix(&p, dnode,
"./destination-network");
masklen2ip(p.prefixlen, &mask);
vty_out(vty, " %pI4 %pI4", &p.u.prefix4, &mask);
} else if (yang_dnode_exists(dnode, "./destination-host"))
vty_out(vty, " host %s",
yang_dnode_get_string(dnode,
"./destination-host"));
else if (yang_dnode_exists(dnode, "./destination-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...",
ACCESS_LIST_STR
ACCESS_LIST_XLEG_STR
ACCESS_LIST_REMARK_STR
ACCESS_LIST_REMARK_LINE_STR)
{
int rv;
char *remark;
char xpath[XPATH_MAXLEN];
snprintf(xpath, sizeof(xpath),
"/frr-filter:lib/access-list-legacy[number='%s']", number_str);
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
remark = argv_concat(argv, argc, 3);
nb_cli_enqueue_change(vty, "./remark", NB_OP_CREATE, remark);
rv = nb_cli_apply_changes(vty, xpath);
XFREE(MTYPE_TMP, remark);
return rv;
}
DEFPY(
no_access_list_legacy_remark, no_access_list_legacy_remark_cmd,
"no access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)>$number remark",
NO_STR
ACCESS_LIST_STR
ACCESS_LIST_XLEG_STR
ACCESS_LIST_REMARK_STR)
{
char xpath[XPATH_MAXLEN];
snprintf(xpath, sizeof(xpath),
"/frr-filter:lib/access-list-legacy[number='%s']/remark",
number_str);
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
}
ALIAS(
no_access_list_legacy_remark, no_access_list_legacy_remark_line_cmd,
"no access-list <(1-99)|(100-199)|(1300-1999)|(2000-2699)>$number remark LINE...",
NO_STR
ACCESS_LIST_STR
ACCESS_LIST_XLEG_STR
ACCESS_LIST_REMARK_STR
ACCESS_LIST_REMARK_LINE_STR)
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.
*/
@ -1077,6 +960,9 @@ void access_list_show(struct vty *vty, struct lyd_node *dnode,
struct prefix p;
bool is_any;
bool is_exact = false;
bool cisco_style = false;
bool cisco_extended = false;
struct in_addr mask;
char macstr[PREFIX2STR_BUFFER];
is_any = yang_dnode_exists(dnode, "./any");
@ -1085,8 +971,19 @@ void access_list_show(struct vty *vty, struct lyd_node *dnode,
if (is_any)
break;
yang_dnode_get_prefix(&p, dnode, "./ipv4-prefix");
is_exact = yang_dnode_get_bool(dnode, "./ipv4-exact-match");
if (yang_dnode_exists(dnode, "./host")
|| yang_dnode_exists(dnode, "./network")
|| yang_dnode_exists(dnode, "./source-any")) {
cisco_style = true;
if (yang_dnode_exists(dnode, "./destination-host")
|| yang_dnode_exists(dnode, "./destination-network")
|| yang_dnode_exists(dnode, "./destination-any"))
cisco_extended = true;
} else {
yang_dnode_get_prefix(&p, dnode, "./ipv4-prefix");
is_exact = yang_dnode_get_bool(dnode,
"./ipv4-exact-match");
}
break;
case YALT_IPV6: /* ipv6 */
vty_out(vty, "ipv6 ");
@ -1110,6 +1007,48 @@ void access_list_show(struct vty *vty, struct lyd_node *dnode,
yang_dnode_get_string(dnode, "./sequence"),
yang_dnode_get_string(dnode, "./action"));
/* Handle Cisco style access lists. */
if (cisco_style) {
if (cisco_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 (cisco_extended)
vty_out(vty, " host");
vty_out(vty, " %s",
yang_dnode_get_string(dnode, "./host"));
} else if (yang_dnode_exists(dnode, "./source-any"))
vty_out(vty, " any");
/* Not extended, exit earlier. */
if (!cisco_extended) {
vty_out(vty, "\n");
return;
}
/* Handle destination address. */
if (yang_dnode_exists(dnode, "./destination-network")) {
yang_dnode_get_prefix(&p, dnode,
"./destination-network");
masklen2ip(p.prefixlen, &mask);
vty_out(vty, " %pI4 %pI4", &p.u.prefix4, &mask);
} else if (yang_dnode_exists(dnode, "./destination-host"))
vty_out(vty, " host %s",
yang_dnode_get_string(dnode,
"./destination-host"));
else if (yang_dnode_exists(dnode, "./destination-any"))
vty_out(vty, " any");
vty_out(vty, "\n");
return;
}
/* Zebra style access list. */
if (!is_any) {
/* If type is MAC don't show '/mask'. */
if (type == 2 /* mac */) {
@ -1648,10 +1587,6 @@ void filter_cli_init(void)
install_element(CONFIG_NODE, &no_access_list_std_cmd);
install_element(CONFIG_NODE, &access_list_ext_cmd);
install_element(CONFIG_NODE, &no_access_list_ext_cmd);
install_element(CONFIG_NODE, &no_access_list_legacy_cmd);
install_element(CONFIG_NODE, &access_list_legacy_remark_cmd);
install_element(CONFIG_NODE, &no_access_list_legacy_remark_cmd);
install_element(CONFIG_NODE, &no_access_list_legacy_remark_line_cmd);
/* access-list zebra-style. */
install_element(CONFIG_NODE, &access_list_cmd);

View File

@ -110,375 +110,6 @@ static void prefix_list_entry_set_empty(struct prefix_list_entry *ple)
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
*/
@ -529,6 +160,43 @@ static int lib_access_list_destroy(struct nb_cb_destroy_args *args)
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list/remark
*/
static int lib_access_list_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_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/entry
*/
@ -537,8 +205,6 @@ 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;
@ -568,6 +234,28 @@ static int lib_access_list_entry_destroy(struct nb_cb_destroy_args *args)
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list/entry/action
*/
static int
lib_access_list_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/entry/ipv4-prefix
*/
@ -581,6 +269,7 @@ lib_access_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args *args)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
f->cisco = 0;
fz = &f->u.zfilter;
yang_dnode_get_prefix(&fz->prefix, args->dnode, NULL);
@ -638,6 +327,241 @@ lib_access_list_entry_ipv4_exact_match_destroy(struct nb_cb_destroy_args *args)
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list/entry/host
*/
static int
lib_access_list_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);
f->cisco = 1;
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_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/entry/network
*/
static int
lib_access_list_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);
f->cisco = 1;
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_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/entry/source-any
*/
static int
lib_access_list_entry_source_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);
f->cisco = 1;
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_entry_source_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/entry/destination-host
*/
static int lib_access_list_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;
fc->extended = 1;
yang_dnode_get_ipv4(&fc->mask, args->dnode, NULL);
fc->mask_mask.s_addr = INADDR_ANY;
return NB_OK;
}
static int lib_access_list_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->extended = 0;
fc->mask.s_addr = INADDR_ANY;
fc->mask_mask.s_addr = INADDR_NONE;
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list/entry/destination-network
*/
static int lib_access_list_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;
fc->extended = 1;
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_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->extended = 0;
fc->mask.s_addr = INADDR_ANY;
fc->mask_mask.s_addr = INADDR_NONE;
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list/entry/destination-any
*/
static int lib_access_list_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->extended = 1;
fc->mask.s_addr = INADDR_ANY;
fc->mask_mask.s_addr = INADDR_NONE;
return NB_OK;
}
static int lib_access_list_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->extended = 0;
fc->mask.s_addr = INADDR_ANY;
fc->mask_mask.s_addr = INADDR_NONE;
return NB_OK;
}
/*
* XPath: /frr-filter:lib/access-list/entry/any
*/
@ -651,6 +575,7 @@ static int lib_access_list_entry_any_create(struct nb_cb_create_args *args)
return NB_OK;
f = nb_running_get_entry(args->dnode, NULL, true);
f->cisco = 0;
fz = &f->u.zfilter;
memset(&fz->prefix, 0, sizeof(fz->prefix));
@ -1058,77 +983,6 @@ static int lib_prefix_list_entry_any_destroy(struct nb_cb_destroy_args *args)
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 = {
@ -1139,8 +993,8 @@ const struct frr_yang_module_info frr_filter_info = {
{
.xpath = "/frr-filter:lib/access-list/remark",
.cbs = {
.modify = lib_access_list_legacy_remark_modify,
.destroy = lib_access_list_legacy_remark_destroy,
.modify = lib_access_list_remark_modify,
.destroy = lib_access_list_remark_destroy,
.cli_show = access_list_remark_show,
}
},
@ -1155,7 +1009,7 @@ const struct frr_yang_module_info frr_filter_info = {
{
.xpath = "/frr-filter:lib/access-list/entry/action",
.cbs = {
.modify = lib_access_list_legacy_entry_action_modify,
.modify = lib_access_list_entry_action_modify,
}
},
{
@ -1172,6 +1026,48 @@ const struct frr_yang_module_info frr_filter_info = {
.destroy = lib_access_list_entry_ipv4_exact_match_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list/entry/host",
.cbs = {
.modify = lib_access_list_entry_host_modify,
.destroy = lib_access_list_entry_host_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list/entry/network",
.cbs = {
.modify = lib_access_list_entry_network_modify,
.destroy = lib_access_list_entry_network_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list/entry/source-any",
.cbs = {
.create = lib_access_list_entry_source_any_create,
.destroy = lib_access_list_entry_source_any_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list/entry/destination-host",
.cbs = {
.modify = lib_access_list_entry_destination_host_modify,
.destroy = lib_access_list_entry_destination_host_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list/entry/destination-network",
.cbs = {
.modify = lib_access_list_entry_destination_network_modify,
.destroy = lib_access_list_entry_destination_network_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list/entry/destination-any",
.cbs = {
.create = lib_access_list_entry_destination_any_create,
.destroy = lib_access_list_entry_destination_any_destroy,
}
},
{
.xpath = "/frr-filter:lib/access-list/entry/ipv6-prefix",
.cbs = {

View File

@ -213,7 +213,7 @@ DEFPY(
DEFPY(
match_ip_address, match_ip_address_cmd,
"match ip address <(1-199)$acll|(1300-2699)$aclh|WORD$name>",
"match ip address <(1-199)|(1300-2699)|WORD>$name",
MATCH_STR
IP_STR
"Match address of route\n"
@ -223,29 +223,10 @@ DEFPY(
{
const char *xpath = "./match-condition[condition='ipv4-address-list']";
char xpath_value[XPATH_MAXLEN + 32];
int acln = acll ? acll : aclh;
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
if (name) {
snprintf(xpath_value, sizeof(xpath_value), "%s/list-name",
xpath);
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name);
} else /* if (acll || aclh) */ {
if ((acln >= 1 && acln <= 99)
|| (acln >= 1300 && acln <= 1999)) {
snprintf(xpath_value, sizeof(xpath_value),
"%s/access-list-num", xpath);
} else {
/*
* if ((acln >= 100 && acln <= 199)
* || (acln >= 2000 && acln <= 2699))
*/
snprintf(xpath_value, sizeof(xpath_value),
"%s/access-list-num-extended", xpath);
}
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
acll_str ? acll_str : aclh_str);
}
snprintf(xpath_value, sizeof(xpath_value), "%s/list-name", xpath);
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name);
return nb_cli_apply_changes(vty, NULL);
}
@ -307,7 +288,7 @@ DEFPY(
DEFPY(
match_ip_next_hop, match_ip_next_hop_cmd,
"match ip next-hop <(1-199)$acll|(1300-2699)$aclh|WORD$name>",
"match ip next-hop <(1-199)|(1300-2699)|WORD>$name",
MATCH_STR
IP_STR
"Match next-hop address of route\n"
@ -317,29 +298,10 @@ DEFPY(
{
const char *xpath = "./match-condition[condition='ipv4-next-hop-list']";
char xpath_value[XPATH_MAXLEN + 32];
int acln = acll ? acll : aclh;
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
if (name) {
snprintf(xpath_value, sizeof(xpath_value), "%s/list-name",
xpath);
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name);
} else /* if (acll || aclh) */ {
if ((acln >= 1 && acln <= 99)
|| (acln >= 1300 && acln <= 1999)) {
snprintf(xpath_value, sizeof(xpath_value),
"%s/access-list-num", xpath);
} else {
/*
* if ((acln >= 100 && acln <= 199)
* || (acln >= 2000 && acln <= 2699))
*/
snprintf(xpath_value, sizeof(xpath_value),
"%s/access-list-num-extended", xpath);
}
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY,
acll_str ? acll_str : aclh_str);
}
snprintf(xpath_value, sizeof(xpath_value), "%s/list-name", xpath);
nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, name);
return nb_cli_apply_changes(vty, NULL);
}
@ -610,8 +572,6 @@ void route_map_condition_show(struct vty *vty, struct lyd_node *dnode,
bool show_defaults)
{
int condition = yang_dnode_get_enum(dnode, "./condition");
struct lyd_node *ln;
const char *acl;
switch (condition) {
case 0: /* interface */
@ -620,25 +580,14 @@ void route_map_condition_show(struct vty *vty, struct lyd_node *dnode,
break;
case 1: /* ipv4-address-list */
case 3: /* ipv4-next-hop-list */
acl = NULL;
if ((ln = yang_dnode_get(dnode, "./list-name")) != NULL)
acl = yang_dnode_get_string(ln, NULL);
else if ((ln = yang_dnode_get(dnode, "./access-list-num"))
!= NULL)
acl = yang_dnode_get_string(ln, NULL);
else if ((ln = yang_dnode_get(dnode,
"./access-list-num-extended"))
!= NULL)
acl = yang_dnode_get_string(ln, NULL);
assert(acl);
switch (condition) {
case 1:
vty_out(vty, " match ip address %s\n", acl);
vty_out(vty, " match ip address %s\n",
yang_dnode_get_string(dnode, "./list-name"));
break;
case 3:
vty_out(vty, " match ip next-hop %s\n", acl);
vty_out(vty, " match ip next-hop %s\n",
yang_dnode_get_string(dnode, "./list-name"));
break;
}
break;

View File

@ -515,77 +515,6 @@ static int lib_route_map_entry_match_condition_interface_destroy(
return lib_route_map_entry_match_destroy(args);
}
/*
* XPath: /frr-route-map:lib/route-map/entry/match-condition/access-list-num
*/
static int lib_route_map_entry_match_condition_access_list_num_modify(
struct nb_cb_modify_args *args)
{
struct routemap_hook_context *rhc;
const char *acl;
int condition, rv;
if (args->event != NB_EV_APPLY)
return NB_OK;
/* Check for hook function. */
rv = CMD_SUCCESS;
acl = yang_dnode_get_string(args->dnode, NULL);
rhc = nb_running_get_entry(args->dnode, NULL, true);
condition = yang_dnode_get_enum(args->dnode, "../condition");
switch (condition) {
case 1: /* ipv4-address-list */
if (rmap_match_set_hook.match_ip_address == NULL)
break;
rhc->rhc_mhook = rmap_match_set_hook.no_match_ip_address;
rhc->rhc_rule = "ip address";
rhc->rhc_event = RMAP_EVENT_FILTER_DELETED;
rv = rmap_match_set_hook.match_ip_address(
NULL, rhc->rhc_rmi, "ip address", acl,
RMAP_EVENT_FILTER_ADDED);
break;
case 3: /* ipv4-next-hop-list */
if (rmap_match_set_hook.match_ip_next_hop == NULL)
break;
rhc->rhc_mhook = rmap_match_set_hook.no_match_ip_next_hop;
rhc->rhc_rule = "ip next-hop";
rhc->rhc_event = RMAP_EVENT_FILTER_DELETED;
rv = rmap_match_set_hook.match_ip_next_hop(
NULL, rhc->rhc_rmi, "ip next-hop", acl,
RMAP_EVENT_FILTER_ADDED);
break;
}
if (rv != CMD_SUCCESS) {
rhc->rhc_mhook = NULL;
return NB_ERR_INCONSISTENCY;
}
return NB_OK;
}
static int lib_route_map_entry_match_condition_access_list_num_destroy(
struct nb_cb_destroy_args *args)
{
return lib_route_map_entry_match_destroy(args);
}
/*
* XPath:
* /frr-route-map:lib/route-map/entry/match-condition/access-list-num-extended
*/
static int lib_route_map_entry_match_condition_access_list_num_extended_modify(
struct nb_cb_modify_args *args)
{
return lib_route_map_entry_match_condition_access_list_num_modify(args);
}
static int lib_route_map_entry_match_condition_access_list_num_extended_destroy(
struct nb_cb_destroy_args *args)
{
return lib_route_map_entry_match_condition_access_list_num_destroy(
args);
}
/*
* XPath: /frr-route-map:lib/route-map/entry/match-condition/list-name
*/
@ -1244,20 +1173,6 @@ const struct frr_yang_module_info frr_route_map_info = {
.destroy = lib_route_map_entry_match_condition_interface_destroy,
}
},
{
.xpath = "/frr-route-map:lib/route-map/entry/match-condition/access-list-num",
.cbs = {
.modify = lib_route_map_entry_match_condition_access_list_num_modify,
.destroy = lib_route_map_entry_match_condition_access_list_num_destroy,
}
},
{
.xpath = "/frr-route-map:lib/route-map/entry/match-condition/access-list-num-extended",
.cbs = {
.modify = lib_route_map_entry_match_condition_access_list_num_extended_modify,
.destroy = lib_route_map_entry_match_condition_access_list_num_extended_destroy,
}
},
{
.xpath = "/frr-route-map:lib/route-map/entry/match-condition/list-name",
.cbs = {

View File

@ -49,28 +49,6 @@ module frr-filter {
/*
* Types.
*/
typedef access-list-standard {
description "Standard IPv4 access list (any, host or a prefix)";
type uint16 {
range "1..99 | 1300..1999";
}
}
typedef access-list-extended {
description
"Extended IPv4 access list (source / destination any, hosts or prefixes)";
type uint16 {
range "100..199 | 2000..2699";
}
}
typedef access-list-legacy {
description "Standard/Extended IPv4 access list";
type uint16 {
range "1..199 | 1300..2699";
}
}
typedef access-list-name {
description "Access list name formatting";
type string {
@ -103,79 +81,6 @@ module frr-filter {
* Configuration data.
*/
container lib {
list access-list-legacy {
description "Access list legacy instance";
key "number";
leaf number {
description "Access list sequence value";
type access-list-legacy;
}
leaf remark {
description "Access list remark";
type string;
}
list entry {
description "Access list legacy entry";
key "sequence";
leaf sequence {
description "Access list sequence value";
type access-list-sequence;
}
leaf action {
description "Access list action on match";
type access-list-action;
mandatory true;
}
choice value {
description
"Standard access list: value to match.
Extended access list: source value to match.";
mandatory true;
leaf host {
description "Host to match";
type inet:ipv4-address;
}
leaf network {
description "Network to match";
type inet:ipv4-prefix;
}
leaf any {
description "Match any";
type empty;
}
}
choice extended-value {
when "../number >= 100 and ../number <= 199 or
../number >= 2000 and ../number <= 2699";
description "Destination value to match";
mandatory true;
leaf destination-host {
description "Host to match";
type inet:ipv4-address;
}
leaf destination-network {
description "Network to match";
type inet:ipv4-prefix;
}
leaf destination-any {
description "Match any";
type empty;
}
}
}
}
list access-list {
description "Access list instance";
@ -232,15 +137,66 @@ module frr-filter {
case ipv4-prefix {
when "../type = 'ipv4'";
leaf ipv4-prefix {
description "Configure IPv4 prefix to match";
type inet:ipv4-prefix;
}
choice style {
description "Access list entry style selection: zebra or cisco.";
mandatory true;
leaf ipv4-exact-match {
description "Exact match of prefix";
type boolean;
default false;
case zebra {
leaf ipv4-prefix {
description "Configure IPv4 prefix to match";
type inet:ipv4-prefix;
}
leaf ipv4-exact-match {
description "Exact match of prefix";
type boolean;
default false;
}
}
case cisco {
leaf host {
description "Host to match";
type inet:ipv4-address;
}
leaf network {
description "Network to match";
type inet:ipv4-prefix;
}
leaf source-any {
/*
* Was `any`, however it conflicts with `any` leaf
* outside this choice.
*/
description "Match any";
type empty;
}
}
choice extended-value {
/*
* Legacy note: before using the new access-list format the
* cisco styled list only accepted identifiers using numbers
* and they had the following restriction:
*
* when "../number >= 100 and ../number <= 199 or
* ../number >= 2000 and ../number <= 2699";
*/
description "Destination value to match";
mandatory true;
leaf destination-host {
description "Host to match";
type inet:ipv4-address;
}
leaf destination-network {
description "Network to match";
type inet:ipv4-prefix;
}
leaf destination-any {
description "Match any";
type empty;
}
}
}
}
case ipv6-prefix {

View File

@ -239,20 +239,6 @@ module frr-route-map {
type string;
}
}
case access-list-num {
when "./condition = 'ipv4-address-list' or
./condition = 'ipv4-next-hop-list'";
leaf access-list-num {
type filter:access-list-standard;
}
}
case access-list-num-extended {
when "./condition = 'ipv4-address-list' or
./condition = 'ipv4-next-hop-list'";
leaf access-list-num-extended {
type filter:access-list-extended;
}
}
case list-name {
when "./condition = 'ipv4-address-list' or
./condition = 'ipv4-prefix-list' or