+// 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>
#include "lib/json.h"
#include "libfrr.h"
+#include <typesafe.h>
#include "plist_int.h"
DEFINE_MTYPE_STATIC(LIB, PREFIX_LIST, "Prefix List");
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;
/* 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)
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)
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)
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);
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;
}
/* 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;
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);
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);
}
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;
return CMD_SUCCESS;
}
-#ifndef VTYSH_EXTRACT_PL
#include "lib/plist_clippy.c"
-#endif
DEFPY (show_ip_prefix_list,
show_ip_prefix_list_cmd,
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;
}
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));
}
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();