Annotation of embedaddon/quagga/ospfd/ospfd.c, revision 1.1.1.3

1.1       misho       1: /* OSPF version 2 daemon program.
                      2:    Copyright (C) 1999, 2000 Toshiaki Takada
                      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 Free
                     18: Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
                     19: 02111-1307, USA.  */
                     20: 
                     21: #include <zebra.h>
                     22: 
                     23: #include "thread.h"
                     24: #include "vty.h"
                     25: #include "command.h"
                     26: #include "linklist.h"
                     27: #include "prefix.h"
                     28: #include "table.h"
                     29: #include "if.h"
                     30: #include "memory.h"
                     31: #include "stream.h"
                     32: #include "log.h"
                     33: #include "sockunion.h"          /* for inet_aton () */
                     34: #include "zclient.h"
                     35: #include "plist.h"
                     36: #include "sockopt.h"
                     37: 
                     38: #include "ospfd/ospfd.h"
                     39: #include "ospfd/ospf_network.h"
                     40: #include "ospfd/ospf_interface.h"
                     41: #include "ospfd/ospf_ism.h"
                     42: #include "ospfd/ospf_asbr.h"
                     43: #include "ospfd/ospf_lsa.h"
                     44: #include "ospfd/ospf_lsdb.h"
                     45: #include "ospfd/ospf_neighbor.h"
                     46: #include "ospfd/ospf_nsm.h"
                     47: #include "ospfd/ospf_spf.h"
                     48: #include "ospfd/ospf_packet.h"
                     49: #include "ospfd/ospf_dump.h"
                     50: #include "ospfd/ospf_zebra.h"
                     51: #include "ospfd/ospf_abr.h"
                     52: #include "ospfd/ospf_flood.h"
                     53: #include "ospfd/ospf_route.h"
                     54: #include "ospfd/ospf_ase.h"
                     55: 
                     56: 
                     57: 
                     58: /* OSPF process wide configuration. */
                     59: static struct ospf_master ospf_master;
                     60: 
                     61: /* OSPF process wide configuration pointer to export. */
                     62: struct ospf_master *om;
                     63: 
                     64: extern struct zclient *zclient;
                     65: extern struct in_addr router_id_zebra;
                     66: 
                     67: 
                     68: static void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);
                     69: static void ospf_network_free (struct ospf *, struct ospf_network *);
                     70: static void ospf_area_free (struct ospf_area *);
                     71: static void ospf_network_run (struct prefix *, struct ospf_area *);
                     72: static void ospf_network_run_interface (struct prefix *, struct ospf_area *,
                     73:                                         struct interface *);
                     74: static int ospf_network_match_iface (const struct connected *,
                     75:                                     const struct prefix *);
                     76: static void ospf_finish_final (struct ospf *);
                     77: 
                     78: #define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
                     79: 
                     80: void
                     81: ospf_router_id_update (struct ospf *ospf)
                     82: {
                     83:   struct in_addr router_id, router_id_old;
                     84:   struct ospf_interface *oi;
                     85:   struct interface *ifp;
                     86:   struct listnode *node;
                     87: 
                     88:   if (IS_DEBUG_OSPF_EVENT)
                     89:     zlog_debug ("Router-ID[OLD:%s]: Update", inet_ntoa (ospf->router_id));
                     90: 
                     91:   router_id_old = ospf->router_id;
                     92: 
                     93:   /* Select the router ID based on these priorities:
                     94:        1. Statically assigned router ID is always the first choice.
                     95:        2. If there is no statically assigned router ID, then try to stick
                     96:           with the most recent value, since changing router ID's is very
                     97:          disruptive.
                     98:        3. Last choice: just go with whatever the zebra daemon recommends.
                     99:   */
                    100:   if (ospf->router_id_static.s_addr != 0)
                    101:     router_id = ospf->router_id_static;
                    102:   else if (ospf->router_id.s_addr != 0)
                    103:     router_id = ospf->router_id;
                    104:   else
                    105:     router_id = router_id_zebra;
                    106: 
                    107:   ospf->router_id = router_id;
                    108:   
                    109:   if (IS_DEBUG_OSPF_EVENT)
                    110:     zlog_debug ("Router-ID[NEW:%s]: Update", inet_ntoa (ospf->router_id));
                    111: 
                    112:   if (!IPV4_ADDR_SAME (&router_id_old, &router_id))
                    113:     {
                    114:       for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
                    115:         /* Update self-neighbor's router_id. */
                    116:         oi->nbr_self->router_id = router_id;
                    117: 
                    118:       /* If AS-external-LSA is queued, then flush those LSAs. */
                    119:       if (router_id_old.s_addr == 0 && ospf->external_origin)
                    120:        {
                    121:          int type;
                    122:          /* Originate each redistributed external route. */
                    123:          for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
                    124:            if (ospf->external_origin & (1 << type))
                    125:              thread_add_event (master, ospf_external_lsa_originate_timer,
                    126:                                ospf, type);
                    127:          /* Originate Deafult. */
                    128:          if (ospf->external_origin & (1 << ZEBRA_ROUTE_MAX))
                    129:            thread_add_event (master, ospf_default_originate_timer, ospf, 0);
                    130: 
                    131:          ospf->external_origin = 0;
                    132:        }
                    133: 
                    134:       /* update router-lsa's for each area */
                    135:       ospf_router_lsa_update (ospf);
                    136:       
                    137:       /* update ospf_interface's */
                    138:       for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
                    139:         ospf_if_update (ospf, ifp);
                    140:     }
                    141: }
                    142: 
                    143: /* For OSPF area sort by area id. */
                    144: static int
                    145: ospf_area_id_cmp (struct ospf_area *a1, struct ospf_area *a2)
                    146: {
                    147:   if (ntohl (a1->area_id.s_addr) > ntohl (a2->area_id.s_addr))
                    148:     return 1;
                    149:   if (ntohl (a1->area_id.s_addr) < ntohl (a2->area_id.s_addr))
                    150:     return -1;
                    151:   return 0;
                    152: }
                    153: 
                    154: /* Allocate new ospf structure. */
                    155: static struct ospf *
                    156: ospf_new (void)
                    157: {
                    158:   int i;
                    159: 
                    160:   struct ospf *new = XCALLOC (MTYPE_OSPF_TOP, sizeof (struct ospf));
                    161: 
                    162:   new->router_id.s_addr = htonl (0);
                    163:   new->router_id_static.s_addr = htonl (0);
                    164: 
                    165:   new->abr_type = OSPF_ABR_DEFAULT;
                    166:   new->oiflist = list_new ();
                    167:   new->vlinks = list_new ();
                    168:   new->areas = list_new ();
                    169:   new->areas->cmp = (int (*)(void *, void *)) ospf_area_id_cmp;
                    170:   new->networks = route_table_init ();
                    171:   new->nbr_nbma = route_table_init ();
                    172: 
                    173:   new->lsdb = ospf_lsdb_new ();
                    174: 
                    175:   new->default_originate = DEFAULT_ORIGINATE_NONE;
                    176: 
                    177:   new->passive_interface_default = OSPF_IF_ACTIVE;
                    178:   
                    179:   new->new_external_route = route_table_init ();
                    180:   new->old_external_route = route_table_init ();
                    181:   new->external_lsas = route_table_init ();
                    182:   
                    183:   new->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED;
                    184:   new->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
1.1.1.3 ! misho     185:   new->stub_router_admin_set     = OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET;
        !           186: 
1.1       misho     187:   /* Distribute parameter init. */
                    188:   for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
                    189:     {
                    190:       new->dmetric[i].type = -1;
                    191:       new->dmetric[i].value = -1;
                    192:     }
                    193:   new->default_metric = -1;
                    194:   new->ref_bandwidth = OSPF_DEFAULT_REF_BANDWIDTH;
                    195: 
                    196:   /* SPF timer value init. */
                    197:   new->spf_delay = OSPF_SPF_DELAY_DEFAULT;
                    198:   new->spf_holdtime = OSPF_SPF_HOLDTIME_DEFAULT;
                    199:   new->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
                    200:   new->spf_hold_multiplier = 1;
                    201: 
                    202:   /* MaxAge init. */
                    203:   new->maxage_delay = OSFP_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;
1.1.1.3 ! misho     204:   new->maxage_lsa = route_table_init();
1.1       misho     205:   new->t_maxage_walker =
                    206:     thread_add_timer (master, ospf_lsa_maxage_walker,
                    207:                       new, OSPF_LSA_MAXAGE_CHECK_INTERVAL);
                    208: 
                    209:   /* Distance table init. */
                    210:   new->distance_table = route_table_init ();
                    211: 
                    212:   new->lsa_refresh_queue.index = 0;
                    213:   new->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
                    214:   new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
                    215:                                           new, new->lsa_refresh_interval);
                    216:   new->lsa_refresher_started = quagga_time (NULL);
                    217: 
                    218:   if ((new->fd = ospf_sock_init()) < 0)
                    219:     {
                    220:       zlog_err("ospf_new: fatal error: ospf_sock_init was unable to open "
                    221:               "a socket");
                    222:       exit(1);
                    223:     }
                    224:   new->maxsndbuflen = getsockopt_so_sendbuf (new->fd);
                    225:   if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
