mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-01 03:36:03 +00:00
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:
parent
798ac49d06
commit
4bef0ec4fb
13
debian/copyright
vendored
13
debian/copyright
vendored
@ -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.
|
||||
|
1510
isisd/dict.c
1510
isisd/dict.c
File diff suppressed because it is too large
Load Diff
121
isisd/dict.h
121
isisd/dict.h
@ -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
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
295
isisd/isis_lsp.c
295
isisd/isis_lsp.c
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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 "
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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"
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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 \
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user