File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / isisd / isis_events.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Oct 9 09:22:28 2012 UTC (11 years, 9 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, v0_99_21, HEAD
quagga

    1: /*
    2:  * IS-IS Rout(e)ing protocol - isis_events.h   
    3:  *
    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: 
   24: #include "log.h"
   25: #include "memory.h"
   26: #include "if.h"
   27: #include "linklist.h"
   28: #include "command.h"
   29: #include "thread.h"
   30: #include "hash.h"
   31: #include "prefix.h"
   32: #include "stream.h"
   33: #include "table.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: #include "isisd/isis_spf.h"
   53: 
   54: /* debug isis-spf spf-events 
   55:  4w4d: ISIS-Spf (tlt): L2 SPF needed, new adjacency, from 0x609229F4
   56:  4w4d: ISIS-Spf (tlt): L2, 0000.0000.0042.01-00 TLV contents changed, code 0x2
   57:  4w4d: ISIS-Spf (tlt): L2, new LSP 0 DEAD.BEEF.0043.00-00
   58:  4w5d: ISIS-Spf (tlt): L1 SPF needed, periodic SPF, from 0x6091C844
   59:  4w5d: ISIS-Spf (tlt): L2 SPF needed, periodic SPF, from 0x6091C844
   60: */
   61: 
   62: void
   63: isis_event_circuit_state_change (struct isis_circuit *circuit,
   64:                                  struct isis_area *area, int up)
   65: {
   66:   area->circuit_state_changes++;
   67: 
   68:   if (isis->debugs & DEBUG_EVENTS)
   69:     zlog_debug ("ISIS-Evt (%s) circuit %s", area->area_tag,
   70:                 up ? "up" : "down");
   71: 
   72:   /*
   73:    * Regenerate LSPs this affects
   74:    */
   75:   lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 0);
   76: 
   77:   return;
   78: }
   79: 
   80: static void
   81: area_resign_level (struct isis_area *area, int level)
   82: {
   83:   if (area->lspdb[level - 1])
   84:     {
   85:       lsp_db_destroy (area->lspdb[level - 1]);
   86:       area->lspdb[level - 1] = NULL;
   87:     }
   88:   if (area->spftree[level - 1])
   89:     {
   90:       isis_spftree_del (area->spftree[level - 1]);
   91:       area->spftree[level - 1] = NULL;
   92:     }
   93: #ifdef HAVE_IPV6
   94:   if (area->spftree6[level - 1])
   95:     {
   96:       isis_spftree_del (area->spftree6[level - 1]);
   97:       area->spftree6[level - 1] = NULL;
   98:     }
   99: #endif
  100:   if (area->route_table[level - 1])
  101:     {
  102:       route_table_finish (area->route_table[level - 1]);
  103:       area->route_table[level - 1] = NULL;
  104:     }
  105: #ifdef HAVE_IPV6
  106:   if (area->route_table6[level - 1])
  107:     {
  108:       route_table_finish (area->route_table6[level - 1]);
  109:       area->route_table6[level - 1] = NULL;
  110:     }
  111: #endif /* HAVE_IPV6 */
  112: 
  113:   THREAD_TIMER_OFF (area->t_lsp_refresh[level - 1]);
  114: }
  115: 
  116: void
  117: isis_event_system_type_change (struct isis_area *area, int newtype)
  118: {
  119:   struct listnode *node;
  120:   struct isis_circuit *circuit;
  121: 
  122:   if (isis->debugs & DEBUG_EVENTS)
  123:     zlog_debug ("ISIS-Evt (%s) system type change %s -> %s", area->area_tag,
  124: 	       circuit_t2string (area->is_type), circuit_t2string (newtype));
  125: 
  126:   if (area->is_type == newtype)
  127:     return;			/* No change */
  128: 
  129:   switch (area->is_type)
  130:   {
  131:     case IS_LEVEL_1:
  132:       if (newtype == IS_LEVEL_2)
  133:         area_resign_level (area, IS_LEVEL_1);
  134: 
  135:       if (area->lspdb[1] == NULL)
  136:         area->lspdb[1] = lsp_db_init ();
  137:       if (area->route_table[1] == NULL)
  138:         area->route_table[1] = route_table_init ();
  139: #ifdef HAVE_IPV6
  140:       if (area->route_table6[1] == NULL)
  141:         area->route_table6[1] = route_table_init ();
  142: #endif /* HAVE_IPV6 */
  143:       break;
  144: 
  145:     case IS_LEVEL_1_AND_2:
  146:       if (newtype == IS_LEVEL_1)
  147:         area_resign_level (area, IS_LEVEL_2);
  148:       else
  149:         area_resign_level (area, IS_LEVEL_1);
  150:       break;
  151: 
  152:     case IS_LEVEL_2:
  153:       if (newtype == IS_LEVEL_1)
  154:         area_resign_level (area, IS_LEVEL_2);
  155: 
  156:       if (area->lspdb[0] == NULL)
  157:         area->lspdb[0] = lsp_db_init ();
  158:       if (area->route_table[0] == NULL)
  159:         area->route_table[0] = route_table_init ();
  160: #ifdef HAVE_IPV6
  161:       if (area->route_table6[0] == NULL)
  162:         area->route_table6[0] = route_table_init ();
  163: #endif /* HAVE_IPV6 */
  164:       break;
  165: 
  166:     default:
  167:       break;
  168:   }
  169: 
  170:   area->is_type = newtype;
  171: 
  172:   /* override circuit's is_type */
  173:   if (area->is_type != IS_LEVEL_1_AND_2)
  174:   {
  175:     for (ALL_LIST_ELEMENTS_RO (area->circuit_list, node, circuit))
  176:       isis_event_circuit_type_change (circuit, newtype);
  177:   }
  178: 
  179:   spftree_area_init (area);
  180: 
  181:   if (newtype & IS_LEVEL_1)
  182:     lsp_generate (area, IS_LEVEL_1);
  183:   if (newtype & IS_LEVEL_2)
  184:     lsp_generate (area, IS_LEVEL_2);
  185:   lsp_regenerate_schedule (area, IS_LEVEL_1 | IS_LEVEL_2, 1);
  186: 
  187:   return;
  188: }
  189: 
  190: static void
  191: circuit_commence_level (struct isis_circuit *circuit, int level)
  192: {
  193:   if (level == 1)
  194:     {
  195:       if (! circuit->is_passive)
  196:         THREAD_TIMER_ON (master, circuit->t_send_psnp[0], send_l1_psnp, circuit,
  197: 		         isis_jitter (circuit->psnp_interval[0], PSNP_JITTER));
  198: 
  199:       if (circuit->circ_type == CIRCUIT_T_BROADCAST)
  200: 	{
  201: 	  THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[0], isis_run_dr_l1,
  202: 			   circuit, 2 * circuit->hello_interval[0]);
  203: 
  204: 	  THREAD_TIMER_ON (master, circuit->u.bc.t_send_lan_hello[0],
  205: 			   send_lan_l1_hello, circuit,
  206: 			   isis_jitter (circuit->hello_interval[0],
  207: 					IIH_JITTER));
  208: 
  209: 	  circuit->u.bc.lan_neighs[0] = list_new ();
  210: 	}
  211:     }
  212:   else
  213:     {
  214:       if (! circuit->is_passive)
  215:         THREAD_TIMER_ON (master, circuit->t_send_psnp[1], send_l2_psnp, circuit,
  216: 		         isis_jitter (circuit->psnp_interval[1], PSNP_JITTER));
  217: 
  218:       if (circuit->circ_type == CIRCUIT_T_BROADCAST)
  219: 	{
  220: 	  THREAD_TIMER_ON (master, circuit->u.bc.t_run_dr[1], isis_run_dr_l2,
  221: 			   circuit, 2 * circuit->hello_interval[1]);
  222: 
  223: 	  THREAD_TIMER_ON (master, circuit->u.bc.t_send_lan_hello[1],
  224: 			   send_lan_l2_hello, circuit,
  225: 			   isis_jitter (circuit->hello_interval[1],
  226: 					IIH_JITTER));
  227: 
  228: 	  circuit->u.bc.lan_neighs[1] = list_new ();
  229: 	}
  230:     }
  231: 
  232:   return;
  233: }
  234: 
  235: static void
  236: circuit_resign_level (struct isis_circuit *circuit, int level)
  237: {
  238:   int idx = level - 1;
  239: 
  240:   THREAD_TIMER_OFF (circuit->t_send_csnp[idx]);
  241:   THREAD_TIMER_OFF (circuit->t_send_psnp[idx]);
  242: 
  243:   if (circuit->circ_type == CIRCUIT_T_BROADCAST)
  244:     {
  245:       THREAD_TIMER_OFF (circuit->u.bc.t_send_lan_hello[idx]);
  246:       THREAD_TIMER_OFF (circuit->u.bc.t_run_dr[idx]);
  247:       THREAD_TIMER_OFF (circuit->u.bc.t_refresh_pseudo_lsp[idx]);
  248:       circuit->u.bc.run_dr_elect[idx] = 0;
  249:       list_delete (circuit->u.bc.lan_neighs[idx]);
  250:       circuit->u.bc.lan_neighs[idx] = NULL;
  251:     }
  252: 
  253:   return;
  254: }
  255: 
  256: void
  257: isis_event_circuit_type_change (struct isis_circuit *circuit, int newtype)
  258: {
  259:   if (circuit->state != C_STATE_UP)
  260:   {
  261:     circuit->is_type = newtype;
  262:     return;
  263:   }
  264: 
  265:   if (isis->debugs & DEBUG_EVENTS)
  266:     zlog_debug ("ISIS-Evt (%s) circuit type change %s -> %s",
  267: 	       circuit->area->area_tag,
  268: 	       circuit_t2string (circuit->is_type),
  269: 	       circuit_t2string (newtype));
  270: 
  271:   if (circuit->is_type == newtype)
  272:     return;			/* No change */
  273: 
  274:   if (!(newtype & circuit->area->is_type))
  275:     {
  276:       zlog_err ("ISIS-Evt (%s) circuit type change - invalid level %s because"
  277: 		" area is %s", circuit->area->area_tag,
  278: 		circuit_t2string (newtype),
  279: 		circuit_t2string (circuit->area->is_type));
  280:       return;
  281:     }
  282: 
  283:   switch (circuit->is_type)
  284:     {
  285:     case IS_LEVEL_1:
  286:       if (newtype == IS_LEVEL_2)
  287: 	circuit_resign_level (circuit, 1);
  288:       circuit_commence_level (circuit, 2);
  289:       break;
  290:     case IS_LEVEL_1_AND_2:
  291:       if (newtype == IS_LEVEL_1)
  292: 	circuit_resign_level (circuit, 2);
  293:       else
  294: 	circuit_resign_level (circuit, 1);
  295:       break;
  296:     case IS_LEVEL_2:
  297:       if (newtype == IS_LEVEL_1)
  298: 	circuit_resign_level (circuit, 2);
  299:       circuit_commence_level (circuit, 1);
  300:       break;
  301:     default:
  302:       break;
  303:     }
  304: 
  305:   circuit->is_type = newtype;
  306:   lsp_regenerate_schedule (circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0);
  307: 
  308:   return;
  309: }
  310: 
  311:  /* 04/18/2002 by Gwak. */
  312:  /**************************************************************************
  313:   *
  314:   * EVENTS for LSP generation
  315:   *
  316:   * 1) an Adajacency or Circuit Up/Down event
  317:   * 2) a chnage in Circuit metric
  318:   * 3) a change in Reachable Address metric
  319:   * 4) a change in manualAreaAddresses
  320:   * 5) a change in systemID
  321:   * 6) a change in DIS status
  322:   * 7) a chnage in the waiting status
  323:   *
  324:   * ***********************************************************************
  325:   *
  326:   * current support event
  327:   *
  328:   * 1) Adjacency Up/Down event
  329:   * 6) a change in DIS status
  330:   *
  331:   * ***********************************************************************/
  332: 
  333: void
  334: isis_event_adjacency_state_change (struct isis_adjacency *adj, int newstate)
  335: {
  336:   /* adjacency state change event. 
  337:    * - the only proto-type was supported */
  338: 
  339:   /* invalid arguments */
  340:   if (!adj || !adj->circuit || !adj->circuit->area)
  341:     return;
  342: 
  343:   if (isis->debugs & DEBUG_EVENTS)
  344:     zlog_debug ("ISIS-Evt (%s) Adjacency State change",
  345: 		adj->circuit->area->area_tag);
  346: 
  347:   /* LSP generation again */
  348:   lsp_regenerate_schedule (adj->circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0);
  349: 
  350:   return;
  351: }
  352: 
  353: /* events supporting code */
  354: 
  355: int
  356: isis_event_dis_status_change (struct thread *thread)
  357: {
  358:   struct isis_circuit *circuit;
  359: 
  360:   circuit = THREAD_ARG (thread);
  361: 
  362:   /* invalid arguments */
  363:   if (!circuit || !circuit->area)
  364:     return 0;
  365:   if (isis->debugs & DEBUG_EVENTS)
  366:     zlog_debug ("ISIS-Evt (%s) DIS status change", circuit->area->area_tag);
  367: 
  368:   /* LSP generation again */
  369:   lsp_regenerate_schedule (circuit->area, IS_LEVEL_1 | IS_LEVEL_2, 0);
  370: 
  371:   return 0;
  372: }
  373: 
  374: void
  375: isis_event_auth_failure (char *area_tag, const char *error_string, u_char *sysid)
  376: {
  377:   if (isis->debugs & DEBUG_EVENTS)
  378:     zlog_debug ("ISIS-Evt (%s) Authentication failure %s from %s",
  379: 		area_tag, error_string, sysid_print (sysid));
  380: 
  381:   return;
  382: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>