summaryrefslogtreecommitdiffstats
path: root/lib/filter_nb.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/filter_nb.c')
-rw-r--r--lib/filter_nb.c225
1 files changed, 133 insertions, 92 deletions
diff --git a/lib/filter_nb.c b/lib/filter_nb.c
index 9511b8f..39042d3 100644
--- a/lib/filter_nb.c
+++ b/lib/filter_nb.c
@@ -17,23 +17,6 @@
#include "lib/plist_int.h"
#include "lib/routemap.h"
-/* Helper function. */
-static void acl_notify_route_map(struct access_list *acl, int route_map_event)
-{
- switch (route_map_event) {
- case RMAP_EVENT_FILTER_ADDED:
- if (acl->master->add_hook)
- (*acl->master->add_hook)(acl);
- break;
- case RMAP_EVENT_FILTER_DELETED:
- if (acl->master->delete_hook)
- (*acl->master->delete_hook)(acl);
- break;
- }
-
- route_map_notify_dependencies(acl->name, route_map_event);
-}
-
static enum nb_error prefix_list_length_validate(struct nb_cb_modify_args *args)
{
int type = yang_dnode_get_enum(args->dnode, "../../type");
@@ -112,7 +95,7 @@ prefix_list_nb_validate_v4_af_type(const struct lyd_node *plist_dnode,
{
int af_type;
- af_type = yang_dnode_get_enum(plist_dnode, "./type");
+ af_type = yang_dnode_get_enum(plist_dnode, "type");
if (af_type != YPLT_IPV4) {
snprintf(errmsg, errmsg_len,
"prefix-list type %u is mismatched.", af_type);
@@ -128,7 +111,7 @@ prefix_list_nb_validate_v6_af_type(const struct lyd_node *plist_dnode,
{
int af_type;
- af_type = yang_dnode_get_enum(plist_dnode, "./type");
+ af_type = yang_dnode_get_enum(plist_dnode, "type");
if (af_type != YPLT_IPV6) {
snprintf(errmsg, errmsg_len,
"prefix-list type %u is mismatched.", af_type);
@@ -153,9 +136,6 @@ static int lib_prefix_list_entry_prefix_length_greater_or_equal_modify(
ple->ge = yang_dnode_get_uint8(args->dnode, NULL);
- /* Finish prefix entry update procedure. */
- prefix_list_entry_update_finish(ple);
-
return NB_OK;
}
@@ -174,9 +154,6 @@ static int lib_prefix_list_entry_prefix_length_lesser_or_equal_modify(
ple->le = yang_dnode_get_uint8(args->dnode, NULL);
- /* Finish prefix entry update procedure. */
- prefix_list_entry_update_finish(ple);
-
return NB_OK;
}
@@ -195,9 +172,6 @@ static int lib_prefix_list_entry_prefix_length_greater_or_equal_destroy(
ple->ge = 0;
- /* Finish prefix entry update procedure. */
- prefix_list_entry_update_finish(ple);
-
return NB_OK;
}
@@ -216,9 +190,6 @@ static int lib_prefix_list_entry_prefix_length_lesser_or_equal_destroy(
ple->le = 0;
- /* Finish prefix entry update procedure. */
- prefix_list_entry_update_finish(ple);
-
return NB_OK;
}
@@ -381,14 +352,14 @@ static void plist_dnode_to_prefix(const struct lyd_node *dnode, bool *any,
*ge = 0;
*le = 0;
- if (yang_dnode_exists(dnode, "./any")) {
+ if (yang_dnode_exists(dnode, "any")) {
*any = true;
return;
}
switch (yang_dnode_get_enum(dnode, "../type")) {
case YPLT_IPV4:
- yang_dnode_get_prefix(p, dnode, "./ipv4-prefix");
+ yang_dnode_get_prefix(p, dnode, "ipv4-prefix");
if (yang_dnode_exists(dnode,
"./ipv4-prefix-length-greater-or-equal"))
*ge = yang_dnode_get_uint8(
@@ -399,7 +370,7 @@ static void plist_dnode_to_prefix(const struct lyd_node *dnode, bool *any,
dnode, "./ipv4-prefix-length-lesser-or-equal");
break;
case YPLT_IPV6:
- yang_dnode_get_prefix(p, dnode, "./ipv6-prefix");
+ yang_dnode_get_prefix(p, dnode, "ipv6-prefix");
if (yang_dnode_exists(dnode,
"./ipv6-prefix-length-greater-or-equal"))
*ge = yang_dnode_get_uint8(
@@ -468,8 +439,8 @@ static int lib_access_list_create(struct nb_cb_create_args *args)
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");
+ type = yang_dnode_get_enum(args->dnode, "type");
+ acl_name = yang_dnode_get_string(args->dnode, "name");
switch (type) {
case YALT_IPV4:
@@ -550,7 +521,7 @@ static int lib_access_list_entry_create(struct nb_cb_create_args *args)
return NB_OK;
f = filter_new();
- f->seq = yang_dnode_get_uint32(args->dnode, "./sequence");
+ f->seq = yang_dnode_get_uint32(args->dnode, "sequence");
acl = nb_running_get_entry(args->dnode, NULL, true);
f->acl = acl;
@@ -575,6 +546,15 @@ static int lib_access_list_entry_destroy(struct nb_cb_destroy_args *args)
return NB_OK;
}
+static void
+lib_access_list_entry_apply_finish(struct nb_cb_apply_finish_args *args)
+{
+ struct filter *f;
+
+ f = nb_running_get_entry(args->dnode, NULL, true);
+ access_list_filter_update(f->acl);
+}
+
/*
* XPath: /frr-filter:lib/access-list/entry/action
*/
@@ -594,8 +574,6 @@ lib_access_list_entry_action_modify(struct nb_cb_modify_args *args)
else
f->type = FILTER_DENY;
- acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
-
return NB_OK;
}
@@ -629,8 +607,6 @@ lib_access_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args *args)
fz = &f->u.zfilter;
yang_dnode_get_prefix(&fz->prefix, args->dnode, NULL);
- acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
-
return NB_OK;
}
@@ -647,8 +623,6 @@ lib_access_list_entry_ipv4_prefix_destroy(struct nb_cb_destroy_args *args)
fz = &f->u.zfilter;
memset(&fz->prefix, 0, sizeof(fz->prefix));
- acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
-
return NB_OK;
}
@@ -681,8 +655,6 @@ lib_access_list_entry_ipv4_exact_match_modify(struct nb_cb_modify_args *args)
fz = &f->u.zfilter;
fz->exact = yang_dnode_get_bool(args->dnode, NULL);
- acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
-
return NB_OK;
}
@@ -699,8 +671,6 @@ lib_access_list_entry_ipv4_exact_match_destroy(struct nb_cb_destroy_args *args)
fz = &f->u.zfilter;
fz->exact = 0;
- acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
-
return NB_OK;
}
@@ -733,8 +703,6 @@ lib_access_list_entry_host_modify(struct nb_cb_modify_args *args)
yang_dnode_get_ipv4(&fc->addr, args->dnode, NULL);
fc->addr_mask.s_addr = CISCO_BIN_HOST_WILDCARD_MASK;
- acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
-
return NB_OK;
}
@@ -751,7 +719,29 @@ lib_access_list_entry_host_destroy(struct nb_cb_destroy_args *args)
fc = &f->u.cfilter;
cisco_unset_addr_mask(&fc->addr, &fc->addr_mask);
- acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-filter:lib/access-list/entry/network
+ */
+static int lib_access_list_entry_network_create(struct nb_cb_create_args *args)
+{
+ /* Nothing to do here, everything is done in children callbacks */
+ 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;
+ cisco_unset_addr_mask(&fc->addr, &fc->addr_mask);
return NB_OK;
}
@@ -784,8 +774,6 @@ lib_access_list_entry_network_address_modify(struct nb_cb_modify_args *args)
fc = &f->u.cfilter;
yang_dnode_get_ipv4(&fc->addr, args->dnode, NULL);
- acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
-
return NB_OK;
}
@@ -817,8 +805,6 @@ lib_access_list_entry_network_mask_modify(struct nb_cb_modify_args *args)
fc = &f->u.cfilter;
yang_dnode_get_ipv4(&fc->addr_mask, args->dnode, NULL);
- acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
-
return NB_OK;
}
@@ -851,8 +837,6 @@ lib_access_list_entry_source_any_create(struct nb_cb_create_args *args)
fc->addr.s_addr = INADDR_ANY;
fc->addr_mask.s_addr = CISCO_BIN_ANY_WILDCARD_MASK;
- acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
-
return NB_OK;
}
@@ -869,8 +853,6 @@ lib_access_list_entry_source_any_destroy(struct nb_cb_destroy_args *args)
fc = &f->u.cfilter;
cisco_unset_addr_mask(&fc->addr, &fc->addr_mask);
- acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
-
return NB_OK;
}
@@ -903,8 +885,6 @@ static int lib_access_list_entry_destination_host_modify(
yang_dnode_get_ipv4(&fc->mask, args->dnode, NULL);
fc->mask_mask.s_addr = CISCO_BIN_HOST_WILDCARD_MASK;
- acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
-
return NB_OK;
}
@@ -922,7 +902,32 @@ static int lib_access_list_entry_destination_host_destroy(
fc->extended = 0;
cisco_unset_addr_mask(&fc->mask, &fc->mask_mask);
- acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-filter:lib/access-list/entry/destination-network
+ */
+static int
+lib_access_list_entry_destination_network_create(struct nb_cb_create_args *args)
+{
+ /* Nothing to do here, everything is done in children callbacks */
+ 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;
+ cisco_unset_addr_mask(&fc->mask, &fc->mask_mask);
return NB_OK;
}
@@ -955,8 +960,6 @@ static int lib_access_list_entry_destination_network_address_modify(
fc->extended = 1;
yang_dnode_get_ipv4(&fc->mask, args->dnode, NULL);
- acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
-
return NB_OK;
}
@@ -988,8 +991,6 @@ static int lib_access_list_entry_destination_network_mask_modify(
fc->extended = 1;
yang_dnode_get_ipv4(&fc->mask_mask, args->dnode, NULL);
- acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
-
return NB_OK;
}
@@ -1022,8 +1023,6 @@ static int lib_access_list_entry_destination_any_create(
fc->mask.s_addr = INADDR_ANY;
fc->mask_mask.s_addr = CISCO_BIN_ANY_WILDCARD_MASK;
- acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
-
return NB_OK;
}
@@ -1041,8 +1040,6 @@ static int lib_access_list_entry_destination_any_destroy(
fc->extended = 0;
cisco_unset_addr_mask(&fc->mask, &fc->mask_mask);
- acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
-
return NB_OK;
}
@@ -1089,8 +1086,6 @@ static int lib_access_list_entry_any_create(struct nb_cb_create_args *args)
break;
}
- acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
-
return NB_OK;
}
@@ -1106,8 +1101,6 @@ static int lib_access_list_entry_any_destroy(struct nb_cb_destroy_args *args)
fz = &f->u.zfilter;
fz->prefix.family = AF_UNSPEC;
- acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
-
return NB_OK;
}
@@ -1123,8 +1116,8 @@ static int lib_prefix_list_create(struct nb_cb_create_args *args)
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");
+ 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);
@@ -1201,7 +1194,7 @@ static int lib_prefix_list_entry_create(struct nb_cb_create_args *args)
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");
+ ple->seq = yang_dnode_get_uint32(args->dnode, "sequence");
prefix_list_entry_set_empty(ple);
nb_running_set_entry(args->dnode, ple);
@@ -1224,6 +1217,22 @@ static int lib_prefix_list_entry_destroy(struct nb_cb_destroy_args *args)
return NB_OK;
}
+static void
+lib_prefix_list_entry_apply_finish(struct nb_cb_apply_finish_args *args)
+{
+ struct prefix_list_entry *ple;
+
+ ple = nb_running_get_entry(args->dnode, NULL, true);
+
+ /*
+ * Finish prefix entry update procedure. The procedure is started in
+ * children callbacks. `prefix_list_entry_update_start` can be called
+ * multiple times if multiple children are modified, but it is actually
+ * executed only once because of the protection by `ple->installed`.
+ */
+ prefix_list_entry_update_finish(ple);
+}
+
/*
* XPath: /frr-filter:lib/prefix-list/entry/action
*/
@@ -1246,9 +1255,6 @@ static int lib_prefix_list_entry_action_modify(struct nb_cb_modify_args *args)
else
ple->type = PREFIX_DENY;
- /* Finish prefix entry update procedure. */
- prefix_list_entry_update_finish(ple);
-
return NB_OK;
}
@@ -1276,10 +1282,6 @@ static int lib_prefix_list_entry_prefix_modify(struct nb_cb_modify_args *args)
prefix_copy(&ple->prefix, &p);
}
-
- /* Finish prefix entry update procedure. */
- prefix_list_entry_update_finish(ple);
-
return NB_OK;
}
@@ -1297,9 +1299,6 @@ static int lib_prefix_list_entry_prefix_destroy(struct nb_cb_destroy_args *args)
memset(&ple->prefix, 0, sizeof(ple->prefix));
- /* Finish prefix entry update procedure. */
- prefix_list_entry_update_finish(ple);
-
return NB_OK;
}
@@ -1547,9 +1546,6 @@ static int lib_prefix_list_entry_any_create(struct nb_cb_create_args *args)
break;
}
- /* Finish prefix entry update procedure. */
- prefix_list_entry_update_finish(ple);
-
return NB_OK;
}
@@ -1567,9 +1563,6 @@ static int lib_prefix_list_entry_any_destroy(struct nb_cb_destroy_args *args)
ple->any = false;
- /* Finish prefix entry update procedure. */
- prefix_list_entry_update_finish(ple);
-
return NB_OK;
}
@@ -1597,6 +1590,7 @@ const struct frr_yang_module_info frr_filter_info = {
.cbs = {
.create = lib_access_list_entry_create,
.destroy = lib_access_list_entry_destroy,
+ .apply_finish = lib_access_list_entry_apply_finish,
.cli_cmp = access_list_cmp,
.cli_show = access_list_show,
}
@@ -1629,6 +1623,13 @@ const struct frr_yang_module_info frr_filter_info = {
}
},
{
+ .xpath = "/frr-filter:lib/access-list/entry/network",
+ .cbs = {
+ .create = lib_access_list_entry_network_create,
+ .destroy = lib_access_list_entry_network_destroy,
+ }
+ },
+ {
.xpath = "/frr-filter:lib/access-list/entry/network/address",
.cbs = {
.modify = lib_access_list_entry_network_address_modify,
@@ -1655,6 +1656,13 @@ const struct frr_yang_module_info frr_filter_info = {
}
},
{
+ .xpath = "/frr-filter:lib/access-list/entry/destination-network",
+ .cbs = {
+ .create = lib_access_list_entry_destination_network_create,
+ .destroy = lib_access_list_entry_destination_network_destroy,
+ }
+ },
+ {
.xpath = "/frr-filter:lib/access-list/entry/destination-network/address",
.cbs = {
.modify = lib_access_list_entry_destination_network_address_modify,
@@ -1721,6 +1729,7 @@ const struct frr_yang_module_info frr_filter_info = {
.cbs = {
.create = lib_prefix_list_entry_create,
.destroy = lib_prefix_list_entry_destroy,
+ .apply_finish = lib_prefix_list_entry_apply_finish,
.cli_cmp = prefix_list_cmp,
.cli_show = prefix_list_show,
}
@@ -1785,3 +1794,35 @@ const struct frr_yang_module_info frr_filter_info = {
},
}
};
+
+const struct frr_yang_module_info frr_filter_cli_info = {
+ .name = "frr-filter",
+ .ignore_cfg_cbs = true,
+ .nodes = {
+ {
+ .xpath = "/frr-filter:lib/access-list/remark",
+ .cbs.cli_show = access_list_remark_show,
+ },
+ {
+ .xpath = "/frr-filter:lib/access-list/entry",
+ .cbs = {
+ .cli_cmp = access_list_cmp,
+ .cli_show = access_list_show,
+ }
+ },
+ {
+ .xpath = "/frr-filter:lib/prefix-list/remark",
+ .cbs.cli_show = prefix_list_remark_show,
+ },
+ {
+ .xpath = "/frr-filter:lib/prefix-list/entry",
+ .cbs = {
+ .cli_cmp = prefix_list_cmp,
+ .cli_show = prefix_list_show,
+ }
+ },
+ {
+ .xpath = NULL,
+ },
+ }
+};