summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/filter_nb.c69
-rw-r--r--lib/plist.c54
-rw-r--r--lib/plist_int.h7
3 files changed, 128 insertions, 2 deletions
diff --git a/lib/filter_nb.c b/lib/filter_nb.c
index 46ea71aeca..0f6e5488fc 100644
--- a/lib/filter_nb.c
+++ b/lib/filter_nb.c
@@ -838,6 +838,7 @@ static int lib_prefix_list_entry_create(struct nb_cb_create_args *args)
ple->pl = pl;
ple->any = 1;
ple->seq = yang_dnode_get_uint32(args->dnode, "./sequence");
+ nb_running_set_entry(args->dnode, ple);
return NB_OK;
}
@@ -850,7 +851,10 @@ static int lib_prefix_list_entry_destroy(struct nb_cb_destroy_args *args)
return NB_OK;
ple = nb_running_unset_entry(args->dnode);
- prefix_list_entry_delete(ple->pl, ple, 1);
+ if (ple->installed)
+ prefix_list_entry_delete(ple->pl, ple, 0);
+ else
+ prefix_list_entry_free(ple);
return NB_OK;
}
@@ -867,12 +871,19 @@ static int lib_prefix_list_entry_action_modify(struct nb_cb_modify_args *args)
return NB_OK;
ple = nb_running_get_entry(args->dnode, NULL, true);
+
+ /* Start prefix entry update procedure. */
+ prefix_list_entry_update_start(ple);
+
action_str = yang_dnode_get_string(args->dnode, NULL);
if (strcmp(action_str, "permit") == 0)
ple->type = PREFIX_PERMIT;
else
ple->type = PREFIX_DENY;
+ /* Finish prefix entry update procedure. */
+ prefix_list_entry_update_finish(ple);
+
return NB_OK;
}
@@ -888,8 +899,15 @@ lib_prefix_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args *args)
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);
+ /* Finish prefix entry update procedure. */
+ prefix_list_entry_update_finish(ple);
+
return NB_OK;
}
@@ -902,9 +920,16 @@ lib_prefix_list_entry_ipv4_prefix_destroy(struct nb_cb_destroy_args *args)
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));
ple->any = 1;
+ /* Finish prefix entry update procedure. */
+ prefix_list_entry_update_finish(ple);
+
return NB_OK;
}
@@ -924,8 +949,15 @@ static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_modify(
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;
}
@@ -938,8 +970,15 @@ static int lib_prefix_list_entry_ipv4_prefix_length_greater_or_equal_destroy(
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;
}
@@ -959,8 +998,15 @@ static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_modify(
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;
}
@@ -973,8 +1019,15 @@ static int lib_prefix_list_entry_ipv4_prefix_length_lesser_or_equal_destroy(
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;
}
@@ -1038,9 +1091,16 @@ static int lib_prefix_list_entry_any_create(struct nb_cb_create_args *args)
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));
ple->any = 1;
+ /* Finish prefix entry update procedure. */
+ prefix_list_entry_update_finish(ple);
+
return NB_OK;
}
@@ -1052,9 +1112,16 @@ static int lib_prefix_list_entry_any_destroy(struct nb_cb_destroy_args *args)
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));
ple->any = 1;
+ /* Finish prefix entry update procedure. */
+ prefix_list_entry_update_finish(ple);
+
return NB_OK;
}
diff --git a/lib/plist.c b/lib/plist.c
index aa420da927..9567fde372 100644
--- a/lib/plist.c
+++ b/lib/plist.c
@@ -187,7 +187,7 @@ struct prefix_list_entry *prefix_list_entry_new(void)
return new;
}
-static void prefix_list_entry_free(struct prefix_list_entry *pentry)
+void prefix_list_entry_free(struct prefix_list_entry *pentry)
{
XFREE(MTYPE_PREFIX_LIST_ENTRY, pentry);
}
@@ -646,6 +646,58 @@ static void prefix_list_entry_add(struct prefix_list *plist,
plist->master->recent = plist;
}
+/**
+ * Prefix list entry update start procedure:
+ * Remove entry from previosly installed tries and notify observers..
+ *
+ * \param[in] ple prefix list entry.
+ */
+void prefix_list_entry_update_start(struct prefix_list_entry *ple)
+{
+ struct prefix_list *pl = ple->pl;
+
+ /* Not installed, nothing to do. */
+ if (!ple->installed)
+ return;
+
+ prefix_list_trie_del(pl, ple);
+ route_map_notify_pentry_dependencies(pl->name, ple,
+ RMAP_EVENT_PLIST_DELETED);
+ pl->count--;
+
+ ple->installed = false;
+}
+
+/**
+ * Prefix list entry update finish procedure:
+ * Add entry back to trie, notify observers and call master hook.
+ *
+ * \param[in] ple prefix list entry.
+ */
+void prefix_list_entry_update_finish(struct prefix_list_entry *ple)
+{
+ struct prefix_list *pl = ple->pl;
+
+ /* Already installed, nothing to do. */
+ if (ple->installed)
+ return;
+
+ prefix_list_trie_add(pl, ple);
+ pl->count++;
+
+ route_map_notify_pentry_dependencies(pl->name, ple,
+ RMAP_EVENT_PLIST_ADDED);
+
+ /* Run hook function. */
+ if (pl->master->add_hook)
+ (*pl->master->add_hook)(pl);
+
+ route_map_notify_dependencies(pl->name, RMAP_EVENT_PLIST_ADDED);
+ pl->master->recent = pl;
+
+ ple->installed = true;
+}
+
/* Return string of prefix_list_type. */
static const char *prefix_list_type_str(struct prefix_list_entry *pentry)
{
diff --git a/lib/plist_int.h b/lib/plist_int.h
index b180d18081..cef78a3ef7 100644
--- a/lib/plist_int.h
+++ b/lib/plist_int.h
@@ -72,8 +72,15 @@ struct prefix_list_entry {
/* up the chain for best match search */
struct prefix_list_entry *next_best;
+
+ /* Flag to track trie/list installation status. */
+ bool installed;
};
+extern void prefix_list_entry_free(struct prefix_list_entry *pentry);
+extern void prefix_list_entry_update_start(struct prefix_list_entry *ple);
+extern void prefix_list_entry_update_finish(struct prefix_list_entry *ple);
+
#ifdef __cplusplus
}
#endif