From 3f045a08812525505e165deea99a79447b44506b Mon Sep 17 00:00:00 2001 From: Josh Bailey Date: Sat, 24 Mar 2012 08:35:20 -0700 Subject: isisd: add Google's changes to IS-IS --- isisd/isis_events.c | 150 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 107 insertions(+), 43 deletions(-) (limited to 'isisd/isis_events.c') diff --git a/isisd/isis_events.c b/isisd/isis_events.c index 43800922..750a4c38 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 @@ extern struct isis *isis; */ 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,45 +127,71 @@ isis_event_system_type_change (struct isis_area *area, int newtype) 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); - spftree_area_init (area); - lsp_regenerate_schedule (area); + /* 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); + } - return; -} + spftree_area_init (area); -void -isis_event_area_addr_change (struct isis_area *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; } static void @@ -148,7 +205,7 @@ circuit_commence_level (struct isis_circuit *circuit, int level) 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 @@ circuit_resign_level (struct isis_circuit *circuit, int level) 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 @@ circuit_resign_level (struct isis_circuit *circuit, int level) 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 @@ isis_event_circuit_type_change (struct isis_circuit *circuit, int newtype) return; } - switch (circuit->circuit_is_type) + switch (circuit->is_type) { case IS_LEVEL_1: if (newtype == IS_LEVEL_2) @@ -243,8 +307,8 @@ isis_event_circuit_type_change (struct isis_circuit *circuit, int newtype) 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 @@ isis_event_adjacency_state_change (struct isis_adjacency *adj, int newstate) 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 @@ isis_event_dis_status_change (struct thread *thread) 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; } -- cgit v1.2.1