1.1.1.3 ! misho     226:     zlog_debug ("%s: starting with OSPF send buffer size %u",
1.1       misho     227:       __func__, new->maxsndbuflen);
                    228:   if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE+1)) == NULL)
                    229:     {
                    230:       zlog_err("ospf_new: fatal error: stream_new(%u) failed allocating ibuf",
                    231:               OSPF_MAX_PACKET_SIZE+1);
                    232:       exit(1);
                    233:     }
                    234:   new->t_read = thread_add_read (master, ospf_read, new, new->fd);
                    235:   new->oi_write_q = list_new ();
                    236:   
                    237:   return new;
                    238: }
                    239: 
                    240: struct ospf *
                    241: ospf_lookup ()
                    242: {
                    243:   if (listcount (om->ospf) == 0)
                    244:     return NULL;
                    245: 
                    246:   return listgetdata (listhead (om->ospf));
                    247: }
                    248: 
                    249: static void
                    250: ospf_add (struct ospf *ospf)
                    251: {
                    252:   listnode_add (om->ospf, ospf);
                    253: }
                    254: 
                    255: static void
                    256: ospf_delete (struct ospf *ospf)
                    257: {
                    258:   listnode_delete (om->ospf, ospf);
                    259: }
                    260: 
                    261: struct ospf *
                    262: ospf_get ()
                    263: {
                    264:   struct ospf *ospf;
                    265: 
                    266:   ospf = ospf_lookup ();
                    267:   if (ospf == NULL)
                    268:     {
                    269:       ospf = ospf_new ();
                    270:       ospf_add (ospf);
                    271: 
                    272:       if (ospf->router_id_static.s_addr == 0)
                    273:        ospf_router_id_update (ospf);
                    274: 
                    275: #ifdef HAVE_OPAQUE_LSA
                    276:       ospf_opaque_type11_lsa_init (ospf);
                    277: #endif /* HAVE_OPAQUE_LSA */
                    278:     }
                    279: 
                    280:   return ospf;
                    281: }
                    282: 
                    283: /* Handle the second half of deferred shutdown. This is called either
                    284:  * from the deferred-shutdown timer thread, or directly through
                    285:  * ospf_deferred_shutdown_check.
                    286:  *
                    287:  * Function is to cleanup G-R state, if required then call ospf_finish_final
                    288:  * to complete shutdown of this ospf instance. Possibly exit if the
                    289:  * whole process is being shutdown and this was the last OSPF instance.
                    290:  */
                    291: static void
                    292: ospf_deferred_shutdown_finish (struct ospf *ospf)
                    293: {
                    294:   ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;  
                    295:   OSPF_TIMER_OFF (ospf->t_deferred_shutdown);
                    296:   
                    297:   ospf_finish_final (ospf);
                    298:   
                    299:   /* *ospf is now invalid */
                    300:   
                    301:   /* ospfd being shut-down? If so, was this the last ospf instance? */
                    302:   if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN)
                    303:       && (listcount (om->ospf) == 0))
                    304:     exit (0);
                    305: 
                    306:   return;
                    307: }
                    308: 
                    309: /* Timer thread for G-R */
                    310: static int
                    311: ospf_deferred_shutdown_timer (struct thread *t)
                    312: {
                    313:   struct ospf *ospf = THREAD_ARG(t);
                    314:   
                    315:   ospf_deferred_shutdown_finish (ospf);
                    316:   
                    317:   return 0;
                    318: }
                    319: 
                    320: /* Check whether deferred-shutdown must be scheduled, otherwise call
                    321:  * down directly into second-half of instance shutdown.
                    322:  */
                    323: static void
                    324: ospf_deferred_shutdown_check (struct ospf *ospf)
                    325: {
                    326:   unsigned long timeout;
                    327:   struct listnode *ln;
                    328:   struct ospf_area *area;
                    329:   
                    330:   /* deferred shutdown already running? */
                    331:   if (ospf->t_deferred_shutdown)
                    332:     return;
                    333:   
                    334:   /* Should we try push out max-metric LSAs? */
                    335:   if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED)
                    336:     {
                    337:       for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area))
                    338:         {
                    339:           SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
                    340:           
                    341:           if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
                    342:             ospf_router_lsa_update_area (area);
                    343:         }
                    344:       timeout = ospf->stub_router_shutdown_time;
                    345:     }
                    346:   else
                    347:     {
                    348:       /* No timer needed */
                    349:       ospf_deferred_shutdown_finish (ospf);
                    350:       return;
                    351:     }
                    352:   
                    353:   OSPF_TIMER_ON (ospf->t_deferred_shutdown, ospf_deferred_shutdown_timer,
                    354:                  timeout);
                    355:   return;
                    356: }
                    357: 
                    358: /* Shut down the entire process */
                    359: void
                    360: ospf_terminate (void)
                    361: {
                    362:   struct ospf *ospf;
                    363:   struct listnode *node, *nnode;
                    364:   
                    365:   /* shutdown already in progress */
                    366:   if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
                    367:     return;
                    368:   
                    369:   SET_FLAG (om->options, OSPF_MASTER_SHUTDOWN);
                    370: 
                    371:   /* exit immediately if OSPF not actually running */
                    372:   if (listcount(om->ospf) == 0)
                    373:     exit(0);
                    374: 
                    375:   for (ALL_LIST_ELEMENTS (om->ospf, node, nnode, ospf))
                    376:     ospf_finish (ospf);
                    377: 
                    378:   /* Deliberately go back up, hopefully to thread scheduler, as
                    379:    * One or more ospf_finish()'s may have deferred shutdown to a timer
                    380:    * thread
                    381:    */
                    382: }
                    383: 
                    384: void
                    385: ospf_finish (struct ospf *ospf)
                    386: {
                    387:   /* let deferred shutdown decide */
                    388:   ospf_deferred_shutdown_check (ospf);
                    389:       
                    390:   /* if ospf_deferred_shutdown returns, then ospf_finish_final is
                    391:    * deferred to expiry of G-S timer thread. Return back up, hopefully
                    392:    * to thread scheduler.
                    393:    */
                    394:   return;
                    395: }
                    396: 
                    397: /* Final cleanup of ospf instance */
                    398: static void
                    399: ospf_finish_final (struct ospf *ospf)
                    400: {
                    401:   struct route_node *rn;
                    402:   struct ospf_nbr_nbma *nbr_nbma;
                    403:   struct ospf_lsa *lsa;
                    404:   struct ospf_interface *oi;
                    405:   struct ospf_area *area;
                    406:   struct ospf_vl_data *vl_data;
                    407:   struct listnode *node, *nnode;
                    408:   int i;
                    409: 
                    410: #ifdef HAVE_OPAQUE_LSA
                    411:   ospf_opaque_type11_lsa_term (ospf);
                    412: #endif /* HAVE_OPAQUE_LSA */
                    413:   
                    414:   /* be nice if this worked, but it doesn't */
                    415:   /*ospf_flush_self_originated_lsas_now (ospf);*/
                    416:   
                    417:   /* Unregister redistribution */
                    418:   for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
                    419:     ospf_redistribute_unset (ospf, i);
                    420:   ospf_redistribute_default_unset (ospf);
                    421: 
                    422:   for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
                    423:     ospf_remove_vls_through_area (ospf, area);
                    424:   
                    425:   for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
                    426:     ospf_vl_delete (ospf, vl_data);
                    427:   
                    428:   list_delete (ospf->vlinks);
                    429: 
                    430:   /* Reset interface. */
                    431:   for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
                    432:     ospf_if_free (oi);
                    433: 
                    434:   /* Clear static neighbors */
                    435:   for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
                    436:     if ((nbr_nbma = rn->info))
                    437:       {
                    438:        OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
                    439: 
                    440:        if (nbr_nbma->nbr)
                    441:          {
                    442:            nbr_nbma->nbr->nbr_nbma = NULL;
                    443:            nbr_nbma->nbr = NULL;
                    444:          }
                    445: 
                    446:        if (nbr_nbma->oi)
                    447:          {
                    448:            listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
                    449:            nbr_nbma->oi = NULL;
                    450:          }
                    451: 
                    452:        XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
                    453:       }
                    454: 
                    455:   route_table_finish (ospf->nbr_nbma);
                    456: 
                    457:   /* Clear networks and Areas. */
                    458:   for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
                    459:     {
                    460:       struct ospf_network *network;
                    461: 
                    462:       if ((network = rn->info) != NULL)
                    463:        {
                    464:          ospf_network_free (ospf, network);
                    465:          rn->info = NULL;
                    466:          route_unlock_node (rn);
                    467:        }
                    468:     }
                    469: 
                    470:   for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
                    471:     {
                    472:       listnode_delete (ospf->areas, area);
                    473:       ospf_area_free (area);
                    474:     }
                    475: 
                    476:   /* Cancel all timers. */
                    477:   OSPF_TIMER_OFF (ospf->t_external_lsa);
                    478:   OSPF_TIMER_OFF (ospf->t_spf_calc);
                    479:   OSPF_TIMER_OFF (ospf->t_ase_calc);
                    480:   OSPF_TIMER_OFF (ospf->t_maxage);
                    481:   OSPF_TIMER_OFF (ospf->t_maxage_walker);
                    482:   OSPF_TIMER_OFF (ospf->t_abr_task);
                    483:   OSPF_TIMER_OFF (ospf->t_asbr_check);
                    484:   OSPF_TIMER_OFF (ospf->t_distribute_update);
                    485:   OSPF_TIMER_OFF (ospf->t_lsa_refresher);
                    486:   OSPF_TIMER_OFF (ospf->t_read);
                    487:   OSPF_TIMER_OFF (ospf->t_write);
                    488: #ifdef HAVE_OPAQUE_LSA
                    489:   OSPF_TIMER_OFF (ospf->t_opaque_lsa_self);
                    490: #endif
                    491: 
                    492:   close (ospf->fd);
                    493:   stream_free(ospf->ibuf);
                    494:    
                    495: #ifdef HAVE_OPAQUE_LSA
                    496:   LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
                    497:     ospf_discard_from_db (ospf, ospf->lsdb, lsa);
                    498: #endif /* HAVE_OPAQUE_LSA */
                    499:   LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
                    500:     ospf_discard_from_db (ospf, ospf->lsdb, lsa);
                    501: 
                    502:   ospf_lsdb_delete_all (ospf->lsdb);
                    503:   ospf_lsdb_free (ospf->lsdb);
                    504: 
1.1.1.3 ! misho     505:   for (rn = route_top (ospf->maxage_lsa); rn; rn = route_next (rn))
        !           506:     {
        !           507:       struct ospf_lsa *lsa;
1.1       misho     508: 
1.1.1.3 ! misho     509:       if ((lsa = rn->info) != NULL)
        !           510:        {
        !           511:          ospf_lsa_unlock (&lsa);
        !           512:          rn->info = NULL;
        !           513:        }
        !           514:       route_unlock_node (rn);
        !           515:     }
        !           516:   route_table_finish (ospf->maxage_lsa);
1.1       misho     517: 
                    518:   if (ospf->old_table)
                    519:     ospf_route_table_free (ospf->old_table);
                    520:   if (ospf->new_table)
                    521:     {
                    522:       ospf_route_delete (ospf->new_table);
                    523:       ospf_route_table_free (ospf->new_table);
                    524:     }
                    525:   if (ospf->old_rtrs)
                    526:     ospf_rtrs_free (ospf->old_rtrs);
                    527:   if (ospf->new_rtrs)
                    528:     ospf_rtrs_free (ospf->new_rtrs);
                    529:   if (ospf->new_external_route)
                    530:     {
                    531:       ospf_route_delete (ospf->new_external_route);
                    532:       ospf_route_table_free (ospf->new_external_route);
                    533:     }
                    534:   if (ospf->old_external_route)
                    535:     {
                    536:       ospf_route_delete (ospf->old_external_route);
                    537:       ospf_route_table_free (ospf->old_external_route);
                    538:     }
                    539:   if (ospf->external_lsas)
                    540:     {
                    541:       ospf_ase_external_lsas_finish (ospf->external_lsas);
                    542:     }
                    543: 
                    544:   list_delete (ospf->areas);
                    545:   
                    546:   for (i = ZEBRA_ROUTE_SYSTEM; i <= ZEBRA_ROUTE_MAX; i++)
                    547:     if (EXTERNAL_INFO (i) != NULL)
                    548:       for (rn = route_top (EXTERNAL_INFO (i)); rn; rn = route_next (rn))
                    549:        {
                    550:          if (rn->info == NULL)
                    551:            continue;
                    552:          
                    553:          XFREE (MTYPE_OSPF_EXTERNAL_INFO, rn->info);
                    554:          rn->info = NULL;
                    555:          route_unlock_node (rn);
                    556:        }
                    557: 
                    558:   ospf_distance_reset (ospf);
                    559:   route_table_finish (ospf->distance_table);
                    560: 
                    561:   ospf_delete (ospf);
                    562: 
                    563:   XFREE (MTYPE_OSPF_TOP, ospf);
                    564: }
                    565: 
                    566: 
                    567: /* allocate new OSPF Area object */
                    568: static struct ospf_area *
                    569: ospf_area_new (struct ospf *ospf, struct in_addr area_id)
                    570: {
                    571:   struct ospf_area *new;
                    572: 
                    573:   /* Allocate new config_network. */
                    574:   new = XCALLOC (MTYPE_OSPF_AREA, sizeof (struct ospf_area));
                    575: 
                    576:   new->ospf = ospf;
                    577: 
                    578:   new->area_id = area_id;
                    579: 
                    580:   new->external_routing = OSPF_AREA_DEFAULT;
                    581:   new->default_cost = 1;
                    582:   new->auth_type = OSPF_AUTH_NULL;
                    583:   
                    584:   /* New LSDB init. */
                    585:   new->lsdb = ospf_lsdb_new ();
                    586: 
                    587:   /* Self-originated LSAs initialize. */
                    588:   new->router_lsa_self = NULL;
                    589: 
                    590: #ifdef HAVE_OPAQUE_LSA
                    591:   ospf_opaque_type10_lsa_init (new);
                    592: #endif /* HAVE_OPAQUE_LSA */
                    593: 
                    594:   new->oiflist = list_new ();
                    595:   new->ranges = route_table_init ();
                    596: 
                    597:   if (area_id.s_addr == OSPF_AREA_BACKBONE)
                    598:     ospf->backbone = new;
                    599: 
                    600:   return new;
                    601: }
                    602: 
                    603: static void
                    604: ospf_area_free (struct ospf_area *area)
                    605: {
                    606:   struct route_node *rn;
                    607:   struct ospf_lsa *lsa;
                    608: 
                    609:   /* Free LSDBs. */
                    610:   LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
                    611:     ospf_discard_from_db (area->ospf, area->lsdb, lsa);
                    612:   LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
                    613:     ospf_discard_from_db (area->ospf, area->lsdb, lsa);
                    614:   LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
                    615:     ospf_discard_from_db (area->ospf, area->lsdb, lsa);
                    616:   LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
                    617:     ospf_discard_from_db (area->ospf, area->lsdb, lsa);
                    618: 
                    619:   LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
                    620:     ospf_discard_from_db (area->ospf, area->lsdb, lsa);
                    621: #ifdef HAVE_OPAQUE_LSA
                    622:   LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
                    623:     ospf_discard_from_db (area->ospf, area->lsdb, lsa);
                    624:   LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
                    625:     ospf_discard_from_db (area->ospf, area->lsdb, lsa);
                    626: #endif /* HAVE_OPAQUE_LSA */
                    627: 
                    628:   ospf_lsdb_delete_all (area->lsdb);
                    629:   ospf_lsdb_free (area->lsdb);
                    630: 
                    631:   ospf_lsa_unlock (&area->router_lsa_self);
                    632:   
                    633:   route_table_finish (area->ranges);
                    634:   list_delete (area->oiflist);
                    635: 
                    636:   if (EXPORT_NAME (area))
                    637:     free (EXPORT_NAME (area));
                    638: 
                    639:   if (IMPORT_NAME (area))
                    640:     free (IMPORT_NAME (area));
                    641: 
                    642:   /* Cancel timer. */
                    643:   OSPF_TIMER_OFF (area->t_stub_router);
                    644: #ifdef HAVE_OPAQUE_LSA
                    645:   OSPF_TIMER_OFF (area->t_opaque_lsa_self);
                    646: #endif /* HAVE_OPAQUE_LSA */
                    647:   
                    648:   if (OSPF_IS_AREA_BACKBONE (area))
                    649:     area->ospf->backbone = NULL;
                    650: 
                    651:   XFREE (MTYPE_OSPF_AREA, area);
                    652: }
                    653: 
                    654: void
                    655: ospf_area_check_free (struct ospf *ospf, struct in_addr area_id)
                    656: {
                    657:   struct ospf_area *area;
                    658: 
                    659:   area = ospf_area_lookup_by_area_id (ospf, area_id);
                    660:   if (area &&
                    661:       listcount (area->oiflist) == 0 &&
                    662:       area->ranges->top == NULL &&
                    663:       area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
                    664:       area->external_routing == OSPF_AREA_DEFAULT &&
                    665:       area->no_summary == 0 &&
                    666:       area->default_cost == 1 &&
                    667:       EXPORT_NAME (area) == NULL &&
                    668:       IMPORT_NAME (area) == NULL &&
                    669:       area->auth_type == OSPF_AUTH_NULL)
                    670:     {
                    671:       listnode_delete (ospf->areas, area);
                    672:       ospf_area_free (area);
                    673:     }
                    674: }
                    675: 
                    676: struct ospf_area *
                    677: ospf_area_get (struct ospf *ospf, struct in_addr area_id, int format)
                    678: {
                    679:   struct ospf_area *area;
                    680:   
                    681:   area = ospf_area_lookup_by_area_id (ospf, area_id);
                    682:   if (!area)
                    683:     {
                    684:       area = ospf_area_new (ospf, area_id);
                    685:       area->format = format;
                    686:       listnode_add_sort (ospf->areas, area);
                    687:       ospf_check_abr_status (ospf);  
1.1.1.3 ! misho     688:       if (ospf->stub_router_admin_set == OSPF_STUB_ROUTER_ADMINISTRATIVE_SET)
        !           689:         {
        !           690:           SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
        !           691:         }
1.1       misho     692:     }
                    693: 
                    694:   return area;
                    695: }
                    696: 
                    697: struct ospf_area *
                    698: ospf_area_lookup_by_area_id (struct ospf *ospf, struct in_addr area_id)
                    699: {
                    700:   struct ospf_area *area;
                    701:   struct listnode *node;
                    702: 
                    703:   for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
                    704:     if (IPV4_ADDR_SAME (&area->area_id, &area_id))
                    705:       return area;
                    706: 
                    707:   return NULL;
                    708: }
                    709: 
                    710: void
                    711: ospf_area_add_if (struct ospf_area *area, struct ospf_interface *oi)
                    712: {
                    713:   listnode_add (area->oiflist, oi);
                    714: }
                    715: 
                    716: void
                    717: ospf_area_del_if (struct ospf_area *area, struct ospf_interface *oi)
                    718: {
                    719:   listnode_delete (area->oiflist, oi);
                    720: }
                    721: 
                    722: 
                    723: /* Config network statement related functions. */
                    724: static struct ospf_network *
                    725: ospf_network_new (struct in_addr area_id, int format)
                    726: {
                    727:   struct ospf_network *new;
                    728:   new = XCALLOC (MTYPE_OSPF_NETWORK, sizeof (struct ospf_network));
                    729: 
                    730:   new->area_id = area_id;
                    731:   new->format = format;
                    732:   
                    733:   return new;
                    734: }
                    735: 
                    736: static void
                    737: ospf_network_free (struct ospf *ospf, struct ospf_network *network)
                    738: {
                    739:   ospf_area_check_free (ospf, network->area_id);
                    740:   ospf_schedule_abr_task (ospf);
                    741:   XFREE (MTYPE_OSPF_NETWORK, network);
                    742: }
                    743: 
                    744: int
                    745: ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,
                    746:                  struct in_addr area_id)
                    747: {
                    748:   struct ospf_network *network;
                    749:   struct ospf_area *area;
                    750:   struct route_node *rn;
                    751:   struct external_info *ei;
                    752:   int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
                    753: 
                    754:   rn = route_node_get (ospf->networks, (struct prefix *)p);
                    755:   if (rn->info)
                    756:     {
                    757:       /* There is already same network statement. */
                    758:       route_unlock_node (rn);
                    759:       return 0;
                    760:     }
                    761: 
                    762:   rn->info = network = ospf_network_new (area_id, ret);
                    763:   area = ospf_area_get (ospf, area_id, ret);
                    764: 
                    765:   /* Run network config now. */
                    766:   ospf_network_run ((struct prefix *)p, area);
                    767: 
                    768:   /* Update connected redistribute. */
                    769:   if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
                    770:     if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
                    771:       for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
                    772:           rn; rn = route_next (rn))
                    773:        if ((ei = rn->info) != NULL)
                    774:          if (ospf_external_info_find_lsa (ospf, &ei->p))
                    775:            if (!ospf_distribute_check_connected (ospf, ei))
                    776:              ospf_external_lsa_flush (ospf, ei->type, &ei->p,
                    777:                                       ei->ifindex /*, ei->nexthop */);
                    778: 
                    779:   ospf_area_check_free (ospf, area_id);
                    780: 
                    781:   return 1;
                    782: }
                    783: 
                    784: int
                    785: ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
                    786:                    struct in_addr area_id)
                    787: {
                    788:   struct route_node *rn;
                    789:   struct ospf_network *network;
                    790:   struct external_info *ei;
                    791:   struct listnode *node, *nnode;
                    792:   struct ospf_interface *oi;
                    793: 
                    794:   rn = route_node_lookup (ospf->networks, (struct prefix *)p);
                    795:   if (rn == NULL)
                    796:     return 0;
                    797: 
                    798:   network = rn->info;
                    799:   route_unlock_node (rn);
                    800:   if (!IPV4_ADDR_SAME (&area_id, &network->area_id))
                    801:     return 0;
                    802: 
                    803:   ospf_network_free (ospf, rn->info);
                    804:   rn->info = NULL;
                    805:   route_unlock_node (rn);      /* initial reference */
                    806: 
                    807:   /* Find interfaces that not configured already.  */
                    808:   for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
                    809:     {
                    810:       int found = 0;
                    811:       struct connected *co = oi->connected;
                    812:       
                    813:       if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
                    814:         continue;
                    815:       
                    816:       for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
                    817:         {
                    818:           if (rn->info == NULL)
                    819:             continue;
                    820:           
                    821:           if (ospf_network_match_iface(co,&rn->p))
                    822:             {
                    823:               found = 1;
                    824:               route_unlock_node (rn);
                    825:               break;
                    826:             }
                    827:         }
                    828: 
                    829:       if (found == 0)
                    830:         ospf_if_free (oi);
                    831:     }
                    832:   
                    833:   /* Update connected redistribute. */
                    834:   if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
                    835:     if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT))
                    836:       for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT));
                    837:           rn; rn = route_next (rn))
                    838:        if ((ei = rn->info) != NULL)
                    839:          if (!ospf_external_info_find_lsa (ospf, &ei->p))
                    840:            if (ospf_distribute_check_connected (ospf, ei))
                    841:              ospf_external_lsa_originate (ospf, ei);
                    842: 
                    843:   return 1;
                    844: }
                    845: 
                    846: /* Check whether interface matches given network
                    847:  * returns: 1, true. 0, false
                    848:  */
                    849: static int
                    850: ospf_network_match_iface(const struct connected *co, const struct prefix *net)
                    851: {
                    852:   /* new approach: more elegant and conceptually clean */
                    853:   return prefix_match(net, CONNECTED_PREFIX(co));
                    854: }
                    855: 
                    856: static void
                    857: ospf_network_run_interface (struct prefix *p, struct ospf_area *area,
                    858:                             struct interface *ifp)
                    859: {
                    860:   struct listnode *cnode;
                    861:   struct connected *co;
                    862:   
                    863:   if (memcmp (ifp->name, "VLINK", 5) == 0)
                    864:     return;
                    865:   
                    866:   /* if interface prefix is match specified prefix,
                    867:      then create socket and join multicast group. */
                    868:   for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co))
                    869:     {
                    870: 
                    871:       if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY))
                    872:         continue;
                    873: 
                    874:       if (p->family == co->address->family 
                    875:          && ! ospf_if_table_lookup(ifp, co->address)
                    876:           && ospf_network_match_iface(co,p))
                    877:         {
                    878:            struct ospf_interface *oi;
                    879:             
                    880:             oi = ospf_if_new (area->ospf, ifp, co->address);
                    881:             oi->connected = co;
                    882:             
                    883:             oi->area = area;
                    884: 
                    885:             oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
                    886:             oi->output_cost = ospf_if_get_output_cost (oi);
                    887:             
                    888:             /* Add pseudo neighbor. */
                    889:             ospf_nbr_add_self (oi);
                    890: 
                    891:             /* Relate ospf interface to ospf instance. */
                    892:             oi->ospf = area->ospf;
                    893: 
                    894:             /* update network type as interface flag */
                    895:             /* If network type is specified previously,
                    896:                skip network type setting. */
                    897:             oi->type = IF_DEF_PARAMS (ifp)->type;
                    898:             
                    899:             ospf_area_add_if (oi->area, oi);
                    900:             
                    901:             /* if router_id is not configured, dont bring up
                    902:              * interfaces.
                    903:              * ospf_router_id_update() will call ospf_if_update
                    904:              * whenever r-id is configured instead.
                    905:              */
                    906:             if ((area->ospf->router_id.s_addr != 0)
                    907:                 && if_is_operative (ifp)) 
                    908:               ospf_if_up (oi);
                    909:           }
                    910:     }
                    911: }
                    912: 
                    913: static void
                    914: ospf_network_run (struct prefix *p, struct ospf_area *area)
                    915: {
                    916:   struct interface *ifp;
                    917:   struct listnode *node;
                    918: 
                    919:   /* Schedule Router ID Update. */
                    920:   if (area->ospf->router_id.s_addr == 0)
                    921:     ospf_router_id_update (area->ospf);
                    922:   
                    923:   /* Get target interface. */
                    924:   for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
                    925:     ospf_network_run_interface (p, area, ifp);
                    926: }
                    927: 
                    928: void
                    929: ospf_ls_upd_queue_empty (struct ospf_interface *oi)
                    930: {
                    931:   struct route_node *rn;
                    932:   struct listnode *node, *nnode;
                    933:   struct list *lst;
                    934:   struct ospf_lsa *lsa;
                    935: 
                    936:   /* empty ls update queue */
                    937:   for (rn = route_top (oi->ls_upd_queue); rn;
                    938:        rn = route_next (rn))
                    939:     if ((lst = (struct list *) rn->info))
                    940:       {
                    941:        for (ALL_LIST_ELEMENTS (lst, node, nnode, lsa))
                    942:           ospf_lsa_unlock (&lsa); /* oi->ls_upd_queue */
                    943:        list_free (lst);
                    944:        rn->info = NULL;
                    945:       }
                    946:   
                    947:   /* remove update event */
                    948:   if (oi->t_ls_upd_event)
                    949:     {
                    950:       thread_cancel (oi->t_ls_upd_event);
                    951:       oi->t_ls_upd_event = NULL;
                    952:     }
                    953: }
                    954: 
                    955: void
                    956: ospf_if_update (struct ospf *ospf, struct interface *ifp)
                    957: {
                    958:   struct route_node *rn;
                    959:   struct ospf_network *network;
                    960:   struct ospf_area *area;
                    961:   
                    962:   if (!ospf)
                    963:     ospf = ospf_lookup ();
                    964: 
                    965:   /* OSPF must be on and Router-ID must be configured. */
                    966:   if (!ospf || ospf->router_id.s_addr == 0)
                    967:     return;
                    968:   
                    969:   /* Run each netowrk for this interface. */
                    970:   for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
                    971:     if (rn->info != NULL)
                    972:       {
                    973:         network = (struct ospf_network *) rn->info;
                    974:         area = ospf_area_get (ospf, network->area_id, network->format);
                    975:         ospf_network_run_interface (&rn->p, area, ifp);
                    976:       }
                    977: }
                    978: 
                    979: void
                    980: ospf_remove_vls_through_area (struct ospf *ospf, struct ospf_area *area)
                    981: {
                    982:   struct listnode *node, *nnode;
                    983:   struct ospf_vl_data *vl_data;
                    984: 
                    985:   for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
                    986:     if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
                    987:       ospf_vl_delete (ospf, vl_data);
                    988: }
                    989: 
                    990: 
                    991: static const struct message ospf_area_type_msg[] =
                    992: {
                    993:   { OSPF_AREA_DEFAULT, "Default" },
                    994:   { OSPF_AREA_STUB,     "Stub" },
                    995:   { OSPF_AREA_NSSA,     "NSSA" },
                    996: };
                    997: static const int ospf_area_type_msg_max = OSPF_AREA_TYPE_MAX;
                    998: 
                    999: static void
                   1000: ospf_area_type_set (struct ospf_area *area, int type)
                   1001: {
                   1002:   struct listnode *node;
                   1003:   struct ospf_interface *oi;
                   1004: 
                   1005:   if (area->external_routing == type)
                   1006:     {
                   1007:       if (IS_DEBUG_OSPF_EVENT)
                   1008:        zlog_debug ("Area[%s]: Types are the same, ignored.",
                   1009:                   inet_ntoa (area->area_id));
                   1010:       return;
                   1011:     }
                   1012: 
                   1013:   area->external_routing = type;
                   1014: 
                   1015:   if (IS_DEBUG_OSPF_EVENT)
                   1016:     zlog_debug ("Area[%s]: Configured as %s", inet_ntoa (area->area_id),
                   1017:               LOOKUP (ospf_area_type_msg, type));
                   1018: 
                   1019:   switch (area->external_routing)
                   1020:     {
                   1021:     case OSPF_AREA_DEFAULT:
                   1022:       for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
                   1023:         if (oi->nbr_self != NULL)
                   1024:           {
                   1025:            UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
                   1026:            SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
                   1027:           }
                   1028:       break;
                   1029:     case OSPF_AREA_STUB:
                   1030:       for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
                   1031:         if (oi->nbr_self != NULL)
                   1032:           {
                   1033:             if (IS_DEBUG_OSPF_EVENT)
                   1034:               zlog_debug ("setting options on %s accordingly", IF_NAME (oi));
                   1035:             UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
                   1036:             UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
                   1037:             if (IS_DEBUG_OSPF_EVENT)
                   1038:               zlog_debug ("options set on %s: %x",
                   1039:                          IF_NAME (oi), OPTIONS (oi));
                   1040:           }
                   1041:       break;
                   1042:     case OSPF_AREA_NSSA:
                   1043:       for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
                   1044:         if (oi->nbr_self != NULL)
                   1045:           {
                   1046:             zlog_debug ("setting nssa options on %s accordingly", IF_NAME (oi));
                   1047:             UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
                   1048:             SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
                   1049:             zlog_debug ("options set on %s: %x", IF_NAME (oi), OPTIONS (oi));
                   1050:           }
                   1051:       break;
                   1052:     default:
                   1053:       break;
                   1054:     }
                   1055: 
                   1056:   ospf_router_lsa_update_area (area);
                   1057:   ospf_schedule_abr_task (area->ospf);
                   1058: }
                   1059: 
                   1060: int
                   1061: ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode)
                   1062: {
                   1063:   if (area->shortcut_configured == mode)
                   1064:     return 0;
                   1065: 
                   1066:   area->shortcut_configured = mode;
                   1067:   ospf_router_lsa_update_area (area);
                   1068:   ospf_schedule_abr_task (ospf);
                   1069: 
                   1070:   ospf_area_check_free (ospf, area->area_id);
                   1071: 
                   1072:   return 1;
                   1073: }
                   1074: 
                   1075: int
                   1076: ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)
                   1077: {
                   1078:   area->shortcut_configured = OSPF_SHORTCUT_DEFAULT;
                   1079:   ospf_router_lsa_update_area (area);
                   1080:   ospf_area_check_free (ospf, area->area_id);
                   1081:   ospf_schedule_abr_task (ospf);
                   1082: 
                   1083:   return 1;
                   1084: }
                   1085: 
                   1086: static int
                   1087: ospf_area_vlink_count (struct ospf *ospf, struct ospf_area *area)
                   1088: {
                   1089:   struct ospf_vl_data *vl;
                   1090:   struct listnode *node;
                   1091:   int count = 0;
                   1092: 
                   1093:   for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl))
                   1094:     if (IPV4_ADDR_SAME (&vl->vl_area_id, &area->area_id))
                   1095:       count++;
                   1096: 
                   1097:   return count;
                   1098: }
                   1099: 
                   1100: int
                   1101: ospf_area_stub_set (struct ospf *ospf, struct in_addr area_id)
                   1102: {
                   1103:   struct ospf_area *area;
                   1104:   int format = OSPF_AREA_ID_FORMAT_ADDRESS;
                   1105: 
                   1106:   area = ospf_area_get (ospf, area_id, format);
                   1107:   if (ospf_area_vlink_count (ospf, area))
                   1108:     return 0;
                   1109: 
                   1110:   if (area->external_routing != OSPF_AREA_STUB)
                   1111:     ospf_area_type_set (area, OSPF_AREA_STUB);
                   1112: 
                   1113:   return 1;
                   1114: }
                   1115: 
                   1116: int
                   1117: ospf_area_stub_unset (struct ospf *ospf, struct in_addr area_id)
                   1118: {
                   1119:   struct ospf_area *area;
                   1120: 
                   1121:   area = ospf_area_lookup_by_area_id (ospf, area_id);
                   1122:   if (area == NULL)
                   1123:     return 1;
                   1124: 
                   1125:   if (area->external_routing == OSPF_AREA_STUB)
                   1126:     ospf_area_type_set (area, OSPF_AREA_DEFAULT);
                   1127: 
                   1128:   ospf_area_check_free (ospf, area_id);
                   1129: 
                   1130:   return 1;
                   1131: }
                   1132: 
                   1133: int
                   1134: ospf_area_no_summary_set (struct ospf *ospf, struct in_addr area_id)
                   1135: {
                   1136:   struct ospf_area *area;
                   1137:   int format = OSPF_AREA_ID_FORMAT_ADDRESS;
                   1138: 
                   1139:   area = ospf_area_get (ospf, area_id, format);
                   1140:   area->no_summary = 1;
                   1141: 
                   1142:   return 1;
                   1143: }
                   1144: 
                   1145: int
                   1146: ospf_area_no_summary_unset (struct ospf *ospf, struct in_addr area_id)
                   1147: {
                   1148:   struct ospf_area *area;
                   1149: 
                   1150:   area = ospf_area_lookup_by_area_id (ospf, area_id);
                   1151:   if (area == NULL)
                   1152:     return 0;
                   1153: 
                   1154:   area->no_summary = 0;
                   1155:   ospf_area_check_free (ospf, area_id);
                   1156: 
                   1157:   return 1;
                   1158: }
                   1159: 
                   1160: int
                   1161: ospf_area_nssa_set (struct ospf *ospf, struct in_addr area_id)
                   1162: {
                   1163:   struct ospf_area *area;
                   1164:   int format = OSPF_AREA_ID_FORMAT_ADDRESS;
                   1165: 
                   1166:   area = ospf_area_get (ospf, area_id, format);
                   1167:   if (ospf_area_vlink_count (ospf, area))
                   1168:     return 0;
                   1169: 
                   1170:   if (area->external_routing != OSPF_AREA_NSSA)
                   1171:     {
                   1172:       ospf_area_type_set (area, OSPF_AREA_NSSA);
                   1173:       ospf->anyNSSA++;
                   1174:     }
                   1175: 
                   1176:   /* set NSSA area defaults */
                   1177:   area->no_summary = 0;
                   1178:   area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
                   1179:   area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
                   1180:   area->NSSATranslatorStabilityInterval = OSPF_NSSA_TRANS_STABLE_DEFAULT;
                   1181: 
                   1182:   return 1;
                   1183: }
                   1184: 
                   1185: int
                   1186: ospf_area_nssa_unset (struct ospf *ospf, struct in_addr area_id)
                   1187: {
                   1188:   struct ospf_area *area;
                   1189: 
                   1190:   area = ospf_area_lookup_by_area_id (ospf, area_id);
                   1191:   if (area == NULL)
                   1192:     return 0;
                   1193: 
                   1194:   if (area->external_routing == OSPF_AREA_NSSA)
                   1195:     {
                   1196:       ospf->anyNSSA--;
                   1197:       ospf_area_type_set (area, OSPF_AREA_DEFAULT);
                   1198:     }
                   1199: 
                   1200:   ospf_area_check_free (ospf, area_id);
                   1201: 
                   1202:   return 1;
                   1203: }
                   1204: 
                   1205: int
                   1206: ospf_area_nssa_translator_role_set (struct ospf *ospf, struct in_addr area_id,
                   1207:                                    int role)
                   1208: {
                   1209:   struct ospf_area *area;
                   1210: 
                   1211:   area = ospf_area_lookup_by_area_id (ospf, area_id);
                   1212:   if (area == NULL)
                   1213:     return 0;
                   1214: 
                   1215:   area->NSSATranslatorRole = role;
                   1216: 
                   1217:   return 1;
                   1218: }
                   1219: 
