]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/plist.c
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / lib / plist.c
index d6a63c1b0cbb34c528fbc290eb6f700b8f381c5b..e286a32f9212ba1b699fba7a5a9eaf4df8f0ac0b 100644 (file)
@@ -1,21 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /* Prefix list functions.
  * Copyright (C) 1999 Kunihiro Ishiguro
- *
- * This file is part of GNU Zebra.
- *
- * GNU Zebra is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * GNU Zebra is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <zebra.h>
@@ -31,6 +16,7 @@
 #include "lib/json.h"
 #include "libfrr.h"
 
+#include <typesafe.h>
 #include "plist_int.h"
 
 DEFINE_MTYPE_STATIC(LIB, PREFIX_LIST, "Prefix List");
@@ -58,17 +44,8 @@ struct pltrie_table {
        struct pltrie_entry entries[PLC_LEN];
 };
 
-/* List of struct prefix_list. */
-struct prefix_list_list {
-       struct prefix_list *head;
-       struct prefix_list *tail;
-};
-
 /* Master structure of prefix_list. */
 struct prefix_master {
-       /* List of prefix_list which name is string. */
-       struct prefix_list_list str;
-
        /* The latest update. */
        struct prefix_list *recent;
 
@@ -80,26 +57,32 @@ struct prefix_master {
 
        /* number of bytes that have a trie level */
        size_t trie_depth;
+
+       struct plist_head str;
 };
+static int prefix_list_compare_func(const struct prefix_list *a,
+                                   const struct prefix_list *b);
+DECLARE_RBTREE_UNIQ(plist, struct prefix_list, plist_item,
+                   prefix_list_compare_func);
 
 /* Static structure of IPv4 prefix_list's master. */
 static struct prefix_master prefix_master_ipv4 = {
-       {NULL, NULL}, NULL, NULL, NULL, PLC_MAXLEVELV4,
+       NULL, NULL, NULL, PLC_MAXLEVELV4,
 };
 
 /* Static structure of IPv6 prefix-list's master. */
 static struct prefix_master prefix_master_ipv6 = {
-       {NULL, NULL}, NULL, NULL, NULL, PLC_MAXLEVELV6,
+       NULL, NULL, NULL, PLC_MAXLEVELV6,
 };
 
 /* Static structure of BGP ORF prefix_list's master. */
 static struct prefix_master prefix_master_orf_v4 = {
-       {NULL, NULL}, NULL, NULL, NULL, PLC_MAXLEVELV4,
+       NULL, NULL, NULL, PLC_MAXLEVELV4,
 };
 
 /* Static structure of BGP ORF prefix_list's master. */
 static struct prefix_master prefix_master_orf_v6 = {
-       {NULL, NULL}, NULL, NULL, NULL, PLC_MAXLEVELV6,
+       NULL, NULL, NULL, PLC_MAXLEVELV6,
 };
 
 static struct prefix_master *prefix_master_get(afi_t afi, int orf)
@@ -124,11 +107,17 @@ afi_t prefix_list_afi(struct prefix_list *plist)
        return AFI_IP6;
 }
 
