[isisd] Bug #437: fix ssert caused by bad list management
2008-01-29 James Carlson <james.d.carlson@sun.com>
* Fix bug #437, assert due to bogus index management
* isis_flags.c: (flags_initialize) new
* (flags_get_index) fix off by one, leading to list assert
on null node data.
(flags_free_index) ditto.
* isisd.c: (isis_area_create) use flags_initialize
(isis_area_destroy) deconfigure circuits when
taking down area.
diff --git a/isisd/ChangeLog b/isisd/ChangeLog
index c2482f0..bb77ffe 100644
--- a/isisd/ChangeLog
+++ b/isisd/ChangeLog
@@ -1,3 +1,14 @@
+2008-01-29 James Carlson <james.d.carlson@sun.com>
+
+ * Fix bug #437, assert due to bogus index management
+ * isis_flags.c: (flags_initialize) new
+ * (flags_get_index) fix off by one, leading to list assert
+ on null node data.
+ (flags_free_index) ditto.
+ * isisd.c: (isis_area_create) use flags_initialize
+ (isis_area_destroy) deconfigure circuits when
+ taking down area.
+
2007-07-18 James Carlson <james.d.carlson@sun.com>
* isis_network.c: split up into isis_bpf.c, isis_dlpi.c, and
diff --git a/isisd/isis_flags.c b/isisd/isis_flags.c
index 9c861c9..03c9110 100644
--- a/isisd/isis_flags.c
+++ b/isisd/isis_flags.c
@@ -29,6 +29,13 @@
#include "isisd/isis_common.h"
#include "isisd/isis_flags.h"
+void
+flags_initialize (struct flags *flags)
+{
+ flags->maxindex = 0;
+ flags->free_idcs = NULL;
+}
+
int
flags_get_index (struct flags *flags)
{
@@ -37,14 +44,14 @@
if (flags->free_idcs == NULL || flags->free_idcs->count == 0)
{
- flags->maxindex++;
- index = flags->maxindex;
+ index = flags->maxindex++;
}
else
{
node = listhead (flags->free_idcs);
index = (int) listgetdata (node);
listnode_delete (flags->free_idcs, (void *) index);
+ index--;
}
return index;
@@ -53,12 +60,18 @@
void
flags_free_index (struct flags *flags, int index)
{
+ if (index + 1 == flags->maxindex)
+ {
+ flags->maxindex--;
+ return;
+ }
+
if (flags->free_idcs == NULL)
{
flags->free_idcs = list_new ();
}
- listnode_add (flags->free_idcs, (void *) index);
+ listnode_add (flags->free_idcs, (void *) (index + 1));
return;
}
diff --git a/isisd/isis_flags.h b/isisd/isis_flags.h
index f2421f2..13dd9e1 100644
--- a/isisd/isis_flags.h
+++ b/isisd/isis_flags.h
@@ -28,6 +28,7 @@
* the support will be achived using the newest drafts */
#define ISIS_MAX_CIRCUITS 32 /* = 1024 */ /*FIXME:defined in lsp.h as well */
+void flags_initialize (struct flags *flags);
struct flags *new_flags (int size);
int flags_get_index (struct flags *flags);
void flags_free_index (struct flags *flags, int index);
diff --git a/isisd/isisd.c b/isisd/isisd.c
index 48ea47a..7c669fc 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -130,7 +130,7 @@
area->circuit_list = list_new ();
area->area_addrs = list_new ();
THREAD_TIMER_ON (master, area->t_tick, lsp_tick, area, 1);
- area->flags.maxindex = -1;
+ flags_initialize (&area->flags);
/*
* Default values
*/
@@ -215,7 +215,11 @@
if (area->circuit_list)
{
for (ALL_LIST_ELEMENTS (area->circuit_list, node, nnode, circuit))
- isis_circuit_del (circuit);
+ {
+ /* The fact that it's in circuit_list means that it was configured */
+ isis_circuit_deconfigure (circuit, area);
+ isis_circuit_del (circuit);
+ }
list_delete (area->circuit_list);
}