diff options
Diffstat (limited to 'isisd/isis_adjacency.c')
| -rw-r--r-- | isisd/isis_adjacency.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c index 72e6d4bdb9..a6e1a55a9f 100644 --- a/isisd/isis_adjacency.c +++ b/isisd/isis_adjacency.c @@ -47,6 +47,7 @@ #include "isisd/isis_spf.h" #include "isisd/isis_events.h" #include "isisd/isis_mt.h" +#include "isisd/isis_tlvs.h" extern struct isis *isis; @@ -78,6 +79,7 @@ struct isis_adjacency *isis_new_adj(const u_char *id, const u_char *snpa, adj->level = level; adj->flaps = 0; adj->last_flap = time(NULL); + adj->threeway_state = ISIS_THREEWAY_DOWN; if (circuit->circ_type == CIRCUIT_T_BROADCAST) { listnode_add(circuit->u.bc.adjdb[level - 1], adj); adj->dischanges[level - 1] = 0; @@ -161,6 +163,51 @@ static const char *adj_state2string(int state) return NULL; /* not reached */ } +void isis_adj_process_threeway(struct isis_adjacency *adj, + struct isis_threeway_adj *tw_adj, + enum isis_adj_usage adj_usage) +{ + enum isis_threeway_state next_tw_state = ISIS_THREEWAY_DOWN; + + if (tw_adj && !adj->circuit->disable_threeway_adj) { + if (tw_adj->state == ISIS_THREEWAY_DOWN) { + next_tw_state = ISIS_THREEWAY_INITIALIZING; + } else if (tw_adj->state == ISIS_THREEWAY_INITIALIZING) { + next_tw_state = ISIS_THREEWAY_UP; + } else if (tw_adj->state == ISIS_THREEWAY_UP) { + if (adj->threeway_state == ISIS_THREEWAY_DOWN) + next_tw_state = ISIS_THREEWAY_DOWN; + else + next_tw_state = ISIS_THREEWAY_UP; + } + } else { + next_tw_state = ISIS_THREEWAY_UP; + } + + if (next_tw_state != adj->threeway_state) { + if (isis->debugs & DEBUG_ADJ_PACKETS) { + zlog_info("ISIS-Adj (%s): Threeway state change %s to %s", + adj->circuit->area->area_tag, + isis_threeway_state_name(adj->threeway_state), + isis_threeway_state_name(next_tw_state)); + } + } + + if (next_tw_state == ISIS_THREEWAY_DOWN) { + isis_adj_state_change(adj, ISIS_ADJ_DOWN, "Neighbor restarted"); + return; + } + + if (next_tw_state == ISIS_THREEWAY_UP) { + if (adj->adj_state != ISIS_ADJ_UP) { + isis_adj_state_change(adj, ISIS_ADJ_UP, NULL); + adj->adj_usage = adj_usage; + } + } + + adj->threeway_state = next_tw_state; +} + void isis_adj_state_change(struct isis_adjacency *adj, enum isis_adj_state new_state, const char *reason) { |
