isis_csm.c 6.1 KB

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