File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospf6d / ospf6_top.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:11 2016 UTC (7 years, 8 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 "vty.h"
   27: #include "linklist.h"
   28: #include "prefix.h"
   29: #include "table.h"
   30: #include "thread.h"
   31: #include "command.h"
   32: 
   33: #include "ospf6_proto.h"
   34: #include "ospf6_message.h"
   35: #include "ospf6_lsa.h"
   36: #include "ospf6_lsdb.h"
   37: #include "ospf6_route.h"
   38: #include "ospf6_zebra.h"
   39: 
   40: #include "ospf6_top.h"
   41: #include "ospf6_area.h"
   42: #include "ospf6_interface.h"
   43: #include "ospf6_neighbor.h"
   44: 
   45: #include "ospf6_flood.h"
   46: #include "ospf6_asbr.h"
   47: #include "ospf6_abr.h"
   48: #include "ospf6_intra.h"
   49: #include "ospf6_spf.h"
   50: #include "ospf6d.h"
   51: 
   52: /* global ospf6d variable */
   53: struct ospf6 *ospf6;
   54: 
   55: static void ospf6_disable (struct ospf6 *o);
   56: 
   57: static void
   58: ospf6_top_lsdb_hook_add (struct ospf6_lsa *lsa)
   59: {
   60:   switch (ntohs (lsa->header->type))
   61:     {
   62:       case OSPF6_LSTYPE_AS_EXTERNAL:
   63:         ospf6_asbr_lsa_add (lsa);
   64:         break;
   65: 
   66:       default:
   67:         break;
   68:     }
   69: }
   70: 
   71: static void
   72: ospf6_top_lsdb_hook_remove (struct ospf6_lsa *lsa)
   73: {
   74:   switch (ntohs (lsa->header->type))
   75:     {
   76:       case OSPF6_LSTYPE_AS_EXTERNAL:
   77:         ospf6_asbr_lsa_remove (lsa);
   78:         break;
   79: 
   80:       default:
   81:         break;
   82:     }
   83: }
   84: 
   85: static void
   86: ospf6_top_route_hook_add (struct ospf6_route *route)
   87: {
   88:   ospf6_abr_originate_summary (route);
   89:   ospf6_zebra_route_update_add (route);
   90: }
   91: 
   92: static void
   93: ospf6_top_route_hook_remove (struct ospf6_route *route)
   94: {
   95:   ospf6_abr_originate_summary (route);
   96:   ospf6_zebra_route_update_remove (route);
   97: }
   98: 
   99: static void
  100: ospf6_top_brouter_hook_add (struct ospf6_route *route)
  101: {
  102:   ospf6_abr_examin_brouter (ADV_ROUTER_IN_PREFIX (&route->prefix));
  103:   ospf6_asbr_lsentry_add (route);
  104:   ospf6_abr_originate_summary (route);
  105: }
  106: 
  107: static void
  108: ospf6_top_brouter_hook_remove (struct ospf6_route *route)
  109: {
  110:   ospf6_abr_examin_brouter (ADV_ROUTER_IN_PREFIX (&route->prefix));
  111:   ospf6_asbr_lsentry_remove (route);
  112:   ospf6_abr_originate_summary (route);
  113: }
  114: 
  115: static struct ospf6 *
  116: ospf6_create (void)
  117: {
  118:   struct ospf6 *o;
  119: 
  120:   o = XCALLOC (MTYPE_OSPF6_TOP, sizeof (struct ospf6));
  121: 
  122:   /* initialize */
  123:   quagga_gettime (QUAGGA_CLK_MONOTONIC, &o->starttime);
  124:   o->area_list = list_new ();
  125:   o->area_list->cmp = ospf6_area_cmp;
  126:   o->lsdb = ospf6_lsdb_create (o);
  127:   o->lsdb_self = ospf6_lsdb_create (o);
  128:   o->lsdb->hook_add = ospf6_top_lsdb_hook_add;
  129:   o->lsdb->hook_remove = ospf6_top_lsdb_hook_remove;
  130: 
  131:   o->spf_delay = OSPF_SPF_DELAY_DEFAULT;
  132:   o->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
  133:   o->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
  134:   o->spf_hold_multiplier = 1;
  135: 
  136:   o->route_table = OSPF6_ROUTE_TABLE_CREATE (GLOBAL, ROUTES);
  137:   o->route_table->scope = o;
  138:   o->route_table->hook_add = ospf6_top_route_hook_add;
  139:   o->route_table->hook_remove = ospf6_top_route_hook_remove;
  140: 
  141:   o->brouter_table = OSPF6_ROUTE_TABLE_CREATE (GLOBAL, BORDER_ROUTERS);
  142:   o->brouter_table->scope = o;
  143:   o->brouter_table->hook_add = ospf6_top_brouter_hook_add;
  144:   o->brouter_table->hook_remove = ospf6_top_brouter_hook_remove;
  145: 
  146:   o->external_table = OSPF6_ROUTE_TABLE_CREATE (GLOBAL, EXTERNAL_ROUTES);
  147:   o->external_table->scope = o;
  148: 
  149:   o->external_id_table = route_table_init ();
  150: 
  151:   o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
  152: 
  153:   return o;
  154: }
  155: 
  156: void
  157: ospf6_delete (struct ospf6 *o)
  158: {
  159:   struct listnode *node, *nnode;
  160:   struct ospf6_area *oa;
  161: 
  162:   ospf6_disable (ospf6);
  163: 
  164:   for (ALL_LIST_ELEMENTS (o->area_list, node, nnode, oa))
  165:     ospf6_area_delete (oa);
  166: 
  167: 
  168:   list_delete (o->area_list);
  169: 
  170:   ospf6_lsdb_delete (o->lsdb);
  171:   ospf6_lsdb_delete (o->lsdb_self);
  172: 
  173:   ospf6_route_table_delete (o->route_table);
  174:   ospf6_route_table_delete (o->brouter_table);
  175: 
  176:   ospf6_route_table_delete (o->external_table);
  177:   route_table_finish (o->external_id_table);
  178: 
  179:   XFREE (MTYPE_OSPF6_TOP, o);
  180: }
  181: 
  182: static void
  183: __attribute__((unused))
  184: ospf6_enable (struct ospf6 *o)
  185: {
  186:   struct listnode *node, *nnode;
  187:   struct ospf6_area *oa;
  188: 
  189:   if (CHECK_FLAG (o->flag, OSPF6_DISABLED))
  190:     {
  191:       UNSET_FLAG (o->flag, OSPF6_DISABLED);
  192:       for (ALL_LIST_ELEMENTS (o->area_list, node, nnode, oa))
  193:         ospf6_area_enable (oa);
  194:     }
  195: }
  196: 
  197: static void
  198: ospf6_disable (struct ospf6 *o)
  199: {
  200:   struct listnode *node, *nnode;
  201:   struct ospf6_area *oa;
  202: 
  203:   if (! CHECK_FLAG (o->flag, OSPF6_DISABLED))
  204:     {
  205:       SET_FLAG (o->flag, OSPF6_DISABLED);
  206:       
  207:       for (ALL_LIST_ELEMENTS (o->area_list, node, nnode, oa))
  208:         ospf6_area_disable (oa);
  209: 
  210:       /* XXX: This also changes persistent settings */
  211:       ospf6_asbr_redistribute_reset();
  212: 
  213:       ospf6_lsdb_remove_all (o->lsdb);
  214:       ospf6_route_remove_all (o->route_table);
  215:       ospf6_route_remove_all (o->brouter_table);
  216: 
  217:       THREAD_OFF(o->maxage_remover);
  218:       THREAD_OFF(o->t_spf_calc);
  219:       THREAD_OFF(o->t_ase_calc);
  220:     }
  221: }
  222: 
  223: static int
  224: ospf6_maxage_remover (struct thread *thread)
  225: {
  226:   struct ospf6 *o = (struct ospf6 *) THREAD_ARG (thread);
  227:   struct ospf6_area *oa;
  228:   struct ospf6_interface *oi;
  229:   struct ospf6_neighbor *on;
  230:   struct listnode *i, *j, *k;
  231:   int reschedule = 0;
  232: 
  233:   o->maxage_remover = (struct thread *) NULL;
  234: 
  235:   for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa))
  236:     {
  237:       for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
  238:         {
  239:           for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on))
  240:             {
  241:               if (on->state != OSPF6_NEIGHBOR_EXCHANGE &&
  242:                   on->state != OSPF6_NEIGHBOR_LOADING)
  243: 		  continue;
  244: 
  245: 	      ospf6_maxage_remove (o);
  246:               return 0;
  247:             }
  248:         }
  249:     }
  250: 
  251:   for (ALL_LIST_ELEMENTS_RO (o->area_list, i, oa))
  252:     {
  253:       for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
  254: 	{
  255: 	  if (ospf6_lsdb_maxage_remover (oi->lsdb))
  256: 	    {
  257: 	      reschedule = 1;
  258: 	    }
  259: 	}
  260:       
  261:       if (ospf6_lsdb_maxage_remover (oa->lsdb))
  262: 	{
  263: 	    reschedule = 1;
  264: 	}
  265:     }
  266: 
  267:   if (ospf6_lsdb_maxage_remover (o->lsdb))
  268:     {
  269:       reschedule = 1;
  270:     }
  271: 
  272:   if (reschedule)
  273:     {
  274:       ospf6_maxage_remove (o);
  275:     }
  276: 
  277:   return 0;
  278: }
  279: 
  280: void
  281: ospf6_maxage_remove (struct ospf6 *o)
  282: {
  283:   if (o && ! o->maxage_remover)
  284:     o->maxage_remover = thread_add_timer (master, ospf6_maxage_remover, o,
  285: 					  OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT);
  286: }
  287: 
  288: /* start ospf6 */
  289: DEFUN (router_ospf6,
  290:        router_ospf6_cmd,
  291:        "router ospf6",
  292:        ROUTER_STR
  293:        OSPF6_STR)
  294: {
  295:   if (ospf6 == NULL)
  296:     ospf6 = ospf6_create ();
  297: 
  298:   /* set current ospf point. */
  299:   vty->node = OSPF6_NODE;
  300:   vty->index = ospf6;
  301: 
  302:   return CMD_SUCCESS;
  303: }
  304: 
  305: /* stop ospf6 */
  306: DEFUN (no_router_ospf6,
  307:        no_router_ospf6_cmd,
  308:        "no router ospf6",
  309:        NO_STR
  310:        OSPF6_ROUTER_STR)
  311: {
  312:   if (ospf6 == NULL)
  313:     vty_out (vty, "OSPFv3 is not configured%s", VNL);
  314:   else
  315:     {
  316:       ospf6_delete (ospf6);
  317:       ospf6 = NULL;
  318:     }
  319: 
  320:   /* return to config node . */
  321:   vty->node = CONFIG_NODE;
  322:   vty->index = NULL;
  323: 
  324:   return CMD_SUCCESS;
  325: }
  326: 
  327: /* change Router_ID commands. */
  328: DEFUN (ospf6_router_id,
  329:        ospf6_router_id_cmd,
  330:        "router-id A.B.C.D",
  331:        "Configure OSPF Router-ID\n"
  332:        V4NOTATION_STR)
  333: {
  334:   int ret;
  335:   u_int32_t router_id;
  336:   struct ospf6 *o;
  337: 
  338:   o = (struct ospf6 *) vty->index;
  339: 
  340:   ret = inet_pton (AF_INET, argv[0], &router_id);
  341:   if (ret == 0)
  342:     {
  343:       vty_out (vty, "malformed OSPF Router-ID: %s%s", argv[0], VNL);
  344:       return CMD_SUCCESS;
  345:     }
  346: 
  347:   o->router_id_static = router_id;
  348:   if (o->router_id  == 0)
  349:     o->router_id  = router_id;
  350: 
  351:   return CMD_SUCCESS;
  352: }
  353: 
  354: DEFUN (ospf6_log_adjacency_changes,
  355:        ospf6_log_adjacency_changes_cmd,
  356:        "log-adjacency-changes",
  357:        "Log changes in adjacency state\n")
  358: {
  359:   struct ospf6 *ospf6 = vty->index;
  360: 
  361:   SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
  362:   return CMD_SUCCESS;
  363: }
  364: 
  365: DEFUN (ospf6_log_adjacency_changes_detail,
  366:        ospf6_log_adjacency_changes_detail_cmd,
  367:        "log-adjacency-changes detail",
  368:               "Log changes in adjacency state\n"
  369:        "Log all state changes\n")
  370: {
  371:   struct ospf6 *ospf6 = vty->index;
  372: 
  373:   SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
  374:   SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
  375:   return CMD_SUCCESS;
  376: }
  377: 
  378: DEFUN (no_ospf6_log_adjacency_changes,
  379:        no_ospf6_log_adjacency_changes_cmd,
  380:        "no log-adjacency-changes",
  381:               NO_STR
  382:        "Log changes in adjacency state\n")
  383: {
  384:   struct ospf6 *ospf6 = vty->index;
  385: 
  386:   UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
  387:   UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
  388:   return CMD_SUCCESS;
  389: }
  390: 
  391: DEFUN (no_ospf6_log_adjacency_changes_detail,
  392:        no_ospf6_log_adjacency_changes_detail_cmd,
  393:        "no log-adjacency-changes detail",
  394:               NO_STR
  395:               "Log changes in adjacency state\n"
  396:        "Log all state changes\n")
  397: {
  398:   struct ospf6 *ospf6 = vty->index;
  399: 
  400:   UNSET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL);
  401:   return CMD_SUCCESS;
  402: }
  403: 
  404: DEFUN (ospf6_interface_area,
  405:        ospf6_interface_area_cmd,
  406:        "interface IFNAME area A.B.C.D",
  407:        "Enable routing on an IPv6 interface\n"
  408:        IFNAME_STR
  409:        "Specify the OSPF6 area ID\n"
  410:        "OSPF6 area ID in IPv4 address notation\n"
  411:       )
  412: {
  413:   struct ospf6 *o;
  414:   struct ospf6_area *oa;
  415:   struct ospf6_interface *oi;
  416:   struct interface *ifp;
  417:   u_int32_t area_id;
  418: 
  419:   o = (struct ospf6 *) vty->index;
  420: 
  421:   /* find/create ospf6 interface */
  422:   ifp = if_get_by_name (argv[0]);
  423:   oi = (struct ospf6_interface *) ifp->info;
  424:   if (oi == NULL)
  425:     oi = ospf6_interface_create (ifp);
  426:   if (oi->area)
  427:     {
  428:       vty_out (vty, "%s already attached to Area %s%s",
  429:                oi->interface->name, oi->area->name, VNL);
  430:       return CMD_SUCCESS;
  431:     }
  432: 
  433:   /* parse Area-ID */
  434:   if (inet_pton (AF_INET, argv[1], &area_id) != 1)
  435:     {
  436:       vty_out (vty, "Invalid Area-ID: %s%s", argv[1], VNL);
  437:       return CMD_SUCCESS;
  438:     }
  439: 
  440:   /* find/create ospf6 area */
  441:   oa = ospf6_area_lookup (area_id, o);
  442:   if (oa == NULL)
  443:     oa = ospf6_area_create (area_id, o);
  444: 
  445:   /* attach interface to area */
  446:   listnode_add (oa->if_list, oi); /* sort ?? */
  447:   oi->area = oa;
  448: 
  449:   SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
  450: 
  451:   /* ospf6 process is currently disabled, not much more to do */
  452:   if (CHECK_FLAG (o->flag, OSPF6_DISABLED))
  453:     return CMD_SUCCESS;
  454: 
  455:   /* start up */
  456:   ospf6_interface_enable (oi);
  457: 
  458:   /* If the router is ABR, originate summary routes */
  459:   if (ospf6_is_router_abr (o))
  460:     ospf6_abr_enable_area (oa);
  461: 
  462:   return CMD_SUCCESS;
  463: }
  464: 
  465: DEFUN (no_ospf6_interface_area,
  466:        no_ospf6_interface_area_cmd,
  467:        "no interface IFNAME area A.B.C.D",
  468:        NO_STR
  469:        "Disable routing on an IPv6 interface\n"
  470:        IFNAME_STR
  471:        "Specify the OSPF6 area ID\n"
  472:        "OSPF6 area ID in IPv4 address notation\n"
  473:        )
  474: {
  475:   struct ospf6_interface *oi;
  476:   struct ospf6_area *oa;
  477:   struct interface *ifp;
  478:   u_int32_t area_id;
  479: 
  480:   ifp = if_lookup_by_name (argv[0]);
  481:   if (ifp == NULL)
  482:     {
  483:       vty_out (vty, "No such interface %s%s", argv[0], VNL);
  484:       return CMD_SUCCESS;
  485:     }
  486: 
  487:   oi = (struct ospf6_interface *) ifp->info;
  488:   if (oi == NULL)
  489:     {
  490:       vty_out (vty, "Interface %s not enabled%s", ifp->name, VNL);
  491:       return CMD_SUCCESS;
  492:     }
  493: 
  494:   /* parse Area-ID */
  495:   if (inet_pton (AF_INET, argv[1], &area_id) != 1)
  496:     {
  497:       vty_out (vty, "Invalid Area-ID: %s%s", argv[1], VNL);
  498:       return CMD_SUCCESS;
  499:     }
  500: 
  501:   /* Verify Area */
  502:   if (oi->area == NULL)
  503:     {
  504:       vty_out (vty, "No such Area-ID: %s%s", argv[1], VNL);
  505:       return CMD_SUCCESS;
  506:     }
  507: 
  508:   if (oi->area->area_id != area_id)
  509:     {
  510:       vty_out (vty, "Wrong Area-ID: %s is attached to area %s%s",
  511:                oi->interface->name, oi->area->name, VNL);
  512:       return CMD_SUCCESS;
  513:     }
  514: 
  515:   thread_execute (master, interface_down, oi, 0);
  516: 
  517:   oa = oi->area;
  518:   listnode_delete (oi->area->if_list, oi);
  519:   oi->area = (struct ospf6_area *) NULL;
  520: 
  521:   /* Withdraw inter-area routes from this area, if necessary */
  522:   if (oa->if_list->count == 0)
  523:     {
  524:       UNSET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
  525:       ospf6_abr_disable_area (oa);
  526:     }
  527: 
  528:   return CMD_SUCCESS;
  529: }
  530: 
  531: DEFUN (ospf6_stub_router_admin,
  532:        ospf6_stub_router_admin_cmd,
  533:        "stub-router administrative",
  534:        "Make router a stub router\n"
  535:        "Advertise inability to be a transit router\n"
  536:        "Administratively applied, for an indefinite period\n")
  537: {
  538:   struct listnode *node;
  539:   struct ospf6_area *oa;
  540: 
  541:   if (!CHECK_FLAG (ospf6->flag, OSPF6_STUB_ROUTER))
  542:     {
  543:       for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
  544: 	{
  545: 	   OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_V6);
  546: 	   OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_R);
  547: 	   OSPF6_ROUTER_LSA_SCHEDULE (oa);
  548: 	}
  549:       SET_FLAG (ospf6->flag, OSPF6_STUB_ROUTER);
  550:     }
  551: 
  552:   return CMD_SUCCESS;
  553: }
  554: 
  555: DEFUN (no_ospf6_stub_router_admin,
  556:        no_ospf6_stub_router_admin_cmd,
  557:        "no stub-router administrative",
  558:        NO_STR
  559:        "Make router a stub router\n"
  560:        "Advertise ability to be a transit router\n"
  561:        "Administratively applied, for an indefinite period\n")
  562: {
  563:   struct listnode *node;
  564:   struct ospf6_area *oa;
  565: 
  566:   if (CHECK_FLAG (ospf6->flag, OSPF6_STUB_ROUTER))
  567:     {
  568:       for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
  569: 	{
  570: 	   OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6);
  571: 	   OSPF6_OPT_SET (oa->options, OSPF6_OPT_R);
  572: 	   OSPF6_ROUTER_LSA_SCHEDULE (oa);
  573: 	}
  574:       UNSET_FLAG (ospf6->flag, OSPF6_STUB_ROUTER);
  575:     }
  576: 
  577:   return CMD_SUCCESS;
  578: }
  579: 
  580: DEFUN (ospf6_stub_router_startup,
  581:        ospf6_stub_router_startup_cmd,
  582:        "stub-router on-startup <5-86400>",
  583:        "Make router a stub router\n"
  584:        "Advertise inability to be a transit router\n"
  585:        "Automatically advertise as stub-router on startup of OSPF6\n"
  586:        "Time (seconds) to advertise self as stub-router\n")
  587: {
  588:   return CMD_SUCCESS;
  589: }
  590: 
  591: DEFUN (no_ospf6_stub_router_startup,
  592:        no_ospf6_stub_router_startup_cmd,
  593:        "no stub-router on-startup",
  594:        NO_STR
  595:        "Make router a stub router\n"
  596:        "Advertise inability to be a transit router\n"
  597:        "Automatically advertise as stub-router on startup of OSPF6\n"
  598:        "Time (seconds) to advertise self as stub-router\n")
  599: {
  600:   return CMD_SUCCESS;
  601: }
  602: 
  603: DEFUN (ospf6_stub_router_shutdown,
  604:        ospf6_stub_router_shutdown_cmd,
  605:        "stub-router on-shutdown <5-86400>",
  606:        "Make router a stub router\n"
  607:        "Advertise inability to be a transit router\n"
  608:        "Automatically advertise as stub-router before shutdown\n"
  609:        "Time (seconds) to advertise self as stub-router\n")
  610: {
  611:   return CMD_SUCCESS;
  612: }
  613: 
  614: DEFUN (no_ospf6_stub_router_shutdown,
  615:        no_ospf6_stub_router_shutdown_cmd,
  616:        "no stub-router on-shutdown",
  617:        NO_STR
  618:        "Make router a stub router\n"
  619:        "Advertise inability to be a transit router\n"
  620:        "Automatically advertise as stub-router before shutdown\n"
  621:        "Time (seconds) to advertise self as stub-router\n")
  622: {
  623:   return CMD_SUCCESS;
  624: }
  625: 
  626: static void
  627: ospf6_show (struct vty *vty, struct ospf6 *o)
  628: {
  629:   struct listnode *n;
  630:   struct ospf6_area *oa;
  631:   char router_id[16], duration[32];
  632:   struct timeval now, running, result;
  633:   char buf[32], rbuf[32];
  634: 
  635:   /* process id, router id */
  636:   inet_ntop (AF_INET, &o->router_id, router_id, sizeof (router_id));
  637:   vty_out (vty, " OSPFv3 Routing Process (0) with Router-ID %s%s",
  638:            router_id, VNL);
  639: 
  640:   /* running time */
  641:   quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
  642:   timersub (&now, &o->starttime, &running);
  643:   timerstring (&running, duration, sizeof (duration));
  644:   vty_out (vty, " Running %s%s", duration, VNL);
  645: 
  646:   /* Redistribute configuration */
  647:   /* XXX */
  648: 
  649:   /* Show SPF parameters */
  650:   vty_out(vty, " Initial SPF scheduling delay %d millisec(s)%s"
  651: 	  " Minimum hold time between consecutive SPFs %d millsecond(s)%s"
  652: 	  " Maximum hold time between consecutive SPFs %d millsecond(s)%s"
  653: 	  " Hold time multiplier is currently %d%s",
  654: 	  o->spf_delay, VNL,
  655: 	  o->spf_holdtime, VNL,
  656: 	  o->spf_max_holdtime, VNL,
  657: 	  o->spf_hold_multiplier, VNL);
  658: 
  659:   vty_out(vty, " SPF algorithm ");
  660:   if (o->ts_spf.tv_sec || o->ts_spf.tv_usec)
  661:     {
  662:       timersub(&now, &o->ts_spf, &result);
  663:       timerstring(&result, buf, sizeof(buf));
  664:       ospf6_spf_reason_string(o->last_spf_reason, rbuf, sizeof(rbuf));
  665:       vty_out(vty, "last executed %s ago, reason %s%s", buf, rbuf, VNL);
  666:       vty_out (vty, " Last SPF duration %lld sec %lld usec%s",
  667:                (long long)o->ts_spf_duration.tv_sec,
  668:                (long long)o->ts_spf_duration.tv_usec, VNL);
  669:     }
  670:   else
  671:     vty_out(vty, "has not been run$%s", VNL);
  672:   threadtimer_string(now, o->t_spf_calc, buf, sizeof(buf));
  673:   vty_out (vty, " SPF timer %s%s%s",
  674: 	   (o->t_spf_calc ? "due in " : "is "), buf, VNL);
  675: 
  676:   if (CHECK_FLAG (o->flag, OSPF6_STUB_ROUTER))
  677:     vty_out (vty, " Router Is Stub Router%s", VNL);
  678: 
  679:   /* LSAs */
  680:   vty_out (vty, " Number of AS scoped LSAs is %u%s",
  681:            o->lsdb->count, VNL);
  682: 
  683:   /* Areas */
  684:   vty_out (vty, " Number of areas in this router is %u%s",
  685:            listcount (o->area_list), VNL);
  686: 
  687:   if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_CHANGES))
  688:     {
  689:       if (CHECK_FLAG(o->config_flags, OSPF6_LOG_ADJACENCY_DETAIL))
  690: 	vty_out(vty, " All adjacency changes are logged%s",VTY_NEWLINE);
  691:       else
  692: 	vty_out(vty, " Adjacency changes are logged%s",VTY_NEWLINE);
  693:     }
  694: 
  695:   vty_out (vty, "%s",VTY_NEWLINE);
  696: 
  697:   for (ALL_LIST_ELEMENTS_RO (o->area_list, n, oa))
  698:     ospf6_area_show (vty, oa);
  699: }
  700: 
  701: /* show top level structures */
  702: DEFUN (show_ipv6_ospf6,
  703:        show_ipv6_ospf6_cmd,
  704:        "show ipv6 ospf6",
  705:        SHOW_STR
  706:        IP6_STR
  707:        OSPF6_STR)
  708: {
  709:   OSPF6_CMD_CHECK_RUNNING ();
  710: 
  711:   ospf6_show (vty, ospf6);
  712:   return CMD_SUCCESS;
  713: }
  714: 
  715: DEFUN (show_ipv6_ospf6_route,
  716:        show_ipv6_ospf6_route_cmd,
  717:        "show ipv6 ospf6 route",
  718:        SHOW_STR
  719:        IP6_STR
  720:        OSPF6_STR
  721:        ROUTE_STR
  722:        )
  723: {
  724:   ospf6_route_table_show (vty, argc, argv, ospf6->route_table);
  725:   return CMD_SUCCESS;
  726: }
  727: 
  728: ALIAS (show_ipv6_ospf6_route,
  729:        show_ipv6_ospf6_route_detail_cmd,
  730:        "show ipv6 ospf6 route (X:X::X:X|X:X::X:X/M|detail|summary)",
  731:        SHOW_STR
  732:        IP6_STR
  733:        OSPF6_STR
  734:        ROUTE_STR
  735:        "Specify IPv6 address\n"
  736:        "Specify IPv6 prefix\n"
  737:        "Detailed information\n"
  738:        "Summary of route table\n"
  739:        )
  740: 
  741: DEFUN (show_ipv6_ospf6_route_match,
  742:        show_ipv6_ospf6_route_match_cmd,
  743:        "show ipv6 ospf6 route X:X::X:X/M match",
  744:        SHOW_STR
  745:        IP6_STR
  746:        OSPF6_STR
  747:        ROUTE_STR
  748:        "Specify IPv6 prefix\n"
  749:        "Display routes which match the specified route\n"
  750:        )
  751: {
  752:   const char *sargv[CMD_ARGC_MAX];
  753:   int i, sargc;
  754: 
  755:   /* copy argv to sargv and then append "match" */
  756:   for (i = 0; i < argc; i++)
  757:     sargv[i] = argv[i];
  758:   sargc = argc;
  759:   sargv[sargc++] = "match";
  760:   sargv[sargc] = NULL;
  761: 
  762:   ospf6_route_table_show (vty, sargc, sargv, ospf6->route_table);
  763:   return CMD_SUCCESS;
  764: }
  765: 
  766: DEFUN (show_ipv6_ospf6_route_match_detail,
  767:        show_ipv6_ospf6_route_match_detail_cmd,
  768:        "show ipv6 ospf6 route X:X::X:X/M match detail",
  769:        SHOW_STR
  770:        IP6_STR
  771:        OSPF6_STR
  772:        ROUTE_STR
  773:        "Specify IPv6 prefix\n"
  774:        "Display routes which match the specified route\n"
  775:        "Detailed information\n"
  776:        )
  777: {
  778:   const char *sargv[CMD_ARGC_MAX];
  779:   int i, sargc;
  780: 
  781:   /* copy argv to sargv and then append "match" and "detail" */
  782:   for (i = 0; i < argc; i++)
  783:     sargv[i] = argv[i];
  784:   sargc = argc;
  785:   sargv[sargc++] = "match";
  786:   sargv[sargc++] = "detail";
  787:   sargv[sargc] = NULL;
  788: 
  789:   ospf6_route_table_show (vty, sargc, sargv, ospf6->route_table);
  790:   return CMD_SUCCESS;
  791: }
  792: 
  793: ALIAS (show_ipv6_ospf6_route_match,
  794:        show_ipv6_ospf6_route_longer_cmd,
  795:        "show ipv6 ospf6 route X:X::X:X/M longer",
  796:        SHOW_STR
  797:        IP6_STR
  798:        OSPF6_STR
  799:        ROUTE_STR
  800:        "Specify IPv6 prefix\n"
  801:        "Display routes longer than the specified route\n"
  802:        )
  803: 
  804: DEFUN (show_ipv6_ospf6_route_match_detail,
  805:        show_ipv6_ospf6_route_longer_detail_cmd,
  806:        "show ipv6 ospf6 route X:X::X:X/M longer detail",
  807:        SHOW_STR
  808:        IP6_STR
  809:        OSPF6_STR
  810:        ROUTE_STR
  811:        "Specify IPv6 prefix\n"
  812:        "Display routes longer than the specified route\n"
  813:        "Detailed information\n"
  814:        );
  815: 
  816: ALIAS (show_ipv6_ospf6_route,
  817:        show_ipv6_ospf6_route_type_cmd,
  818:        "show ipv6 ospf6 route (intra-area|inter-area|external-1|external-2)",
  819:        SHOW_STR
  820:        IP6_STR
  821:        OSPF6_STR
  822:        ROUTE_STR
  823:        "Display Intra-Area routes\n"
  824:        "Display Inter-Area routes\n"
  825:        "Display Type-1 External routes\n"
  826:        "Display Type-2 External routes\n"
  827:        )
  828: 
  829: DEFUN (show_ipv6_ospf6_route_type_detail,
  830:        show_ipv6_ospf6_route_type_detail_cmd,
  831:        "show ipv6 ospf6 route (intra-area|inter-area|external-1|external-2) detail",
  832:        SHOW_STR
  833:        IP6_STR
  834:        OSPF6_STR
  835:        ROUTE_STR
  836:        "Display Intra-Area routes\n"
  837:        "Display Inter-Area routes\n"
  838:        "Display Type-1 External routes\n"
  839:        "Display Type-2 External routes\n"
  840:        "Detailed information\n"
  841:        )
  842: {
  843:   const char *sargv[CMD_ARGC_MAX];
  844:   int i, sargc;
  845: 
  846:   /* copy argv to sargv and then append "detail" */
  847:   for (i = 0; i < argc; i++)
  848:     sargv[i] = argv[i];
  849:   sargc = argc;
  850:   sargv[sargc++] = "detail";
  851:   sargv[sargc] = NULL;
  852: 
  853:   ospf6_route_table_show (vty, sargc, sargv, ospf6->route_table);
  854:   return CMD_SUCCESS;
  855: }
  856: 
  857: static void
  858: ospf6_stub_router_config_write (struct vty *vty)
  859: {
  860:   if (CHECK_FLAG (ospf6->flag, OSPF6_STUB_ROUTER))
  861:     {
  862:       vty_out (vty, " stub-router administrative%s", VNL);
  863:     }
  864:     return;
  865: }
  866: 
  867: /* OSPF configuration write function. */
  868: static int
  869: config_write_ospf6 (struct vty *vty)
  870: {
  871:   char router_id[16];
  872:   struct listnode *j, *k;
  873:   struct ospf6_area *oa;
  874:   struct ospf6_interface *oi;
  875: 
  876:   /* OSPFv6 configuration. */
  877:   if (ospf6 == NULL)
  878:     return CMD_SUCCESS;
  879: 
  880:   inet_ntop (AF_INET, &ospf6->router_id_static, router_id, sizeof (router_id));
  881:   vty_out (vty, "router ospf6%s", VNL);
  882:   if (ospf6->router_id_static != 0)
  883:     vty_out (vty, " router-id %s%s", router_id, VNL);
  884: 
  885:   /* log-adjacency-changes flag print. */
  886:   if (CHECK_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES))
  887:     {
  888:       vty_out(vty, " log-adjacency-changes");
  889:       if (CHECK_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL))
  890: 	vty_out(vty, " detail");
  891:       vty_out(vty, "%s", VTY_NEWLINE);
  892:     }
  893: 
  894:   if (ospf6->ref_bandwidth != OSPF6_REFERENCE_BANDWIDTH)
  895:     vty_out (vty, " auto-cost reference-bandwidth %d%s", ospf6->ref_bandwidth / 1000,
  896:              VNL);
  897: 
  898:   ospf6_stub_router_config_write (vty);
  899:   ospf6_redistribute_config_write (vty);
  900:   ospf6_area_config_write (vty);
  901:   ospf6_spf_config_write (vty);
  902: 
  903:   for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, j, oa))
  904:     {
  905:       for (ALL_LIST_ELEMENTS_RO (oa->if_list, k, oi))
  906:         vty_out (vty, " interface %s area %s%s",
  907:                  oi->interface->name, oa->name, VNL);
  908:     }
  909:   vty_out (vty, "!%s", VNL);
  910:   return 0;
  911: }
  912: 
  913: /* OSPF6 node structure. */
  914: static struct cmd_node ospf6_node =
  915: {
  916:   OSPF6_NODE,
  917:   "%s(config-ospf6)# ",
  918:   1 /* VTYSH */
  919: };
  920: 
  921: /* Install ospf related commands. */
  922: void
  923: ospf6_top_init (void)
  924: {
  925:   /* Install ospf6 top node. */
  926:   install_node (&ospf6_node, config_write_ospf6);
  927: 
  928:   install_element (VIEW_NODE, &show_ipv6_ospf6_cmd);
  929:   install_element (ENABLE_NODE, &show_ipv6_ospf6_cmd);
  930:   install_element (CONFIG_NODE, &router_ospf6_cmd);
  931:   install_element (CONFIG_NODE, &no_router_ospf6_cmd);
  932: 
  933:   install_element (VIEW_NODE, &show_ipv6_ospf6_route_cmd);
  934:   install_element (VIEW_NODE, &show_ipv6_ospf6_route_detail_cmd);
  935:   install_element (VIEW_NODE, &show_ipv6_ospf6_route_match_cmd);
  936:   install_element (VIEW_NODE, &show_ipv6_ospf6_route_match_detail_cmd);
  937:   install_element (VIEW_NODE, &show_ipv6_ospf6_route_longer_cmd);
  938:   install_element (VIEW_NODE, &show_ipv6_ospf6_route_longer_detail_cmd);
  939:   install_element (VIEW_NODE, &show_ipv6_ospf6_route_type_cmd);
  940:   install_element (VIEW_NODE, &show_ipv6_ospf6_route_type_detail_cmd);
  941:   install_element (ENABLE_NODE, &show_ipv6_ospf6_route_cmd);
  942:   install_element (ENABLE_NODE, &show_ipv6_ospf6_route_detail_cmd);
  943:   install_element (ENABLE_NODE, &show_ipv6_ospf6_route_match_cmd);
  944:   install_element (ENABLE_NODE, &show_ipv6_ospf6_route_match_detail_cmd);
  945:   install_element (ENABLE_NODE, &show_ipv6_ospf6_route_longer_cmd);
  946:   install_element (ENABLE_NODE, &show_ipv6_ospf6_route_longer_detail_cmd);
  947:   install_element (ENABLE_NODE, &show_ipv6_ospf6_route_type_cmd);
  948:   install_element (ENABLE_NODE, &show_ipv6_ospf6_route_type_detail_cmd);
  949: 
  950:   install_default (OSPF6_NODE);
  951:   install_element (OSPF6_NODE, &ospf6_router_id_cmd);
  952:   install_element (OSPF6_NODE, &ospf6_log_adjacency_changes_cmd);
  953:   install_element (OSPF6_NODE, &ospf6_log_adjacency_changes_detail_cmd);
  954:   install_element (OSPF6_NODE, &no_ospf6_log_adjacency_changes_cmd);
  955:   install_element (OSPF6_NODE, &no_ospf6_log_adjacency_changes_detail_cmd);
  956:   install_element (OSPF6_NODE, &ospf6_interface_area_cmd);
  957:   install_element (OSPF6_NODE, &no_ospf6_interface_area_cmd);
  958:   install_element (OSPF6_NODE, &ospf6_stub_router_admin_cmd);
  959:   install_element (OSPF6_NODE, &no_ospf6_stub_router_admin_cmd);
  960:   /* For a later time
  961:   install_element (OSPF6_NODE, &ospf6_stub_router_startup_cmd);
  962:   install_element (OSPF6_NODE, &no_ospf6_stub_router_startup_cmd);
  963:   install_element (OSPF6_NODE, &ospf6_stub_router_shutdown_cmd);
  964:   install_element (OSPF6_NODE, &no_ospf6_stub_router_shutdown_cmd);
  965:   */
  966: }
  967: 
  968: 

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