Annotation of embedaddon/quagga/ospf6d/ospf6_area.c, revision 1.1.1.1

1.1       misho       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>