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