1.1.1.2   misho    1220: #if 0
1.1       misho    1221: /* XXX: unused? Leave for symmetry? */
                   1222: static int
                   1223: ospf_area_nssa_translator_role_unset (struct ospf *ospf,
                   1224:                                      struct in_addr area_id)
                   1225: {
                   1226:   struct ospf_area *area;
                   1227: 
                   1228:   area = ospf_area_lookup_by_area_id (ospf, area_id);
                   1229:   if (area == NULL)
                   1230:     return 0;
                   1231: 
                   1232:   area->NSSATranslatorRole = OSPF_NSSA_ROLE_CANDIDATE;
                   1233: 
                   1234:   ospf_area_check_free (ospf, area_id);
                   1235: 
                   1236:   return 1;
                   1237: }
1.1.1.2   misho    1238: #endif
1.1       misho    1239: 
                   1240: int
                   1241: ospf_area_export_list_set (struct ospf *ospf,
                   1242:                           struct ospf_area *area, const char *list_name)
                   1243: {
                   1244:   struct access_list *list;
                   1245:   list = access_list_lookup (AFI_IP, list_name);
                   1246: 
                   1247:   EXPORT_LIST (area) = list;
                   1248: 
                   1249:   if (EXPORT_NAME (area))
                   1250:     free (EXPORT_NAME (area));
                   1251: 
                   1252:   EXPORT_NAME (area) = strdup (list_name);
                   1253:   ospf_schedule_abr_task (ospf);
                   1254: 
                   1255:   return 1;
                   1256: }
                   1257: 
                   1258: int
                   1259: ospf_area_export_list_unset (struct ospf *ospf, struct ospf_area * area)
                   1260: {
                   1261: 
                   1262:   EXPORT_LIST (area) = 0;
                   1263: 
                   1264:   if (EXPORT_NAME (area))
                   1265:     free (EXPORT_NAME (area));
                   1266: 
                   1267:   EXPORT_NAME (area) = NULL;
                   1268: 
                   1269:   ospf_area_check_free (ospf, area->area_id);
                   1270:   
                   1271:   ospf_schedule_abr_task (ospf);
                   1272: 
                   1273:   return 1;
                   1274: }
                   1275: 
                   1276: int
                   1277: ospf_area_import_list_set (struct ospf *ospf, struct ospf_area *area, 
                   1278:                            const char *name)
                   1279: {
                   1280:   struct access_list *list;
                   1281:   list = access_list_lookup (AFI_IP, name);
                   1282: 
                   1283:   IMPORT_LIST (area) = list;
                   1284: 
                   1285:   if (IMPORT_NAME (area))
                   1286:     free (IMPORT_NAME (area));
                   1287: 
                   1288:   IMPORT_NAME (area) = strdup (name);
                   1289:   ospf_schedule_abr_task (ospf);
                   1290: 
                   1291:   return 1;
                   1292: }
                   1293: 
                   1294: int
                   1295: ospf_area_import_list_unset (struct ospf *ospf, struct ospf_area * area)
                   1296: {
                   1297:   IMPORT_LIST (area) = 0;
                   1298: 
                   1299:   if (IMPORT_NAME (area))
                   1300:     free (IMPORT_NAME (area));
                   1301: 
                   1302:   IMPORT_NAME (area) = NULL;
                   1303:   ospf_area_check_free (ospf, area->area_id);
                   1304: 
                   1305:   ospf_schedule_abr_task (ospf);
                   1306: 
                   1307:   return 1;
                   1308: }
                   1309: 
                   1310: int
                   1311: ospf_timers_refresh_set (struct ospf *ospf, int interval)
                   1312: {
                   1313:   int time_left;
                   1314: 
                   1315:   if (ospf->lsa_refresh_interval == interval)
                   1316:     return 1;
                   1317: 
                   1318:   time_left = ospf->lsa_refresh_interval -
                   1319:     (quagga_time (NULL) - ospf->lsa_refresher_started);
                   1320:   
                   1321:   if (time_left > interval)
                   1322:     {
                   1323:       OSPF_TIMER_OFF (ospf->t_lsa_refresher);
                   1324:       ospf->t_lsa_refresher =
                   1325:        thread_add_timer (master, ospf_lsa_refresh_walker, ospf, interval);
                   1326:     }
                   1327:   ospf->lsa_refresh_interval = interval;
                   1328: 
                   1329:   return 1;
                   1330: }
                   1331: 
                   1332: int
                   1333: ospf_timers_refresh_unset (struct ospf *ospf)
                   1334: {
                   1335:   int time_left;
                   1336: 
                   1337:   time_left = ospf->lsa_refresh_interval -
                   1338:     (quagga_time (NULL) - ospf->lsa_refresher_started);
                   1339: 
                   1340:   if (time_left > OSPF_LSA_REFRESH_INTERVAL_DEFAULT)
                   1341:     {
                   1342:       OSPF_TIMER_OFF (ospf->t_lsa_refresher);
                   1343:       ospf->t_lsa_refresher =
                   1344:        thread_add_timer (master, ospf_lsa_refresh_walker, ospf,
                   1345:                          OSPF_LSA_REFRESH_INTERVAL_DEFAULT);
                   1346:     }
                   1347: 
                   1348:   ospf->lsa_refresh_interval = OSPF_LSA_REFRESH_INTERVAL_DEFAULT;
                   1349: 
                   1350:   return 1;
                   1351: }
                   1352: 
                   1353: 
                   1354: static struct ospf_nbr_nbma *
                   1355: ospf_nbr_nbma_new (void)
                   1356: {
                   1357:   struct ospf_nbr_nbma *nbr_nbma;
                   1358: 
                   1359:   nbr_nbma = XCALLOC (MTYPE_OSPF_NEIGHBOR_STATIC,
                   1360:                      sizeof (struct ospf_nbr_nbma));
                   1361: 
                   1362:   nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
                   1363:   nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
                   1364: 
                   1365:   return nbr_nbma;
                   1366: }
                   1367: 
                   1368: static void
                   1369: ospf_nbr_nbma_free (struct ospf_nbr_nbma *nbr_nbma)
                   1370: {
                   1371:   XFREE (MTYPE_OSPF_NEIGHBOR_STATIC, nbr_nbma);
                   1372: }
                   1373: 
                   1374: static void
                   1375: ospf_nbr_nbma_delete (struct ospf *ospf, struct ospf_nbr_nbma *nbr_nbma)
                   1376: {
                   1377:   struct route_node *rn;
                   1378:   struct prefix_ipv4 p;
                   1379: 
                   1380:   p.family = AF_INET;
                   1381:   p.prefix = nbr_nbma->addr;
                   1382:   p.prefixlen = IPV4_MAX_BITLEN;
                   1383: 
                   1384:   rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
                   1385:   if (rn)
                   1386:     {
                   1387:       ospf_nbr_nbma_free (rn->info);
                   1388:       rn->info = NULL;
                   1389:       route_unlock_node (rn);
                   1390:       route_unlock_node (rn);
                   1391:     }
                   1392: }
                   1393: 
                   1394: static void
                   1395: ospf_nbr_nbma_down (struct ospf_nbr_nbma *nbr_nbma)
                   1396: {
                   1397:   OSPF_TIMER_OFF (nbr_nbma->t_poll);
                   1398: 
                   1399:   if (nbr_nbma->nbr)
                   1400:     {
                   1401:       nbr_nbma->nbr->nbr_nbma = NULL;
                   1402:       OSPF_NSM_EVENT_EXECUTE (nbr_nbma->nbr, NSM_KillNbr);
                   1403:     }
                   1404: 
                   1405:   if (nbr_nbma->oi)
                   1406:     listnode_delete (nbr_nbma->oi->nbr_nbma, nbr_nbma);
                   1407: }
                   1408: 
                   1409: static void
                   1410: ospf_nbr_nbma_add (struct ospf_nbr_nbma *nbr_nbma,
                   1411:                   struct ospf_interface *oi)
                   1412: {
                   1413:   struct ospf_neighbor *nbr;
                   1414:   struct route_node *rn;
                   1415:   struct prefix p;
                   1416: 
                   1417:   if (oi->type != OSPF_IFTYPE_NBMA)
                   1418:     return;
                   1419: 
                   1420:   if (nbr_nbma->nbr != NULL)
                   1421:     return;
                   1422: 
                   1423:   if (IPV4_ADDR_SAME (&oi->nbr_self->address.u.prefix4, &nbr_nbma->addr))
                   1424:     return;
                   1425:       
                   1426:   nbr_nbma->oi = oi;
                   1427:   listnode_add (oi->nbr_nbma, nbr_nbma);
                   1428: 
                   1429:   /* Get neighbor information from table. */
                   1430:   p.family = AF_INET;
                   1431:   p.prefixlen = IPV4_MAX_BITLEN;
                   1432:   p.u.prefix4 = nbr_nbma->addr;
                   1433: 
                   1434:   rn = route_node_get (oi->nbrs, (struct prefix *)&p);
                   1435:   if (rn->info)
                   1436:     {
                   1437:       nbr = rn->info;
                   1438:       nbr->nbr_nbma = nbr_nbma;
                   1439:       nbr_nbma->nbr = nbr;
                   1440: 
                   1441:       route_unlock_node (rn);
                   1442:     }
                   1443:   else
                   1444:     {
                   1445:       nbr = rn->info = ospf_nbr_new (oi);
                   1446:       nbr->state = NSM_Down;
                   1447:       nbr->src = nbr_nbma->addr;
                   1448:       nbr->nbr_nbma = nbr_nbma;
                   1449:       nbr->priority = nbr_nbma->priority;
                   1450:       nbr->address = p;
                   1451: 
                   1452:       nbr_nbma->nbr = nbr;
                   1453: 
                   1454:       OSPF_NSM_EVENT_EXECUTE (nbr, NSM_Start);
                   1455:     }
                   1456: }
                   1457: 
                   1458: void
                   1459: ospf_nbr_nbma_if_update (struct ospf *ospf, struct ospf_interface *oi)
                   1460: {
                   1461:   struct ospf_nbr_nbma *nbr_nbma;
                   1462:   struct route_node *rn;
                   1463:   struct prefix_ipv4 p;
                   1464: 
                   1465:   if (oi->type != OSPF_IFTYPE_NBMA)
                   1466:     return;
                   1467: 
                   1468:   for (rn = route_top (ospf->nbr_nbma); rn; rn = route_next (rn))
                   1469:     if ((nbr_nbma = rn->info))
                   1470:       if (nbr_nbma->oi == NULL && nbr_nbma->nbr == NULL)
                   1471:        {
                   1472:          p.family = AF_INET;
                   1473:          p.prefix = nbr_nbma->addr;
                   1474:          p.prefixlen = IPV4_MAX_BITLEN;
                   1475: 
                   1476:          if (prefix_match (oi->address, (struct prefix *)&p))
                   1477:            ospf_nbr_nbma_add (nbr_nbma, oi);
                   1478:        }
                   1479: }
                   1480: 
                   1481: struct ospf_nbr_nbma *
                   1482: ospf_nbr_nbma_lookup (struct ospf *ospf, struct in_addr nbr_addr)
                   1483: {
                   1484:   struct route_node *rn;
                   1485:   struct prefix_ipv4 p;
                   1486: 
                   1487:   p.family = AF_INET;
                   1488:   p.prefix = nbr_addr;
                   1489:   p.prefixlen = IPV4_MAX_BITLEN;
                   1490: 
                   1491:   rn = route_node_lookup (ospf->nbr_nbma, (struct prefix *)&p);
                   1492:   if (rn)
                   1493:     {
                   1494:       route_unlock_node (rn);
                   1495:       return rn->info;
                   1496:     }
                   1497:   return NULL;
                   1498: }
                   1499: 
                   1500: struct ospf_nbr_nbma *
                   1501: ospf_nbr_nbma_lookup_next (struct ospf *ospf, struct in_addr *addr, int first)
                   1502: {
                   1503: #if 0
                   1504:   struct ospf_nbr_nbma *nbr_nbma;
                   1505:   struct listnode *node;
                   1506: #endif
                   1507: 
                   1508:   if (ospf == NULL)
                   1509:     return NULL;
                   1510: 
                   1511: #if 0
                   1512:   for (ALL_LIST_ELEMENTS_RO (ospf->nbr_nbma, node, nbr_nbma))
                   1513:     {
                   1514:       if (first)
                   1515:        {
                   1516:          *addr = nbr_nbma->addr;
                   1517:          return nbr_nbma;
                   1518:        }
                   1519:       else if (ntohl (nbr_nbma->addr.s_addr) > ntohl (addr->s_addr))
                   1520:        {
                   1521:          *addr = nbr_nbma->addr;
                   1522:          return nbr_nbma;
                   1523:        }
                   1524:     }
                   1525: #endif
                   1526:   return NULL;
                   1527: }
                   1528: 
                   1529: int
                   1530: ospf_nbr_nbma_set (struct ospf *ospf, struct in_addr nbr_addr)
                   1531: {
                   1532:   struct ospf_nbr_nbma *nbr_nbma;
                   1533:   struct ospf_interface *oi;
                   1534:   struct prefix_ipv4 p;
                   1535:   struct route_node *rn;
                   1536:   struct listnode *node;
                   1537: 
                   1538:   nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
                   1539:   if (nbr_nbma)
                   1540:     return 0;
                   1541: 
                   1542:   nbr_nbma = ospf_nbr_nbma_new ();
                   1543:   nbr_nbma->addr = nbr_addr;
                   1544: 
                   1545:   p.family = AF_INET;
                   1546:   p.prefix = nbr_addr;
                   1547:   p.prefixlen = IPV4_MAX_BITLEN;
                   1548: 
                   1549:   rn = route_node_get (ospf->nbr_nbma, (struct prefix *)&p);
                   1550:   rn->info = nbr_nbma;
                   1551: 
                   1552:   for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
                   1553:     {
                   1554:       if (oi->type == OSPF_IFTYPE_NBMA)
                   1555:        if (prefix_match (oi->address, (struct prefix *)&p))
                   1556:          {
                   1557:            ospf_nbr_nbma_add (nbr_nbma, oi);
                   1558:            break;
                   1559:          }
                   1560:     }
                   1561: 
                   1562:   return 1;
                   1563: }
                   1564: 
                   1565: int
                   1566: ospf_nbr_nbma_unset (struct ospf *ospf, struct in_addr nbr_addr)
                   1567: {
                   1568:   struct ospf_nbr_nbma *nbr_nbma;
                   1569: 
                   1570:   nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
                   1571:   if (nbr_nbma == NULL)
                   1572:     return 0;
                   1573: 
                   1574:   ospf_nbr_nbma_down (nbr_nbma);
                   1575:   ospf_nbr_nbma_delete (ospf, nbr_nbma);
                   1576: 
                   1577:   return 1;
                   1578: }
                   1579: 
                   1580: int
                   1581: ospf_nbr_nbma_priority_set (struct ospf *ospf, struct in_addr nbr_addr,
                   1582:                            u_char priority)
                   1583: {
                   1584:   struct ospf_nbr_nbma *nbr_nbma;
                   1585: 
                   1586:   nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
                   1587:   if (nbr_nbma == NULL)
                   1588:     return 0;
                   1589: 
                   1590:   if (nbr_nbma->priority != priority)
                   1591:     nbr_nbma->priority = priority;
                   1592: 
                   1593:   return 1;
                   1594: }
                   1595: 
                   1596: int
                   1597: ospf_nbr_nbma_priority_unset (struct ospf *ospf, struct in_addr nbr_addr)
                   1598: {
                   1599:   struct ospf_nbr_nbma *nbr_nbma;
                   1600: 
                   1601:   nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
                   1602:   if (nbr_nbma == NULL)
                   1603:     return 0;
                   1604: 
                   1605:   if (nbr_nbma != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
                   1606:     nbr_nbma->priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT;
                   1607: 
                   1608:   return 1;
                   1609: }
                   1610: 
                   1611: int
                   1612: ospf_nbr_nbma_poll_interval_set (struct ospf *ospf, struct in_addr nbr_addr,
                   1613:                                 unsigned int interval)
                   1614: {
                   1615:   struct ospf_nbr_nbma *nbr_nbma;
                   1616: 
                   1617:   nbr_nbma = ospf_nbr_nbma_lookup (ospf, nbr_addr);
                   1618:   if (nbr_nbma == NULL)
                   1619:     return 0;
                   1620: 
                   1621:   if (nbr_nbma->v_poll != interval)
                   1622:     {
                   1623:       nbr_nbma->v_poll = interval;
                   1624:       if (nbr_nbma->oi && ospf_if_is_up (nbr_nbma->oi))
                   1625:        {
                   1626:          OSPF_TIMER_OFF (nbr_nbma->t_poll);
                   1627:          OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
                   1628:                              nbr_nbma->v_poll);
                   1629:        }
                   1630:     }
                   1631: 
                   1632:   return 1;
                   1633: }
                   1634: 
                   1635: int
                   1636: ospf_nbr_nbma_poll_interval_unset (struct ospf *ospf, struct in_addr addr)
                   1637: {
                   1638:   struct ospf_nbr_nbma *nbr_nbma;
                   1639: 
                   1640:   nbr_nbma = ospf_nbr_nbma_lookup (ospf, addr);
                   1641:   if (nbr_nbma == NULL)
                   1642:     return 0;
                   1643: 
                   1644:   if (nbr_nbma->v_poll != OSPF_POLL_INTERVAL_DEFAULT)
                   1645:     nbr_nbma->v_poll = OSPF_POLL_INTERVAL_DEFAULT;
                   1646: 
                   1647:   return 1;
                   1648: }
                   1649: 
                   1650: void
                   1651: ospf_master_init ()
                   1652: {
                   1653:   memset (&ospf_master, 0, sizeof (struct ospf_master));
                   1654: 
                   1655:   om = &ospf_master;
                   1656:   om->ospf = list_new ();
                   1657:   om->master = thread_master_create ();
                   1658:   om->start_time = quagga_time (NULL);
                   1659: }

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