]> git.proxmox.com Git - mirror_frr.git/blob - isisd/isis_csm.c
Merge branch '-rip' into stable/2.0
[mirror_frr.git] / isisd / isis_csm.c
1 /*
2 * IS-IS Rout(e)ing protocol - isis_csm.c
3 * IS-IS circuit state machine
4 * Copyright (C) 2001,2002 Sampo Saaristo
5 * Tampere University of Technology
6 * Institute of Communications Engineering
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public Licenseas published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22
23 #include <zebra.h>
24
25 #include "log.h"
26 #include "memory.h"
27 #include "if.h"
28 #include "linklist.h"
29 #include "command.h"
30 #include "thread.h"
31 #include "hash.h"
32 #include "prefix.h"
33 #include "stream.h"
34
35 #include "isisd/dict.h"
36 #include "isisd/isis_constants.h"
37 #include "isisd/isis_common.h"
38 #include "isisd/isis_flags.h"
39 #include "isisd/isis_circuit.h"
40 #include "isisd/isis_tlv.h"
41 #include "isisd/isis_lsp.h"
42 #include "isisd/isis_pdu.h"
43 #include "isisd/isis_network.h"
44 #include "isisd/isis_misc.h"
45 #include "isisd/isis_constants.h"
46 #include "isisd/isis_adjacency.h"
47 #include "isisd/isis_dr.h"
48 #include "isisd/isisd.h"
49 #include "isisd/isis_csm.h"
50 #include "isisd/isis_events.h"
51
52 extern struct isis *isis;
53
54 static const char *csm_statestr[] = {
55 "C_STATE_NA",
56 "C_STATE_INIT",
57 "C_STATE_CONF",
58 "C_STATE_UP"
59 };
60
61 #define STATE2STR(S) csm_statestr[S]
62
63 static const char *csm_eventstr[] = {
64 "NO_STATE",
65 "ISIS_ENABLE",
66 "IF_UP_FROM_Z",
67 "ISIS_DISABLE",
68 "IF_DOWN_FROM_Z",
69 };
70
71 #define EVENT2STR(E) csm_eventstr[E]
72
73 struct isis_circuit *
74 isis_csm_state_change (int event, struct isis_circuit *circuit, void *arg)
75 {
76 int old_state;
77
78 old_state = circuit ? circuit->state : C_STATE_NA;
79 if (isis->debugs & DEBUG_EVENTS)
80 zlog_debug ("CSM_EVENT: %s", EVENT2STR (event));
81
82 switch (old_state)
83 {
84 case C_STATE_NA:
85 if (circuit)
86 zlog_warn ("Non-null circuit while state C_STATE_NA");
87 assert (circuit == NULL);
88 switch (event)
89 {
90 case ISIS_ENABLE:
91 circuit = isis_circuit_new ();
92 isis_circuit_configure (circuit, (struct isis_area *) arg);
93 circuit->state = C_STATE_CONF;
94 break;
95 case IF_UP_FROM_Z:
96 circuit = isis_circuit_new ();
97 isis_circuit_if_add (circuit, (struct interface *) arg);
98 listnode_add (isis->init_circ_list, circuit);
99 circuit->state = C_STATE_INIT;
100 break;
101 case ISIS_DISABLE:
102 zlog_warn ("circuit already disabled");
103 break;
104 case IF_DOWN_FROM_Z:
105 zlog_warn ("circuit already disconnected");
106 break;
107 }
108 break;
109 case C_STATE_INIT:
110 assert (circuit);
111 switch (event)
112 {
113 case ISIS_ENABLE:
114 isis_circuit_configure (circuit, (struct isis_area *) arg);
115 if (isis_circuit_up (circuit) != ISIS_OK)
116 {
117 isis_circuit_deconfigure (circuit, (struct isis_area *) arg);
118 break;
119 }
120 circuit->state = C_STATE_UP;
121 isis_event_circuit_state_change (circuit, circuit->area, 1);
122 listnode_delete (isis->init_circ_list, circuit);
123 break;
124 case IF_UP_FROM_Z:
125 assert (circuit);
126 zlog_warn ("circuit already connected");
127 break;
128 case ISIS_DISABLE:
129 zlog_warn ("circuit already disabled");
130 break;
131 case IF_DOWN_FROM_Z:
132 isis_circuit_if_del (circuit, (struct interface *) arg);
133 listnode_delete (isis->init_circ_list, circuit);
134 isis_circuit_del (circuit);
135 circuit = NULL;
136 break;
137 }
138 break;
139 case C_STATE_CONF:
140 assert (circuit);
141 switch (event)
142 {
143 case ISIS_ENABLE:
144 zlog_warn ("circuit already enabled");
145 break;
146 case IF_UP_FROM_Z:
147 isis_circuit_if_add (circuit, (struct interface *) arg);
148 if (isis_circuit_up (circuit) != ISIS_OK)
149 {
150 zlog_err("Could not bring up %s because of invalid config.",
151 circuit->interface->name);
152 zlog_err("Clearing config for %s. Please re-examine it.",
153 circuit->interface->name);
154 if (circuit->ip_router)
155 {
156 circuit->ip_router = 0;
157 circuit->area->ip_circuits--;
158 }
159 if (circuit->ipv6_router)
160 {
161 circuit->ipv6_router = 0;
162 circuit->area->ipv6_circuits--;
163 }
164 circuit_update_nlpids(circuit);
165 isis_circuit_deconfigure(circuit, circuit->area);
166 listnode_add (isis->init_circ_list, circuit);
167 circuit->state = C_STATE_INIT;
168 break;
169 }
170 circuit->state = C_STATE_UP;
171 isis_event_circuit_state_change (circuit, circuit->area, 1);
172 break;
173 case ISIS_DISABLE:
174 isis_circuit_deconfigure (circuit, (struct isis_area *) arg);
175 isis_circuit_del (circuit);
176 circuit = NULL;
177 break;
178 case IF_DOWN_FROM_Z:
179 zlog_warn ("circuit already disconnected");
180 break;
181 }
182 break;
183 case C_STATE_UP:
184 assert (circuit);
185 switch (event)
186 {
187 case ISIS_ENABLE:
188 zlog_warn ("circuit already configured");
189 break;
190 case IF_UP_FROM_Z:
191 zlog_warn ("circuit already connected");
192 break;
193 case ISIS_DISABLE:
194 isis_circuit_down (circuit);
195 isis_circuit_deconfigure (circuit, (struct isis_area *) arg);
196 circuit->state = C_STATE_INIT;
197 isis_event_circuit_state_change (circuit,
198 (struct isis_area *)arg, 0);
199 listnode_add (isis->init_circ_list, circuit);
200 break;
201 case IF_DOWN_FROM_Z:
202 isis_circuit_down (circuit);
203 isis_circuit_if_del (circuit, (struct interface *) arg);
204 circuit->state = C_STATE_CONF;
205 isis_event_circuit_state_change (circuit, circuit->area, 0);
206 break;
207 }
208 break;
209
210 default:
211 zlog_warn ("Invalid circuit state %d", old_state);
212 }
213
214 if (isis->debugs & DEBUG_EVENTS)
215 zlog_debug ("CSM_STATE_CHANGE: %s -> %s ", STATE2STR (old_state),
216 circuit ? STATE2STR (circuit->state) : STATE2STR (C_STATE_NA));
217
218 return circuit;
219 }