File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospf6d / ospf6_neighbor.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:11 2016 UTC (7 years, 7 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    1: /*
    2:  * Copyright (C) 2003 Yasuhiro Ohara
    3:  *
    4:  * This file is part of GNU Zebra.
    5:  *
    6:  * GNU Zebra is free software; you can redistribute it and/or modify it
    7:  * under the terms of the GNU General Public License as published by the
    8:  * Free Software Foundation; either version 2, or (at your option) any
    9:  * later version.
   10:  *
   11:  * GNU Zebra is distributed in the hope that it will be useful, but
   12:  * WITHOUT ANY WARRANTY; without even the implied warranty of
   13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14:  * General Public License for more details.
   15:  *
   16:  * You should have received a copy of the GNU General Public License
   17:  * along with GNU Zebra; see the file COPYING.  If not, write to the 
   18:  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
   19:  * Boston, MA 02111-1307, USA.  
   20:  */
   21: 
   22: #include <zebra.h>
   23: 
   24: #include "log.h"
   25: #include "memory.h"
   26: #include "thread.h"
   27: #include "linklist.h"
   28: #include "vty.h"
   29: #include "command.h"
   30: 
   31: #include "ospf6_proto.h"
   32: #include "ospf6_lsa.h"
   33: #include "ospf6_lsdb.h"
   34: #include "ospf6_message.h"
   35: #include "ospf6_top.h"
   36: #include "ospf6_area.h"
   37: #include "ospf6_interface.h"
   38: #include "ospf6_neighbor.h"
   39: #include "ospf6_intra.h"
   40: #include "ospf6_flood.h"
   41: #include "ospf6_snmp.h"
   42: #include "ospf6d.h"
   43: 
   44: unsigned char conf_debug_ospf6_neighbor = 0;
   45: 
   46: const char *ospf6_neighbor_state_str[] =
   47: { "None", "Down", "Attempt", "Init", "Twoway", "ExStart", "ExChange",
   48:   "Loading", "Full", NULL };
   49: 
   50: static const char *ospf6_neighbor_event_str[] =
   51:   {
   52:     "NoEvent",
   53:     "HelloReceived",
   54:     "2-WayReceived",
   55:     "NegotiationDone",
   56:     "ExchangeDone",
   57:     "LoadingDone",
   58:     "AdjOK?",
   59:     "SeqNumberMismatch",
   60:     "BadLSReq",
   61:     "1-WayReceived",
   62:     "InactivityTimer",
   63:   };
   64: 
   65: static const char *
   66: ospf6_neighbor_event_string (int event)
   67: {
   68:   #define OSPF6_NEIGHBOR_UNKNOWN_EVENT_STRING "UnknownEvent"
   69: 
   70:   if (event < OSPF6_NEIGHBOR_EVENT_MAX_EVENT)
   71:       return ospf6_neighbor_event_str[event];
   72:   return OSPF6_NEIGHBOR_UNKNOWN_EVENT_STRING;
   73: }
   74: 
   75: int
   76: ospf6_neighbor_cmp (void *va, void *vb)
   77: {
   78:   struct ospf6_neighbor *ona = (struct ospf6_neighbor *) va;
   79:   struct ospf6_neighbor *onb = (struct ospf6_neighbor *) vb;
   80:   return (ntohl (ona->router_id) < ntohl (onb->router_id) ? -1 : 1);
   81: }
   82: 
   83: struct ospf6_neighbor *
   84: ospf6_neighbor_lookup (u_int32_t router_id,
   85:                        struct ospf6_interface *oi)
   86: {
   87:   struct listnode *n;
   88:   struct ospf6_neighbor *on;
   89: 
   90:   for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, n, on))
   91:     if (on->router_id == router_id)
   92:       return on;
   93:   
   94:   return (struct ospf6_neighbor *) NULL;
   95: }
   96: 
   97: /* create ospf6_neighbor */
   98: struct ospf6_neighbor *
   99: ospf6_neighbor_create (u_int32_t router_id, struct ospf6_interface *oi)
  100: {
  101:   struct ospf6_neighbor *on;
  102:   char buf[16];
  103: 
  104:   on = (struct ospf6_neighbor *)
  105:     XMALLOC (MTYPE_OSPF6_NEIGHBOR, sizeof (struct ospf6_neighbor));
  106:   if (on == NULL)
  107:     {
  108:       zlog_warn ("neighbor: malloc failed");
  109:       return NULL;
  110:     }
  111: 
  112:   memset (on, 0, sizeof (struct ospf6_neighbor));
  113:   inet_ntop (AF_INET, &router_id, buf, sizeof (buf));
  114:   snprintf (on->name, sizeof (on->name), "%s%%%s",
  115:             buf, oi->interface->name);
  116:   on->ospf6_if = oi;
  117:   on->state = OSPF6_NEIGHBOR_DOWN;
  118:   on->state_change = 0;
  119:   quagga_gettime (QUAGGA_CLK_MONOTONIC, &on->last_changed);
  120:   on->router_id = router_id;
  121: 
  122:   on->summary_list = ospf6_lsdb_create (on);
  123:   on->request_list = ospf6_lsdb_create (on);
  124:   on->retrans_list = ospf6_lsdb_create (on);
  125: 
  126:   on->dbdesc_list = ospf6_lsdb_create (on);
  127:   on->lsupdate_list = ospf6_lsdb_create (on);
  128:   on->lsack_list = ospf6_lsdb_create (on);
  129: 
  130:   listnode_add_sort (oi->neighbor_list, on);
  131:   return on;
  132: }
  133: 
  134: void
  135: ospf6_neighbor_delete (struct ospf6_neighbor *on)
  136: {
  137:   struct ospf6_lsa *lsa;
  138: 
  139:   ospf6_lsdb_remove_all (on->summary_list);
  140:   ospf6_lsdb_remove_all (on->request_list);
  141:   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  142:        lsa = ospf6_lsdb_next (lsa))
  143:     {
  144:       ospf6_decrement_retrans_count (lsa);
  145:       ospf6_lsdb_remove (lsa, on->retrans_list);
  146:     }
  147: 
  148:   ospf6_lsdb_remove_all (on->dbdesc_list);
  149:   ospf6_lsdb_remove_all (on->lsupdate_list);
  150:   ospf6_lsdb_remove_all (on->lsack_list);
  151: 
  152:   ospf6_lsdb_delete (on->summary_list);
  153:   ospf6_lsdb_delete (on->request_list);
  154:   ospf6_lsdb_delete (on->retrans_list);
  155: 
  156:   ospf6_lsdb_delete (on->dbdesc_list);
  157:   ospf6_lsdb_delete (on->lsupdate_list);
  158:   ospf6_lsdb_delete (on->lsack_list);
  159: 
  160:   THREAD_OFF (on->inactivity_timer);
  161: 
  162:   THREAD_OFF (on->thread_send_dbdesc);
  163:   THREAD_OFF (on->thread_send_lsreq);
  164:   THREAD_OFF (on->thread_send_lsupdate);
  165:   THREAD_OFF (on->thread_send_lsack);
  166: 
  167:   XFREE (MTYPE_OSPF6_NEIGHBOR, on);
  168: }
  169: 
  170: static void
  171: ospf6_neighbor_state_change (u_char next_state, struct ospf6_neighbor *on, int event)
  172: {
  173:   u_char prev_state;
  174: 
  175:   prev_state = on->state;
  176:   on->state = next_state;
  177: 
  178:   if (prev_state == next_state)
  179:     return;
  180: 
  181:   on->state_change++;
  182:   quagga_gettime (QUAGGA_CLK_MONOTONIC, &on->last_changed);
  183: 
  184:   /* log */
  185:   if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
  186:     {
  187:       zlog_debug ("Neighbor state change %s: [%s]->[%s] (%s)", on->name,
  188: 		  ospf6_neighbor_state_str[prev_state],
  189: 		  ospf6_neighbor_state_str[next_state],
  190: 		  ospf6_neighbor_event_string(event));
  191:     }
  192: 
  193:   /* Optionally notify about adjacency changes */
  194:   if (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags,
  195: 		 OSPF6_LOG_ADJACENCY_CHANGES) &&
  196:       (CHECK_FLAG(on->ospf6_if->area->ospf6->config_flags,
  197: 		  OSPF6_LOG_ADJACENCY_DETAIL) ||
  198:        (next_state == OSPF6_NEIGHBOR_FULL) || (next_state < prev_state)))
  199:     zlog_notice("AdjChg: Nbr %s: %s -> %s (%s)", on->name,
  200: 		ospf6_neighbor_state_str[prev_state],
  201: 		ospf6_neighbor_state_str[next_state],
  202: 		ospf6_neighbor_event_string(event));
  203: 
  204:   if (prev_state == OSPF6_NEIGHBOR_FULL || next_state == OSPF6_NEIGHBOR_FULL)
  205:     {
  206:       OSPF6_ROUTER_LSA_SCHEDULE (on->ospf6_if->area);
  207:       if (on->ospf6_if->state == OSPF6_INTERFACE_DR)
  208:         {
  209:           OSPF6_NETWORK_LSA_SCHEDULE (on->ospf6_if);
  210:           OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (on->ospf6_if);
  211:         }
  212:       OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (on->ospf6_if->area);
  213:     }
  214: 
  215:   if ((prev_state == OSPF6_NEIGHBOR_EXCHANGE ||
  216:        prev_state == OSPF6_NEIGHBOR_LOADING) &&
  217:       (next_state != OSPF6_NEIGHBOR_EXCHANGE &&
  218:        next_state != OSPF6_NEIGHBOR_LOADING))
  219:     ospf6_maxage_remove (on->ospf6_if->area->ospf6);
  220: 
  221: #ifdef HAVE_SNMP
  222:   /* Terminal state or regression */ 
  223:   if ((next_state == OSPF6_NEIGHBOR_FULL)  ||
  224:       (next_state == OSPF6_NEIGHBOR_TWOWAY) ||
  225:       (next_state < prev_state))
  226:     ospf6TrapNbrStateChange (on);
  227: #endif
  228: 
  229: }
  230: 
  231: /* RFC2328 section 10.4 */
  232: static int
  233: need_adjacency (struct ospf6_neighbor *on)
  234: {
  235:   if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT ||
  236:       on->ospf6_if->state == OSPF6_INTERFACE_DR ||
  237:       on->ospf6_if->state == OSPF6_INTERFACE_BDR)
  238:     return 1;
  239: 
  240:   if (on->ospf6_if->drouter == on->router_id ||
  241:       on->ospf6_if->bdrouter == on->router_id)
  242:     return 1;
  243: 
  244:   return 0;
  245: }
  246: 
  247: int
  248: hello_received (struct thread *thread)
  249: {
  250:   struct ospf6_neighbor *on;
  251: 
  252:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  253:   assert (on);
  254: 
  255:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  256:     zlog_debug ("Neighbor Event %s: *HelloReceived*", on->name);
  257: 
  258:   /* reset Inactivity Timer */
  259:   THREAD_OFF (on->inactivity_timer);
  260:   on->inactivity_timer = thread_add_timer (master, inactivity_timer, on,
  261:                                            on->ospf6_if->dead_interval);
  262: 
  263:   if (on->state <= OSPF6_NEIGHBOR_DOWN)
  264:     ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on,
  265: 				 OSPF6_NEIGHBOR_EVENT_HELLO_RCVD);
  266: 
  267:   return 0;
  268: }
  269: 
  270: int
  271: twoway_received (struct thread *thread)
  272: {
  273:   struct ospf6_neighbor *on;
  274: 
  275:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  276:   assert (on);
  277: 
  278:   if (on->state > OSPF6_NEIGHBOR_INIT)
  279:     return 0;
  280: 
  281:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  282:     zlog_debug ("Neighbor Event %s: *2Way-Received*", on->name);
  283: 
  284:   thread_add_event (master, neighbor_change, on->ospf6_if, 0);
  285: 
  286:   if (! need_adjacency (on))
  287:     {
  288:       ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on,
  289: 				   OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD);
  290:       return 0;
  291:     }
  292: 
  293:   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on,
  294: 			       OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD);
  295:   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
  296:   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
  297:   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
  298: 
  299:   THREAD_OFF (on->thread_send_dbdesc);
  300:   on->thread_send_dbdesc =
  301:     thread_add_event (master, ospf6_dbdesc_send, on, 0);
  302: 
  303:   return 0;
  304: }
  305: 
  306: int
  307: negotiation_done (struct thread *thread)
  308: {
  309:   struct ospf6_neighbor *on;
  310:   struct ospf6_lsa *lsa;
  311: 
  312:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  313:   assert (on);
  314: 
  315:   if (on->state != OSPF6_NEIGHBOR_EXSTART)
  316:     return 0;
  317: 
  318:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  319:     zlog_debug ("Neighbor Event %s: *NegotiationDone*", on->name);
  320: 
  321:   /* clear ls-list */
  322:   ospf6_lsdb_remove_all (on->summary_list);
  323:   ospf6_lsdb_remove_all (on->request_list);
  324:   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  325:        lsa = ospf6_lsdb_next (lsa))
  326:     {
  327:       ospf6_decrement_retrans_count (lsa);
  328:       ospf6_lsdb_remove (lsa, on->retrans_list);
  329:     }
  330: 
  331:   /* Interface scoped LSAs */
  332:   for (lsa = ospf6_lsdb_head (on->ospf6_if->lsdb); lsa;
  333:        lsa = ospf6_lsdb_next (lsa))
  334:     {
  335:       if (OSPF6_LSA_IS_MAXAGE (lsa))
  336:         {
  337:           ospf6_increment_retrans_count (lsa);
  338:           ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
  339:         }
  340:       else
  341:         ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
  342:     }
  343: 
  344:   /* Area scoped LSAs */
  345:   for (lsa = ospf6_lsdb_head (on->ospf6_if->area->lsdb); lsa;
  346:        lsa = ospf6_lsdb_next (lsa))
  347:     {
  348:       if (OSPF6_LSA_IS_MAXAGE (lsa))
  349:         {
  350:           ospf6_increment_retrans_count (lsa);
  351:           ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
  352:         }
  353:       else
  354:         ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
  355:     }
  356: 
  357:   /* AS scoped LSAs */
  358:   for (lsa = ospf6_lsdb_head (on->ospf6_if->area->ospf6->lsdb); lsa;
  359:        lsa = ospf6_lsdb_next (lsa))
  360:     {
  361:       if (OSPF6_LSA_IS_MAXAGE (lsa))
  362:         {
  363:           ospf6_increment_retrans_count (lsa);
  364:           ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
  365:         }
  366:       else
  367:         ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->summary_list);
  368:     }
  369: 
  370:   UNSET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
  371:   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXCHANGE, on,
  372: 			       OSPF6_NEIGHBOR_EVENT_NEGOTIATION_DONE);
  373: 
  374:   return 0;
  375: }
  376: 
  377: int
  378: exchange_done (struct thread *thread)
  379: {
  380:   struct ospf6_neighbor *on;
  381: 
  382:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  383:   assert (on);
  384: 
  385:   if (on->state != OSPF6_NEIGHBOR_EXCHANGE)
  386:     return 0;
  387: 
  388:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  389:     zlog_debug ("Neighbor Event %s: *ExchangeDone*", on->name);
  390: 
  391:   THREAD_OFF (on->thread_send_dbdesc);
  392:   ospf6_lsdb_remove_all (on->dbdesc_list);
  393: 
  394: /* XXX
  395:   thread_add_timer (master, ospf6_neighbor_last_dbdesc_release, on,
  396:                     on->ospf6_if->dead_interval);
  397: */
  398: 
  399:   if (on->request_list->count == 0)
  400:     ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on,
  401: 				 OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE);
  402:   else
  403:     {
  404:       ospf6_neighbor_state_change (OSPF6_NEIGHBOR_LOADING, on,
  405: 				   OSPF6_NEIGHBOR_EVENT_EXCHANGE_DONE);
  406: 
  407:       if (on->thread_send_lsreq == NULL)
  408: 	on->thread_send_lsreq =
  409: 	  thread_add_event (master, ospf6_lsreq_send, on, 0);
  410:     }
  411: 
  412:   return 0;
  413: }
  414: 
  415: /* Check loading state. */
  416: void
  417: ospf6_check_nbr_loading (struct ospf6_neighbor *on)
  418: {
  419: 
  420:   /* RFC2328 Section 10.9: When the neighbor responds to these requests
  421:      with the proper Link State Update packet(s), the Link state request
  422:      list is truncated and a new Link State Request packet is sent.
  423:   */
  424:   if ((on->state == OSPF6_NEIGHBOR_LOADING) ||
  425:       (on->state == OSPF6_NEIGHBOR_EXCHANGE))
  426:     {
  427:       if (on->request_list->count == 0)
  428: 	thread_add_event (master, loading_done, on, 0);
  429:       else if (on->last_ls_req == NULL)
  430: 	{
  431: 	  if (on->thread_send_lsreq != NULL)
  432: 	    THREAD_OFF (on->thread_send_lsreq);
  433: 	  on->thread_send_lsreq =
  434: 	    thread_add_event (master, ospf6_lsreq_send, on, 0);
  435: 	}
  436:     }
  437: }
  438: 
  439: int
  440: loading_done (struct thread *thread)
  441: {
  442:   struct ospf6_neighbor *on;
  443: 
  444:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  445:   assert (on);
  446: 
  447:   if (on->state != OSPF6_NEIGHBOR_LOADING)
  448:     return 0;
  449: 
  450:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  451:     zlog_debug ("Neighbor Event %s: *LoadingDone*", on->name);
  452: 
  453:   assert (on->request_list->count == 0);
  454: 
  455:   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_FULL, on,
  456: 			       OSPF6_NEIGHBOR_EVENT_LOADING_DONE);
  457: 
  458:   return 0;
  459: }
  460: 
  461: int
  462: adj_ok (struct thread *thread)
  463: {
  464:   struct ospf6_neighbor *on;
  465:   struct ospf6_lsa *lsa;
  466: 
  467:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  468:   assert (on);
  469: 
  470:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  471:     zlog_debug ("Neighbor Event %s: *AdjOK?*", on->name);
  472: 
  473:   if (on->state == OSPF6_NEIGHBOR_TWOWAY && need_adjacency (on))
  474:     {
  475:       ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on,
  476: 				   OSPF6_NEIGHBOR_EVENT_ADJ_OK);
  477:       SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
  478:       SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
  479:       SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
  480: 
  481:       THREAD_OFF (on->thread_send_dbdesc);
  482:       on->thread_send_dbdesc =
  483:         thread_add_event (master, ospf6_dbdesc_send, on, 0);
  484: 
  485:     }
  486:   else if (on->state >= OSPF6_NEIGHBOR_EXSTART &&
  487:            ! need_adjacency (on))
  488:     {
  489:       ospf6_neighbor_state_change (OSPF6_NEIGHBOR_TWOWAY, on,
  490: 				   OSPF6_NEIGHBOR_EVENT_ADJ_OK);
  491:       ospf6_lsdb_remove_all (on->summary_list);
  492:       ospf6_lsdb_remove_all (on->request_list);
  493:       for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  494:            lsa = ospf6_lsdb_next (lsa))
  495:         {
  496:           ospf6_decrement_retrans_count (lsa);
  497:           ospf6_lsdb_remove (lsa, on->retrans_list);
  498:         }
  499:     }
  500: 
  501:   return 0;
  502: }
  503: 
  504: int
  505: seqnumber_mismatch (struct thread *thread)
  506: {
  507:   struct ospf6_neighbor *on;
  508:   struct ospf6_lsa *lsa;
  509: 
  510:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  511:   assert (on);
  512: 
  513:   if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
  514:     return 0;
  515: 
  516:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  517:     zlog_debug ("Neighbor Event %s: *SeqNumberMismatch*", on->name);
  518: 
  519:   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on,
  520: 			       OSPF6_NEIGHBOR_EVENT_SEQNUMBER_MISMATCH);
  521:   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
  522:   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
  523:   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
  524: 
  525:   ospf6_lsdb_remove_all (on->summary_list);
  526:   ospf6_lsdb_remove_all (on->request_list);
  527:   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  528:        lsa = ospf6_lsdb_next (lsa))
  529:     {
  530:       ospf6_decrement_retrans_count (lsa);
  531:       ospf6_lsdb_remove (lsa, on->retrans_list);
  532:     }
  533: 
  534:   THREAD_OFF (on->thread_send_dbdesc);
  535:   on->dbdesc_seqnum++;		/* Incr seqnum as per RFC2328, sec 10.3 */
  536: 
  537:   on->thread_send_dbdesc =
  538:     thread_add_event (master, ospf6_dbdesc_send, on, 0);
  539: 
  540:   return 0;
  541: }
  542: 
  543: int
  544: bad_lsreq (struct thread *thread)
  545: {
  546:   struct ospf6_neighbor *on;
  547:   struct ospf6_lsa *lsa;
  548: 
  549:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  550:   assert (on);
  551: 
  552:   if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
  553:     return 0;
  554: 
  555:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  556:     zlog_debug ("Neighbor Event %s: *BadLSReq*", on->name);
  557: 
  558:   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_EXSTART, on,
  559: 			       OSPF6_NEIGHBOR_EVENT_BAD_LSREQ);
  560:   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT);
  561:   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT);
  562:   SET_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT);
  563: 
  564:   ospf6_lsdb_remove_all (on->summary_list);
  565:   ospf6_lsdb_remove_all (on->request_list);
  566:   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  567:        lsa = ospf6_lsdb_next (lsa))
  568:     {
  569:       ospf6_decrement_retrans_count (lsa);
  570:       ospf6_lsdb_remove (lsa, on->retrans_list);
  571:     }
  572: 
  573:   THREAD_OFF (on->thread_send_dbdesc);
  574:   on->dbdesc_seqnum++;		/* Incr seqnum as per RFC2328, sec 10.3 */
  575: 
  576:   on->thread_send_dbdesc =
  577:     thread_add_event (master, ospf6_dbdesc_send, on, 0);
  578: 
  579:   return 0;
  580: }
  581: 
  582: int
  583: oneway_received (struct thread *thread)
  584: {
  585:   struct ospf6_neighbor *on;
  586:   struct ospf6_lsa *lsa;
  587: 
  588:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  589:   assert (on);
  590: 
  591:   if (on->state < OSPF6_NEIGHBOR_TWOWAY)
  592:     return 0;
  593: 
  594:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  595:     zlog_debug ("Neighbor Event %s: *1Way-Received*", on->name);
  596: 
  597:   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_INIT, on,
  598: 			       OSPF6_NEIGHBOR_EVENT_ONEWAY_RCVD);
  599:   thread_add_event (master, neighbor_change, on->ospf6_if, 0);
  600: 
  601:   ospf6_lsdb_remove_all (on->summary_list);
  602:   ospf6_lsdb_remove_all (on->request_list);
  603:   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  604:        lsa = ospf6_lsdb_next (lsa))
  605:     {
  606:       ospf6_decrement_retrans_count (lsa);
  607:       ospf6_lsdb_remove (lsa, on->retrans_list);
  608:     }
  609: 
  610:   THREAD_OFF (on->thread_send_dbdesc);
  611:   THREAD_OFF (on->thread_send_lsreq);
  612:   THREAD_OFF (on->thread_send_lsupdate);
  613:   THREAD_OFF (on->thread_send_lsack);
  614: 
  615:   return 0;
  616: }
  617: 
  618: int
  619: inactivity_timer (struct thread *thread)
  620: {
  621:   struct ospf6_neighbor *on;
  622: 
  623:   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
  624:   assert (on);
  625: 
  626:   if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
  627:     zlog_debug ("Neighbor Event %s: *InactivityTimer*", on->name);
  628: 
  629:   on->inactivity_timer = NULL;
  630:   on->drouter = on->prev_drouter = 0;
  631:   on->bdrouter = on->prev_bdrouter = 0;
  632: 
  633:   ospf6_neighbor_state_change (OSPF6_NEIGHBOR_DOWN, on,
  634: 			       OSPF6_NEIGHBOR_EVENT_INACTIVITY_TIMER);
  635:   thread_add_event (master, neighbor_change, on->ospf6_if, 0);
  636: 
  637:   listnode_delete (on->ospf6_if->neighbor_list, on);
  638:   ospf6_neighbor_delete (on);
  639: 
  640:   return 0;
  641: }
  642: 
  643: 
  644: 
  645: /* vty functions */
  646: /* show neighbor structure */
  647: static void
  648: ospf6_neighbor_show (struct vty *vty, struct ospf6_neighbor *on)
  649: {
  650:   char router_id[16];
  651:   char duration[16];
  652:   struct timeval now, res;
  653:   char nstate[16];
  654:   char deadtime[16];
  655:   long h, m, s;
  656: 
  657:   /* Router-ID (Name) */
  658:   inet_ntop (AF_INET, &on->router_id, router_id, sizeof (router_id));
  659: #ifdef HAVE_GETNAMEINFO
  660:   {
  661:   }
  662: #endif /*HAVE_GETNAMEINFO*/
  663: 
  664:   quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
  665: 
  666:   /* Dead time */
  667:   h = m = s = 0;
  668:   if (on->inactivity_timer)
  669:     {
  670:       s = on->inactivity_timer->u.sands.tv_sec - recent_relative_time().tv_sec;
  671:       h = s / 3600;
  672:       s -= h * 3600;
  673:       m = s / 60;
  674:       s -= m * 60;
  675:     }
  676:   snprintf (deadtime, sizeof (deadtime), "%02ld:%02ld:%02ld", h, m, s);
  677: 
  678:   /* Neighbor State */
  679:   if (if_is_pointopoint (on->ospf6_if->interface))
  680:     snprintf (nstate, sizeof (nstate), "PointToPoint");
  681:   else
  682:     {
  683:       if (on->router_id == on->drouter)
  684:         snprintf (nstate, sizeof (nstate), "DR");
  685:       else if (on->router_id == on->bdrouter)
  686:         snprintf (nstate, sizeof (nstate), "BDR");
  687:       else
  688:         snprintf (nstate, sizeof (nstate), "DROther");
  689:     }
  690: 
  691:   /* Duration */
  692:   timersub (&now, &on->last_changed, &res);
  693:   timerstring (&res, duration, sizeof (duration));
  694: 
  695:   /*
  696:   vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
  697:            "Neighbor ID", "Pri", "DeadTime", "State", "", "Duration",
  698:            "I/F", "State", VNL);
  699:   */
  700: 
  701:   vty_out (vty, "%-15s %3d %11s %6s/%-12s %11s %s[%s]%s",
  702:            router_id, on->priority, deadtime,
  703:            ospf6_neighbor_state_str[on->state], nstate, duration,
  704:            on->ospf6_if->interface->name,
  705:            ospf6_interface_state_str[on->ospf6_if->state], VNL);
  706: }
  707: 
  708: static void
  709: ospf6_neighbor_show_drchoice (struct vty *vty, struct ospf6_neighbor *on)
  710: {
  711:   char router_id[16];
  712:   char drouter[16], bdrouter[16];
  713:   char duration[16];
  714:   struct timeval now, res;
  715: 
  716: /*
  717:     vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
  718:              "RouterID", "State", "Duration", "DR", "BDR", "I/F",
  719:              "State", VNL);
  720: */
  721: 
  722:   inet_ntop (AF_INET, &on->router_id, router_id, sizeof (router_id));
  723:   inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter));
  724:   inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter));
  725: 
  726:   quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
  727:   timersub (&now, &on->last_changed, &res);
  728:   timerstring (&res, duration, sizeof (duration));
  729: 
  730:   vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
  731:            router_id, ospf6_neighbor_state_str[on->state],
  732:            duration, drouter, bdrouter, on->ospf6_if->interface->name,
  733:            ospf6_interface_state_str[on->ospf6_if->state],
  734:            VNL);
  735: }
  736: 
  737: static void
  738: ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
  739: {
  740:   char drouter[16], bdrouter[16];
  741:   char linklocal_addr[64], duration[32];
  742:   struct timeval now, res;
  743:   struct ospf6_lsa *lsa;
  744: 
  745:   inet_ntop (AF_INET6, &on->linklocal_addr, linklocal_addr,
  746:              sizeof (linklocal_addr));
  747:   inet_ntop (AF_INET, &on->drouter, drouter, sizeof (drouter));
  748:   inet_ntop (AF_INET, &on->bdrouter, bdrouter, sizeof (bdrouter));
  749: 
  750:   quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
  751:   timersub (&now, &on->last_changed, &res);
  752:   timerstring (&res, duration, sizeof (duration));
  753: 
  754:   vty_out (vty, " Neighbor %s%s", on->name,
  755:            VNL);
  756:   vty_out (vty, "    Area %s via interface %s (ifindex %d)%s",
  757:            on->ospf6_if->area->name,
  758:            on->ospf6_if->interface->name,
  759:            on->ospf6_if->interface->ifindex,
  760:            VNL);
  761:   vty_out (vty, "    His IfIndex: %d Link-local address: %s%s",
  762:            on->ifindex, linklocal_addr,
  763:            VNL);
  764:   vty_out (vty, "    State %s for a duration of %s%s",
  765:            ospf6_neighbor_state_str[on->state], duration,
  766:            VNL);
  767:   vty_out (vty, "    His choice of DR/BDR %s/%s, Priority %d%s",
  768:            drouter, bdrouter, on->priority,
  769:            VNL);
  770:   vty_out (vty, "    DbDesc status: %s%s%s SeqNum: %#lx%s",
  771:            (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_IBIT) ? "Initial " : ""),
  772:            (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MBIT) ? "More " : ""),
  773:            (CHECK_FLAG (on->dbdesc_bits, OSPF6_DBDESC_MSBIT) ?
  774:             "Master" : "Slave"), (u_long) ntohl (on->dbdesc_seqnum),
  775:            VNL);
  776: 
  777:   vty_out (vty, "    Summary-List: %d LSAs%s", on->summary_list->count,
  778:            VNL);
  779:   for (lsa = ospf6_lsdb_head (on->summary_list); lsa;
  780:        lsa = ospf6_lsdb_next (lsa))
  781:     vty_out (vty, "      %s%s", lsa->name, VNL);
  782: 
  783:   vty_out (vty, "    Request-List: %d LSAs%s", on->request_list->count,
  784:            VNL);
  785:   for (lsa = ospf6_lsdb_head (on->request_list); lsa;
  786:        lsa = ospf6_lsdb_next (lsa))
  787:     vty_out (vty, "      %s%s", lsa->name, VNL);
  788: 
  789:   vty_out (vty, "    Retrans-List: %d LSAs%s", on->retrans_list->count,
  790:            VNL);
  791:   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
  792:        lsa = ospf6_lsdb_next (lsa))
  793:     vty_out (vty, "      %s%s", lsa->name, VNL);
  794: 
  795:   timerclear (&res);
  796:   if (on->thread_send_dbdesc)
  797:     timersub (&on->thread_send_dbdesc->u.sands, &now, &res);
  798:   timerstring (&res, duration, sizeof (duration));
  799:   vty_out (vty, "    %d Pending LSAs for DbDesc in Time %s [thread %s]%s",
  800:            on->dbdesc_list->count, duration,
  801:            (on->thread_send_dbdesc ? "on" : "off"),
  802:            VNL);
  803:   for (lsa = ospf6_lsdb_head (on->dbdesc_list); lsa;
  804:        lsa = ospf6_lsdb_next (lsa))
  805:     vty_out (vty, "      %s%s", lsa->name, VNL);
  806: 
  807:   timerclear (&res);
  808:   if (on->thread_send_lsreq)
  809:     timersub (&on->thread_send_lsreq->u.sands, &now, &res);
  810:   timerstring (&res, duration, sizeof (duration));
  811:   vty_out (vty, "    %d Pending LSAs for LSReq in Time %s [thread %s]%s",
  812:            on->request_list->count, duration,
  813:            (on->thread_send_lsreq ? "on" : "off"),
  814:            VNL);
  815:   for (lsa = ospf6_lsdb_head (on->request_list); lsa;
  816:        lsa = ospf6_lsdb_next (lsa))
  817:     vty_out (vty, "      %s%s", lsa->name, VNL);
  818: 
  819:   timerclear (&res);
  820:   if (on->thread_send_lsupdate)
  821:     timersub (&on->thread_send_lsupdate->u.sands, &now, &res);
  822:   timerstring (&res, duration, sizeof (duration));
  823:   vty_out (vty, "    %d Pending LSAs for LSUpdate in Time %s [thread %s]%s",
  824:            on->lsupdate_list->count, duration,
  825:            (on->thread_send_lsupdate ? "on" : "off"),
  826:            VNL);
  827:   for (lsa = ospf6_lsdb_head (on->lsupdate_list); lsa;
  828:        lsa = ospf6_lsdb_next (lsa))
  829:     vty_out (vty, "      %s%s", lsa->name, VNL);
  830: 
  831:   timerclear (&res);
  832:   if (on->thread_send_lsack)
  833:     timersub (&on->thread_send_lsack->u.sands, &now, &res);
  834:   timerstring (&res, duration, sizeof (duration));
  835:   vty_out (vty, "    %d Pending LSAs for LSAck in Time %s [thread %s]%s",
  836:            on->lsack_list->count, duration,
  837:            (on->thread_send_lsack ? "on" : "off"),
  838:            VNL);
  839:   for (lsa = ospf6_lsdb_head (on->lsack_list); lsa;
  840:        lsa = ospf6_lsdb_next (lsa))
  841:     vty_out (vty, "      %s%s", lsa->name, VNL);
  842: 
  843: }
  844: 
  845: DEFUN (show_ipv6_ospf6_neighbor,
  846:        show_ipv6_ospf6_neighbor_cmd,
  847:        "show ipv6 ospf6 neighbor",
  848:        SHOW_STR
  849:        IP6_STR
  850:        OSPF6_STR
  851:        "Neighbor list\n"
  852:       )
  853: {
  854:   struct ospf6_neighbor *on;
  855:   struct ospf6_interface *oi;
  856:   struct ospf6_area *oa;
  857:   struct listnode *i, *j, *k;
  858:   void (*showfunc) (struct vty *, struct ospf6_neighbor *);
  859: 
  860:   OSPF6_CMD_CHECK_RUNNING ();
  861:   showfunc = ospf6_neighbor_show;
  862: 
  863:   if (argc)
  864:     {
  865:       if (! strncmp (argv[0], "de", 2))
  866:         showfunc = ospf6_neighbor_show_detail;
  867:       else if (! strncmp (argv[0], "dr", 2))
  868:         showfunc = ospf6_neighbor_show_drchoice;
  869:     }
  870: 
  871:   if (showfunc == ospf6_neighbor_show)
  872:     vty_out (vty, "%-15s %3s %11s %6s/%-12s %11s %s[%s]%s",
  873:              "Neighbor ID", "Pri", "DeadTime", "State", "IfState", "Duration",
  874:              "I/F", "State", VNL);
  875:   else if (showfunc == ospf6_neighbor_show_drchoice)
  876:     vty_out (vty, "%-15s %6s/%-11s %-15s %-15s %s[%s]%s",
  877:              "RouterID", "State", "Duration", "DR", "BDR", "I/F",
  878:              "State", VNL);
  879: 
  880:   for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, i, oa))
  881:     for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
  882:       for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on))
  883:         (*showfunc) (vty, on);
  884: 
  885:   return CMD_SUCCESS;
  886: }
  887: 
  888: ALIAS (show_ipv6_ospf6_neighbor,
  889:        show_ipv6_ospf6_neighbor_detail_cmd,
  890:        "show ipv6 ospf6 neighbor (detail|drchoice)",
  891:        SHOW_STR
  892:        IP6_STR
  893:        OSPF6_STR
  894:        "Neighbor list\n"
  895:        "Display details\n"
  896:        "Display DR choices\n"
  897:       )
  898: 
  899: DEFUN (show_ipv6_ospf6_neighbor_one,
  900:        show_ipv6_ospf6_neighbor_one_cmd,
  901:        "show ipv6 ospf6 neighbor A.B.C.D",
  902:        SHOW_STR
  903:        IP6_STR
  904:        OSPF6_STR
  905:        "Neighbor list\n"
  906:        "Specify Router-ID as IPv4 address notation\n"
  907:       )
  908: {
  909:   struct ospf6_neighbor *on;
  910:   struct ospf6_interface *oi;
  911:   struct ospf6_area *oa;
  912:   struct listnode *i, *j, *k;
  913:   void (*showfunc) (struct vty *, struct ospf6_neighbor *);
  914:   u_int32_t router_id;
  915: 
  916:   OSPF6_CMD_CHECK_RUNNING ();
  917:   showfunc = ospf6_neighbor_show_detail;
  918: 
  919:   if ((inet_pton (AF_INET, argv[0], &router_id)) != 1)
  920:     {
  921:       vty_out (vty, "Router-ID is not parsable: %s%s", argv[0],
  922:                VNL);
  923:       return CMD_SUCCESS;
  924:     }
  925: 
  926:   for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, i, oa))
  927:     for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
  928:       for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on))
  929:         (*showfunc) (vty, on);
  930:   
  931:   return CMD_SUCCESS;
  932: }
  933: 
  934: void
  935: ospf6_neighbor_init (void)
  936: {
  937:   install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_cmd);
  938:   install_element (VIEW_NODE, &show_ipv6_ospf6_neighbor_detail_cmd);
  939:   install_element (ENABLE_NODE, &show_ipv6_ospf6_neighbor_cmd);
  940:   install_element (ENABLE_NODE, &show_ipv6_ospf6_neighbor_detail_cmd);
  941: }
  942: 
  943: DEFUN (debug_ospf6_neighbor,
  944:        debug_ospf6_neighbor_cmd,
  945:        "debug ospf6 neighbor",
  946:        DEBUG_STR
  947:        OSPF6_STR
  948:        "Debug OSPFv3 Neighbor\n"
  949:       )
  950: {
  951:   unsigned char level = 0;
  952:   if (argc)
  953:     {
  954:       if (! strncmp (argv[0], "s", 1))
  955:         level = OSPF6_DEBUG_NEIGHBOR_STATE;
  956:       if (! strncmp (argv[0], "e", 1))
  957:         level = OSPF6_DEBUG_NEIGHBOR_EVENT;
  958:     }
  959:   else
  960:     level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
  961: 
  962:   OSPF6_DEBUG_NEIGHBOR_ON (level);
  963:   return CMD_SUCCESS;
  964: }
  965: 
  966: ALIAS (debug_ospf6_neighbor,
  967:        debug_ospf6_neighbor_detail_cmd,
  968:        "debug ospf6 neighbor (state|event)",
  969:        DEBUG_STR
  970:        OSPF6_STR
  971:        "Debug OSPFv3 Neighbor\n"
  972:        "Debug OSPFv3 Neighbor State Change\n"
  973:        "Debug OSPFv3 Neighbor Event\n"
  974:       )
  975: 
  976: DEFUN (no_debug_ospf6_neighbor,
  977:        no_debug_ospf6_neighbor_cmd,
  978:        "no debug ospf6 neighbor",
  979:        NO_STR
  980:        DEBUG_STR
  981:        OSPF6_STR
  982:        "Debug OSPFv3 Neighbor\n"
  983:       )
  984: {
  985:   unsigned char level = 0;
  986:   if (argc)
  987:     {
  988:       if (! strncmp (argv[0], "s", 1))
  989:         level = OSPF6_DEBUG_NEIGHBOR_STATE;
  990:       if (! strncmp (argv[0], "e", 1))
  991:         level = OSPF6_DEBUG_NEIGHBOR_EVENT;
  992:     }
  993:   else
  994:     level = OSPF6_DEBUG_NEIGHBOR_STATE | OSPF6_DEBUG_NEIGHBOR_EVENT;
  995: 
  996:   OSPF6_DEBUG_NEIGHBOR_OFF (level);
  997:   return CMD_SUCCESS;
  998: }
  999: 
 1000: ALIAS (no_debug_ospf6_neighbor,
 1001:        no_debug_ospf6_neighbor_detail_cmd,
 1002:        "no debug ospf6 neighbor (state|event)",
 1003:        NO_STR
 1004:        DEBUG_STR
 1005:        OSPF6_STR
 1006:        "Debug OSPFv3 Neighbor\n"
 1007:        "Debug OSPFv3 Neighbor State Change\n"
 1008:        "Debug OSPFv3 Neighbor Event\n"
 1009:       )
 1010: 
 1011: int
 1012: config_write_ospf6_debug_neighbor (struct vty *vty)
 1013: {
 1014:   if (IS_OSPF6_DEBUG_NEIGHBOR (STATE) &&
 1015:       IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
 1016:     vty_out (vty, "debug ospf6 neighbor%s", VNL);
 1017:   else if (IS_OSPF6_DEBUG_NEIGHBOR (STATE))
 1018:     vty_out (vty, "debug ospf6 neighbor state%s", VNL);
 1019:   else if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
 1020:     vty_out (vty, "debug ospf6 neighbor event%s", VNL);
 1021:   return 0;
 1022: }
 1023: 
 1024: void
 1025: install_element_ospf6_debug_neighbor (void)
 1026: {
 1027:   install_element (ENABLE_NODE, &debug_ospf6_neighbor_cmd);
 1028:   install_element (ENABLE_NODE, &debug_ospf6_neighbor_detail_cmd);
 1029:   install_element (ENABLE_NODE, &no_debug_ospf6_neighbor_cmd);
 1030:   install_element (ENABLE_NODE, &no_debug_ospf6_neighbor_detail_cmd);
 1031:   install_element (CONFIG_NODE, &debug_ospf6_neighbor_cmd);
 1032:   install_element (CONFIG_NODE, &debug_ospf6_neighbor_detail_cmd);
 1033:   install_element (CONFIG_NODE, &no_debug_ospf6_neighbor_cmd);
 1034:   install_element (CONFIG_NODE, &no_debug_ospf6_neighbor_detail_cmd);
 1035: }
 1036: 
 1037: 
 1038: 

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