File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospfd / ospfd.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:12 2016 UTC (7 years, 8 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

    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 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 *);
   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
   81: 
   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))
  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: 	}
  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: }
  150: 
  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;
  193:   new->stub_router_admin_set     = OSPF_STUB_ROUTER_ADMINISTRATIVE_UNSET;
  194: 
  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: 
  204:   /* LSA timers */
  205:   new->min_ls_interval = OSPF_MIN_LS_INTERVAL;
  206:   new->min_ls_arrival = OSPF_MIN_LS_ARRIVAL;
  207: 
  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. */
  215:   new->maxage_delay = OSPF_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;
  216:   new->maxage_lsa = route_table_init();
  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))
  238:     zlog_debug ("%s: starting with OSPF send buffer size %u",
  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: 
  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: 
  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: }
  302: 
  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: }
  377: 
  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: 
  519:   for (rn = route_top (ospf->maxage_lsa); rn; rn = route_next (rn))
  520:     {
  521:       struct ospf_lsa *lsa;
  522: 
  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);
  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: 
  580: 
  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);  
  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:         }
  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: 
  730: 
  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: 
  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: 
  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. */
  840:   update_redistributed(ospf, 1);
  841:   
  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:       
  875:       ospf_network_run_subnet (ospf, oi->connected, NULL, NULL);
  876:     }
  877:   
  878:   /* Update connected redistribute. */
  879:   update_redistributed(ospf, 0);
  880:   
  881:   ospf_area_check_free (ospf, area_id);
  882:   
  883:   return 1;
  884: }
  885: 
  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: 
  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
  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)
 1038: {
 1039:   struct listnode *cnode;
 1040:   struct connected *co;
 1041:   
 1042:   if (memcmp (ifp->name, "VLINK", 5) == 0)
 1043:     return;
 1044:   
 1045:   /* Network prefix without area is nonsensical */
 1046:   if (p)
 1047:     assert (given_area != NULL);
 1048:   
 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))
 1052:     ospf_network_run_subnet (ospf, co, p, given_area);  
 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))
 1067:     ospf_network_run_interface (area->ospf, ifp, p, area);
 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: 
 1103:   /* OSPF must be ready. */
 1104:   if (!ospf_is_ready (ospf))
 1105:     return;
 1106:   
 1107:   ospf_network_run_interface (ospf, ifp, NULL, NULL);
 1108:   
 1109:   /* Update connected redistribute. */
 1110:   update_redistributed(ospf, 1);
 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: 
 1124: 
 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: 
 1354: #if 0
 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: }
 1372: #endif
 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: 
 1487: 
 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);
 1684:   if (rn->info)
 1685:     route_unlock_node (rn);
 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>