summaryrefslogtreecommitdiff
path: root/lib/plist.c
diff options
context:
space:
mode:
authorRafael Zalamena <rzalamena@opensourcerouting.org>2020-05-01 12:10:40 -0300
committerRafael Zalamena <rzalamena@opensourcerouting.org>2020-06-05 14:36:53 -0300
commit744ad1afb4f889494fb809242ae08609f0b1db68 (patch)
tree5452b4d6d3ff7b349b2bd0e4429c21d174ad8d9e /lib/plist.c
parenta7b2821884074b0e16a4de4588a8b27b6ae086be (diff)
lib: properly apply prefix list entries
After the commands started working I noticed that prefix lists were still not working and displaying incorrect information in `show ip prefix-list`. Turns out `any` must be set to `0` when a prefix is set and the prefix entry **must** be installed in the prefix list head. Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Diffstat (limited to 'lib/plist.c')
-rw-r--r--lib/plist.c48
1 files changed, 46 insertions, 2 deletions
diff --git a/lib/plist.c b/lib/plist.c
index 9567fde372..958d98dc96 100644
--- a/lib/plist.c
+++ b/lib/plist.c
@@ -648,7 +648,8 @@ static void prefix_list_entry_add(struct prefix_list *plist,
/**
* Prefix list entry update start procedure:
- * Remove entry from previosly installed tries and notify observers..
+ * Remove entry from previosly installed master list, tries and notify
+ * observers.
*
* \param[in] ple prefix list entry.
*/
@@ -660,6 +661,16 @@ void prefix_list_entry_update_start(struct prefix_list_entry *ple)
if (!ple->installed)
return;
+ /* List manipulation: shameless copy from `prefix_list_entry_delete`. */
+ if (ple->prev)
+ ple->prev->next = ple->next;
+ else
+ pl->head = ple->next;
+ if (ple->next)
+ ple->next->prev = ple->prev;
+ else
+ pl->tail = ple->prev;
+
prefix_list_trie_del(pl, ple);
route_map_notify_pentry_dependencies(pl->name, ple,
RMAP_EVENT_PLIST_DELETED);
@@ -670,18 +681,51 @@ void prefix_list_entry_update_start(struct prefix_list_entry *ple)
/**
* Prefix list entry update finish procedure:
- * Add entry back to trie, notify observers and call master hook.
+ * Add entry back master list, to the 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;
+ struct prefix_list_entry *point;
/* Already installed, nothing to do. */
if (ple->installed)
return;
+ /* List manipulation: shameless copy from `prefix_list_entry_add`. */
+ if (pl->tail && ple->seq > pl->tail->seq)
+ point = NULL;
+ else {
+ /* Check insert point. */
+ for (point = pl->head; point; point = point->next)
+ if (point->seq >= ple->seq)
+ break;
+ }
+
+ /* In case of this is the first element of the list. */
+ ple->next = point;
+
+ if (point) {
+ if (point->prev)
+ point->prev->next = ple;
+ else
+ pl->head = ple;
+
+ ple->prev = point->prev;
+ point->prev = ple;
+ } else {
+ if (pl->tail)
+ pl->tail->next = ple;
+ else
+ pl->head = ple;
+
+ ple->prev = pl->tail;
+ pl->tail = ple;
+ }
+
prefix_list_trie_add(pl, ple);
pl->count++;