isisd: add Google's changes to IS-IS
diff --git a/isisd/isis_events.c b/isisd/isis_events.c
index 4380092..750a4c3 100644
--- a/isisd/isis_events.c
+++ b/isisd/isis_events.c
@@ -30,11 +30,13 @@
#include "hash.h"
#include "prefix.h"
#include "stream.h"
+#include "table.h"
#include "isisd/dict.h"
#include "isisd/include-netbsd/iso.h"
#include "isisd/isis_constants.h"
#include "isisd/isis_common.h"
+#include "isisd/isis_flags.h"
#include "isisd/isis_circuit.h"
#include "isisd/isis_tlv.h"
#include "isisd/isis_lsp.h"
@@ -44,15 +46,11 @@
#include "isisd/isis_constants.h"
#include "isisd/isis_adjacency.h"
#include "isisd/isis_dr.h"
-#include "isisd/isis_flags.h"
#include "isisd/isisd.h"
#include "isisd/isis_csm.h"
#include "isisd/isis_events.h"
#include "isisd/isis_spf.h"
-extern struct thread_master *master;
-extern struct isis *isis;
-
/* debug isis-spf spf-events
4w4d: ISIS-Spf (tlt): L2 SPF needed, new adjacency, from 0x609229F4
4w4d: ISIS-Spf (tlt): L2, 0000.0000.0042.01-00 TLV contents changed, code 0x2
@@ -62,26 +60,59 @@
*/
void
-isis_event_circuit_state_change (struct isis_circuit *circuit, int up)
+isis_event_circuit_state_change (struct isis_circuit *circuit,
+ struct isis_area *area, int up)
{
- struct isis_area *area;
-
- area = circuit->area;
- assert (area);
area->circuit_state_changes++;
if (isis->debugs & DEBUG_EVENTS)
- zlog_debug ("ISIS-Evt (%s) circuit %s", circuit->area->area_tag,
- up ? "up" : "down");
+ zlog_debug ("ISIS-Evt (%s) circuit %s", area->area_tag,
+ up ? "up" : "down");
/*
* Regenerate LSPs this affects
*/
- lsp_regenerate_schedule (area);
+ lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 0);
return;
}
+static void
+area_resign_level (struct isis_area *area, int level)
+{
+ if (area->lspdb[level - 1])
+ {
+ lsp_db_destroy (area->lspdb[level - 1]);
+ area->lspdb[level - 1] = NULL;
+ }
+ if (area->spftree[level - 1])
+ {
+ isis_spftree_del (area->spftree[level - 1]);
+ area->spftree[level - 1] = NULL;
+ }
+#ifdef HAVE_IPV6
+ if (area->spftree6[level - 1])
+ {
+ isis_spftree_del (area->spftree6[level - 1]);
+ area->spftree6[level - 1] = NULL;
+ }
+#endif
+ if (area->route_table[level - 1])
+ {
+ route_table_finish (area->route_table[level - 1]);
+ area->route_table[level - 1] = NULL;
+ }
+#ifdef HAVE_IPV6
+ if (area->route_table6[level - 1])
+ {
+ route_table_finish (area->route_table6[level - 1]);
+ area->route_table6[level - 1] = NULL;
+ }
+#endif /* HAVE_IPV6 */
+
+ THREAD_TIMER_OFF (area->t_lsp_refresh[level - 1]);
+}
+
void
isis_event_system_type_change (struct isis_area *area, int newtype)
{
@@ -96,47 +127,73 @@
return; /* No change */
switch (area->is_type)
- {
+ {
case IS_LEVEL_1:
- if (area->lspdb[1] == NULL)
- area->lspdb[1] = lsp_db_init ();
- lsp_l2_generate (area);
+ if (newtype == IS_LEVEL_2)
+ {
+ area_resign_level (area, IS_LEVEL_1);
+ }
+ else
+ {
+ if (area->lspdb[1] == NULL)
+ area->lspdb[1] = lsp_db_init ();
+ if (area->route_table[1] == NULL)
+ area->route_table[1] = route_table_init ();
+#ifdef HAVE_IPV6
+ if (area->route_table6[1] == NULL)
+ area->route_table6[1] = route_table_init ();
+#endif /* HAVE_IPV6 */
+ }
break;
+
case IS_LEVEL_1_AND_2:
if (newtype == IS_LEVEL_1)
- {
- lsp_db_destroy (area->lspdb[1]);
- }
+ area_resign_level (area, IS_LEVEL_2);
else
- {
- lsp_db_destroy (area->lspdb[0]);
- }
+ area_resign_level (area, IS_LEVEL_1);
break;
+
case IS_LEVEL_2:
- if (area->lspdb[0] == NULL)
- area->lspdb[0] = lsp_db_init ();
- lsp_l1_generate (area);
+ if (newtype == IS_LEVEL_1)
+ {
+ area_resign_level (area, IS_LEVEL_2);
+ }
+ else
+ {
+ if (area->lspdb[0] == NULL)
+ area->lspdb[0] = lsp_db_init ();
+ if (area->route_table[0] == NULL)
+ area->route_table[0] = route_table_init ();
+#ifdef HAVE_IPV6
+ if (area->route_table6[0] == NULL)
+ area->route_table6[0] = route_table_init ();
+#endif /* HAVE_IPV6 */
+ }
break;
default:
break;
- }
+ }
area->is_type = newtype;
- for (ALL_LIST_ELEMENTS_RO (area->circuit_list, node, circuit))
- isis_event_circuit_type_change (circuit, newtype);
+
+ /* override circuit's is_type */
+ if (area->is_type != IS_LEVEL_1_AND_2)
+ {
+ for (ALL_LIST_ELEMENTS_RO (area->circuit_list, node, circuit))
+ isis_event_circuit_type_change (circuit, newtype);
+ }
spftree_area_init (area);
- lsp_regenerate_schedule (area);
+
+ if (newtype & IS_LEVEL_1)
+ lsp_generate (area, IS_LEVEL_1);
+ if (newtype & IS_LEVEL_2)
+ lsp_generate (area, IS_LEVEL_2);
+ lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1);
return;
}
-void
-isis_event_area_addr_change (struct isis_area *area)
-{
-
-}
-
static void
circuit_commence_level (struct isis_circuit *circuit, int level)
{
@@ -148,7 +205,7 @@
if (circuit->circ_type == CIRCUIT_T_BROADCAST)
{
THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[0], isis_run_dr_l1,
- circuit, 2 * circuit->hello_interval[1]);
+ circuit, 2 * circuit->hello_interval[0]);
THREAD_TIMER_ON (master, circuit->u.bc.t_send_lan_hello[0],
send_lan_l1_hello, circuit,
@@ -194,6 +251,8 @@
THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[idx]);
THREAD_TIMER_OFF (circuit->u.bc.t_refresh_pseudo_lsp[idx]);
circuit->u.bc.run_dr_elect[idx] = 0;
+ list_delete (circuit->u.bc.lan_neighs[idx]);
+ circuit->u.bc.lan_neighs[idx] = NULL;
}
return;
@@ -202,14 +261,19 @@
void
isis_event_circuit_type_change (struct isis_circuit *circuit, int newtype)
{
+ if (circuit->state != C_STATE_UP)
+ {
+ circuit->is_type = newtype;
+ return;
+ }
if (isis->debugs & DEBUG_EVENTS)
zlog_debug ("ISIS-Evt (%s) circuit type change %s -> %s",
circuit->area->area_tag,
- circuit_t2string (circuit->circuit_is_type),
+ circuit_t2string (circuit->is_type),
circuit_t2string (newtype));
- if (circuit->circuit_is_type == newtype)
+ if (circuit->is_type == newtype)
return; /* No change */
if (!(newtype & circuit->area->is_type))
@@ -221,7 +285,7 @@
return;
}
- switch (circuit->circuit_is_type)
+ switch (circuit->is_type)
{
case IS_LEVEL_1:
if (newtype == IS_LEVEL_2)
@@ -243,8 +307,8 @@
break;
}
- circuit->circuit_is_type = newtype;
- lsp_regenerate_schedule (circuit->area);
+ circuit->is_type = newtype;
+ lsp_regenerate_schedule (circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0);
return;
}
@@ -286,7 +350,7 @@
adj->circuit->area->area_tag);
/* LSP generation again */
- lsp_regenerate_schedule (adj->circuit->area);
+ lsp_regenerate_schedule (adj->circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0);
return;
}
@@ -307,7 +371,7 @@
zlog_debug ("ISIS-Evt (%s) DIS status change", circuit->area->area_tag);
/* LSP generation again */
- lsp_regenerate_schedule (circuit->area);
+ lsp_regenerate_schedule (circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0);
return 0;
}