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

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

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