File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospf6d / ospf6_area.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 "linklist.h"
   27: #include "thread.h"
   28: #include "vty.h"
   29: #include "command.h"
   30: #include "if.h"
   31: #include "prefix.h"
   32: #include "table.h"
   33: #include "plist.h"
   34: #include "filter.h"
   35: 
   36: #include "ospf6_proto.h"
   37: #include "ospf6_lsa.h"
   38: #include "ospf6_lsdb.h"
   39: #include "ospf6_route.h"
   40: #include "ospf6_spf.h"
   41: #include "ospf6_top.h"
   42: #include "ospf6_area.h"
   43: #include "ospf6_interface.h"
   44: #include "ospf6_intra.h"
   45: #include "ospf6_abr.h"
   46: #include "ospf6d.h"
   47: 
   48: int
   49: ospf6_area_cmp (void *va, void *vb)
   50: {
   51:   struct ospf6_area *oa = (struct ospf6_area *) va;
   52:   struct ospf6_area *ob = (struct ospf6_area *) vb;
   53:   return (ntohl (oa->area_id) < ntohl (ob->area_id) ? -1 : 1);
   54: }
   55: 
   56: /* schedule routing table recalculation */
   57: static void
   58: ospf6_area_lsdb_hook_add (struct ospf6_lsa *lsa)
   59: {
   60:   switch (ntohs (lsa->header->type))
   61:     {
   62:     case OSPF6_LSTYPE_ROUTER:
   63:     case OSPF6_LSTYPE_NETWORK:
   64:       if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
   65:         {
   66:           zlog_debug ("Examin %s", lsa->name);
   67:           zlog_debug ("Schedule SPF Calculation for %s",
   68: 		      OSPF6_AREA (lsa->lsdb->data)->name);
   69:         }
   70:       ospf6_spf_schedule (OSPF6_PROCESS(OSPF6_AREA (lsa->lsdb->data)->ospf6),
   71: 			  ospf6_lsadd_to_spf_reason(lsa));
   72:       break;
   73: 
   74:     case OSPF6_LSTYPE_INTRA_PREFIX:
   75:       ospf6_intra_prefix_lsa_add (lsa);
   76:       break;
   77: 
   78:     case OSPF6_LSTYPE_INTER_PREFIX:
   79:     case OSPF6_LSTYPE_INTER_ROUTER:
   80:       ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data);
   81:       break;
   82: 
   83:     default:
   84:       break;
   85:     }
   86: }
   87: 
   88: static void
   89: ospf6_area_lsdb_hook_remove (struct ospf6_lsa *lsa)
   90: {
   91:   switch (ntohs (lsa->header->type))
   92:     {
   93:     case OSPF6_LSTYPE_ROUTER:
   94:     case OSPF6_LSTYPE_NETWORK:
   95:       if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
   96:         {
   97:           zlog_debug ("LSA disappearing: %s", lsa->name);
   98:           zlog_debug ("Schedule SPF Calculation for %s",
   99:                      OSPF6_AREA (lsa->lsdb->data)->name);
  100:         }
  101:       ospf6_spf_schedule (OSPF6_PROCESS(OSPF6_AREA (lsa->lsdb->data)->ospf6),
  102: 			  ospf6_lsremove_to_spf_reason(lsa));
  103:       break;
  104: 
  105:     case OSPF6_LSTYPE_INTRA_PREFIX:
  106:       ospf6_intra_prefix_lsa_remove (lsa);
  107:       break;
  108: 
  109:     case OSPF6_LSTYPE_INTER_PREFIX:
  110:     case OSPF6_LSTYPE_INTER_ROUTER:
  111:       ospf6_abr_examin_summary (lsa, (struct ospf6_area *) lsa->lsdb->data);
  112:       break;
  113: 
  114:     default:
  115:       break;
  116:     }
  117: }
  118: 
  119: static void
  120: ospf6_area_route_hook_add (struct ospf6_route *route)
  121: {
  122:   struct ospf6_route *copy = ospf6_route_copy (route);
  123:   ospf6_route_add (copy, ospf6->route_table);
  124: }
  125: 
  126: static void
  127: ospf6_area_route_hook_remove (struct ospf6_route *route)
  128: {
  129:   struct ospf6_route *copy;
  130: 
  131:   copy = ospf6_route_lookup_identical (route, ospf6->route_table);
  132:   if (copy)
  133:     ospf6_route_remove (copy, ospf6->route_table);
  134: }
  135: 
  136: /* Make new area structure */
  137: struct ospf6_area *
  138: ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
  139: {
  140:   struct ospf6_area *oa;
  141:   struct ospf6_route *route;
  142: 
  143:   oa = XCALLOC (MTYPE_OSPF6_AREA, sizeof (struct ospf6_area));
  144: 
  145:   inet_ntop (AF_INET, &area_id, oa->name, sizeof (oa->name));
  146:   oa->area_id = area_id;
  147:   oa->if_list = list_new ();
  148: 
  149:   oa->lsdb = ospf6_lsdb_create (oa);
  150:   oa->lsdb->hook_add = ospf6_area_lsdb_hook_add;
  151:   oa->lsdb->hook_remove = ospf6_area_lsdb_hook_remove;
  152:   oa->lsdb_self = ospf6_lsdb_create (oa);
  153: 
  154:   oa->spf_table = OSPF6_ROUTE_TABLE_CREATE (AREA, SPF_RESULTS);
  155:   oa->spf_table->scope = oa;
  156:   oa->route_table = OSPF6_ROUTE_TABLE_CREATE (AREA, ROUTES);
  157:   oa->route_table->scope = oa;
  158:   oa->route_table->hook_add = ospf6_area_route_hook_add;
  159:   oa->route_table->hook_remove = ospf6_area_route_hook_remove;
  160: 
  161:   oa->range_table = OSPF6_ROUTE_TABLE_CREATE (AREA, PREFIX_RANGES);
  162:   oa->range_table->scope = oa;
  163:   oa->summary_prefix = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_PREFIXES);
  164:   oa->summary_prefix->scope = oa;
  165:   oa->summary_router = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_ROUTERS);
  166:   oa->summary_router->scope = oa;
  167: 
  168:   /* set default options */
  169:   if (CHECK_FLAG (o->flag, OSPF6_STUB_ROUTER))
  170:     {
  171:       OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_V6);
  172:       OSPF6_OPT_CLEAR (oa->options, OSPF6_OPT_R);
  173:     }
  174:   else
  175:     {
  176:       OSPF6_OPT_SET (oa->options, OSPF6_OPT_V6);
  177:       OSPF6_OPT_SET (oa->options, OSPF6_OPT_R);
  178:     }
  179: 
  180:   OSPF6_OPT_SET (oa->options, OSPF6_OPT_E);
  181: 
  182:   oa->ospf6 = o;
  183:   listnode_add_sort (o->area_list, oa);
  184: 
  185:   /* import athoer area's routes as inter-area routes */
  186:   for (route = ospf6_route_head (o->route_table); route;
  187:        route = ospf6_route_next (route))
  188:     ospf6_abr_originate_summary_to_area (route, oa);
  189: 
  190:   return oa;
  191: }
  192: 
  193: void
  194: ospf6_area_delete (struct ospf6_area *oa)
  195: {
  196:   struct listnode *n;
  197:   struct ospf6_interface *oi;
  198: 
  199:   ospf6_route_table_delete (oa->range_table);
  200:   ospf6_route_table_delete (oa->summary_prefix);
  201:   ospf6_route_table_delete (oa->summary_router);
  202: 
  203:   /* The ospf6_interface structs store configuration
  204:    * information which should not be lost/reset when
  205:    * deleting an area.
  206:    * So just detach the interface from the area and
  207:    * keep it around. */
  208:   for (ALL_LIST_ELEMENTS_RO (oa->if_list, n, oi))
  209:     oi->area = NULL;
  210: 
  211:   list_delete (oa->if_list);
  212: 
  213:   ospf6_lsdb_delete (oa->lsdb);
  214:   ospf6_lsdb_delete (oa->lsdb_self);
  215: 
  216:   ospf6_spf_table_finish (oa->spf_table);
  217:   ospf6_route_table_delete (oa->spf_table);
  218:   ospf6_route_table_delete (oa->route_table);
  219: 
  220:   THREAD_OFF (oa->thread_spf_calculation);
  221:   THREAD_OFF (oa->thread_route_calculation);
  222: 
  223:   listnode_delete (oa->ospf6->area_list, oa);
  224:   oa->ospf6 = NULL;
  225: 
  226:   /* free area */
  227:   XFREE (MTYPE_OSPF6_AREA, oa);
  228: }
  229: 
  230: struct ospf6_area *
  231: ospf6_area_lookup (u_int32_t area_id, struct ospf6 *ospf6)
  232: {
  233:   struct ospf6_area *oa;
  234:   struct listnode *n;
  235: 
  236:   for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, n, oa))
  237:     if (oa->area_id == area_id)
  238:       return oa;
  239: 
  240:   return (struct ospf6_area *) NULL;
  241: }
  242: 
  243: static struct ospf6_area *
  244: ospf6_area_get (u_int32_t area_id, struct ospf6 *o)
  245: {
  246:   struct ospf6_area *oa;
  247:   oa = ospf6_area_lookup (area_id, o);
  248:   if (oa == NULL)
  249:     oa = ospf6_area_create (area_id, o);
  250:   return oa;
  251: }
  252: 
  253: void
  254: ospf6_area_enable (struct ospf6_area *oa)
  255: {
  256:   struct listnode *node, *nnode;
  257:   struct ospf6_interface *oi;
  258: 
  259:   SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
  260: 
  261:   for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
  262:     ospf6_interface_enable (oi);
  263:   ospf6_abr_enable_area (oa);
  264: }
  265: 
  266: void
  267: ospf6_area_disable (struct ospf6_area *oa)
  268: {
  269:   struct listnode *node, *nnode;
  270:   struct ospf6_interface *oi;
  271: 
  272:   UNSET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
  273: 
  274:   for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
  275:     ospf6_interface_disable (oi);
  276: 
  277:   ospf6_abr_disable_area (oa);
  278:   ospf6_lsdb_remove_all (oa->lsdb);
  279:   ospf6_lsdb_remove_all (oa->lsdb_self);
  280: 
  281:   ospf6_spf_table_finish(oa->spf_table);
  282:   ospf6_route_remove_all(oa->route_table);
  283: 
  284:   THREAD_OFF (oa->thread_spf_calculation);
  285:   THREAD_OFF (oa->thread_route_calculation);
  286: 
  287:   THREAD_OFF (oa->thread_router_lsa);
  288:   THREAD_OFF (oa->thread_intra_prefix_lsa);
  289: }
  290: 
  291: 
  292: void
  293: ospf6_area_show (struct vty *vty, struct ospf6_area *oa)
  294: {
  295:   struct listnode *i;
  296:   struct ospf6_interface *oi;
  297: 
  298:   vty_out (vty, " Area %s%s", oa->name, VNL);
  299:   vty_out (vty, "     Number of Area scoped LSAs is %u%s",
  300:            oa->lsdb->count, VNL);
  301: 
  302:   vty_out (vty, "     Interface attached to this area:");
  303:   for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
  304:     vty_out (vty, " %s", oi->interface->name);
  305:   
  306:   vty_out (vty, "%s", VNL);
  307: }
  308: 
  309: 
  310: #define OSPF6_CMD_AREA_LOOKUP(str, oa)                     \
  311: {                                                          \
  312:   u_int32_t area_id = 0;                                   \
  313:   if (inet_pton (AF_INET, str, &area_id) != 1)             \
  314:     {                                                      \
  315:       vty_out (vty, "Malformed Area-ID: %s%s", str, VNL);  \
  316:       return CMD_SUCCESS;                                  \
  317:     }                                                      \
  318:   oa = ospf6_area_lookup (area_id, ospf6);                 \
  319:   if (oa == NULL)                                          \
  320:     {                                                      \
  321:       vty_out (vty, "No such Area: %s%s", str, VNL);       \
  322:       return CMD_SUCCESS;                                  \
  323:     }                                                      \
  324: }
  325: 
  326: #define OSPF6_CMD_AREA_GET(str, oa)                        \
  327: {                                                          \
  328:   u_int32_t area_id = 0;                                   \
  329:   if (inet_pton (AF_INET, str, &area_id) != 1)             \
  330:     {                                                      \
  331:       vty_out (vty, "Malformed Area-ID: %s%s", str, VNL);  \
  332:       return CMD_SUCCESS;                                  \
  333:     }                                                      \
  334:   oa = ospf6_area_get (area_id, ospf6);                    \
  335: }
  336: 
  337: DEFUN (area_range,
  338:        area_range_cmd,
  339:        "area A.B.C.D range X:X::X:X/M",
  340:        "OSPF area parameters\n"
  341:        OSPF6_AREA_ID_STR
  342:        "Configured address range\n"
  343:        "Specify IPv6 prefix\n"
  344:        )
  345: {
  346:   int ret;
  347:   struct ospf6_area *oa;
  348:   struct prefix prefix;
  349:   struct ospf6_route *range;
  350: 
  351:   OSPF6_CMD_AREA_GET (argv[0], oa);
  352:   argc--;
  353:   argv++;
  354: 
  355:   ret = str2prefix (argv[0], &prefix);
  356:   if (ret != 1 || prefix.family != AF_INET6)
  357:     {
  358:       vty_out (vty, "Malformed argument: %s%s", argv[0], VNL);
  359:       return CMD_SUCCESS;
  360:     }
  361:   argc--;
  362:   argv++;
  363: 
  364:   range = ospf6_route_lookup (&prefix, oa->range_table);
  365:   if (range == NULL)
  366:     {
  367:       range = ospf6_route_create ();
  368:       range->type = OSPF6_DEST_TYPE_RANGE;
  369:       range->prefix = prefix;
  370:     }
  371: 
  372:   if (argc)
  373:     {
  374:       if (! strcmp (argv[0], "not-advertise"))
  375:         SET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
  376:       else if (! strcmp (argv[0], "advertise"))
  377:         UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
  378:     }
  379: 
  380:   if (range->rnode)
  381:     {
  382:       vty_out (vty, "Range already defined: %s%s", argv[-1], VNL);
  383:       return CMD_WARNING;
  384:     }
  385: 
  386:   ospf6_route_add (range, oa->range_table);
  387:   return CMD_SUCCESS;
  388: }
  389: 
  390: ALIAS (area_range,
  391:        area_range_advertise_cmd,
  392:        "area A.B.C.D range X:X::X:X/M (advertise|not-advertise)",
  393:        "OSPF area parameters\n"
  394:        OSPF6_AREA_ID_STR
  395:        "Configured address range\n"
  396:        "Specify IPv6 prefix\n"
  397:        )
  398: 
  399: DEFUN (no_area_range,
  400:        no_area_range_cmd,
  401:        "no area A.B.C.D range X:X::X:X/M",
  402:        "OSPF area parameters\n"
  403:        OSPF6_AREA_ID_STR
  404:        "Configured address range\n"
  405:        "Specify IPv6 prefix\n"
  406:        )
  407: {
  408:   int ret;
  409:   struct ospf6_area *oa;
  410:   struct prefix prefix;
  411:   struct ospf6_route *range;
  412: 
  413:   OSPF6_CMD_AREA_GET (argv[0], oa);
  414:   argc--;
  415:   argv++;
  416: 
  417:   ret = str2prefix (argv[0], &prefix);
  418:   if (ret != 1 || prefix.family != AF_INET6)
  419:     {
  420:       vty_out (vty, "Malformed argument: %s%s", argv[0], VNL);
  421:       return CMD_SUCCESS;
  422:     }
  423: 
  424:   range = ospf6_route_lookup (&prefix, oa->range_table);
  425:   if (range == NULL)
  426:     {
  427:       vty_out (vty, "Range %s does not exists.%s", argv[0], VNL);
  428:       return CMD_SUCCESS;
  429:     }
  430: 
  431:   ospf6_route_remove (range, oa->range_table);
  432: 
  433:   return CMD_SUCCESS;
  434: }
  435: 
  436: void
  437: ospf6_area_config_write (struct vty *vty)
  438: {
  439:   struct listnode *node;
  440:   struct ospf6_area *oa;
  441:   struct ospf6_route *range;
  442:   char buf[128];
  443: 
  444:   for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
  445:     {
  446:       for (range = ospf6_route_head (oa->range_table); range;
  447:            range = ospf6_route_next (range))
  448:         {
  449:           prefix2str (&range->prefix, buf, sizeof (buf));
  450:           vty_out (vty, " area %s range %s%s", oa->name, buf, VNL);
  451:         }
  452:       if (PREFIX_NAME_IN (oa))
  453:         vty_out (vty, " area %s filter-list prefix %s in%s",
  454:                  oa->name, PREFIX_NAME_IN (oa), VNL);
  455:       if (PREFIX_NAME_OUT (oa))
  456:         vty_out (vty, " area %s filter-list prefix %s out%s",
  457:                  oa->name, PREFIX_NAME_OUT (oa), VNL);
  458:       if (IMPORT_NAME (oa))
  459:         vty_out (vty, " area %s import-list %s%s",
  460:                  oa->name, IMPORT_NAME (oa), VNL);
  461:       if (EXPORT_NAME (oa))
  462:         vty_out (vty, " area %s export-list %s%s",
  463:                  oa->name, EXPORT_NAME (oa), VNL);
  464:     }
  465: }
  466: 
  467: DEFUN (area_filter_list,
  468:        area_filter_list_cmd,
  469:        "area A.B.C.D filter-list prefix WORD (in|out)",
  470:        "OSPFv6 area parameters\n"
  471:        "OSPFv6 area ID in IP address format\n"
  472:        "Filter networks between OSPFv6 areas\n"
  473:        "Filter prefixes between OSPFv6 areas\n"
  474:        "Name of an IPv6 prefix-list\n"
  475:        "Filter networks sent to this area\n"
  476:        "Filter networks sent from this area\n")
  477: {
  478:   struct ospf6_area *area;
  479:   struct prefix_list *plist;
  480: 
  481:   OSPF6_CMD_AREA_GET (argv[0], area);
  482:   argc--;
  483:   argv++;
  484: 
  485:   plist = prefix_list_lookup (AFI_IP6, argv[0]);
  486:   if (strncmp (argv[1], "in", 2) == 0)
  487:     {
  488:       PREFIX_LIST_IN (area) = plist;
  489:       if (PREFIX_NAME_IN (area))
  490: 	free (PREFIX_NAME_IN (area));
  491: 
  492:       PREFIX_NAME_IN (area) = strdup (argv[0]);
  493:       ospf6_abr_reimport (area);
  494:     }
  495:   else
  496:     {
  497:       PREFIX_LIST_OUT (area) = plist;
  498:       if (PREFIX_NAME_OUT (area))
  499: 	free (PREFIX_NAME_OUT (area));
  500: 
  501:       PREFIX_NAME_OUT (area) = strdup (argv[0]);
  502:       ospf6_abr_enable_area (area);
  503:     }
  504: 
  505:   return CMD_SUCCESS;
  506: }
  507:      
  508: DEFUN (no_area_filter_list,
  509:        no_area_filter_list_cmd,
  510:        "no area A.B.C.D filter-list prefix WORD (in|out)",
  511:        NO_STR
  512:        "OSPFv6 area parameters\n"
  513:        "OSPFv6 area ID in IP address format\n"
  514:        "Filter networks between OSPFv6 areas\n"
  515:        "Filter prefixes between OSPFv6 areas\n"
  516:        "Name of an IPv6 prefix-list\n"
  517:        "Filter networks sent to this area\n"
  518:        "Filter networks sent from this area\n")
  519: {
  520:   struct ospf6_area *area;
  521: 
  522:   OSPF6_CMD_AREA_GET (argv[0], area);
  523:   argc--;
  524:   argv++;
  525: 
  526:   if (strncmp (argv[1], "in", 2) == 0)
  527:     {
  528:       if (PREFIX_NAME_IN (area))
  529: 	if (strcmp (PREFIX_NAME_IN (area), argv[0]) != 0)
  530: 	  return CMD_SUCCESS;
  531: 
  532:       PREFIX_LIST_IN (area) = NULL;
  533:       if (PREFIX_NAME_IN (area))
  534: 	free (PREFIX_NAME_IN (area));
  535: 
  536:       PREFIX_NAME_IN (area) = NULL;
  537:       ospf6_abr_reimport (area);
  538:     }
  539:   else
  540:     {
  541:       if (PREFIX_NAME_OUT (area))
  542: 	if (strcmp (PREFIX_NAME_OUT (area), argv[0]) != 0)
  543: 	  return CMD_SUCCESS;
  544: 
  545:       PREFIX_LIST_OUT (area) = NULL;
  546:       if (PREFIX_NAME_OUT (area))
  547: 	free (PREFIX_NAME_OUT (area));
  548: 
  549:       PREFIX_NAME_OUT (area) = NULL;
  550:       ospf6_abr_enable_area (area);
  551:     }
  552: 
  553:   return CMD_SUCCESS;
  554: }
  555: 
  556: DEFUN (area_import_list,
  557:        area_import_list_cmd,
  558:        "area A.B.C.D import-list NAME",
  559:        "OSPFv6 area parameters\n"
  560:        "OSPFv6 area ID in IP address format\n"
  561:        "Set the filter for networks from other areas announced to the specified one\n"
  562:        "Name of the acess-list\n")
  563: {
  564:   struct ospf6_area *area;
  565:   struct access_list *list;
  566: 
  567:   OSPF6_CMD_AREA_GET(argv[0], area);
  568: 
  569:   list = access_list_lookup (AFI_IP6, argv[1]);
  570: 
  571:   IMPORT_LIST (area) = list;
  572: 
  573:   if (IMPORT_NAME (area))
  574:     free (IMPORT_NAME (area));
  575: 
  576:   IMPORT_NAME (area) = strdup (argv[1]);
  577:   ospf6_abr_reimport (area);
  578: 
  579:   return CMD_SUCCESS; 
  580: }
  581: 
  582: DEFUN (no_area_import_list,
  583:        no_area_import_list_cmd,
  584:        "no area A.B.C.D import-list NAME",
  585:        "OSPFv6 area parameters\n"
  586:        "OSPFv6 area ID in IP address format\n"
  587:        "Unset the filter for networks announced to other areas\n"
  588:        "NAme of the access-list\n")
  589: {
  590:   struct ospf6_area *area;
  591: 
  592:   OSPF6_CMD_AREA_GET(argv[0], area);
  593: 
  594:   IMPORT_LIST (area) = 0;
  595: 
  596:   if (IMPORT_NAME (area))
  597:     free (IMPORT_NAME (area));
  598: 
  599:   IMPORT_NAME (area) = NULL;
  600:   ospf6_abr_reimport (area);
  601: 
  602:   return CMD_SUCCESS;
  603: }
  604: 
  605: DEFUN (area_export_list,
  606:        area_export_list_cmd,
  607:        "area A.B.C.D export-list NAME",
  608:        "OSPFv6 area parameters\n"
  609:        "OSPFv6 area ID in IP address format\n"
  610:        "Set the filter for networks announced to other areas\n"
  611:        "Name of the acess-list\n")
  612: {
  613:   struct ospf6_area *area;
  614:   struct access_list *list;
  615: 
  616:   OSPF6_CMD_AREA_GET(argv[0], area);
  617: 
  618:   list = access_list_lookup (AFI_IP6, argv[1]);
  619: 
  620:   EXPORT_LIST (area) = list;
  621: 
  622:   if (EXPORT_NAME (area))
  623:     free (EXPORT_NAME (area));
  624: 
  625:   EXPORT_NAME (area) = strdup (argv[1]);
  626:   ospf6_abr_enable_area (area);
  627: 
  628:   return CMD_SUCCESS; 
  629: }
  630: 
  631: DEFUN (no_area_export_list,
  632:        no_area_export_list_cmd,
  633:        "no area A.B.C.D export-list NAME",
  634:        "OSPFv6 area parameters\n"
  635:        "OSPFv6 area ID in IP address format\n"
  636:        "Unset the filter for networks announced to other areas\n"
  637:        "Name of the access-list\n")
  638: {
  639:   struct ospf6_area *area;
  640: 
  641:   OSPF6_CMD_AREA_GET(argv[0], area);
  642: 
  643:   EXPORT_LIST (area) = 0;
  644: 
  645:   if (EXPORT_NAME (area))
  646:     free (EXPORT_NAME (area));
  647: 
  648:   EXPORT_NAME (area) = NULL;
  649:   ospf6_abr_enable_area (area);
  650: 
  651:   return CMD_SUCCESS;
  652: }
  653: 
  654: DEFUN (show_ipv6_ospf6_spf_tree,
  655:        show_ipv6_ospf6_spf_tree_cmd,
  656:        "show ipv6 ospf6 spf tree",
  657:        SHOW_STR
  658:        IP6_STR
  659:        OSPF6_STR
  660:        "Shortest Path First caculation\n"
  661:        "Show SPF tree\n")
  662: {
  663:   struct listnode *node;
  664:   struct ospf6_area *oa;
  665:   struct ospf6_vertex *root;
  666:   struct ospf6_route *route;
  667:   struct prefix prefix;
  668: 
  669:   ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
  670: 
  671:   for (ALL_LIST_ELEMENTS_RO (ospf6->area_list, node, oa))
  672:     {
  673:       route = ospf6_route_lookup (&prefix, oa->spf_table);
  674:       if (route == NULL)
  675:         {
  676:           vty_out (vty, "LS entry for root not found in area %s%s",
  677:                    oa->name, VNL);
  678:           continue;
  679:         }
  680:       root = (struct ospf6_vertex *) route->route_option;
  681:       ospf6_spf_display_subtree (vty, "", 0, root);
  682:     }
  683: 
  684:   return CMD_SUCCESS;
  685: }
  686: 
  687: DEFUN (show_ipv6_ospf6_area_spf_tree,
  688:        show_ipv6_ospf6_area_spf_tree_cmd,
  689:        "show ipv6 ospf6 area A.B.C.D spf tree",
  690:        SHOW_STR
  691:        IP6_STR
  692:        OSPF6_STR
  693:        OSPF6_AREA_STR
  694:        OSPF6_AREA_ID_STR
  695:        "Shortest Path First caculation\n"
  696:        "Show SPF tree\n")
  697: {
  698:   u_int32_t area_id;
  699:   struct ospf6_area *oa;
  700:   struct ospf6_vertex *root;
  701:   struct ospf6_route *route;
  702:   struct prefix prefix;
  703: 
  704:   ospf6_linkstate_prefix (ospf6->router_id, htonl (0), &prefix);
  705: 
  706:   if (inet_pton (AF_INET, argv[0], &area_id) != 1)
  707:     {
  708:       vty_out (vty, "Malformed Area-ID: %s%s", argv[0], VNL);
  709:       return CMD_SUCCESS;
  710:     }
  711:   oa = ospf6_area_lookup (area_id, ospf6);
  712:   if (oa == NULL)
  713:     {
  714:       vty_out (vty, "No such Area: %s%s", argv[0], VNL);
  715:       return CMD_SUCCESS;
  716:     }
  717: 
  718:   route = ospf6_route_lookup (&prefix, oa->spf_table);
  719:   if (route == NULL)
  720:     {
  721:       vty_out (vty, "LS entry for root not found in area %s%s",
  722:                oa->name, VNL);
  723:       return CMD_SUCCESS;
  724:     }
  725:   root = (struct ospf6_vertex *) route->route_option;
  726:   ospf6_spf_display_subtree (vty, "", 0, root);
  727: 
  728:   return CMD_SUCCESS;
  729: }
  730: 
  731: DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
  732:        show_ipv6_ospf6_simulate_spf_tree_root_cmd,
  733:        "show ipv6 ospf6 simulate spf-tree A.B.C.D area A.B.C.D",
  734:        SHOW_STR
  735:        IP6_STR
  736:        OSPF6_STR
  737:        "Shortest Path First caculation\n"
  738:        "Show SPF tree\n"
  739:        "Specify root's router-id to calculate another router's SPF tree\n")
  740: {
  741:   u_int32_t area_id;
  742:   struct ospf6_area *oa;
  743:   struct ospf6_vertex *root;
  744:   struct ospf6_route *route;
  745:   struct prefix prefix;
  746:   u_int32_t router_id;
  747:   struct ospf6_route_table *spf_table;
  748:   unsigned char tmp_debug_ospf6_spf = 0;
  749: 
  750:   inet_pton (AF_INET, argv[0], &router_id);
  751:   ospf6_linkstate_prefix (router_id, htonl (0), &prefix);
  752: 
  753:   if (inet_pton (AF_INET, argv[1], &area_id) != 1)
  754:     {
  755:       vty_out (vty, "Malformed Area-ID: %s%s", argv[1], VNL);
  756:       return CMD_SUCCESS;
  757:     }
  758:   oa = ospf6_area_lookup (area_id, ospf6);
  759:   if (oa == NULL)
  760:     {
  761:       vty_out (vty, "No such Area: %s%s", argv[1], VNL);
  762:       return CMD_SUCCESS;
  763:     }
  764: 
  765:   tmp_debug_ospf6_spf = conf_debug_ospf6_spf;
  766:   conf_debug_ospf6_spf = 0;
  767: 
  768:   spf_table = OSPF6_ROUTE_TABLE_CREATE (NONE, SPF_RESULTS);
  769:   ospf6_spf_calculation (router_id, spf_table, oa);
  770: 
  771:   conf_debug_ospf6_spf = tmp_debug_ospf6_spf;
  772: 
  773:   route = ospf6_route_lookup (&prefix, spf_table);
  774:   if (route == NULL)
  775:     {
  776:       ospf6_spf_table_finish (spf_table);
  777:       ospf6_route_table_delete (spf_table);
  778:       return CMD_SUCCESS;
  779:     }
  780:   root = (struct ospf6_vertex *) route->route_option;
  781:   ospf6_spf_display_subtree (vty, "", 0, root);
  782: 
  783:   ospf6_spf_table_finish (spf_table);
  784:   ospf6_route_table_delete (spf_table);
  785: 
  786:   return CMD_SUCCESS;
  787: }
  788: 
  789: void
  790: ospf6_area_init (void)
  791: {
  792:   install_element (VIEW_NODE, &show_ipv6_ospf6_spf_tree_cmd);
  793:   install_element (VIEW_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
  794:   install_element (VIEW_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
  795: 
  796:   install_element (ENABLE_NODE, &show_ipv6_ospf6_spf_tree_cmd);
  797:   install_element (ENABLE_NODE, &show_ipv6_ospf6_area_spf_tree_cmd);
  798:   install_element (ENABLE_NODE, &show_ipv6_ospf6_simulate_spf_tree_root_cmd);
  799: 
  800:   install_element (OSPF6_NODE, &area_range_cmd);
  801:   install_element (OSPF6_NODE, &area_range_advertise_cmd);
  802:   install_element (OSPF6_NODE, &no_area_range_cmd);
  803: 
  804:   install_element (OSPF6_NODE, &area_import_list_cmd);
  805:   install_element (OSPF6_NODE, &no_area_import_list_cmd);
  806:   install_element (OSPF6_NODE, &area_export_list_cmd);
  807:   install_element (OSPF6_NODE, &no_area_export_list_cmd);
  808: 
  809:   install_element (OSPF6_NODE, &area_filter_list_cmd);
  810:   install_element (OSPF6_NODE, &no_area_filter_list_cmd);
  811: 
  812: }
  813: 
  814: 

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