File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospf6d / ospf6_area.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:26:12 2012 UTC (12 years, 5 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, v0_99_21, v0_99_20_1, v0_99_20, HEAD
quagga

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

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