+static int prefix_list_compare_func(const struct prefix_list *a,
+                                   const struct prefix_list *b)
+{
+       return strcmp(a->name, b->name);
+}
+
 /* Lookup prefix_list from list of prefix_list by name. */
 static struct prefix_list *prefix_list_lookup_do(afi_t afi, int orf,
                                                 const char *name)
 {
-       struct prefix_list *plist;
+       struct prefix_list *plist, lookup;
        struct prefix_master *master;
 
        if (name == NULL)
@@ -138,11 +127,10 @@ static struct prefix_list *prefix_list_lookup_do(afi_t afi, int orf,
        if (master == NULL)
                return NULL;
 
-       for (plist = master->str.head; plist; plist = plist->next)
-               if (strcmp(plist->name, name) == 0)
-                       return plist;
-
-       return NULL;
+       lookup.name = XSTRDUP(MTYPE_TMP, name);
+       plist = plist_find(&master->str, &lookup);
+       XFREE(MTYPE_TMP, lookup.name);
+       return plist;
 }
 
 struct prefix_list *prefix_list_lookup(afi_t afi, const char *name)
@@ -188,8 +176,6 @@ static struct prefix_list *prefix_list_insert(afi_t afi, int orf,
                                              const char *name)
 {
        struct prefix_list *plist;
-       struct prefix_list *point;
-       struct prefix_list_list *list;
        struct prefix_master *master;
 
        master = prefix_master_get(afi, orf);
@@ -203,43 +189,7 @@ static struct prefix_list *prefix_list_insert(afi_t afi, int orf,
        plist->trie =
                XCALLOC(MTYPE_PREFIX_LIST_TRIE, sizeof(struct pltrie_table));
 
-       /* Set prefix_list to string list. */
-       list = &master->str;
-
-       /* Set point to insertion point. */
-       for (point = list->head; point; point = point->next)
-               if (strcmp(point->name, name) >= 0)
-                       break;
-
-       /* In case of this is the first element of master. */
-       if (list->head == NULL) {
-               list->head = list->tail = plist;
-               return plist;
-       }
-
-       /* In case of insertion is made at the tail of access_list. */
-       if (point == NULL) {
-               plist->prev = list->tail;
-               list->tail->next = plist;
-               list->tail = plist;
-               return plist;
-       }
-
-       /* In case of insertion is made at the head of access_list. */
-       if (point == list->head) {
-               plist->next = list->head;
-               list->head->prev = plist;
-               list->head = plist;
-               return plist;
-       }
-
-       /* Insertion is made at middle of the access_list. */
-       plist->next = point;
-       plist->prev = point->prev;
-
-       if (point->prev)
-               point->prev->next = plist;
-       point->prev = plist;
+       plist_add(&master->str, plist);
 
        return plist;
 }
@@ -261,7 +211,6 @@ static void prefix_list_trie_del(struct prefix_list *plist,
 /* Delete prefix-list from prefix_list_master and free it. */
 void prefix_list_delete(struct prefix_list *plist)
 {
-       struct prefix_list_list *list;
        struct prefix_master *master;
        struct prefix_list_entry *pentry;
        struct prefix_list_entry *next;
@@ -278,17 +227,7 @@ void prefix_list_delete(struct prefix_list *plist)
 
        master = plist->master;
 
-       list = &master->str;
-
-       if (plist->next)
-               plist->next->prev = plist->prev;
-       else
-               list->tail = plist->prev;
-
-       if (plist->prev)
-               plist->prev->next = plist->next;
-       else
-               list->head = plist->next;
+       plist_del(&master->str, plist);
 
        XFREE(MTYPE_TMP, plist->desc);
 
@@ -1120,7 +1059,7 @@ static int vty_show_prefix_list(struct vty *vty, afi_t afi, const char *name,
                                        master->recent->name);
                }
 
-               for (plist = master->str.head; plist; plist = plist->next)
+               frr_each (plist, &master->str, plist)
                        vty_show_prefix_entry(vty, json_proto, afi, plist,
                                              master, dtype, seqnum);
        }
@@ -1208,7 +1147,7 @@ static int vty_clear_prefix_list(struct vty *vty, afi_t afi, const char *name,
                return CMD_WARNING;
 
        if (name == NULL && prefix == NULL) {
-               for (plist = master->str.head; plist; plist = plist->next)
+               frr_each (plist, &master->str, plist)
                        for (pentry = plist->head; pentry;
                             pentry = pentry->next)
                                pentry->hitcnt = 0;
@@ -1239,9 +1178,7 @@ static int vty_clear_prefix_list(struct vty *vty, afi_t afi, const char *name,
        return CMD_SUCCESS;
 }
 
-#ifndef VTYSH_EXTRACT_PL
 #include "lib/plist_clippy.c"
-#endif
 
 DEFPY (show_ip_prefix_list,
        show_ip_prefix_list_cmd,
@@ -1608,21 +1545,16 @@ int prefix_bgp_show_prefix_list(struct vty *vty, afi_t afi, char *name,
 static void prefix_list_reset_afi(afi_t afi, int orf)
 {
        struct prefix_list *plist;
-       struct prefix_list *next;
        struct prefix_master *master;
 
        master = prefix_master_get(afi, orf);
        if (master == NULL)
                return;
 
-       for (plist = master->str.head; plist; plist = next) {
-               next = plist->next;
+       while ((plist = plist_first(&master->str))) {
                prefix_list_delete(plist);
        }
 
-       assert(master->str.head == NULL);
-       assert(master->str.tail == NULL);
-
        master->recent = NULL;
 }
 
@@ -1643,7 +1575,7 @@ static void plist_autocomplete_afi(afi_t afi, vector comps,
        if (master == NULL)
                return;
 
-       for (plist = master->str.head; plist; plist = plist->next)
+       frr_each (plist, &master->str, plist)
                vector_set(comps, XSTRDUP(MTYPE_COMPLETION, plist->name));
 }
 
@@ -1696,6 +1628,11 @@ static void prefix_list_init_ipv6(void)
 
 void prefix_list_init(void)
 {
+       plist_init(&prefix_master_ipv4.str);
+       plist_init(&prefix_master_orf_v4.str);
+       plist_init(&prefix_master_ipv6.str);
+       plist_init(&prefix_master_orf_v6.str);
+
        cmd_variable_handler_register(plist_var_handlers);
 
        prefix_list_init_ipv4();