File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospf6d / ospf6_neighbor.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jul 21 23:54:39 2013 UTC (10 years, 11 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, HEAD
0.99.22

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

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