isisd: replace dict_* with DECLARE_RBTREE

Historically, isisd has been carrying around its own red-black tree to
manage its LSP DB in.  This replaces that with the newly-added
DECLARE_RBTREE_*.  This allows completely removing the dict_* code.

Signed-off-by: David Lamparter <equinox@diac24.net>
This commit is contained in:
David Lamparter 2019-02-04 01:22:03 +01:00 committed by David Lamparter
parent 798ac49d06
commit 4bef0ec4fb
33 changed files with 221 additions and 1948 deletions

13
debian/copyright vendored
View File

@ -324,19 +324,6 @@ Copyright:
Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org>
Copyright (c) 2006, 2007, 2008 Reyk Floeter <reyk@openbsd.org>
Files: isisd/dict.*
Copyright: Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
License: custom-BSD-like
All rights are reserved by the author, with the following exceptions:
Permission is granted to freely reproduce and distribute this software,
possibly in exchange for a fee, provided that this copyright notice appears
intact. Permission is also granted to adapt this software to produce
derivative works, as long as the modified versions carry this copyright
notice and additional notices stating that the work has been modified.
This source code may be translated into executable form and incorporated
into proprietary software; there is no requirement for such software to
contain a copyright notice related to this source.
Files: qpb/qpb.proto fpm/fpm.proto
License: ISC
Copyright: Copyright (C) 2016 Sproute Networks, Inc.

File diff suppressed because it is too large Load Diff

View File

@ -1,121 +0,0 @@
/*
* Dictionary Abstract Data Type
* Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
*
* Free Software License:
*
* All rights are reserved by the author, with the following exceptions:
* Permission is granted to freely reproduce and distribute this software,
* possibly in exchange for a fee, provided that this copyright notice appears
* intact. Permission is also granted to adapt this software to produce
* derivative works, as long as the modified versions carry this copyright
* notice and additional notices stating that the work has been modified.
* This source code may be translated into executable form and incorporated
* into proprietary software; there is no requirement for such software to
* contain a copyright notice related to this source.
*
*/
#ifndef DICT_H
#define DICT_H
#include <limits.h>
/*
* Blurb for inclusion into C++ translation units
*/
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned long dictcount_t;
#define DICTCOUNT_T_MAX ULONG_MAX
/*
* The dictionary is implemented as a red-black tree
*/
typedef enum { dnode_red, dnode_black } dnode_color_t;
typedef struct dnode_t {
struct dnode_t *dict_left;
struct dnode_t *dict_right;
struct dnode_t *dict_parent;
dnode_color_t dict_color;
const void *dict_key;
void *dict_data;
} dnode_t;
typedef int (*dict_comp_t)(const void *, const void *);
typedef dnode_t *(*dnode_alloc_t)(void *);
typedef void (*dnode_free_t)(dnode_t *, void *);
typedef struct dict_t {
dnode_t dict_nilnode;
dictcount_t dict_nodecount;
dictcount_t dict_maxcount;
dict_comp_t dict_compare;
dnode_alloc_t dict_allocnode;
dnode_free_t dict_freenode;
void *dict_context;
int dict_dupes;
} dict_t;
typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
typedef struct dict_load_t {
dict_t *dict_dictptr;
dnode_t dict_nilnode;
} dict_load_t;
extern dict_t *dict_create(dictcount_t, dict_comp_t);
extern void dict_set_allocator(dict_t *, dnode_alloc_t, dnode_free_t, void *);
extern void dict_destroy(dict_t *);
extern void dict_free_nodes(dict_t *);
extern void dict_free(dict_t *);
extern dict_t *dict_init(dict_t *, dictcount_t, dict_comp_t);
extern void dict_init_like(dict_t *, const dict_t *);
extern int dict_verify(dict_t *);
extern int dict_similar(const dict_t *, const dict_t *);
extern dnode_t *dict_lookup(dict_t *, const void *);
extern dnode_t *dict_lower_bound(dict_t *, const void *);
extern dnode_t *dict_upper_bound(dict_t *, const void *);
extern void dict_insert(dict_t *, dnode_t *, const void *);
extern dnode_t *dict_delete(dict_t *, dnode_t *);
extern int dict_alloc_insert(dict_t *, const void *, void *);
extern void dict_delete_free(dict_t *, dnode_t *);
extern dnode_t *dict_first(dict_t *);
extern dnode_t *dict_last(dict_t *);
extern dnode_t *dict_next(dict_t *, dnode_t *);
extern dnode_t *dict_prev(dict_t *, dnode_t *);
extern dictcount_t dict_count(dict_t *);
extern int dict_isempty(dict_t *);
extern int dict_isfull(dict_t *);
extern int dict_contains(dict_t *, dnode_t *);
extern void dict_allow_dupes(dict_t *);
extern int dnode_is_in_a_dict(dnode_t *);
extern dnode_t *dnode_create(void *);
extern dnode_t *dnode_init(dnode_t *, void *);
extern void dnode_destroy(dnode_t *);
extern void *dnode_get(dnode_t *);
extern const void *dnode_getkey(dnode_t *);
extern void dnode_put(dnode_t *, void *);
extern void dict_process(dict_t *, void *, dnode_process_t);
extern void dict_load_begin(dict_load_t *, dict_t *);
extern void dict_load_next(dict_load_t *, dnode_t *, const void *);
extern void dict_load_end(dict_load_t *);
extern void dict_merge(dict_t *, dict_t *);
#define dict_isfull(D) ((D)->dict_nodecount == (D)->dict_maxcount)
#define dict_count(D) ((D)->dict_nodecount)
#define dict_isempty(D) ((D)->dict_nodecount == 0)
#define dnode_get(N) ((N)->dict_data)
#define dnode_getkey(N) ((N)->dict_key)
#define dnode_put(N, X) ((N)->dict_data = (X))
#ifdef __cplusplus
}
#endif
#endif

View File

@ -32,7 +32,6 @@
#include "if.h"
#include "stream.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"

View File

@ -34,7 +34,6 @@
#include "if.h"
#include "lib_errors.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_circuit.h"

View File

