]>
Commit | Line | Data |
---|---|---|
acddc0ed | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
eb5d44eb | 2 | /* |
3 | * IS-IS Rout(e)ing protocol - isis_csm.c | |
4 | * IS-IS circuit state machine | |
5 | * Copyright (C) 2001,2002 Sampo Saaristo | |
d62a17ae | 6 | * Tampere University of Technology |
eb5d44eb | 7 | * Institute of Communications Engineering |
eb5d44eb | 8 | */ |
9 | ||
10 | #include <zebra.h> | |
eb5d44eb | 11 | |
12 | #include "log.h" | |
13 | #include "memory.h" | |
14 | #include "if.h" | |
15 | #include "linklist.h" | |
16 | #include "command.h" | |
17 | #include "thread.h" | |
18 | #include "hash.h" | |
19 | #include "prefix.h" | |
20 | #include "stream.h" | |
21 | ||
eb5d44eb | 22 | #include "isisd/isis_constants.h" |
23 | #include "isisd/isis_common.h" | |
3f045a08 | 24 | #include "isisd/isis_flags.h" |
eb5d44eb | 25 | #include "isisd/isis_circuit.h" |
eb5d44eb | 26 | #include "isisd/isis_lsp.h" |
27 | #include "isisd/isis_pdu.h" | |
28 | #include "isisd/isis_network.h" | |
29 | #include "isisd/isis_misc.h" | |
30 | #include "isisd/isis_constants.h" | |
31 | #include "isisd/isis_adjacency.h" | |
32 | #include "isisd/isis_dr.h" | |
eb5d44eb | 33 | #include "isisd/isisd.h" |
34 | #include "isisd/isis_csm.h" | |
35 | #include "isisd/isis_events.h" | |
54ece698 | 36 | #include "isisd/isis_errors.h" |
eb5d44eb | 37 | |
2b64873d | 38 | static const char *const csm_statestr[] = {"C_STATE_NA", "C_STATE_INIT", |
d62a17ae | 39 | "C_STATE_CONF", "C_STATE_UP"}; |
eb5d44eb | 40 | |
41 | #define STATE2STR(S) csm_statestr[S] | |
42 | ||
2b64873d | 43 | static const char *const csm_eventstr[] = { |
d62a17ae | 44 | "NO_STATE", "ISIS_ENABLE", "IF_UP_FROM_Z", |
45 | "ISIS_DISABLE", "IF_DOWN_FROM_Z", | |
eb5d44eb | 46 | }; |
47 | ||
48 | #define EVENT2STR(E) csm_eventstr[E] | |
49 | ||
9d454ad2 DS |
50 | struct isis_circuit *isis_csm_state_change(enum isis_circuit_event event, |
51 | struct isis_circuit *circuit, | |
52 | void *arg) | |
eb5d44eb | 53 | { |
61cd5761 | 54 | enum isis_circuit_state old_state; |
bfa51457 | 55 | struct isis_area *area = NULL; |
c5b8ce06 | 56 | struct interface *ifp; |
eb5d44eb | 57 | |
bcf22081 IR |
58 | assert(circuit); |
59 | ||
60 | old_state = circuit->state; | |
e740f9c1 | 61 | if (IS_DEBUG_EVENTS) |
bcf22081 IR |
62 | zlog_debug("CSM_EVENT for %s: %s", circuit->interface->name, |
63 | EVENT2STR(event)); | |
f390d2c7 | 64 | |
d62a17ae | 65 | switch (old_state) { |
66 | case C_STATE_NA: | |
d62a17ae | 67 | switch (event) { |
68 | case ISIS_ENABLE: | |
bfa51457 DS |
69 | area = arg; |
70 | ||
bfa51457 | 71 | isis_circuit_configure(circuit, area); |
d62a17ae | 72 | circuit->state = C_STATE_CONF; |
73 | break; | |
74 | case IF_UP_FROM_Z: | |
c5b8ce06 | 75 | ifp = arg; |
bcf22081 | 76 | |
c5b8ce06 | 77 | isis_circuit_if_add(circuit, ifp); |
d62a17ae | 78 | circuit->state = C_STATE_INIT; |
79 | break; | |
80 | case ISIS_DISABLE: | |
c5b8ce06 | 81 | if (IS_DEBUG_EVENTS) |
bcf22081 IR |
82 | zlog_debug("circuit %s already disabled", |
83 | circuit->interface->name); | |
d62a17ae | 84 | break; |
85 | case IF_DOWN_FROM_Z: | |
c5b8ce06 | 86 | if (IS_DEBUG_EVENTS) |
bcf22081 IR |
87 | zlog_debug("circuit %s already disconnected", |
88 | circuit->interface->name); | |
d62a17ae | 89 | break; |
90 | } | |
91 | break; | |
92 | case C_STATE_INIT: | |
d62a17ae | 93 | switch (event) { |
94 | case ISIS_ENABLE: | |
bcf22081 IR |
95 | area = arg; |
96 | ||
97 | isis_circuit_configure(circuit, area); | |
d62a17ae | 98 | if (isis_circuit_up(circuit) != ISIS_OK) { |
bcf22081 | 99 | isis_circuit_deconfigure(circuit, area); |
d62a17ae | 100 | break; |
101 | } | |
102 | circuit->state = C_STATE_UP; | |
103 | isis_event_circuit_state_change(circuit, circuit->area, | |
104 | 1); | |
d62a17ae | 105 | break; |
106 | case IF_UP_FROM_Z: | |
c5b8ce06 DS |
107 | if (IS_DEBUG_EVENTS) |
108 | zlog_debug("circuit %s already connected", | |
109 | circuit->interface->name); | |
d62a17ae | 110 | break; |
111 | case ISIS_DISABLE: | |
c5b8ce06 DS |
112 | if (IS_DEBUG_EVENTS) |
113 | zlog_debug("circuit %s already disabled", | |
114 | circuit->interface->name); | |
d62a17ae | 115 | break; |
116 | case IF_DOWN_FROM_Z: | |
bcf22081 IR |
117 | ifp = arg; |
118 | ||
119 | isis_circuit_if_del(circuit, ifp); | |
120 | circuit->state = C_STATE_NA; | |
d62a17ae | 121 | break; |
122 | } | |
123 | break; | |
124 | case C_STATE_CONF: | |
d62a17ae | 125 | switch (event) { |
126 | case ISIS_ENABLE: | |
c5b8ce06 | 127 | if (IS_DEBUG_EVENTS) |
bcf22081 IR |
128 | zlog_debug("circuit %s is already enabled", |
129 | circuit->interface->name); | |
d62a17ae | 130 | break; |
131 | case IF_UP_FROM_Z: | |
bcf22081 IR |
132 | ifp = arg; |
133 | ||
134 | isis_circuit_if_add(circuit, ifp); | |
d62a17ae | 135 | if (isis_circuit_up(circuit) != ISIS_OK) { |
bcf22081 | 136 | isis_circuit_if_del(circuit, ifp); |
af4c2728 | 137 | flog_err( |
1a7ecb96 | 138 | EC_ISIS_CONFIG, |
d62a17ae | 139 | "Could not bring up %s because of invalid config.", |
140 | circuit->interface->name); | |
d62a17ae | 141 | break; |
142 | } | |
143 | circuit->state = C_STATE_UP; | |
144 | isis_event_circuit_state_change(circuit, circuit->area, | |
145 | 1); | |
146 | break; | |
147 | case ISIS_DISABLE: | |
bcf22081 IR |
148 | area = arg; |
149 | ||
150 | isis_circuit_deconfigure(circuit, area); | |
151 | circuit->state = C_STATE_NA; | |
d62a17ae | 152 | break; |
153 | case IF_DOWN_FROM_Z: | |
c5b8ce06 | 154 | if (IS_DEBUG_EVENTS) |
bcf22081 IR |
155 | zlog_debug("circuit %s already disconnected", |
156 | circuit->interface->name); | |
d62a17ae | 157 | break; |
158 | } | |
159 | break; | |
160 | case C_STATE_UP: | |
d62a17ae | 161 | switch (event) { |
162 | case ISIS_ENABLE: | |
c5b8ce06 | 163 | if (IS_DEBUG_EVENTS) |
bcf22081 | 164 | zlog_debug("circuit %s already enabled", |
c5b8ce06 | 165 | circuit->interface->name); |
d62a17ae | 166 | break; |
167 | case IF_UP_FROM_Z: | |
c5b8ce06 DS |
168 | if (IS_DEBUG_EVENTS) |
169 | zlog_debug("circuit %s already connected", | |
170 | circuit->interface->name); | |
d62a17ae | 171 | break; |
172 | case ISIS_DISABLE: | |
bcf22081 IR |
173 | area = arg; |
174 | ||
d62a17ae | 175 | isis_circuit_down(circuit); |
bcf22081 | 176 | isis_circuit_deconfigure(circuit, area); |
d62a17ae | 177 | circuit->state = C_STATE_INIT; |
bcf22081 | 178 | isis_event_circuit_state_change(circuit, area, 0); |
d62a17ae | 179 | break; |
180 | case IF_DOWN_FROM_Z: | |
bcf22081 IR |
181 | ifp = arg; |
182 | ||
d62a17ae | 183 | isis_circuit_down(circuit); |
bcf22081 | 184 | isis_circuit_if_del(circuit, ifp); |
d62a17ae | 185 | circuit->state = C_STATE_CONF; |
186 | isis_event_circuit_state_change(circuit, circuit->area, | |
187 | 0); | |
188 | break; | |
189 | } | |
190 | break; | |
d62a17ae | 191 | } |
f390d2c7 | 192 | |
e740f9c1 | 193 | if (IS_DEBUG_EVENTS) |
d62a17ae | 194 | zlog_debug("CSM_STATE_CHANGE: %s -> %s ", STATE2STR(old_state), |
bcf22081 | 195 | STATE2STR(circuit->state)); |
eb5d44eb | 196 | |
d62a17ae | 197 | return circuit; |
eb5d44eb | 198 | } |