2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2003-12-23 09:09:43 +01:00
|
|
|
/*
|
|
|
|
* IS-IS Rout(e)ing protocol - isis_events.h
|
|
|
|
*
|
|
|
|
* Copyright (C) 2001,2002 Sampo Saaristo
|
|
|
|
* Tampere University of Technology
|
|
|
|
* Institute of Communications Engineering
|
|
|
|
*/
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "log.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "if.h"
|
|
|
|
#include "linklist.h"
|
|
|
|
#include "command.h"
|
2023-03-07 20:22:48 +01:00
|
|
|
#include "frrevent.h"
|
2003-12-23 09:09:43 +01:00
|
|
|
#include "hash.h"
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "stream.h"
|
2012-03-24 16:35:20 +01:00
|
|
|
#include "table.h"
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
#include "isisd/isis_constants.h"
|
|
|
|
#include "isisd/isis_common.h"
|
2012-03-24 16:35:20 +01:00
|
|
|
#include "isisd/isis_flags.h"
|
2003-12-23 09:09:43 +01:00
|
|
|
#include "isisd/isis_circuit.h"
|
|
|
|
#include "isisd/isis_lsp.h"
|
|
|
|
#include "isisd/isis_pdu.h"
|
|
|
|
#include "isisd/isis_network.h"
|
|
|
|
#include "isisd/isis_misc.h"
|
|
|
|
#include "isisd/isis_constants.h"
|
|
|
|
#include "isisd/isis_adjacency.h"
|
|
|
|
#include "isisd/isis_dr.h"
|
|
|
|
#include "isisd/isisd.h"
|
|
|
|
#include "isisd/isis_csm.h"
|
|
|
|
#include "isisd/isis_events.h"
|
|
|
|
#include "isisd/isis_spf.h"
|
2018-06-18 20:56:15 +02:00
|
|
|
#include "isisd/isis_errors.h"
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
void isis_event_circuit_state_change(struct isis_circuit *circuit,
|
|
|
|
struct isis_area *area, int up)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
area->circuit_state_changes++;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2020-06-19 21:04:33 +02:00
|
|
|
if (IS_DEBUG_EVENTS)
|
2012-03-24 16:35:20 +01:00
|
|
|
zlog_debug("ISIS-Evt (%s) circuit %s", area->area_tag,
|
|
|
|
up ? "up" : "down");
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/*
|
|
|
|
* Regenerate LSPs this affects
|
|
|
|
*/
|
2012-03-24 16:35:20 +01:00
|
|
|
lsp_regenerate_schedule(area, IS_LEVEL_1 | IS_LEVEL_2, 0);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void circuit_commence_level(struct isis_circuit *circuit, int level)
|
|
|
|
{
|
2020-09-11 11:07:37 +02:00
|
|
|
if (IS_DEBUG_EVENTS)
|
|
|
|
zlog_debug(
|
|
|
|
"ISIS-Evt (%s) circuit %u on iface %s commencing on L%d",
|
|
|
|
circuit->area->area_tag, circuit->circuit_id,
|
|
|
|
circuit->interface->name, level);
|
|
|
|
|
2018-10-10 11:16:39 +02:00
|
|
|
if (!circuit->is_passive) {
|
|
|
|
if (level == 1) {
|
2022-05-20 20:19:08 +02:00
|
|
|
event_add_timer(master, send_l1_psnp, circuit,
|
|
|
|
isis_jitter(circuit->psnp_interval[0],
|
|
|
|
PSNP_JITTER),
|
|
|
|
&circuit->t_send_psnp[0]);
|
2018-10-10 11:16:39 +02:00
|
|
|
} else {
|
2022-05-20 20:19:08 +02:00
|
|
|
event_add_timer(master, send_l2_psnp, circuit,
|
|
|
|
isis_jitter(circuit->psnp_interval[1],
|
|
|
|
PSNP_JITTER),
|
|
|
|
&circuit->t_send_psnp[1]);
|
2018-10-10 11:16:39 +02:00
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-10-10 11:16:39 +02:00
|
|
|
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
2022-05-20 20:19:08 +02:00
|
|
|
event_add_timer(master, isis_run_dr,
|
|
|
|
&circuit->level_arg[level - 1],
|
|
|
|
2 * circuit->hello_interval[level - 1],
|
|
|
|
&circuit->u.bc.t_run_dr[level - 1]);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2018-10-10 15:43:01 +02:00
|
|
|
send_hello_sched(circuit, level, TRIGGERED_IIH_DELAY);
|
2018-10-10 11:16:39 +02:00
|
|
|
circuit->u.bc.lan_neighs[level - 1] = list_new();
|
isisd: After the router switches IS-IS type several times, the neighbor adjacency cannot be established.
1. Router A is configured with "is-type level-1-2", while Router B is configured with "is-type level-1". Only level 1 neighbor entries are present on Router A.
2. After configuring Router B with "is-type level-2-only", both level 1 and level 2 neighbor entries exist on Router A. The state of these entries is UP, and the level 1 neighbor entry is currently aging.
3. Before the level 1 neighbor entry on Router A ages out, configuring Router B with "is-type level-1", both level 1 and level 2 neighbor entries exist on Router A. The level 2 neighbor entry is UP and will age out normally. However, the level 1 neighbor entry remains in the Initializing state, preventing the establishment of level 1 neighbor adjacency between Router A and Router B.
When the adjacency type of the link is switched in function isis_circuit_is_type_set, the function circuit_resign_level() is called to delete the old level's circuit->u.bc.lan_neighs linked list. If the old level is not level-1-2, the function circuit_commence_level() is called to create a new level's circuit->u.bc.lan_neighs linked list, but neither of these functions handle the circuit->u.bc.adjdb linked list. This leads to a situation where upon receiving hello packets again before the circuit->u.bc.adjdb linked list entries age out, the circuit->u.bc.lan_neighs linked list is not constructed based on the circuit->u.bc.adjdb linked list. As a result, the hello packets sent will consistently lack an SNPA, causing the neighbor to remain unable to establish an adjacency upon receiving the hello packets.
Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com>
2024-06-17 10:45:09 +02:00
|
|
|
circuit->u.bc.adjdb[level - 1] = list_new();
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void circuit_resign_level(struct isis_circuit *circuit, int level)
|
|
|
|
{
|
|
|
|
int idx = level - 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-09-11 11:07:37 +02:00
|
|
|
if (IS_DEBUG_EVENTS)
|
|
|
|
zlog_debug(
|
|
|
|
"ISIS-Evt (%s) circuit %u on iface %s resigning on L%d",
|
|
|
|
circuit->area->area_tag, circuit->circuit_id,
|
|
|
|
circuit->interface->name, level);
|
|
|
|
|
2022-12-25 16:26:52 +01:00
|
|
|
EVENT_OFF(circuit->t_send_csnp[idx]);
|
|
|
|
EVENT_OFF(circuit->t_send_psnp[idx]);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
|
2022-12-25 16:26:52 +01:00
|
|
|
EVENT_OFF(circuit->u.bc.t_send_lan_hello[idx]);
|
|
|
|
EVENT_OFF(circuit->u.bc.t_run_dr[idx]);
|
|
|
|
EVENT_OFF(circuit->u.bc.t_refresh_pseudo_lsp[idx]);
|
2015-11-10 18:43:34 +01:00
|
|
|
circuit->lsp_regenerate_pending[idx] = 0;
|
2004-09-10 22:48:21 +02:00
|
|
|
circuit->u.bc.run_dr_elect[idx] = 0;
|
2020-09-11 11:07:37 +02:00
|
|
|
circuit->u.bc.is_dr[idx] = 0;
|
2017-10-05 16:51:01 +02:00
|
|
|
if (circuit->u.bc.lan_neighs[idx] != NULL)
|
2018-10-02 11:39:51 +02:00
|
|
|
list_delete(&circuit->u.bc.lan_neighs[idx]);
|
isisd: After the router switches IS-IS type several times, the neighbor adjacency cannot be established.
1. Router A is configured with "is-type level-1-2", while Router B is configured with "is-type level-1". Only level 1 neighbor entries are present on Router A.
2. After configuring Router B with "is-type level-2-only", both level 1 and level 2 neighbor entries exist on Router A. The state of these entries is UP, and the level 1 neighbor entry is currently aging.
3. Before the level 1 neighbor entry on Router A ages out, configuring Router B with "is-type level-1", both level 1 and level 2 neighbor entries exist on Router A. The level 2 neighbor entry is UP and will age out normally. However, the level 1 neighbor entry remains in the Initializing state, preventing the establishment of level 1 neighbor adjacency between Router A and Router B.
When the adjacency type of the link is switched in function isis_circuit_is_type_set, the function circuit_resign_level() is called to delete the old level's circuit->u.bc.lan_neighs linked list. If the old level is not level-1-2, the function circuit_commence_level() is called to create a new level's circuit->u.bc.lan_neighs linked list, but neither of these functions handle the circuit->u.bc.adjdb linked list. This leads to a situation where upon receiving hello packets again before the circuit->u.bc.adjdb linked list entries age out, the circuit->u.bc.lan_neighs linked list is not constructed based on the circuit->u.bc.adjdb linked list. As a result, the hello packets sent will consistently lack an SNPA, causing the neighbor to remain unable to establish an adjacency upon receiving the hello packets.
Signed-off-by: zhou-run <166502045+zhou-run@users.noreply.github.com>
2024-06-17 10:45:09 +02:00
|
|
|
if (circuit->u.bc.adjdb[idx]) {
|
|
|
|
circuit->u.bc.adjdb[idx]->del = isis_delete_adj;
|
|
|
|
list_delete(&circuit->u.bc.adjdb[idx]);
|
|
|
|
}
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-08-13 01:32:52 +02:00
|
|
|
void isis_circuit_is_type_set(struct isis_circuit *circuit, int newtype)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2021-10-30 02:15:24 +02:00
|
|
|
if (!circuit->area) {
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit->is_type = newtype;
|
|
|
|
return;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-06-19 21:04:33 +02:00
|
|
|
if (IS_DEBUG_EVENTS)
|
2004-12-24 01:14:50 +01:00
|
|
|
zlog_debug("ISIS-Evt (%s) circuit type change %s -> %s",
|
2004-09-10 22:48:21 +02:00
|
|
|
circuit->area->area_tag,
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit_t2string(circuit->is_type),
|
2003-12-23 09:09:43 +01:00
|
|
|
circuit_t2string(newtype));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
if (circuit->is_type == newtype)
|
2004-09-10 22:48:21 +02:00
|
|
|
return; /* No change */
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-09-10 22:48:21 +02:00
|
|
|
if (!(newtype & circuit->area->is_type)) {
|
2018-08-03 20:03:29 +02:00
|
|
|
flog_err(
|
2018-09-13 21:12:08 +02:00
|
|
|
EC_ISIS_CONFIG,
|
2018-06-18 20:56:15 +02:00
|
|
|
"ISIS-Evt (%s) circuit type change - invalid level %s because area is %s",
|
2004-09-10 22:48:21 +02:00
|
|
|
circuit->area->area_tag, circuit_t2string(newtype),
|
|
|
|
circuit_t2string(circuit->area->is_type));
|
|
|
|
return;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-10-30 02:15:24 +02:00
|
|
|
if (circuit->state != C_STATE_UP) {
|
|
|
|
circuit->is_type = newtype;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-01-08 02:21:02 +01:00
|
|
|
if (!circuit->is_passive) {
|
|
|
|
switch (circuit->is_type) {
|
|
|
|
case IS_LEVEL_1:
|
|
|
|
if (newtype == IS_LEVEL_2)
|
|
|
|
circuit_resign_level(circuit, 1);
|
|
|
|
circuit_commence_level(circuit, 2);
|
|
|
|
break;
|
|
|
|
case IS_LEVEL_1_AND_2:
|
|
|
|
if (newtype == IS_LEVEL_1)
|
|
|
|
circuit_resign_level(circuit, 2);
|
|
|
|
else
|
|
|
|
circuit_resign_level(circuit, 1);
|
|
|
|
break;
|
|
|
|
case IS_LEVEL_2:
|
|
|
|
if (newtype == IS_LEVEL_1)
|
|
|
|
circuit_resign_level(circuit, 2);
|
|
|
|
circuit_commence_level(circuit, 1);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2004-09-10 22:48:21 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
circuit->is_type = newtype;
|
|
|
|
lsp_regenerate_schedule(circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 04/18/2002 by Gwak. */
|
|
|
|
/**************************************************************************
|
|
|
|
*
|
|
|
|
* EVENTS for LSP generation
|
|
|
|
*
|
|
|
|
* 1) an Adajacency or Circuit Up/Down event
|
|
|
|
* 2) a chnage in Circuit metric
|
|
|
|
* 3) a change in Reachable Address metric
|
|
|
|
* 4) a change in manualAreaAddresses
|
|
|
|
* 5) a change in systemID
|
|
|
|
* 6) a change in DIS status
|
|
|
|
* 7) a chnage in the waiting status
|
|
|
|
*
|
|
|
|
* ***********************************************************************
|
|
|
|
*
|
|
|
|
* current support event
|
|
|
|
*
|
|
|
|
* 1) Adjacency Up/Down event
|
|
|
|
* 6) a change in DIS status
|
|
|
|
*
|
|
|
|
* ***********************************************************************/
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/* events supporting code */
|
|
|
|
|
2022-03-01 22:18:12 +01:00
|
|
|
void isis_event_dis_status_change(struct event *thread)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
|
|
|
struct isis_circuit *circuit;
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2022-12-25 16:26:52 +01:00
|
|
|
circuit = EVENT_ARG(thread);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
/* invalid arguments */
|
2004-09-10 22:48:21 +02:00
|
|
|
if (!circuit || !circuit->area)
|
2022-02-23 01:04:25 +01:00
|
|
|
return;
|
2020-06-19 21:04:33 +02:00
|
|
|
if (IS_DEBUG_EVENTS)
|
2005-09-04 23:36:36 +02:00
|
|
|
zlog_debug("ISIS-Evt (%s) DIS status change",
|
|
|
|
circuit->area->area_tag);
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
/* LSP generation again */
|
2012-03-24 16:35:20 +01:00
|
|
|
lsp_regenerate_schedule(circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0);
|
2003-12-23 09:09:43 +01:00
|
|
|
}
|
|
|
|
|
2004-10-07 22:07:40 +02:00
|
|
|
void isis_event_auth_failure(char *area_tag, const char *error_string,
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t *sysid)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2020-06-19 21:04:33 +02:00
|
|
|
if (IS_DEBUG_EVENTS)
|
2023-01-26 17:47:04 +01:00
|
|
|
zlog_debug("ISIS-Evt (%s) Authentication failure %s from %pSY",
|
|
|
|
area_tag, error_string, sysid);
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2003-12-23 09:09:43 +01:00
|
|
|
return;
|
|
|
|
}
|