@ -40,7 +40,6 @@
#include "qobj.h"
#include "lib/northbound_cli.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"
@ -540,7 +539,6 @@ static void isis_circuit_update_all_srmflags(struct isis_circuit *circuit,
{
struct isis_area *area;
struct isis_lsp *lsp;
dnode_t *dnode;
int level;
assert(circuit);
@ -550,14 +548,10 @@ static void isis_circuit_update_all_srmflags(struct isis_circuit *circuit,
if (!(level & circuit->is_type))
continue;
if (!area->lspdb[level - 1]
|| !dict_count(area->lspdb[level - 1]))
if (!lspdb_count(&area->lspdb[level - 1]))
continue;
for (dnode = dict_first(area->lspdb[level - 1]);
dnode != NULL;
dnode = dict_next(area->lspdb[level - 1], dnode)) {
lsp = dnode_get(dnode);
for_each (lspdb, &area->lspdb[level - 1], lsp) {
if (is_set) {
isis_tx_queue_add(circuit->tx_queue, lsp,
TX_LSP_NORMAL);

View File

@ -32,7 +32,6 @@
#include "prefix.h"
#include "stream.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"

View File

@ -38,7 +38,6 @@
#include "if.h"
#include "lib_errors.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_circuit.h"

View File

@ -32,7 +32,6 @@
#include "stream.h"
#include "if.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_misc.h"

View File

@ -31,7 +31,6 @@
#include "if.h"
#include "thread.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"

View File

@ -32,7 +32,6 @@
#include "stream.h"
#include "table.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"

View File

@ -40,7 +40,6 @@
#include "srcdest_table.h"
#include "lib_errors.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"
@ -63,41 +62,38 @@ static int lsp_refresh(struct thread *thread);
static int lsp_l1_refresh_pseudo(struct thread *thread);
static int lsp_l2_refresh_pseudo(struct thread *thread);
static void lsp_destroy(struct isis_lsp *lsp);
int lsp_id_cmp(uint8_t *id1, uint8_t *id2)
{
return memcmp(id1, id2, ISIS_SYS_ID_LEN + 2);
}
dict_t *lsp_db_init(void)
int lspdb_compare(const struct isis_lsp *a, const struct isis_lsp *b)
{
dict_t *dict;
dict = dict_create(DICTCOUNT_T_MAX, (dict_comp_t)lsp_id_cmp);
return dict;
return memcmp(a->hdr.lsp_id, b->hdr.lsp_id, sizeof(a->hdr.lsp_id));
}
struct isis_lsp *lsp_search(uint8_t *id, dict_t *lspdb)
void lsp_db_init(struct lspdb_head *head)
{
dnode_t *node;
lspdb_init(head);
}
#ifdef EXTREME_DEBUG
dnode_t *dn;
void lsp_db_fini(struct lspdb_head *head)
{
struct isis_lsp *lsp;
zlog_debug("searching db");
for (dn = dict_first(lspdb); dn; dn = dict_next(lspdb, dn)) {
zlog_debug("%s\t%pX",
rawlspid_print((uint8_t *)dnode_getkey(dn)),
dnode_get(dn));
}
#endif /* EXTREME DEBUG */
while ((lsp = lspdb_pop(head)))
lsp_destroy(lsp);
lspdb_fini(head);
}
node = dict_lookup(lspdb, id);
struct isis_lsp *lsp_search(struct lspdb_head *head, const uint8_t *id)
{
struct isis_lsp searchfor;
memcpy(searchfor.hdr.lsp_id, id, sizeof(searchfor.hdr.lsp_id));
if (node)
return (struct isis_lsp *)dnode_get(node);
return NULL;
return lspdb_find(head, &searchfor);
}
static void lsp_clear_data(struct isis_lsp *lsp)
@ -109,7 +105,7 @@ static void lsp_clear_data(struct isis_lsp *lsp)
lsp->tlvs = NULL;
}
static void lsp_remove_frags(struct list *frags, dict_t *lspdb);
static void lsp_remove_frags(struct lspdb_head *head, struct list *frags);
static void lsp_destroy(struct isis_lsp *lsp)
{
@ -128,8 +124,8 @@ static void lsp_destroy(struct isis_lsp *lsp)
if (!LSP_FRAGMENT(lsp->hdr.lsp_id)) {
if (lsp->lspu.frags) {
lsp_remove_frags(lsp->lspu.frags,
lsp->area->lspdb[lsp->level - 1]);
lsp_remove_frags(&lsp->area->lspdb[lsp->level - 1],
lsp->lspu.frags);
list_delete(&lsp->lspu.frags);
}
} else {
@ -148,56 +144,34 @@ static void lsp_destroy(struct isis_lsp *lsp)
XFREE(MTYPE_ISIS_LSP, lsp);
}
void lsp_db_destroy(dict_t *lspdb)
{
dnode_t *dnode, *next;
struct isis_lsp *lsp;
dnode = dict_first(lspdb);
while (dnode) {
next = dict_next(lspdb, dnode);
lsp = dnode_get(dnode);
lsp_destroy(lsp);
dict_delete_free(lspdb, dnode);
dnode = next;
}
dict_free(lspdb);
return;
}
/*
* Remove all the frags belonging to the given lsp
*/
static void lsp_remove_frags(struct list *frags, dict_t *lspdb)
static void lsp_remove_frags(struct lspdb_head *head, struct list *frags)
{
dnode_t *dnode;
struct listnode *lnode, *lnnode;
struct isis_lsp *lsp;
for (ALL_LIST_ELEMENTS(frags, lnode, lnnode, lsp)) {
dnode = dict_lookup(lspdb, lsp->hdr.lsp_id);
lsp = lsp_search(head, lsp->hdr.lsp_id);
lspdb_del(head, lsp);
lsp_destroy(lsp);
dnode_destroy(dict_delete(lspdb, dnode));
}
}
void lsp_search_and_destroy(uint8_t *id, dict_t *lspdb)
void lsp_search_and_destroy(struct lspdb_head *head, const uint8_t *id)
{
dnode_t *node;
struct isis_lsp *lsp;
node = dict_lookup(lspdb, id);
if (node) {
node = dict_delete(lspdb, node);
lsp = dnode_get(node);
lsp = lsp_search(head, id);
if (lsp) {
lspdb_del(head, lsp);
/*
* If this is a zero lsp, remove all the frags now
*/
if (LSP_FRAGMENT(lsp->hdr.lsp_id) == 0) {
if (lsp->lspu.frags)
lsp_remove_frags(lsp->lspu.frags, lspdb);
lsp_remove_frags(head, lsp->lspu.frags);
} else {
/*
* else just remove this frag, from the zero lsps' frag
@ -209,7 +183,6 @@ void lsp_search_and_destroy(uint8_t *id, dict_t *lspdb)
lsp);
}
lsp_destroy(lsp);
dnode_destroy(node);
}
}
@ -514,7 +487,7 @@ void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr,
memcpy(lspid, lsp->hdr.lsp_id, ISIS_SYS_ID_LEN + 1);
LSP_FRAGMENT(lspid) = 0;
lsp0 = lsp_search(lspid, area->lspdb[level - 1]);
lsp0 = lsp_search(&area->lspdb[level - 1], lspid);
if (lsp0)
lsp_link_fragment(lsp, lsp0);
}
@ -582,9 +555,9 @@ struct isis_lsp *lsp_new(struct isis_area *area, uint8_t *lsp_id,
return lsp;
}
void lsp_insert(struct isis_lsp *lsp, dict_t *lspdb)
void lsp_insert(struct lspdb_head *head, struct isis_lsp *lsp)
{
dict_alloc_insert(lspdb, lsp->hdr.lsp_id, lsp);
lspdb_add(head, lsp);
if (lsp->hdr.seqno)
isis_spf_schedule(lsp->area, lsp->level);
}
@ -592,13 +565,16 @@ void lsp_insert(struct isis_lsp *lsp, dict_t *lspdb)
/*
* Build a list of LSPs with non-zero ht bounded by start and stop ids
*/
void lsp_build_list_nonzero_ht(uint8_t *start_id, uint8_t *stop_id,
struct list *list, dict_t *lspdb)
void lsp_build_list_nonzero_ht(struct lspdb_head *head, const uint8_t *start_id,
const uint8_t *stop_id, struct list *list)
{
for (dnode_t *curr = dict_lower_bound(lspdb, start_id);
curr; curr = dict_next(lspdb, curr)) {
struct isis_lsp *lsp = curr->dict_data;
struct isis_lsp searchfor;
struct isis_lsp *lsp, *start;
memcpy(&searchfor.hdr.lsp_id, start_id, sizeof(searchfor.hdr.lsp_id));
start = lspdb_find_gteq(head, &searchfor);
for_each_from (lspdb, head, lsp, start) {
if (memcmp(lsp->hdr.lsp_id, stop_id,
ISIS_SYS_ID_LEN + 2) > 0)
break;
@ -699,26 +675,20 @@ void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost)
}
/* print all the lsps info in the local lspdb */
int lsp_print_all(struct vty *vty, dict_t *lspdb, char detail, char dynhost)
int lsp_print_all(struct vty *vty, struct lspdb_head *head, char detail,
char dynhost)
{
dnode_t *node = dict_first(lspdb), *next;
struct isis_lsp *lsp;
int lsp_count = 0;
if (detail == ISIS_UI_LEVEL_BRIEF) {
while (node != NULL) {
/* I think it is unnecessary, so I comment it out */
/* dict_contains (lspdb, node); */
next = dict_next(lspdb, node);
lsp_print(dnode_get(node), vty, dynhost);
node = next;
for_each (lspdb, head, lsp) {
lsp_print(lsp, vty, dynhost);
lsp_count++;
}
} else if (detail == ISIS_UI_LEVEL_DETAIL) {
while (node != NULL) {
next = dict_next(lspdb, node);
lsp_print_detail(dnode_get(node), vty, dynhost);
node = next;
for_each (lspdb, head, lsp) {
lsp_print_detail(lsp, vty, dynhost);
lsp_count++;
}
}
@ -847,7 +817,7 @@ static struct isis_lsp *lsp_next_frag(uint8_t frag_num, struct isis_lsp *lsp0,
memcpy(frag_id, lsp0->hdr.lsp_id, ISIS_SYS_ID_LEN + 1);
LSP_FRAGMENT(frag_id) = frag_num;
lsp = lsp_search(frag_id, area->lspdb[level - 1]);
lsp = lsp_search(&area->lspdb[level - 1], frag_id);
if (lsp) {
lsp_clear_data(lsp);
if (!lsp->lspu.zero_lsp)
@ -860,7 +830,7 @@ static struct isis_lsp *lsp_next_frag(uint8_t frag_num, struct isis_lsp *lsp0,
area->attached_bit),
0, lsp0, level);
lsp->own_lsp = 1;
lsp_insert(lsp, area->lspdb[level - 1]);
lsp_insert(&area->lspdb[level - 1], lsp);
return lsp;
}
@ -1228,12 +1198,12 @@ int lsp_generate(struct isis_area *area, int level)
memcpy(&lspid, isis->sysid, ISIS_SYS_ID_LEN);
/* only builds the lsp if the area shares the level */
oldlsp = lsp_search(lspid, area->lspdb[level - 1]);
oldlsp = lsp_search(&area->lspdb[level - 1], lspid);
if (oldlsp) {
/* FIXME: we should actually initiate a purge */
seq_num = oldlsp->hdr.seqno;
lsp_search_and_destroy(oldlsp->hdr.lsp_id,
area->lspdb[level - 1]);
lsp_search_and_destroy(&area->lspdb[level - 1],
oldlsp->hdr.lsp_id);
}
rem_lifetime = lsp_rem_lifetime(area, level);
newlsp =
@ -1243,7 +1213,7 @@ int lsp_generate(struct isis_area *area, int level)
newlsp->area = area;
newlsp->own_lsp = 1;
lsp_insert(newlsp, area->lspdb[level - 1]);
lsp_insert(&area->lspdb[level - 1], newlsp);
/* build_lsp_data (newlsp, area); */
lsp_build(newlsp, area);
/* time to calculate our checksum */
@ -1288,7 +1258,7 @@ int lsp_generate(struct isis_area *area, int level)
*/
static int lsp_regenerate(struct isis_area *area, int level)
{
dict_t *lspdb;
struct lspdb_head *head;
struct isis_lsp *lsp, *frag;
struct listnode *node;
uint8_t lspid[ISIS_SYS_ID_LEN + 2];
@ -1297,12 +1267,12 @@ static int lsp_regenerate(struct isis_area *area, int level)
if ((area == NULL) || (area->is_type & level) != level)
return ISIS_ERROR;
lspdb = area->lspdb[level - 1];
head = &area->lspdb[level - 1];
memset(lspid, 0, ISIS_SYS_ID_LEN + 2);
memcpy(lspid, isis->sysid, ISIS_SYS_ID_LEN);
lsp = lsp_search(lspid, lspdb);
lsp = lsp_search(head, lspid);
if (!lsp) {
flog_err(EC_LIB_DEVELOPMENT,
@ -1445,7 +1415,7 @@ int _lsp_regenerate_schedule(struct isis_area *area, int level,
continue;
}
lsp = lsp_search(id, area->lspdb[lvl - 1]);
lsp = lsp_search(&area->lspdb[lvl - 1], id);
if (!lsp) {
sched_debug(
"ISIS (%s): We do not have any LSPs to regenerate, nothing todo.",
@ -1597,7 +1567,7 @@ static void lsp_build_pseudo(struct isis_lsp *lsp, struct isis_circuit *circuit,
int lsp_generate_pseudo(struct isis_circuit *circuit, int level)
{
dict_t *lspdb = circuit->area->lspdb[level - 1];
struct lspdb_head *head = &circuit->area->lspdb[level - 1];
struct isis_lsp *lsp;
uint8_t lsp_id[ISIS_SYS_ID_LEN + 2];
uint16_t rem_lifetime, refresh_time;
@ -1615,7 +1585,7 @@ int lsp_generate_pseudo(struct isis_circuit *circuit, int level)
/*
* If for some reason have a pseudo LSP in the db already -> regenerate
*/
if (lsp_search(lsp_id, lspdb))
if (lsp_search(head, lsp_id))
return lsp_regenerate_schedule_pseudo(circuit, level);
rem_lifetime = lsp_rem_lifetime(circuit->area, level);
@ -1628,7 +1598,7 @@ int lsp_generate_pseudo(struct isis_circuit *circuit, int level)
lsp_build_pseudo(lsp, circuit, level);
lsp_pack_pdu(lsp);
lsp->own_lsp = 1;
lsp_insert(lsp, lspdb);
lsp_insert(head, lsp);
lsp_flood(lsp, NULL);
refresh_time = lsp_refresh_time(lsp, rem_lifetime);
@ -1659,7 +1629,7 @@ int lsp_generate_pseudo(struct isis_circuit *circuit, int level)
static int lsp_regenerate_pseudo(struct isis_circuit *circuit, int level)
{
dict_t *lspdb = circuit->area->lspdb[level - 1];
struct lspdb_head *head = &circuit->area->lspdb[level - 1];
struct isis_lsp *lsp;
uint8_t lsp_id[ISIS_SYS_ID_LEN + 2];
uint16_t rem_lifetime, refresh_time;
@ -1674,7 +1644,7 @@ static int lsp_regenerate_pseudo(struct isis_circuit *circuit, int level)
LSP_PSEUDO_ID(lsp_id) = circuit->circuit_id;
LSP_FRAGMENT(lsp_id) = 0;
lsp = lsp_search(lsp_id, lspdb);
lsp = lsp_search(head, lsp_id);
if (!lsp) {
flog_err(EC_LIB_DEVELOPMENT,
@ -1813,7 +1783,7 @@ int lsp_regenerate_schedule_pseudo(struct isis_circuit *circuit, int level)
continue;
}
lsp = lsp_search(lsp_id, circuit->area->lspdb[lvl - 1]);
lsp = lsp_search(&circuit->area->lspdb[lvl - 1], lsp_id);
if (!lsp) {
sched_debug(
"ISIS (%s): Pseudonode LSP does not exist yet, nothing to regenerate.",
@ -1869,7 +1839,6 @@ int lsp_tick(struct thread *thread)
{
struct isis_area *area;
struct isis_lsp *lsp;
dnode_t *dnode, *dnode_next;
int level;
uint16_t rem_lifetime;
bool fabricd_sync_incomplete = false;
@ -1885,83 +1854,69 @@ int lsp_tick(struct thread *thread)
* Remove LSPs which have aged out
*/
for (level = 0; level < ISIS_LEVELS; level++) {
if (area->lspdb[level] && dict_count(area->lspdb[level]) > 0) {
for (dnode = dict_first(area->lspdb[level]);
dnode != NULL; dnode = dnode_next) {
dnode_next =
dict_next(area->lspdb[level], dnode);
lsp = dnode_get(dnode);
struct isis_lsp *next = lspdb_first(&area->lspdb[level]);
for_each_from (lspdb, &area->lspdb[level], lsp, next) {
/*
* The lsp rem_lifetime is kept at 0 for MaxAge
* or
* ZeroAgeLifetime depending on explicit purge
* or
* natural age out. So schedule spf only once
* when
* the first time rem_lifetime becomes 0.
*/
rem_lifetime = lsp->hdr.rem_lifetime;
lsp_set_time(lsp);
/*
* The lsp rem_lifetime is kept at 0 for MaxAge
* or
* ZeroAgeLifetime depending on explicit purge
* or
* natural age out. So schedule spf only once
* when
* the first time rem_lifetime becomes 0.
/*
* Schedule may run spf which should be done
* only after
* the lsp rem_lifetime becomes 0 for the first
* time.
* ISO 10589 - 7.3.16.4 first paragraph.
*/
if (rem_lifetime == 1 && lsp->hdr.seqno != 0) {
/* 7.3.16.4 a) set SRM flags on all */
/* 7.3.16.4 b) retain only the header */
if (lsp->area->purge_originator)
lsp_purge(lsp, lsp->level, NULL);
else
lsp_flood(lsp, NULL);
/* 7.3.16.4 c) record the time to purge
* FIXME */
isis_spf_schedule(lsp->area, lsp->level);
}
if (lsp->age_out == 0) {
zlog_debug(
"ISIS-Upd (%s): L%u LSP %s seq "
"0x%08" PRIx32 " aged out",
area->area_tag, lsp->level,
rawlspid_print(lsp->hdr.lsp_id),
lsp->hdr.seqno);
/* if we're aging out fragment 0, lsp_destroy()
* below will delete all other fragments too,
* so we need to skip over those
*/
rem_lifetime = lsp->hdr.rem_lifetime;
lsp_set_time(lsp);
if (!LSP_FRAGMENT(lsp->hdr.lsp_id))
while (next &&
!memcmp(next->hdr.lsp_id,
lsp->hdr.lsp_id,
ISIS_SYS_ID_LEN + 1))
next = lspdb_next(
&area->lspdb[level],
next);
/*
* Schedule may run spf which should be done
* only after
* the lsp rem_lifetime becomes 0 for the first
* time.
* ISO 10589 - 7.3.16.4 first paragraph.
*/
if (rem_lifetime == 1 && lsp->hdr.seqno != 0) {
/* 7.3.16.4 a) set SRM flags on all */
/* 7.3.16.4 b) retain only the header */
if (lsp->area->purge_originator)
lsp_purge(lsp, lsp->level, NULL);
else
lsp_flood(lsp, NULL);
/* 7.3.16.4 c) record the time to purge
* FIXME */
isis_spf_schedule(lsp->area, lsp->level);
}
lspdb_del(&area->lspdb[level], lsp);
lsp_destroy(lsp);
lsp = NULL;
}
if (lsp->age_out == 0) {
zlog_debug(
"ISIS-Upd (%s): L%u LSP %s seq "
"0x%08" PRIx32 " aged out",
area->area_tag, lsp->level,
rawlspid_print(lsp->hdr.lsp_id),
lsp->hdr.seqno);
/* if we're aging out fragment 0,
* lsp_destroy() below will delete all
* other fragments too, so we need to
* skip over those
*/
while (!LSP_FRAGMENT(lsp->hdr.lsp_id)
&& dnode_next) {
struct isis_lsp *nextlsp;
nextlsp = dnode_get(dnode_next);
if (memcmp(nextlsp->hdr.lsp_id,
lsp->hdr.lsp_id,
ISIS_SYS_ID_LEN + 1))
break;
dnode_next = dict_next(
area->lspdb[level],
dnode_next);
}
lsp_destroy(lsp);
lsp = NULL;
dict_delete_free(area->lspdb[level],
dnode);
}
if (fabricd_init_c && lsp) {
fabricd_sync_incomplete |=
ISIS_CHECK_FLAG(lsp->SSNflags,
fabricd_init_c);
}
if (fabricd_init_c && lsp) {
fabricd_sync_incomplete |=
ISIS_CHECK_FLAG(lsp->SSNflags,
fabricd_init_c);
}
}
}
@ -1979,7 +1934,7 @@ void lsp_purge_pseudo(uint8_t *id, struct isis_circuit *circuit, int level)
{
struct isis_lsp *lsp;
lsp = lsp_search(id, circuit->area->lspdb[level - 1]);
lsp = lsp_search(&circuit->area->lspdb[level - 1], id);
if (!lsp)
return;
@ -2012,7 +1967,7 @@ void lsp_purge_non_exist(int level, struct isis_lsp_hdr *hdr,
lsp_pack_pdu(lsp);
lsp_insert(lsp, area->lspdb[lsp->level - 1]);
lsp_insert(&area->lspdb[lsp->level - 1], lsp);
lsp_flood(lsp, NULL);
return;

View File

@ -24,13 +24,18 @@
#ifndef _ZEBRA_ISIS_LSP_H
#define _ZEBRA_ISIS_LSP_H
#include "lib/typesafe.h"
#include "isisd/isis_pdu.h"
PREDECL_RBTREE_UNIQ(lspdb)
/* Structure for isis_lsp, this structure will only support the fixed
* System ID (Currently 6) (atleast for now). In order to support more
* We will have to split the header into two parts, and for readability
* sake it should better be avoided */
struct isis_lsp {
struct lspdb_item dbe;
struct isis_lsp_hdr hdr;
struct stream *pdu; /* full pdu lsp */
union {
@ -54,8 +59,11 @@ struct isis_lsp {
bool flooding_circuit_scoped;
};
dict_t *lsp_db_init(void);
void lsp_db_destroy(dict_t *lspdb);
extern int lspdb_compare(const struct isis_lsp *a, const struct isis_lsp *b);
DECLARE_RBTREE_UNIQ(lspdb, struct isis_lsp, dbe, lspdb_compare)
void lsp_db_init(struct lspdb_head *head);
void lsp_db_fini(struct lspdb_head *head);
int lsp_tick(struct thread *thread);
int lsp_generate(struct isis_area *area, int level);
@ -76,14 +84,16 @@ struct isis_lsp *lsp_new_from_recv(struct isis_lsp_hdr *hdr,
struct isis_tlvs *tlvs,
struct stream *stream, struct isis_lsp *lsp0,
struct isis_area *area, int level);
void lsp_insert(struct isis_lsp *lsp, dict_t *lspdb);
struct isis_lsp *lsp_search(uint8_t *id, dict_t *lspdb);
void lsp_insert(struct lspdb_head *head, struct isis_lsp *lsp);
struct isis_lsp *lsp_search(struct lspdb_head *head, const uint8_t *id);
void lsp_build_list(uint8_t *start_id, uint8_t *stop_id, uint8_t num_lsps,
struct list *list, dict_t *lspdb);
void lsp_build_list_nonzero_ht(uint8_t *start_id, uint8_t *stop_id,
struct list *list, dict_t *lspdb);
void lsp_search_and_destroy(uint8_t *id, dict_t *lspdb);
void lsp_build_list(struct lspdb_head *head, const uint8_t *start_id,
const uint8_t *stop_id, uint8_t num_lsps,
struct list *list);
void lsp_build_list_nonzero_ht(struct lspdb_head *head,
const uint8_t *start_id,
const uint8_t *stop_id, struct list *list);
void lsp_search_and_destroy(struct lspdb_head *head, const uint8_t *id);
void lsp_purge_pseudo(uint8_t *id, struct isis_circuit *circuit, int level);
void lsp_purge_non_exist(int level, struct isis_lsp_hdr *hdr,
struct isis_area *area);
@ -108,7 +118,8 @@ void lsp_inc_seqno(struct isis_lsp *lsp, uint32_t seqno);
void lspid_print(uint8_t *lsp_id, char *dest, char dynhost, char frag);
void lsp_print(struct isis_lsp *lsp, struct vty *vty, char dynhost);
void lsp_print_detail(struct isis_lsp *lsp, struct vty *vty, char dynhost);
int lsp_print_all(struct vty *vty, dict_t *lspdb, char detail, char dynhost);
int lsp_print_all(struct vty *vty, struct lspdb_head *head, char detail,
char dynhost);
/* sets SRMflags for all active circuits of an lsp */
void lsp_set_all_srmflags(struct isis_lsp *lsp, bool set);

View File

@ -41,7 +41,6 @@
#include "qobj.h"
#include "libfrr.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"

View File

@ -30,7 +30,6 @@
#include "command.h"
#include "log_int.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"

View File

@ -25,7 +25,6 @@
#include "libfrr.h"
#include "linklist.h"
#include "log.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"

View File

@ -36,7 +36,6 @@
#include "md5.h"
#include "lib_errors.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"
@ -959,7 +958,7 @@ static int process_lsp(uint8_t pdu_type, struct isis_circuit *circuit,
/* Find the LSP in our database and compare it to this Link State header
*/
struct isis_lsp *lsp =
lsp_search(hdr.lsp_id, circuit->area->lspdb[level - 1]);
lsp_search(&circuit->area->lspdb[level - 1], hdr.lsp_id);
int comp = 0;
if (lsp)
comp = lsp_compare(circuit->area->area_tag, lsp, hdr.seqno,
@ -1186,7 +1185,7 @@ dontcheckadj:
memcpy(lspid, hdr.lsp_id, ISIS_SYS_ID_LEN + 1);
LSP_FRAGMENT(lspid) = 0;
lsp0 = lsp_search(
lspid, circuit->area->lspdb[level - 1]);
&circuit->area->lspdb[level - 1], lspid);
if (!lsp0) {
zlog_debug(
"Got lsp frag, while zero lsp not in database");
@ -1199,8 +1198,8 @@ dontcheckadj:
&hdr, tlvs, circuit->rcv_stream, lsp0,
circuit->area, level);
tlvs = NULL;
lsp_insert(lsp,
circuit->area->lspdb[level - 1]);
lsp_insert(&circuit->area->lspdb[level - 1],
lsp);
} else /* exists, so we overwrite */
{
lsp_update(lsp, &hdr, tlvs, circuit->rcv_stream,
@ -1416,7 +1415,7 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
for (struct isis_lsp_entry *entry = entry_head; entry;
entry = entry->next) {
struct isis_lsp *lsp =
lsp_search(entry->id, circuit->area->lspdb[level - 1]);
lsp_search(&circuit->area->lspdb[level - 1], entry->id);
bool own_lsp = !memcmp(entry->id, isis->sysid, ISIS_SYS_ID_LEN);
if (lsp) {
/* 7.3.15.2 b) 1) is this LSP newer */
@ -1467,8 +1466,8 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
ISIS_SYS_ID_LEN + 1);
LSP_FRAGMENT(lspid) = 0;
lsp0 = lsp_search(
lspid,
circuit->area->lspdb[level - 1]);
&circuit->area->lspdb[level - 1],
lspid);
if (!lsp0) {
zlog_debug("Got lsp frag in snp, while zero not in database");
continue;
@ -1477,8 +1476,8 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
lsp = lsp_new(circuit->area, entry->id,
entry->rem_lifetime, 0, 0,
entry->checksum, lsp0, level);
lsp_insert(lsp,
circuit->area->lspdb[level - 1]);
lsp_insert(&circuit->area->lspdb[level - 1],
lsp);
lsp_set_all_srmflags(lsp, false);
ISIS_SET_FLAG(lsp->SSNflags, circuit);
@ -1495,8 +1494,8 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
* start_lsp_id and stop_lsp_id
*/
struct list *lsp_list = list_new();
lsp_build_list_nonzero_ht(start_lsp_id, stop_lsp_id, lsp_list,
circuit->area->lspdb[level - 1]);
lsp_build_list_nonzero_ht(&circuit->area->lspdb[level - 1],
start_lsp_id, stop_lsp_id, lsp_list);
/* Fixme: Find a better solution */
struct listnode *node, *nnode;
@ -2040,8 +2039,7 @@ static uint16_t get_max_lsp_count(uint16_t size)
int send_csnp(struct isis_circuit *circuit, int level)
{
if (circuit->area->lspdb[level - 1] == NULL
|| dict_count(circuit->area->lspdb[level - 1]) == 0)
if (lspdb_count(&circuit->area->lspdb[level - 1]) == 0)
return ISIS_OK;
uint8_t pdu_type = (level == ISIS_LEVEL1) ? L1_COMPLETE_SEQ_NUM
@ -2094,7 +2092,7 @@ int send_csnp(struct isis_circuit *circuit, int level)
struct isis_lsp *last_lsp;
isis_tlvs_add_csnp_entries(tlvs, start, stop, num_lsps,
circuit->area->lspdb[level - 1],
&circuit->area->lspdb[level - 1],
&last_lsp);
/*
* Update the stop lsp_id before encoding this CSNP.
@ -2215,8 +2213,7 @@ static int send_psnp(int level, struct isis_circuit *circuit)
&& circuit->u.bc.is_dr[level - 1])
return ISIS_OK;
if (circuit->area->lspdb[level - 1] == NULL
|| dict_count(circuit->area->lspdb[level - 1]) == 0)
if (lspdb_count(&circuit->area->lspdb[level - 1]) == 0)
return ISIS_OK;
if (!circuit->snd_stream)
@ -2254,16 +2251,13 @@ static int send_psnp(int level, struct isis_circuit *circuit)
get_max_lsp_count(STREAM_WRITEABLE(circuit->snd_stream));
while (1) {
struct isis_lsp *lsp;
tlvs = isis_alloc_tlvs();
if (CHECK_FLAG(passwd->snp_auth, SNP_AUTH_SEND))
isis_tlvs_add_auth(tlvs, passwd);
for (dnode_t *dnode =
dict_first(circuit->area->lspdb[level - 1]);
dnode; dnode = dict_next(circuit->area->lspdb[level - 1],
dnode)) {
struct isis_lsp *lsp = dnode_get(dnode);
for_each (lspdb, &circuit->area->lspdb[level - 1], lsp) {
if (ISIS_CHECK_FLAG(lsp->SSNflags, circuit))
isis_tlvs_add_lsp_entry(tlvs, lsp);

View File

@ -33,7 +33,6 @@
#include "if.h"
#include "lib_errors.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_circuit.h"

View File

@ -32,7 +32,6 @@
#include "vty.h"
#include "srcdest_table.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"

View File

@ -38,7 +38,6 @@
#include "isis_constants.h"
#include "isis_common.h"
#include "isis_flags.h"
#include "dict.h"
#include "isisd.h"
#include "isis_misc.h"
#include "isis_adjacency.h"

View File

@ -37,7 +37,6 @@
#include "isis_constants.h"
#include "isis_common.h"
#include "isis_flags.h"
#include "dict.h"
#include "isisd.h"
#include "isis_misc.h"
#include "isis_adjacency.h"

View File

@ -39,7 +39,6 @@
#include "isis_constants.h"
#include "isis_common.h"
#include "isis_flags.h"
#include "dict.h"
#include "isisd.h"
#include "isis_misc.h"
#include "isis_adjacency.h"
@ -313,7 +312,7 @@ static struct isis_lsp *isis_root_system_lsp(struct isis_area *area, int level,
memcpy(lspid, sysid, ISIS_SYS_ID_LEN);
LSP_PSEUDO_ID(lspid) = 0;
LSP_FRAGMENT(lspid) = 0;
lsp = lsp_search(lspid, area->lspdb[level - 1]);
lsp = lsp_search(&area->lspdb[level - 1], lspid);
if (lsp && lsp->hdr.rem_lifetime != 0)
return lsp;
return NULL;
@ -870,10 +869,8 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
[spftree->level - 1],
parent);
lsp = lsp_search(
lsp_id,
spftree->area
->lspdb[spftree->level
- 1]);
&spftree->area->lspdb[spftree->level- 1],
lsp_id);
if (lsp == NULL
|| lsp->hdr.rem_lifetime == 0)
zlog_warn(
@ -923,8 +920,8 @@ static int isis_spf_preload_tent(struct isis_spftree *spftree,
continue;
}
lsp = lsp_search(
lsp_id,
spftree->area->lspdb[spftree->level - 1]);
&spftree->area->lspdb[spftree->level - 1],
lsp_id);
if (lsp == NULL || lsp->hdr.rem_lifetime == 0) {
zlog_warn(
"ISIS-Spf: No lsp (%p) found from root "

View File

@ -347,8 +347,8 @@ static struct isis_lsp *lsp_for_vertex(struct isis_spftree *spftree,
memcpy(lsp_id, vertex->N.id, ISIS_SYS_ID_LEN + 1);
LSP_FRAGMENT(lsp_id) = 0;
dict_t *lspdb = spftree->area->lspdb[spftree->level - 1];
struct isis_lsp *lsp = lsp_search(lsp_id, lspdb);
struct lspdb_head *lspdb = &spftree->area->lspdb[spftree->level - 1];
struct isis_lsp *lsp = lsp_search(lspdb, lsp_id);
if (lsp && lsp->hdr.rem_lifetime != 0)
return lsp;

View File

@ -43,7 +43,6 @@
#include "network.h"
#include "sbuf.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"

View File

@ -3522,26 +3522,24 @@ void isis_tlvs_add_lsp_entry(struct isis_tlvs *tlvs, struct isis_lsp *lsp)
void isis_tlvs_add_csnp_entries(struct isis_tlvs *tlvs, uint8_t *start_id,
uint8_t *stop_id, uint16_t num_lsps,
dict_t *lspdb, struct isis_lsp **last_lsp)
struct lspdb_head *head,
struct isis_lsp **last_lsp)
{
dnode_t *first = dict_lower_bound(lspdb, start_id);
struct isis_lsp searchfor;
struct isis_lsp *first, *lsp;
memcpy(&searchfor.hdr.lsp_id, start_id, sizeof(searchfor.hdr.lsp_id));
first = lspdb_find_gteq(head, &searchfor);
if (!first)
return;
dnode_t *last = dict_upper_bound(lspdb, stop_id);
dnode_t *curr = first;
isis_tlvs_add_lsp_entry(tlvs, first->dict_data);
*last_lsp = first->dict_data;
while (curr) {
curr = dict_next(lspdb, curr);
if (curr) {
isis_tlvs_add_lsp_entry(tlvs, curr->dict_data);
*last_lsp = curr->dict_data;
}
if (curr == last || tlvs->lsp_entries.count == num_lsps)
for_each_from (lspdb, head, lsp, first) {
if (memcmp(lsp->hdr.lsp_id, stop_id, sizeof(lsp->hdr.lsp_id))
> 0 || tlvs->lsp_entries.count == num_lsps)
break;
isis_tlvs_add_lsp_entry(tlvs, lsp);
*last_lsp = lsp;
}
}

View File

@ -25,8 +25,8 @@
#include "openbsd-tree.h"
#include "prefix.h"
#include "isisd/dict.h"
struct lspdb_head;
struct isis_subtlvs;
struct isis_area_address;
@ -355,7 +355,8 @@ bool isis_tlvs_own_snpa_found(struct isis_tlvs *tlvs, uint8_t *snpa);
void isis_tlvs_add_lsp_entry(struct isis_tlvs *tlvs, struct isis_lsp *lsp);
void isis_tlvs_add_csnp_entries(struct isis_tlvs *tlvs, uint8_t *start_id,
uint8_t *stop_id, uint16_t num_lsps,
dict_t *lspdb, struct isis_lsp **last_lsp);
struct lspdb_head *lspdb,
struct isis_lsp **last_lsp);
void isis_tlvs_set_dynamic_hostname(struct isis_tlvs *tlvs,
const char *hostname);
void isis_tlvs_set_te_router_id(struct isis_tlvs *tlvs,

View File

@ -27,7 +27,6 @@
#include "isisd/isisd.h"
#include "isisd/isis_memory.h"
#include "isisd/isis_flags.h"
#include "dict.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_lsp.h"
#include "isisd/isis_misc.h"

View File

@ -161,13 +161,14 @@ DEFUN (show_lsp_flooding,
struct isis_area *area;
for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) {
dict_t *lspdb = area->lspdb[ISIS_LEVEL2 - 1];
struct lspdb_head *head = &area->lspdb[ISIS_LEVEL2 - 1];
struct isis_lsp *lsp;
vty_out(vty, "Area %s:\n", area->area_tag ?
area->area_tag : "null");
if (lspid) {
struct isis_lsp *lsp = lsp_for_arg(lspid, lspdb);
struct isis_lsp *lsp = lsp_for_arg(head, lspid);
if (lsp)
lsp_print_flooding(vty, lsp);
@ -175,9 +176,8 @@ DEFUN (show_lsp_flooding,
continue;
}
for (dnode_t *dnode = dict_first(lspdb); dnode;
dnode = dict_next(lspdb, dnode)) {
lsp_print_flooding(vty, dnode_get(dnode));
for_each (lspdb, head, lsp) {
lsp_print_flooding(vty, lsp);
vty_out(vty, "\n");
}
}

View File

@ -37,7 +37,6 @@
#include "vrf.h"
#include "libfrr.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"

View File

@ -38,7 +38,6 @@
#include "spf_backoff.h"
#include "lib/northbound_cli.h"
#include "isisd/dict.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"
@ -122,12 +121,10 @@ struct isis_area *isis_area_create(const char *area_tag)
/*
* intialize the databases
*/
if (area->is_type & IS_LEVEL_1) {
area->lspdb[0] = lsp_db_init();
}
if (area->is_type & IS_LEVEL_2) {
area->lspdb[1] = lsp_db_init();
}
if (area->is_type & IS_LEVEL_1)
lsp_db_init(&area->lspdb[0]);
if (area->is_type & IS_LEVEL_2)
lsp_db_init(&area->lspdb[1]);
spftree_area_init(area);
@ -268,14 +265,8 @@ int isis_area_destroy(const char *area_tag)
list_delete(&area->circuit_list);
}
if (area->lspdb[0] != NULL) {
lsp_db_destroy(area->lspdb[0]);
area->lspdb[0] = NULL;
}
if (area->lspdb[1] != NULL) {
lsp_db_destroy(area->lspdb[1]);
area->lspdb[1] = NULL;
}
lsp_db_fini(&area->lspdb[0]);
lsp_db_fini(&area->lspdb[1]);
/* invalidate and verify to delete all routes from zebra */
isis_area_invalidate_routes(area, ISIS_LEVEL1 & ISIS_LEVEL2);
@ -1341,7 +1332,7 @@ DEFUN (show_isis_summary,
return CMD_SUCCESS;
}
struct isis_lsp *lsp_for_arg(const char *argv, dict_t *lspdb)
struct isis_lsp *lsp_for_arg(struct lspdb_head *head, const char *argv)
{
char sysid[255] = {0};
uint8_t number[3];
@ -1389,13 +1380,13 @@ struct isis_lsp *lsp_for_arg(const char *argv, dict_t *lspdb)
* hostname.<pseudo-id>-<fragment>
*/
if (sysid2buff(lspid, sysid)) {
lsp = lsp_search(lspid, lspdb);
lsp = lsp_search(head, lspid);
} else if ((dynhn = dynhn_find_by_name(sysid))) {
memcpy(lspid, dynhn->id, ISIS_SYS_ID_LEN);
lsp = lsp_search(lspid, lspdb);
lsp = lsp_search(head, lspid);
} else if (strncmp(cmd_hostname_get(), sysid, 15) == 0) {
memcpy(lspid, isis->sysid, ISIS_SYS_ID_LEN);
lsp = lsp_search(lspid, lspdb);
lsp = lsp_search(head, lspid);
}
return lsp;
@ -1432,9 +1423,8 @@ static int show_isis_database(struct vty *vty, const char *argv, int ui_level)
area->area_tag ? area->area_tag : "null");
for (level = 0; level < ISIS_LEVELS; level++) {
if (area->lspdb[level]
&& dict_count(area->lspdb[level]) > 0) {
lsp = lsp_for_arg(argv, area->lspdb[level]);
if (lspdb_count(&area->lspdb[level]) > 0) {
lsp = lsp_for_arg(&area->lspdb[level], argv);
if (lsp != NULL || argv == NULL) {
vty_out(vty,
@ -1456,7 +1446,7 @@ static int show_isis_database(struct vty *vty, const char *argv, int ui_level)
area->dynhostname);
} else if (argv == NULL) {
lsp_count = lsp_print_all(
vty, area->lspdb[level],
vty, &area->lspdb[level],
ui_level, area->dynhostname);
vty_out(vty, " %u LSPs\n\n",
@ -1696,10 +1686,7 @@ static void area_resign_level(struct isis_area *area, int level)
isis_area_invalidate_routes(area, level);
isis_area_verify_routes(area);
if (area->lspdb[level - 1]) {
lsp_db_destroy(area->lspdb[level - 1]);
area->lspdb[level - 1] = NULL;
}
lsp_db_fini(&area->lspdb[level - 1]);
for (int tree = SPFTREE_IPV4; tree < SPFTREE_COUNT; tree++) {
if (area->spftree[tree][level - 1]) {
@ -1735,8 +1722,7 @@ void isis_area_is_type_set(struct isis_area *area, int is_type)
if (is_type == IS_LEVEL_2)
area_resign_level(area, IS_LEVEL_1);
if (area->lspdb[1] == NULL)
area->lspdb[1] = lsp_db_init();
lsp_db_init(&area->lspdb[1]);
break;
case IS_LEVEL_1_AND_2:
@ -1750,8 +1736,7 @@ void isis_area_is_type_set(struct isis_area *area, int is_type)
if (is_type == IS_LEVEL_1)
area_resign_level(area, IS_LEVEL_2);
if (area->lspdb[0] == NULL)
area->lspdb[0] = lsp_db_init();
lsp_db_init(&area->lspdb[0]);
break;
default:

View File

@ -31,7 +31,7 @@
#include "isisd/isis_pdu_counter.h"
#include "isisd/isis_circuit.h"
#include "isis_flags.h"
#include "dict.h"
#include "isis_lsp.h"
#include "isis_memory.h"
#include "qobj.h"
@ -107,7 +107,7 @@ enum isis_metric_style {
struct isis_area {
struct isis *isis; /* back pointer */
dict_t *lspdb[ISIS_LEVELS]; /* link-state dbs */
struct lspdb_head lspdb[ISIS_LEVELS]; /* link-state dbs */
struct isis_spftree *spftree[SPFTREE_COUNT][ISIS_LEVELS];
#define DEFAULT_LSP_MTU 1497
unsigned int lsp_mtu; /* Size of LSPs to generate */
@ -195,7 +195,7 @@ struct isis_area *isis_area_lookup(const char *);
int isis_area_get(struct vty *vty, const char *area_tag);
int isis_area_destroy(const char *area_tag);
void print_debug(struct vty *, int, int);
struct isis_lsp *lsp_for_arg(const char *argv, dict_t *lspdb);
struct isis_lsp *lsp_for_arg(struct lspdb_head *head, const char *argv);
void isis_area_invalidate_routes(struct isis_area *area, int levels);
void isis_area_verify_routes(struct isis_area *area);

View File

@ -25,7 +25,6 @@ dist_examples_DATA += isisd/fabricd.conf.sample
endif
noinst_HEADERS += \
isisd/dict.h \
isisd/isis_adjacency.h \
isisd/isis_bfd.h \
isisd/isis_circuit.h \
@ -61,7 +60,6 @@ noinst_HEADERS += \
# end
LIBISIS_SOURCES = \
isisd/dict.c \
isisd/isis_adjacency.c \
isisd/isis_bfd.c \
isisd/isis_circuit.c \

View File

@ -28,21 +28,22 @@ static void test_lsp_build_list_nonzero_ht(void)
area->lsp_mtu = 1500;
dict_t *lspdb = lsp_db_init();
struct lspdb_head _lspdb, *lspdb = &_lspdb;
lsp_db_init(&_lspdb);
struct isis_lsp *lsp1 = lsp_new(area, lsp_id1, 6000, 0, 0, 0, NULL,
ISIS_LEVEL2);
lsp_insert(lsp1, lspdb);
lsp_insert(lspdb, lsp1);
struct isis_lsp *lsp2 = lsp_new(area, lsp_id2, 6000, 0, 0, 0, NULL,
ISIS_LEVEL2);
lsp_insert(lsp2, lspdb);
lsp_insert(lspdb, lsp2);
struct list *list = list_new();
lsp_build_list_nonzero_ht(lsp_id1, lsp_id_end, list, lspdb);
lsp_build_list_nonzero_ht(lspdb, lsp_id1, lsp_id_end, list);
assert(list->count == 1);
assert(listgetdata(listhead(list)) == lsp1);
list_delete_all_node(list);
@ -50,7 +51,7 @@ static void test_lsp_build_list_nonzero_ht(void)
lsp_id_end[5] = 0x03;
lsp_id_end[6] = 0x00;
lsp_build_list_nonzero_ht(lsp_id1, lsp_id_end, list, lspdb);
lsp_build_list_nonzero_ht(lspdb, lsp_id1, lsp_id_end, list);
assert(list->count == 2);
assert(listgetdata(listhead(list)) == lsp1);
assert(listgetdata(listtail(list)) == lsp2);
@ -58,7 +59,7 @@ static void test_lsp_build_list_nonzero_ht(void)
memcpy(lsp_id1, lsp_id2, sizeof(lsp_id1));
lsp_build_list_nonzero_ht(lsp_id1, lsp_id_end, list, lspdb);
lsp_build_list_nonzero_ht(lspdb, lsp_id1, lsp_id_end, list);
assert(list->count == 1);
assert(listgetdata(listhead(list)) == lsp2);
list_delete_all_node(list);
@ -66,13 +67,13 @@ static void test_lsp_build_list_nonzero_ht(void)
lsp_id1[5] = 0x03;
lsp_id_end[5] = 0x04;
lsp_build_list_nonzero_ht(lsp_id1, lsp_id_end, list, lspdb);
lsp_build_list_nonzero_ht(lspdb, lsp_id1, lsp_id_end, list);
assert(list->count == 0);
list_delete_all_node(list);
lsp_id1[5] = 0x00;
lsp_build_list_nonzero_ht(lsp_id1, lsp_id_end, list, lspdb);
lsp_build_list_nonzero_ht(lspdb, lsp_id1, lsp_id_end, list);
assert(list->count == 2);
assert(listgetdata(listhead(list)) == lsp1);
assert(listgetdata(listtail(list)) == lsp2);