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_csm.c
|
|
|
|
* IS-IS circuit state machine
|
|
|
|
* 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"
|
|
|
|
|
|
|
|
#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"
|
2018-06-18 20:56:15 +02:00
|
|
|
#include "isisd/isis_errors.h"
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2019-11-20 17:26:59 +01:00
|
|
|
static const char *const csm_statestr[] = {"C_STATE_NA", "C_STATE_INIT",
|
2003-12-23 09:09:43 +01:00
|
|
|
"C_STATE_CONF", "C_STATE_UP"};
|
|
|
|
|
|
|
|
#define STATE2STR(S) csm_statestr[S]
|
|
|
|
|
2019-11-20 17:26:59 +01:00
|
|
|
static const char *const csm_eventstr[] = {
|
2003-12-23 09:09:43 +01:00
|
|
|
"NO_STATE", "ISIS_ENABLE", "IF_UP_FROM_Z",
|
|
|
|
"ISIS_DISABLE", "IF_DOWN_FROM_Z",
|
|
|
|
};
|
|
|
|
|
|
|
|
#define EVENT2STR(E) csm_eventstr[E]
|
|
|
|
|
2021-04-22 20:52:40 +02:00
|
|
|
struct isis_circuit *isis_csm_state_change(enum isis_circuit_event event,
|
|
|
|
struct isis_circuit *circuit,
|
|
|
|
void *arg)
|
2003-12-23 09:09:43 +01:00
|
|
|
{
|
2021-04-22 20:46:53 +02:00
|
|
|
enum isis_circuit_state old_state;
|
2020-10-09 14:10:20 +02:00
|
|
|
struct isis_area *area = NULL;
|
2021-04-22 21:04:15 +02:00
|
|
|
struct interface *ifp;
|
2003-12-23 09:09:43 +01:00
|
|
|
|
2021-04-28 00:57:21 +02:00
|
|
|
assert(circuit);
|
|
|
|
|
|
|
|
old_state = circuit->state;
|
2020-06-19 21:04:33 +02:00
|
|
|
if (IS_DEBUG_EVENTS)
|
2021-04-28 00:57:21 +02:00
|
|
|
zlog_debug("CSM_EVENT for %s: %s", circuit->interface->name,
|
|
|
|
EVENT2STR(event));
|
2004-09-10 22:48:21 +02:00
|
|
|
|
|
|
|
switch (old_state) {
|
|
|
|
case C_STATE_NA:
|
|
|
|
switch (event) {
|
|
|
|
case ISIS_ENABLE:
|
2020-10-09 14:10:20 +02:00
|
|
|
area = arg;
|
|
|
|
|
|
|
|
isis_circuit_configure(circuit, area);
|
2004-09-10 22:48:21 +02:00
|
|
|
circuit->state = C_STATE_CONF;
|
|
|
|
break;
|
|
|
|
case IF_UP_FROM_Z:
|
2021-04-22 21:04:15 +02:00
|
|
|
ifp = arg;
|
2021-04-28 00:57:21 +02:00
|
|
|
|
2021-04-22 21:04:15 +02:00
|
|
|
isis_circuit_if_add(circuit, ifp);
|
2004-09-10 22:48:21 +02:00
|
|
|
circuit->state = C_STATE_INIT;
|
|
|
|
break;
|
|
|
|
case ISIS_DISABLE:
|
2021-04-22 21:04:15 +02:00
|
|
|
if (IS_DEBUG_EVENTS)
|
2021-04-28 00:57:21 +02:00
|
|
|
zlog_debug("circuit %s already disabled",
|
|
|
|
circuit->interface->name);
|
2012-11-27 02:10:30 +01:00
|
|
|
break;
|
2004-09-10 22:48:21 +02:00
|
|
|
case IF_DOWN_FROM_Z:
|
2021-04-22 21:04:15 +02:00
|
|
|
if (IS_DEBUG_EVENTS)
|
2021-04-28 00:57:21 +02:00
|
|
|
zlog_debug("circuit %s already disconnected",
|
|
|
|
circuit->interface->name);
|
2004-09-10 22:48:21 +02:00
|
|
|
break;
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
break;
|
2004-09-10 22:48:21 +02:00
|
|
|
case C_STATE_INIT:
|
|
|
|
switch (event) {
|
|
|
|
case ISIS_ENABLE:
|
2021-04-28 00:57:21 +02:00
|
|
|
area = arg;
|
|
|
|
|
|
|
|
isis_circuit_configure(circuit, area);
|
2012-03-24 16:35:20 +01:00
|
|
|
if (isis_circuit_up(circuit) != ISIS_OK) {
|
2021-04-28 00:57:21 +02:00
|
|
|
isis_circuit_deconfigure(circuit, area);
|
2012-03-24 16:35:20 +01:00
|
|
|
break;
|
|
|
|
}
|
2004-09-10 22:48:21 +02:00
|
|
|
circuit->state = C_STATE_UP;
|
2012-03-24 16:35:20 +01:00
|
|
|
isis_event_circuit_state_change(circuit, circuit->area,
|
|
|
|
1);
|
2004-09-10 22:48:21 +02:00
|
|
|
break;
|
|
|
|
case IF_UP_FROM_Z:
|
2021-04-22 21:04:15 +02:00
|
|
|
if (IS_DEBUG_EVENTS)
|
|
|
|
zlog_debug("circuit %s already connected",
|
|
|
|
circuit->interface->name);
|
2004-09-10 22:48:21 +02:00
|
|
|
break;
|
|
|
|
case ISIS_DISABLE:
|
2021-04-22 21:04:15 +02:00
|
|
|
if (IS_DEBUG_EVENTS)
|
|
|
|
zlog_debug("circuit %s already disabled",
|
|
|
|
circuit->interface->name);
|
2004-09-10 22:48:21 +02:00
|
|
|
break;
|
|
|
|
case IF_DOWN_FROM_Z:
|
2021-04-28 00:57:21 +02:00
|
|
|
ifp = arg;
|
|
|
|
|
|
|
|
isis_circuit_if_del(circuit, ifp);
|
|
|
|
circuit->state = C_STATE_NA;
|
2004-09-10 22:48:21 +02:00
|
|
|
break;
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
break;
|
2004-09-10 22:48:21 +02:00
|
|
|
case C_STATE_CONF:
|
|
|
|
switch (event) {
|
|
|
|
case ISIS_ENABLE:
|
2021-04-22 21:04:15 +02:00
|
|
|
if (IS_DEBUG_EVENTS)
|
2021-04-28 00:57:21 +02:00
|
|
|
zlog_debug("circuit %s is already enabled",
|
|
|
|
circuit->interface->name);
|
2004-09-10 22:48:21 +02:00
|
|
|
break;
|
|
|
|
case IF_UP_FROM_Z:
|
2021-04-28 00:57:21 +02:00
|
|
|
ifp = arg;
|
|
|
|
|
|
|
|
isis_circuit_if_add(circuit, ifp);
|
2012-03-24 16:35:20 +01:00
|
|
|
if (isis_circuit_up(circuit) != ISIS_OK) {
|
2021-04-28 00:57:21 +02:00
|
|
|
isis_circuit_if_del(circuit, ifp);
|
2018-08-03 20:03:29 +02:00
|
|
|
flog_err(
|
2018-09-13 21:12:08 +02:00
|
|
|
EC_ISIS_CONFIG,
|
2016-04-03 17:46:26 +02:00
|
|
|
"Could not bring up %s because of invalid config.",
|
|
|
|
circuit->interface->name);
|
2012-03-24 16:35:20 +01:00
|
|
|
break;
|
2016-04-03 17:46:26 +02:00
|
|
|
}
|
2004-09-10 22:48:21 +02:00
|
|
|
circuit->state = C_STATE_UP;
|
2012-03-24 16:35:20 +01:00
|
|
|
isis_event_circuit_state_change(circuit, circuit->area,
|
|
|
|
1);
|
2004-09-10 22:48:21 +02:00
|
|
|
break;
|
|
|
|
case ISIS_DISABLE:
|
2021-04-28 00:57:21 +02:00
|
|
|
area = arg;
|
|
|
|
|
|
|
|
isis_circuit_deconfigure(circuit, area);
|
|
|
|
circuit->state = C_STATE_NA;
|
2004-09-10 22:48:21 +02:00
|
|
|
break;
|
|
|
|
case IF_DOWN_FROM_Z:
|
2021-04-22 21:04:15 +02:00
|
|
|
if (IS_DEBUG_EVENTS)
|
2021-04-28 00:57:21 +02:00
|
|
|
zlog_debug("circuit %s already disconnected",
|
|
|
|
circuit->interface->name);
|
2004-09-10 22:48:21 +02:00
|
|
|
break;
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
break;
|
2004-09-10 22:48:21 +02:00
|
|
|
case C_STATE_UP:
|
|
|
|
switch (event) {
|
|
|
|
case ISIS_ENABLE:
|
2021-04-22 21:04:15 +02:00
|
|
|
if (IS_DEBUG_EVENTS)
|
2021-04-28 00:57:21 +02:00
|
|
|
zlog_debug("circuit %s already enabled",
|
2021-04-22 21:04:15 +02:00
|
|
|
circuit->interface->name);
|
2004-09-10 22:48:21 +02:00
|
|
|
break;
|
|
|
|
case IF_UP_FROM_Z:
|
2021-04-22 21:04:15 +02:00
|
|
|
if (IS_DEBUG_EVENTS)
|
|
|
|
zlog_debug("circuit %s already connected",
|
|
|
|
circuit->interface->name);
|
2004-09-10 22:48:21 +02:00
|
|
|
break;
|
|
|
|
case ISIS_DISABLE:
|
2021-04-28 00:57:21 +02:00
|
|
|
area = arg;
|
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
isis_circuit_down(circuit);
|
2021-04-28 00:57:21 +02:00
|
|
|
isis_circuit_deconfigure(circuit, area);
|
2004-09-10 22:48:21 +02:00
|
|
|
circuit->state = C_STATE_INIT;
|
2021-04-28 00:57:21 +02:00
|
|
|
isis_event_circuit_state_change(circuit, area, 0);
|
2004-09-10 22:48:21 +02:00
|
|
|
break;
|
|
|
|
case IF_DOWN_FROM_Z:
|
2021-04-28 00:57:21 +02:00
|
|
|
ifp = arg;
|
|
|
|
|
2012-03-24 16:35:20 +01:00
|
|
|
isis_circuit_down(circuit);
|
2021-04-28 00:57:21 +02:00
|
|
|
isis_circuit_if_del(circuit, ifp);
|
2004-09-10 22:48:21 +02:00
|
|
|
circuit->state = C_STATE_CONF;
|
2012-03-24 16:35:20 +01:00
|
|
|
isis_event_circuit_state_change(circuit, circuit->area,
|
|
|
|
0);
|
2004-09-10 22:48:21 +02:00
|
|
|
break;
|
|
|
|
}
|
2003-12-23 09:09:43 +01:00
|
|
|
break;
|
|
|
|
}
|
2004-09-10 22:48:21 +02:00
|
|
|
|
2020-06-19 21:04:33 +02:00
|
|
|
if (IS_DEBUG_EVENTS)
|
2005-09-04 23:36:36 +02:00
|
|
|
zlog_debug("CSM_STATE_CHANGE: %s -> %s ", STATE2STR(old_state),
|
2021-04-28 00:57:21 +02:00
|
|
|
STATE2STR(circuit->state));
|
2003-12-23 09:09:43 +01:00
|
|
|
|
|
|
|
return circuit;
|
|
|
|
}
|