]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: properly apply prefix list entries
authorRafael Zalamena <rzalamena@opensourcerouting.org>
Fri, 1 May 2020 15:10:40 +0000 (12:10 -0300)
committerRafael Zalamena <rzalamena@opensourcerouting.org>
Fri, 5 Jun 2020 17:36:53 +0000 (14:36 -0300)
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>
lib/filter_nb.c
lib/plist.c

index 0f6e5488fc6280a918d579ba06baf0f96fb0679d..54811ac24576a63c54dda81163021bed4b645b18 100644 (file)
@@ -409,8 +409,8 @@ static int lib_access_list_legacy_entry_destination_network_modify(
        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);
+       fc->mask.s_addr = ipv4_network_addr(p.u.prefix4.s_addr, p.prefixlen);
+       masklen2ip(p.prefixlen, &fc->mask_mask);
 
        return NB_OK;
 }
@@ -904,6 +904,7 @@ lib_prefix_list_entry_ipv4_prefix_modify(struct nb_cb_modify_args *args)
        prefix_list_entry_update_start(ple);
 
        yang_dnode_get_prefix(&ple->prefix, args->dnode, NULL);
+       ple->any = 0;
 
        /* Finish prefix entry update procedure. */
        prefix_list_entry_update_finish(ple);
index 9567fde372b8b428c212cdd409e73811899556b7..958d98dc966f85a04a5142dc9c6c6b41f5beefd1 100644 (file)
@@ -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++;