File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospfd / ospfd.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jul 21 23:54:40 2013 UTC (10 years, 11 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_22p0, v0_99_22, HEAD
0.99.22

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

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