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/include-netbsd/iso.h" 37#include "isisd/isis_constants.h" 38#include "isisd/isis_common.h" 39#include "isisd/isis_flags.h" 40#include "isisd/isis_circuit.h" 41#include "isisd/isis_tlv.h" 42#include "isisd/isis_lsp.h" 43#include "isisd/isis_pdu.h" 44#include "isisd/isis_network.h" 45#include "isisd/isis_misc.h" 46#include "isisd/isis_constants.h" 47#include "isisd/isis_adjacency.h" 48#include "isisd/isis_dr.h" 49#include "isisd/isisd.h" 50#include "isisd/isis_csm.h" 51#include "isisd/isis_events.h" 52 53extern struct isis *isis; 54 55static const char *csm_statestr[] = { 56 "C_STATE_NA", 57 "C_STATE_INIT", 58 "C_STATE_CONF", 59 "C_STATE_UP" 60}; 61 62#define STATE2STR(S) csm_statestr[S] 63 64static const char *csm_eventstr[] = { 65 "NO_STATE", 66 "ISIS_ENABLE", 67 "IF_UP_FROM_Z", 68 "ISIS_DISABLE", 69 "IF_DOWN_FROM_Z", 70}; 71 72#define EVENT2STR(E) csm_eventstr[E] 73 74struct isis_circuit * 75isis_csm_state_change (int event, struct isis_circuit *circuit, void *arg) 76{ 77 int old_state; 78 79 old_state = circuit ? circuit->state : C_STATE_NA; 80 if (isis->debugs & DEBUG_EVENTS) 81 zlog_debug ("CSM_EVENT: %s", EVENT2STR (event)); 82 83 switch (old_state) 84 { 85 case C_STATE_NA: 86 if (circuit) 87 zlog_warn ("Non-null circuit while state C_STATE_NA"); 88 assert (circuit == NULL); 89 switch (event) 90 { 91 case ISIS_ENABLE: 92 circuit = isis_circuit_new (); 93 isis_circuit_configure (circuit, (struct isis_area *) arg); 94 circuit->state = C_STATE_CONF; 95 break; 96 case IF_UP_FROM_Z: 97 circuit = isis_circuit_new (); 98 isis_circuit_if_add (circuit, (struct interface *) arg); 99 listnode_add (isis->init_circ_list, circuit); 100 circuit->state = C_STATE_INIT; 101 break; 102 case ISIS_DISABLE: 103 zlog_warn ("circuit already disabled"); 104 break; 105 case IF_DOWN_FROM_Z: 106 zlog_warn ("circuit already disconnected"); 107 break; 108 } 109 break; 110 case C_STATE_INIT: 111 assert (circuit); 112 switch (event) 113 { 114 case ISIS_ENABLE: 115 isis_circuit_configure (circuit, (struct isis_area *) arg); 116 if (isis_circuit_up (circuit) != ISIS_OK) 117 { 118 isis_circuit_deconfigure (circuit, (struct isis_area *) arg); 119 break; 120 } 121 circuit->state = C_STATE_UP; 122 isis_event_circuit_state_change (circuit, circuit->area, 1); 123 listnode_delete (isis->init_circ_list, circuit); 124 break; 125 case IF_UP_FROM_Z: 126 assert (circuit); 127 zlog_warn ("circuit already connected"); 128 break; 129 case ISIS_DISABLE: 130 zlog_warn ("circuit already disabled"); 131 break; 132 case IF_DOWN_FROM_Z: 133 isis_circuit_if_del (circuit, (struct interface *) arg); 134 listnode_delete (isis->init_circ_list, circuit); 135 isis_circuit_del (circuit); 136 circuit = NULL; 137 break; 138 } 139 break; 140 case C_STATE_CONF: 141 assert (circuit); 142 switch (event) 143 { 144 case ISIS_ENABLE: 145 zlog_warn ("circuit already enabled"); 146 break; 147 case IF_UP_FROM_Z: 148 isis_circuit_if_add (circuit, (struct interface *) arg); 149 if (isis_circuit_up (circuit) != ISIS_OK) 150 { 151 isis_circuit_if_del (circuit, (struct interface *) arg); 152 break; 153 } 154 circuit->state = C_STATE_UP; 155 isis_event_circuit_state_change (circuit, circuit->area, 1); 156 break; 157 case ISIS_DISABLE: 158 isis_circuit_deconfigure (circuit, (struct isis_area *) arg); 159 isis_circuit_del (circuit); 160 circuit = NULL; 161 break; 162 case IF_DOWN_FROM_Z: 163 zlog_warn ("circuit already disconnected"); 164 break; 165 } 166 break; 167 case C_STATE_UP: 168 assert (circuit); 169 switch (event) 170 { 171 case ISIS_ENABLE: 172 zlog_warn ("circuit already configured"); 173 break; 174 case IF_UP_FROM_Z: 175 zlog_warn ("circuit already connected"); 176 break; 177 case ISIS_DISABLE: 178 isis_circuit_down (circuit); 179 isis_circuit_deconfigure (circuit, (struct isis_area *) arg); 180 circuit->state = C_STATE_INIT; 181 isis_event_circuit_state_change (circuit, 182 (struct isis_area *)arg, 0); 183 listnode_add (isis->init_circ_list, circuit); 184 break; 185 case IF_DOWN_FROM_Z: 186 isis_circuit_down (circuit); 187 isis_circuit_if_del (circuit, (struct interface *) arg); 188 circuit->state = C_STATE_CONF; 189 isis_event_circuit_state_change (circuit, circuit->area, 0); 190 break; 191 } 192 break; 193 194 default: 195 zlog_warn ("Invalid circuit state %d", old_state); 196 } 197 198 if (isis->debugs & DEBUG_EVENTS) 199 zlog_debug ("CSM_STATE_CHANGE: %s -> %s ", STATE2STR (old_state), 200 circuit ? STATE2STR (circuit->state) : STATE2STR (C_STATE_NA)); 201 202 return circuit; 203} 204