summaryrefslogtreecommitdiffstats
path: root/isisd/isis_dynhn.c
diff options
context:
space:
mode:
authorIgor Ryzhov <iryzhov@nfware.com>2021-06-11 17:27:46 +0200
committerIgor Ryzhov <iryzhov@nfware.com>2021-06-11 17:30:47 +0200
commit240f48b36b59bc53599e8df6579513e0d7744680 (patch)
treec12e2c5b6dec823c01b4f37fde490fbc59863e10 /isisd/isis_dynhn.c
parentMerge pull request #8831 from sworleys/Fix-No-Ospf-Func (diff)
downloadfrr-240f48b36b59bc53599e8df6579513e0d7744680.tar.xz
frr-240f48b36b59bc53599e8df6579513e0d7744680.zip
isisd: per-instance dynamic hostname cache
Currently, the dynamic hostname cache is global. It is incorrect because neighbors in different VRFs may have the same system ID and different hostnames. This also fixes a memory leak - when the instance is deleted, the cache must be cleaned up and the cleanup thread must be cancelled. Fixes #8832. Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
Diffstat (limited to 'isisd/isis_dynhn.c')
-rw-r--r--isisd/isis_dynhn.c49
1 files changed, 25 insertions, 24 deletions
diff --git a/isisd/isis_dynhn.c b/isisd/isis_dynhn.c
index decd3e892..ade6e8222 100644
--- a/isisd/isis_dynhn.c
+++ b/isisd/isis_dynhn.c
@@ -42,30 +42,29 @@
DEFINE_MTYPE_STATIC(ISISD, ISIS_DYNHN, "ISIS dyn hostname");
-extern struct host host;
-
-struct list *dyn_cache = NULL;
static int dyn_cache_cleanup(struct thread *);
void dyn_cache_init(struct isis *isis)
{
- if (dyn_cache == NULL)
- dyn_cache = list_new();
+ isis->dyn_cache = list_new();
if (!CHECK_FLAG(im->options, F_ISIS_UNIT_TEST))
thread_add_timer(master, dyn_cache_cleanup, isis, 120,
&isis->t_dync_clean);
- return;
}
-void dyn_cache_cleanup_all(void)
+void dyn_cache_finish(struct isis *isis)
{
struct listnode *node, *nnode;
struct isis_dynhn *dyn;
- for (ALL_LIST_ELEMENTS(dyn_cache, node, nnode, dyn)) {
- list_delete_node(dyn_cache, node);
+ thread_cancel(&isis->t_dync_clean);
+
+ for (ALL_LIST_ELEMENTS(isis->dyn_cache, node, nnode, dyn)) {
+ list_delete_node(isis->dyn_cache, node);
XFREE(MTYPE_ISIS_DYNHN, dyn);
}
+
+ list_delete(&isis->dyn_cache);
}
static int dyn_cache_cleanup(struct thread *thread)
@@ -79,10 +78,10 @@ static int dyn_cache_cleanup(struct thread *thread)
isis->t_dync_clean = NULL;
- for (ALL_LIST_ELEMENTS(dyn_cache, node, nnode, dyn)) {
+ for (ALL_LIST_ELEMENTS(isis->dyn_cache, node, nnode, dyn)) {
if ((now - dyn->refresh) < MAX_LSP_LIFETIME)
continue;
- list_delete_node(dyn_cache, node);
+ list_delete_node(isis->dyn_cache, node);
XFREE(MTYPE_ISIS_DYNHN, dyn);
}
@@ -92,54 +91,55 @@ static int dyn_cache_cleanup(struct thread *thread)
return ISIS_OK;
}
-struct isis_dynhn *dynhn_find_by_id(const uint8_t *id)
+struct isis_dynhn *dynhn_find_by_id(struct isis *isis, const uint8_t *id)
{
struct listnode *node = NULL;
struct isis_dynhn *dyn = NULL;
- for (ALL_LIST_ELEMENTS_RO(dyn_cache, node, dyn))
+ for (ALL_LIST_ELEMENTS_RO(isis->dyn_cache, node, dyn))
if (memcmp(dyn->id, id, ISIS_SYS_ID_LEN) == 0)
return dyn;
return NULL;
}
-struct isis_dynhn *dynhn_find_by_name(const char *hostname)
+struct isis_dynhn *dynhn_find_by_name(struct isis *isis, const char *hostname)
{
struct listnode *node = NULL;
struct isis_dynhn *dyn = NULL;
- for (ALL_LIST_ELEMENTS_RO(dyn_cache, node, dyn))
+ for (ALL_LIST_ELEMENTS_RO(isis->dyn_cache, node, dyn))
if (strncmp(dyn->hostname, hostname, 255) == 0)
return dyn;
return NULL;
}
-void isis_dynhn_insert(const uint8_t *id, const char *hostname, int level)
+void isis_dynhn_insert(struct isis *isis, const uint8_t *id,
+ const char *hostname, int level)
{
struct isis_dynhn *dyn;
- dyn = dynhn_find_by_id(id);
+ dyn = dynhn_find_by_id(isis, id);
if (!dyn) {
dyn = XCALLOC(MTYPE_ISIS_DYNHN, sizeof(struct isis_dynhn));
memcpy(dyn->id, id, ISIS_SYS_ID_LEN);
dyn->level = level;
- listnode_add(dyn_cache, dyn);
+ listnode_add(isis->dyn_cache, dyn);
}
snprintf(dyn->hostname, sizeof(dyn->hostname), "%s", hostname);
dyn->refresh = time(NULL);
}
-void isis_dynhn_remove(const uint8_t *id)
+void isis_dynhn_remove(struct isis *isis, const uint8_t *id)
{
struct isis_dynhn *dyn;
- dyn = dynhn_find_by_id(id);
+ dyn = dynhn_find_by_id(isis, id);
if (!dyn)
return;
- listnode_delete(dyn_cache, dyn);
+ listnode_delete(isis->dyn_cache, dyn);
XFREE(MTYPE_ISIS_DYNHN, dyn);
}
@@ -158,7 +158,7 @@ void dynhn_print_all(struct vty *vty, struct isis *isis)
if (!isis->sysid_set)
return;
vty_out(vty, "Level System ID Dynamic Hostname\n");
- for (ALL_LIST_ELEMENTS_RO(dyn_cache, node, dyn)) {
+ for (ALL_LIST_ELEMENTS_RO(isis->dyn_cache, node, dyn)) {
vty_out(vty, "%-7d", dyn->level);
vty_out(vty, "%-15s%-15s\n", sysid_print(dyn->id),
dyn->hostname);
@@ -169,14 +169,15 @@ void dynhn_print_all(struct vty *vty, struct isis *isis)
return;
}
-struct isis_dynhn *dynhn_snmp_next(const uint8_t *id, int level)
+struct isis_dynhn *dynhn_snmp_next(struct isis *isis, const uint8_t *id,
+ int level)
{
struct listnode *node = NULL;
struct isis_dynhn *dyn = NULL;
struct isis_dynhn *found_dyn = NULL;
int res;
- for (ALL_LIST_ELEMENTS_RO(dyn_cache, node, dyn)) {
+ for (ALL_LIST_ELEMENTS_RO(isis->dyn_cache, node, dyn)) {
res = memcmp(dyn->id, id, ISIS_SYS_ID_LEN);
if (res < 0)