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

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

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