File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ospfd / ospf_interface.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:26:12 2012 UTC (12 years, 4 months ago) by misho
Branches: quagga, MAIN
CVS tags: v0_99_21, v0_99_20_1, v0_99_20, HEAD
quagga

    1: /*
    2:  * OSPF Interface functions.
    3:  * Copyright (C) 1999, 2000 Toshiaki Takada
    4:  *
    5:  * This file is part of GNU Zebra.
    6:  * 
    7:  * GNU Zebra is free software; you can redistribute it and/or modify
    8:  * it under the terms of the GNU General Public License as published
    9:  * by the Free Software Foundation; either version 2, or (at your
   10:  * option) any later version.
   11:  *
   12:  * GNU Zebra is distributed in the hope that it will be useful, but
   13:  * WITHOUT ANY WARRANTY; without even the implied warranty of
   14:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   15:  * General Public License for more details.
   16:  *
   17:  * You should have received a copy of the GNU General Public License
   18:  * along with GNU Zebra; see the file COPYING.  If not, write to the
   19:  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   20:  * Boston, MA 02111-1307, USA.
   21:  */
   22: 
   23: #include <zebra.h>
   24: 
   25: #include "thread.h"
   26: #include "linklist.h"
   27: #include "prefix.h"
   28: #include "if.h"
   29: #include "table.h"
   30: #include "memory.h"
   31: #include "command.h"
   32: #include "stream.h"
   33: #include "log.h"
   34: 
   35: #include "ospfd/ospfd.h"
   36: #include "ospfd/ospf_spf.h"
   37: #include "ospfd/ospf_interface.h"
   38: #include "ospfd/ospf_ism.h"
   39: #include "ospfd/ospf_asbr.h"
   40: #include "ospfd/ospf_lsa.h"
   41: #include "ospfd/ospf_lsdb.h"
   42: #include "ospfd/ospf_neighbor.h"
   43: #include "ospfd/ospf_nsm.h"
   44: #include "ospfd/ospf_packet.h"
   45: #include "ospfd/ospf_abr.h"
   46: #include "ospfd/ospf_network.h"
   47: #include "ospfd/ospf_dump.h"
   48: #ifdef HAVE_SNMP
   49: #include "ospfd/ospf_snmp.h"
   50: #endif /* HAVE_SNMP */
   51: 
   52: 
   53: int
   54: ospf_if_get_output_cost (struct ospf_interface *oi)
   55: {
   56:   /* If all else fails, use default OSPF cost */
   57:   u_int32_t cost;
   58:   u_int32_t bw, refbw;
   59: 
   60:   bw = oi->ifp->bandwidth ? oi->ifp->bandwidth : OSPF_DEFAULT_BANDWIDTH;
   61:   refbw = oi->ospf->ref_bandwidth;
   62: 
   63:   /* A specifed ip ospf cost overrides a calculated one. */
   64:   if (OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (oi->ifp), output_cost_cmd) ||
   65:       OSPF_IF_PARAM_CONFIGURED (oi->params, output_cost_cmd))
   66:     cost = OSPF_IF_PARAM (oi, output_cost_cmd);
   67:   /* See if a cost can be calculated from the zebra processes
   68:      interface bandwidth field. */
   69:   else
   70:     {
   71:       cost = (u_int32_t) ((double)refbw / (double)bw + (double)0.5);
   72:       if (cost < 1)
   73: 	cost = 1;
   74:       else if (cost > 65535)
   75: 	cost = 65535;
   76:     }
   77: 
   78:   return cost;
   79: }
   80: 
   81: void
   82: ospf_if_recalculate_output_cost (struct interface *ifp)
   83: {
   84:   u_int32_t newcost;
   85:   struct route_node *rn;
   86:   
   87:   for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
   88:     {
   89:       struct ospf_interface *oi;
   90:       
   91:       if ( (oi = rn->info) == NULL)
   92: 	continue;
   93: 
   94:       newcost = ospf_if_get_output_cost (oi);
   95: 
   96:       /* Is actual output cost changed? */
   97:       if (oi->output_cost != newcost)
   98: 	{
   99: 	  oi->output_cost = newcost;
  100: 	  ospf_router_lsa_update_area (oi->area);
  101: 	}
  102:     }
  103: }
  104: 
  105: /* Simulate down/up on the interface.  This is needed, for example, when 
  106:    the MTU changes. */
  107: void
  108: ospf_if_reset(struct interface *ifp)
  109: {
  110:   struct route_node *rn;
  111:   
  112:   for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
  113:     {
  114:       struct ospf_interface *oi;
  115:       
  116:       if ( (oi = rn->info) == NULL)
  117: 	continue;
  118: 
  119:       ospf_if_down(oi);
  120:       ospf_if_up(oi);
  121:     }
  122: }
  123: 
  124: void
  125: ospf_if_reset_variables (struct ospf_interface *oi)
  126: {
  127:   /* Set default values. */
  128:   /* don't clear this flag.  oi->flag = OSPF_IF_DISABLE; */
  129: 
  130:   if (oi->vl_data)
  131:     oi->type = OSPF_IFTYPE_VIRTUALLINK;
  132:   else 
  133:   /* preserve network-type */
  134:   if (oi->type != OSPF_IFTYPE_NBMA)
  135:     oi->type = OSPF_IFTYPE_BROADCAST;
  136: 
  137:   oi->state = ISM_Down;
  138: 
  139:   oi->crypt_seqnum = 0;
  140: 
  141:   /* This must be short, (less than RxmtInterval) 
  142:      - RFC 2328 Section 13.5 para 3.  Set to 1 second to avoid Acks being
  143:        held back for too long - MAG */
  144:   oi->v_ls_ack = 1;  
  145: }
  146: 
  147: /* lookup oi for specified prefix/ifp */
  148: struct ospf_interface *
  149: ospf_if_table_lookup (struct interface *ifp, struct prefix *prefix)
  150: {
  151:   struct prefix p;
  152:   struct route_node *rn;
  153:   struct ospf_interface *rninfo = NULL;
  154:   
  155:   p = *prefix;
  156:   p.prefixlen = IPV4_MAX_PREFIXLEN;
  157:   
  158:   /* route_node_get implicitely locks */
  159:   if ((rn = route_node_lookup (IF_OIFS (ifp), &p)))
  160:     {
  161:       rninfo = (struct ospf_interface *) rn->info;
  162:       route_unlock_node (rn);
  163:     }
  164:   
  165:   return rninfo;
  166: }
  167: 
  168: static void
  169: ospf_add_to_if (struct interface *ifp, struct ospf_interface *oi)
  170: {
  171:   struct route_node *rn;
  172:   struct prefix p;
  173: 
  174:   p = *oi->address;
  175:   p.prefixlen = IPV4_MAX_PREFIXLEN;
  176: 
  177:   rn = route_node_get (IF_OIFS (ifp), &p);
  178:   /* rn->info should either be NULL or equal to this oi
  179:    * as route_node_get may return an existing node
  180:    */
  181:   assert (!rn->info || rn->info == oi);
  182:   rn->info = oi;
  183: }
  184: 
  185: static void
  186: ospf_delete_from_if (struct interface *ifp, struct ospf_interface *oi)
  187: {
  188:   struct route_node *rn;
  189:   struct prefix p;
  190: 
  191:   p = *oi->address;
  192:   p.prefixlen = IPV4_MAX_PREFIXLEN;
  193: 
  194:   rn = route_node_lookup (IF_OIFS (oi->ifp), &p);
  195:   assert (rn);
  196:   assert (rn->info);
  197:   rn->info = NULL;
  198:   route_unlock_node (rn);
  199:   route_unlock_node (rn);
  200: }
  201: 
  202: struct ospf_interface *
  203: ospf_if_new (struct ospf *ospf, struct interface *ifp, struct prefix *p)
  204: {
  205:   struct ospf_interface *oi;
  206: 
  207:   if ((oi = ospf_if_table_lookup (ifp, p)) == NULL)
  208:     {
  209:       oi = XCALLOC (MTYPE_OSPF_IF, sizeof (struct ospf_interface));
  210:       memset (oi, 0, sizeof (struct ospf_interface));
  211:     }
  212:   else
  213:     return oi;
  214:     
  215:   /* Set zebra interface pointer. */
  216:   oi->ifp = ifp;
  217:   oi->address = p;
  218:   
  219:   ospf_add_to_if (ifp, oi);
  220:   listnode_add (ospf->oiflist, oi);
  221:   
  222:   /* Initialize neighbor list. */
  223:   oi->nbrs = route_table_init ();
  224: 
  225:   /* Initialize static neighbor list. */
  226:   oi->nbr_nbma = list_new ();
  227: 
  228:   /* Initialize Link State Acknowledgment list. */
  229:   oi->ls_ack = list_new ();
  230:   oi->ls_ack_direct.ls_ack = list_new ();
  231: 
  232:   /* Set default values. */
  233:   ospf_if_reset_variables (oi);
  234: 
  235:   /* Add pseudo neighbor. */
  236:   oi->nbr_self = ospf_nbr_new (oi);
  237: 
  238:   oi->ls_upd_queue = route_table_init ();
  239:   oi->t_ls_upd_event = NULL;
  240:   oi->t_ls_ack_direct = NULL;
  241: 
  242:   oi->crypt_seqnum = time (NULL);
  243: 
  244: #ifdef HAVE_OPAQUE_LSA
  245:   ospf_opaque_type9_lsa_init (oi);
  246: #endif /* HAVE_OPAQUE_LSA */
  247: 
  248:   oi->ospf = ospf;
  249:   
  250:   return oi;
  251: }
  252: 
  253: /* Restore an interface to its pre UP state
  254:    Used from ism_interface_down only */
  255: void
  256: ospf_if_cleanup (struct ospf_interface *oi)
  257: {
  258:   struct route_node *rn;
  259:   struct listnode *node, *nnode;
  260:   struct ospf_neighbor *nbr;
  261:   struct ospf_nbr_nbma *nbr_nbma;
  262:   struct ospf_lsa *lsa;
  263: 
  264:   /* oi->nbrs and oi->nbr_nbma should be deleted on InterfaceDown event */
  265:   /* delete all static neighbors attached to this interface */
  266:   for (ALL_LIST_ELEMENTS (oi->nbr_nbma, node, nnode, nbr_nbma))
  267:     {
  268:       OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
  269: 
  270:       if (nbr_nbma->nbr)
  271: 	{
  272: 	  nbr_nbma->nbr->nbr_nbma = NULL;
  273: 	  nbr_nbma->nbr = NULL;
  274: 	}
  275: 
  276:       nbr_nbma->oi = NULL;
  277:       
  278:       listnode_delete (oi->nbr_nbma, nbr_nbma);
  279:     }
  280: 
  281:   /* send Neighbor event KillNbr to all associated neighbors. */
  282:   for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
  283:     if ((nbr = rn->info) != NULL)
  284:       if (nbr != oi->nbr_self)
  285: 	OSPF_NSM_EVENT_EXECUTE (nbr, NSM_KillNbr);
  286: 
  287:   /* Cleanup Link State Acknowlegdment list. */
  288:   for (ALL_LIST_ELEMENTS (oi->ls_ack, node, nnode, lsa))
  289:     ospf_lsa_unlock (&lsa); /* oi->ls_ack */
  290:   list_delete_all_node (oi->ls_ack);
  291: 
  292:   oi->crypt_seqnum = 0;
  293:   
  294:   /* Empty link state update queue */
  295:   ospf_ls_upd_queue_empty (oi);
  296:   
  297:   /* Reset pseudo neighbor. */
  298:   ospf_nbr_delete (oi->nbr_self);
  299:   oi->nbr_self = ospf_nbr_new (oi);
  300:   ospf_nbr_add_self (oi);
  301: }
  302: 
  303: void
  304: ospf_if_free (struct ospf_interface *oi)
  305: {
  306:   ospf_if_down (oi);
  307: 
  308:   assert (oi->state == ISM_Down);
  309: 
  310: #ifdef HAVE_OPAQUE_LSA
  311:   ospf_opaque_type9_lsa_term (oi);
  312: #endif /* HAVE_OPAQUE_LSA */
  313: 
  314:   /* Free Pseudo Neighbour */
  315:   ospf_nbr_delete (oi->nbr_self);
  316:   
  317:   route_table_finish (oi->nbrs);
  318:   route_table_finish (oi->ls_upd_queue);
  319:   
  320:   /* Free any lists that should be freed */
  321:   list_free (oi->nbr_nbma);
  322:   
  323:   list_free (oi->ls_ack);
  324:   list_free (oi->ls_ack_direct.ls_ack);
  325:   
  326:   ospf_delete_from_if (oi->ifp, oi);
  327: 
  328:   listnode_delete (oi->ospf->oiflist, oi);
  329:   listnode_delete (oi->area->oiflist, oi);
  330: 
  331:   thread_cancel_event (master, oi);
  332: 
  333:   memset (oi, 0, sizeof (*oi));
  334:   XFREE (MTYPE_OSPF_IF, oi);
  335: }
  336: 
  337: 
  338: /*
  339: *  check if interface with given address is configured and
  340: *  return it if yes.  special treatment for PtP networks.
  341: */
  342: struct ospf_interface *
  343: ospf_if_is_configured (struct ospf *ospf, struct in_addr *address)
  344: {
  345:   struct listnode *node, *nnode;
  346:   struct ospf_interface *oi;
  347:   struct prefix_ipv4 addr;
  348: 
  349:   addr.family = AF_INET;
  350:   addr.prefix = *address;
  351:   addr.prefixlen = IPV4_MAX_PREFIXLEN;
  352: 
  353:   for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
  354:     if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
  355:       {
  356:         if (oi->type == OSPF_IFTYPE_POINTOPOINT)
  357: 	  {
  358: 	    /* special leniency: match if addr is anywhere on peer subnet */
  359: 	    if (prefix_match(CONNECTED_PREFIX(oi->connected),
  360: 			     (struct prefix *)&addr))
  361: 	      return oi;
  362: 	  }
  363:         else
  364: 	  {
  365: 	    if (IPV4_ADDR_SAME (address, &oi->address->u.prefix4))
  366: 	      return oi;
  367: 	  }
  368:       }
  369:   return NULL;
  370: }
  371: 
  372: int
  373: ospf_if_is_up (struct ospf_interface *oi)
  374: {
  375:   return if_is_up (oi->ifp);
  376: }
  377: 
  378: struct ospf_interface *
  379: ospf_if_exists (struct ospf_interface *oic)
  380: { 
  381:   struct listnode *node;
  382:   struct ospf *ospf;
  383:   struct ospf_interface *oi;
  384: 
  385:   if ((ospf = ospf_lookup ()) == NULL)
  386:     return NULL;
  387: 
  388:   for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
  389:     if (oi == oic)
  390:       return oi;
  391: 
  392:   return NULL;
  393: }
  394: 
  395: struct ospf_interface *
  396: ospf_if_lookup_by_local_addr (struct ospf *ospf,
  397: 			      struct interface *ifp, struct in_addr address)
  398: {
  399:   struct listnode *node;
  400:   struct ospf_interface *oi;
  401:   
  402:   for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
  403:     if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
  404:       {
  405: 	if (ifp && oi->ifp != ifp)
  406: 	  continue;
  407: 	
  408: 	if (IPV4_ADDR_SAME (&address, &oi->address->u.prefix4))
  409: 	  return oi;
  410:       }
  411: 
  412:   return NULL;
  413: }
  414: 
  415: struct ospf_interface *
  416: ospf_if_lookup_by_prefix (struct ospf *ospf, struct prefix_ipv4 *p)
  417: {
  418:   struct listnode *node;
  419:   struct ospf_interface *oi;
  420:   
  421:   /* Check each Interface. */
  422:   for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
  423:     {
  424:       if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
  425: 	{
  426: 	  struct prefix ptmp;
  427: 
  428: 	  prefix_copy (&ptmp, CONNECTED_PREFIX(oi->connected));
  429: 	  apply_mask (&ptmp);
  430: 	  if (prefix_same (&ptmp, (struct prefix *) p))
  431: 	    return oi;
  432: 	}
  433:     }
  434:   return NULL;
  435: }
  436: 
  437: /* determine receiving interface by ifp and source address */
  438: struct ospf_interface *
  439: ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr src,
  440: 			struct interface *ifp)
  441: {
  442:   struct route_node *rn;
  443:   struct prefix_ipv4 addr;
  444:   struct ospf_interface *oi, *match;
  445: 
  446:   addr.family = AF_INET;
  447:   addr.prefix = src;
  448:   addr.prefixlen = IPV4_MAX_BITLEN;
  449: 
  450:   match = NULL;
  451: 
  452:   for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
  453:     {
  454:       oi = rn->info;
  455: 
  456:       if (!oi) /* oi can be NULL for PtP aliases */
  457: 	continue;
  458: 
  459:       if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
  460: 	continue;
  461: 
  462:       if (if_is_loopback (oi->ifp))
  463:         continue;
  464: 
  465:       if (prefix_match (CONNECTED_PREFIX(oi->connected),
  466:       			(struct prefix *) &addr))
  467: 	{
  468: 	  if ( (match == NULL) || 
  469: 	       (match->address->prefixlen < oi->address->prefixlen)
  470: 	     )
  471: 	    match = oi;
  472: 	}
  473:     }
  474: 
  475:   return match;
  476: }
  477: 
  478: void
  479: ospf_if_stream_set (struct ospf_interface *oi)
  480: {
  481:   /* set output fifo queue. */
  482:   if (oi->obuf == NULL) 
  483:     oi->obuf = ospf_fifo_new ();
  484: }
  485: 
  486: void
  487: ospf_if_stream_unset (struct ospf_interface *oi)
  488: {
  489:   struct ospf *ospf = oi->ospf;
  490: 
  491:   if (oi->obuf)
  492:     {
  493:      ospf_fifo_free (oi->obuf);
  494:      oi->obuf = NULL;
  495: 
  496:      if (oi->on_write_q)
  497:        {
  498: 	 listnode_delete (ospf->oi_write_q, oi);
  499:          if (list_isempty(ospf->oi_write_q))
  500:            OSPF_TIMER_OFF (ospf->t_write);
  501: 	 oi->on_write_q = 0;
  502:        }
  503:     }
  504: }
  505: 
  506: 
  507: static struct ospf_if_params *
  508: ospf_new_if_params (void)
  509: {
  510:   struct ospf_if_params *oip;
  511: 
  512:   oip = XCALLOC (MTYPE_OSPF_IF_PARAMS, sizeof (struct ospf_if_params));
  513: 
  514:   if (!oip)
  515:     return NULL;
  516: 
  517:   UNSET_IF_PARAM (oip, output_cost_cmd);
  518:   UNSET_IF_PARAM (oip, transmit_delay);
  519:   UNSET_IF_PARAM (oip, retransmit_interval);
  520:   UNSET_IF_PARAM (oip, passive_interface);
  521:   UNSET_IF_PARAM (oip, v_hello);
  522:   UNSET_IF_PARAM (oip, fast_hello);
  523:   UNSET_IF_PARAM (oip, v_wait);
  524:   UNSET_IF_PARAM (oip, priority);
  525:   UNSET_IF_PARAM (oip, type);
  526:   UNSET_IF_PARAM (oip, auth_simple);
  527:   UNSET_IF_PARAM (oip, auth_crypt);
  528:   UNSET_IF_PARAM (oip, auth_type);
  529: 
  530:   oip->auth_crypt = list_new ();
  531:   
  532:   oip->network_lsa_seqnum = htonl(OSPF_INITIAL_SEQUENCE_NUMBER);
  533: 
  534:   return oip;
  535: }
  536: 
  537: void
  538: ospf_del_if_params (struct ospf_if_params *oip)
  539: {
  540:   list_delete (oip->auth_crypt);
  541:   XFREE (MTYPE_OSPF_IF_PARAMS, oip);
  542: }
  543: 
  544: void
  545: ospf_free_if_params (struct interface *ifp, struct in_addr addr)
  546: {
  547:   struct ospf_if_params *oip;
  548:   struct prefix_ipv4 p;
  549:   struct route_node *rn;
  550: 
  551:   p.family = AF_INET;
  552:   p.prefixlen = IPV4_MAX_PREFIXLEN;
  553:   p.prefix = addr;
  554:   rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
  555:   if (!rn || !rn->info)
  556:     return;
  557: 
  558:   oip = rn->info;
  559:   route_unlock_node (rn);
  560:   
  561:   if (!OSPF_IF_PARAM_CONFIGURED (oip, output_cost_cmd) &&
  562:       !OSPF_IF_PARAM_CONFIGURED (oip, transmit_delay) &&
  563:       !OSPF_IF_PARAM_CONFIGURED (oip, retransmit_interval) &&
  564:       !OSPF_IF_PARAM_CONFIGURED (oip, passive_interface) &&
  565:       !OSPF_IF_PARAM_CONFIGURED (oip, v_hello) &&
  566:       !OSPF_IF_PARAM_CONFIGURED (oip, fast_hello) &&
  567:       !OSPF_IF_PARAM_CONFIGURED (oip, v_wait) &&
  568:       !OSPF_IF_PARAM_CONFIGURED (oip, priority) &&
  569:       !OSPF_IF_PARAM_CONFIGURED (oip, type) &&
  570:       !OSPF_IF_PARAM_CONFIGURED (oip, auth_simple) &&
  571:       !OSPF_IF_PARAM_CONFIGURED (oip, auth_type) &&
  572:       listcount (oip->auth_crypt) == 0 &&
  573:       ntohl (oip->network_lsa_seqnum) != OSPF_INITIAL_SEQUENCE_NUMBER)
  574:     {
  575:       ospf_del_if_params (oip);
  576:       rn->info = NULL;
  577:       route_unlock_node (rn);
  578:     }
  579: }
  580: 
  581: struct ospf_if_params *
  582: ospf_lookup_if_params (struct interface *ifp, struct in_addr addr)
  583: {
  584:   struct prefix_ipv4 p;
  585:   struct route_node *rn;
  586: 
  587:   p.family = AF_INET;
  588:   p.prefixlen = IPV4_MAX_PREFIXLEN;
  589:   p.prefix = addr;
  590: 
  591:   rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
  592:   
  593:   if (rn)
  594:     {
  595:       route_unlock_node (rn);
  596:       return rn->info;
  597:     }
  598: 
  599:   return NULL;
  600: }
  601: 
  602: struct ospf_if_params *
  603: ospf_get_if_params (struct interface *ifp, struct in_addr addr)
  604: {
  605:   struct prefix_ipv4 p;
  606:   struct route_node *rn;
  607: 
  608:   p.family = AF_INET;
  609:   p.prefixlen = IPV4_MAX_PREFIXLEN;
  610:   p.prefix = addr;
  611: 
  612:   rn = route_node_get (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
  613:   
  614:   if (rn->info == NULL)
  615:     rn->info = ospf_new_if_params ();
  616:   else
  617:     route_unlock_node (rn);
  618:   
  619:   return rn->info;
  620: }
  621: 
  622: void
  623: ospf_if_update_params (struct interface *ifp, struct in_addr addr)
  624: {
  625:   struct route_node *rn;
  626:   struct ospf_interface *oi;
  627:   
  628:   for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
  629:     {
  630:       if ((oi = rn->info) == NULL)
  631: 	continue;
  632: 
  633:       if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &addr))
  634: 	oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
  635:     }
  636: }
  637: 
  638: int
  639: ospf_if_new_hook (struct interface *ifp)
  640: {
  641:   int rc = 0;
  642: 
  643:   ifp->info = XCALLOC (MTYPE_OSPF_IF_INFO, sizeof (struct ospf_if_info));
  644:   
  645:   IF_OIFS (ifp) = route_table_init ();
  646:   IF_OIFS_PARAMS (ifp) = route_table_init ();
  647:   
  648:   IF_DEF_PARAMS (ifp) = ospf_new_if_params ();
  649:   
  650:   SET_IF_PARAM (IF_DEF_PARAMS (ifp), transmit_delay);
  651:   IF_DEF_PARAMS (ifp)->transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT;
  652:   
  653:   SET_IF_PARAM (IF_DEF_PARAMS (ifp), retransmit_interval);
  654:   IF_DEF_PARAMS (ifp)->retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
  655: 
  656:   SET_IF_PARAM (IF_DEF_PARAMS (ifp), priority);
  657:   IF_DEF_PARAMS (ifp)->priority = OSPF_ROUTER_PRIORITY_DEFAULT;
  658: 
  659:   IF_DEF_PARAMS (ifp)->mtu_ignore = OSPF_MTU_IGNORE_DEFAULT;
  660: 
  661:   SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_hello);
  662:   IF_DEF_PARAMS (ifp)->v_hello = OSPF_HELLO_INTERVAL_DEFAULT;
  663: 
  664:   SET_IF_PARAM (IF_DEF_PARAMS (ifp), fast_hello);
  665:   IF_DEF_PARAMS (ifp)->fast_hello = OSPF_FAST_HELLO_DEFAULT;
  666: 
  667:   SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_wait);
  668:   IF_DEF_PARAMS (ifp)->v_wait = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
  669: 
  670:   SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_simple);
  671:   memset (IF_DEF_PARAMS (ifp)->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE);
  672:   
  673:   SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_type);
  674:   IF_DEF_PARAMS (ifp)->auth_type = OSPF_AUTH_NOTSET;
  675:   
  676: #ifdef HAVE_OPAQUE_LSA
  677:   rc = ospf_opaque_new_if (ifp);
  678: #endif /* HAVE_OPAQUE_LSA */
  679:   return rc;
  680: }
  681: 
  682: static int
  683: ospf_if_delete_hook (struct interface *ifp)
  684: {
  685:   int rc = 0;
  686:   struct route_node *rn;
  687: #ifdef HAVE_OPAQUE_LSA
  688:   rc = ospf_opaque_del_if (ifp);
  689: #endif /* HAVE_OPAQUE_LSA */
  690: 
  691:   route_table_finish (IF_OIFS (ifp));
  692: 
  693:   for (rn = route_top (IF_OIFS_PARAMS (ifp)); rn; rn = route_next (rn))
  694:     if (rn->info)
  695:       ospf_del_if_params (rn->info);
  696:   route_table_finish (IF_OIFS_PARAMS (ifp));
  697: 
  698:   ospf_del_if_params ((struct ospf_if_params *) IF_DEF_PARAMS (ifp));
  699:   XFREE (MTYPE_OSPF_IF_INFO, ifp->info);
  700:   ifp->info = NULL;
  701: 
  702:   return rc;
  703: }
  704: 
  705: int
  706: ospf_if_is_enable (struct ospf_interface *oi)
  707: {
  708:   if (!if_is_loopback (oi->ifp))
  709:     if (if_is_up (oi->ifp))
  710: 	return 1;
  711: 
  712:   return 0;
  713: }
  714: 
  715: void
  716: ospf_if_set_multicast(struct ospf_interface *oi)
  717: {
  718:   if ((oi->state > ISM_Loopback) &&
  719:       (oi->type != OSPF_IFTYPE_LOOPBACK) &&
  720:       (oi->type != OSPF_IFTYPE_VIRTUALLINK) &&
  721:       (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE))
  722:     {
  723:       /* The interface should belong to the OSPF-all-routers group. */
  724:       if (!OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS) &&
  725: 	  (ospf_if_add_allspfrouters(oi->ospf, oi->address,
  726: 				     oi->ifp->ifindex) >= 0))
  727: 	  /* Set the flag only if the system call to join succeeded. */
  728: 	  OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
  729:     }
  730:   else
  731:     {
  732:       /* The interface should NOT belong to the OSPF-all-routers group. */
  733:       if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS))
  734:         {
  735:           /* Only actually drop if this is the last reference */
  736:           if (OI_MEMBER_COUNT(oi, MEMBER_ALLROUTERS) == 1)
  737: 	    ospf_if_drop_allspfrouters (oi->ospf, oi->address,
  738: 	                                oi->ifp->ifindex);
  739: 	  /* Unset the flag regardless of whether the system call to leave
  740: 	     the group succeeded, since it's much safer to assume that
  741: 	     we are not a member. */
  742:           OI_MEMBER_LEFT(oi,MEMBER_ALLROUTERS);
  743:         }
  744:     }
  745: 
  746:   if (((oi->type == OSPF_IFTYPE_BROADCAST) ||
  747:        (oi->type == OSPF_IFTYPE_POINTOPOINT)) &&
  748:       ((oi->state == ISM_DR) || (oi->state == ISM_Backup)) &&
  749:       (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE))
  750:     {
  751:       /* The interface should belong to the OSPF-designated-routers group. */
  752:       if (!OI_MEMBER_CHECK(oi, MEMBER_DROUTERS) &&
  753: 	  (ospf_if_add_alldrouters(oi->ospf, oi->address,
  754: 	  			   oi->ifp->ifindex) >= 0))
  755: 	/* Set the flag only if the system call to join succeeded. */
  756: 	OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
  757:     }
  758:   else
  759:     {
  760:       /* The interface should NOT belong to the OSPF-designated-routers group */
  761:       if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS))
  762:         {
  763:           /* drop only if last reference */
  764:           if (OI_MEMBER_COUNT(oi, MEMBER_DROUTERS) == 1)
  765: 	    ospf_if_drop_alldrouters(oi->ospf, oi->address, oi->ifp->ifindex);
  766:           
  767: 	  /* Unset the flag regardless of whether the system call to leave
  768: 	     the group succeeded, since it's much safer to assume that
  769: 	     we are not a member. */
  770:           OI_MEMBER_LEFT(oi, MEMBER_DROUTERS);
  771:         }
  772:     }
  773: }
  774: 
  775: int
  776: ospf_if_up (struct ospf_interface *oi)
  777: {
  778:   if (oi == NULL)
  779:     return 0;
  780: 
  781:   if (oi->type == OSPF_IFTYPE_LOOPBACK)
  782:     OSPF_ISM_EVENT_SCHEDULE (oi, ISM_LoopInd);
  783:   else
  784:     {
  785:       struct ospf *ospf = ospf_lookup ();
  786:       if (ospf != NULL)
  787:         ospf_adjust_sndbuflen (ospf, oi->ifp->mtu);
  788:       else
  789:         zlog_warn ("%s: ospf_lookup() returned NULL", __func__);
  790:       ospf_if_stream_set (oi);
  791:       OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceUp);
  792:     }
  793: 
  794:   return 1;
  795: }
  796: 
  797: int
  798: ospf_if_down (struct ospf_interface *oi)
  799: {
  800:   if (oi == NULL)
  801:     return 0;
  802: 
  803:   OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown);
  804:   /* Shutdown packet reception and sending */
  805:   ospf_if_stream_unset (oi);
  806: 
  807:   return 1;
  808: }
  809: 
  810: 
  811: /* Virtual Link related functions. */
  812: 
  813: struct ospf_vl_data *
  814: ospf_vl_data_new (struct ospf_area *area, struct in_addr vl_peer)
  815: {
  816:   struct ospf_vl_data *vl_data;
  817: 
  818:   vl_data = XCALLOC (MTYPE_OSPF_VL_DATA, sizeof (struct ospf_vl_data));
  819: 
  820:   vl_data->vl_peer.s_addr = vl_peer.s_addr;
  821:   vl_data->vl_area_id = area->area_id;
  822:   vl_data->format = area->format;
  823: 
  824:   return vl_data;
  825: }
  826: 
  827: void
  828: ospf_vl_data_free (struct ospf_vl_data *vl_data)
  829: {
  830:   XFREE (MTYPE_OSPF_VL_DATA, vl_data);
  831: }
  832: 
  833: u_int vlink_count = 0;
  834: 
  835: struct ospf_interface * 
  836: ospf_vl_new (struct ospf *ospf, struct ospf_vl_data *vl_data)
  837: {
  838:   struct ospf_interface * voi;
  839:   struct interface * vi;
  840:   char   ifname[INTERFACE_NAMSIZ + 1];
  841:   struct ospf_area *area;
  842:   struct in_addr area_id;
  843:   struct connected *co;
  844:   struct prefix_ipv4 *p;
  845:   
  846:   if (IS_DEBUG_OSPF_EVENT)
  847:     zlog_debug ("ospf_vl_new(): Start");
  848:   if (vlink_count == OSPF_VL_MAX_COUNT)
  849:     {
  850:       if (IS_DEBUG_OSPF_EVENT)
  851: 	zlog_debug ("ospf_vl_new(): Alarm: "
  852: 		   "cannot create more than OSPF_MAX_VL_COUNT virtual links");
  853:       return NULL;
  854:     }
  855: 
  856:   if (IS_DEBUG_OSPF_EVENT)
  857:     zlog_debug ("ospf_vl_new(): creating pseudo zebra interface");
  858: 
  859:   snprintf (ifname, sizeof(ifname), "VLINK%d", vlink_count);
  860:   vi = if_create (ifname, strnlen(ifname, sizeof(ifname)));
  861:   co = connected_new ();
  862:   co->ifp = vi;
  863:   listnode_add (vi->connected, co);
  864: 
  865:   p = prefix_ipv4_new ();
  866:   p->family = AF_INET;
  867:   p->prefix.s_addr = 0;
  868:   p->prefixlen = 0;
  869:  
  870:   co->address = (struct prefix *)p;
  871:   
  872:   voi = ospf_if_new (ospf, vi, co->address);
  873:   if (voi == NULL)
  874:     {
  875:       if (IS_DEBUG_OSPF_EVENT)
  876: 	zlog_debug ("ospf_vl_new(): Alarm: OSPF int structure is not created");
  877:       return NULL;
  878:     }
  879:   voi->connected = co;
  880:   voi->vl_data = vl_data;
  881:   voi->ifp->mtu = OSPF_VL_MTU;
  882:   voi->type = OSPF_IFTYPE_VIRTUALLINK;
  883: 
  884:   vlink_count++;
  885:   if (IS_DEBUG_OSPF_EVENT)
  886:     zlog_debug ("ospf_vl_new(): Created name: %s", ifname);
  887:   if (IS_DEBUG_OSPF_EVENT)
  888:     zlog_debug ("ospf_vl_new(): set if->name to %s", vi->name);
  889: 
  890:   area_id.s_addr = 0;
  891:   area = ospf_area_get (ospf, area_id, OSPF_AREA_ID_FORMAT_ADDRESS);
  892:   voi->area = area;
  893: 
  894:   if (IS_DEBUG_OSPF_EVENT)
  895:     zlog_debug ("ospf_vl_new(): set associated area to the backbone");
  896: 
  897:   ospf_nbr_add_self (voi);
  898:   ospf_area_add_if (voi->area, voi);
  899: 
  900:   ospf_if_stream_set (voi);
  901: 
  902:   if (IS_DEBUG_OSPF_EVENT)
  903:     zlog_debug ("ospf_vl_new(): Stop");
  904:   return voi;
  905: }
  906: 
  907: static void
  908: ospf_vl_if_delete (struct ospf_vl_data *vl_data)
  909: {
  910:   struct interface *ifp = vl_data->vl_oi->ifp;
  911:   vl_data->vl_oi->address->u.prefix4.s_addr = 0;
  912:   vl_data->vl_oi->address->prefixlen = 0;
  913:   ospf_if_free (vl_data->vl_oi);
  914:   if_delete (ifp);
  915:   vlink_count--;
  916: }
  917: 
  918: /* Look up vl_data for given peer, optionally qualified to be in the
  919:  * specified area. NULL area returns first found..
  920:  */
  921: struct ospf_vl_data *
  922: ospf_vl_lookup (struct ospf *ospf, struct ospf_area *area,
  923:                 struct in_addr vl_peer)
  924: {
  925:   struct ospf_vl_data *vl_data;
  926:   struct listnode *node;
  927:   
  928:   if (IS_DEBUG_OSPF_EVENT)
  929:     {
  930:       zlog_debug ("%s: Looking for %s", __func__, inet_ntoa (vl_peer));
  931:       if (area)
  932:         zlog_debug ("%s: in area %s", __func__, inet_ntoa (area->area_id));
  933:     }
  934:   
  935:   for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
  936:     {
  937:       if (IS_DEBUG_OSPF_EVENT)
  938:         zlog_debug ("%s: VL %s, peer %s", __func__,
  939:                     vl_data->vl_oi->ifp->name,
  940:                     inet_ntoa (vl_data->vl_peer));
  941:       
  942:       if (area && !IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
  943:         continue;
  944:       
  945:       if (IPV4_ADDR_SAME (&vl_data->vl_peer, &vl_peer))
  946:         return vl_data;
  947:     }
  948: 
  949:   return NULL;
  950: }
  951: 
  952: static void 
  953: ospf_vl_shutdown (struct ospf_vl_data *vl_data)
  954: {
  955:   struct ospf_interface *oi;
  956: 
  957:   if ((oi = vl_data->vl_oi) == NULL)
  958:     return;
  959: 
  960:   oi->address->u.prefix4.s_addr = 0;
  961:   oi->address->prefixlen = 0;
  962: 
  963:   UNSET_FLAG (oi->ifp->flags, IFF_UP);
  964:   /* OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceDown); */
  965:   OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown);
  966: }
  967: 
  968: void
  969: ospf_vl_add (struct ospf *ospf, struct ospf_vl_data *vl_data)
  970: {
  971:   listnode_add (ospf->vlinks, vl_data);
  972: #ifdef HAVE_SNMP
  973:   ospf_snmp_vl_add (vl_data);
  974: #endif /* HAVE_SNMP */
  975: }
  976: 
  977: void
  978: ospf_vl_delete (struct ospf *ospf, struct ospf_vl_data *vl_data)
  979: {
  980:   ospf_vl_shutdown (vl_data);
  981:   ospf_vl_if_delete (vl_data);
  982: 
  983: #ifdef HAVE_SNMP
  984:   ospf_snmp_vl_delete (vl_data);
  985: #endif /* HAVE_SNMP */
  986:   listnode_delete (ospf->vlinks, vl_data);
  987: 
  988:   ospf_vl_data_free (vl_data);
  989: }
  990: 
  991: static int
  992: ospf_vl_set_params (struct ospf_vl_data *vl_data, struct vertex *v)
  993: {
  994:   int changed = 0;
  995:   struct ospf_interface *voi;
  996:   struct listnode *node;
  997:   struct vertex_parent *vp = NULL;
  998:   int i;
  999:   struct router_lsa *rl;
 1000: 
 1001:   voi = vl_data->vl_oi;
 1002: 
 1003:   if (voi->output_cost != v->distance)
 1004:     {
 1005:      
 1006:       voi->output_cost = v->distance;
 1007:       changed = 1;
 1008:     }
 1009: 
 1010:   for (ALL_LIST_ELEMENTS_RO (v->parents, node, vp))
 1011:     {
 1012:       vl_data->nexthop.oi = vp->nexthop->oi;
 1013:       vl_data->nexthop.router = vp->nexthop->router;
 1014:       
 1015:       if (!IPV4_ADDR_SAME(&voi->address->u.prefix4,
 1016:                           &vl_data->nexthop.oi->address->u.prefix4))
 1017:         changed = 1;
 1018:         
 1019:       voi->address->u.prefix4 = vl_data->nexthop.oi->address->u.prefix4;
 1020:       voi->address->prefixlen = vl_data->nexthop.oi->address->prefixlen;
 1021: 
 1022:       break; /* We take the first interface. */
 1023:     }
 1024: 
 1025:   rl = (struct router_lsa *)v->lsa;
 1026: 
 1027:   /* use SPF determined backlink index in struct vertex
 1028:    * for virtual link destination address
 1029:    */
 1030:   if (vp && vp->backlink >= 0)
 1031:     {
 1032:       if (!IPV4_ADDR_SAME (&vl_data->peer_addr,
 1033:                            &rl->link[vp->backlink].link_data))
 1034:         changed = 1;
 1035:       vl_data->peer_addr = rl->link[vp->backlink].link_data;
 1036:     }
 1037:   else
 1038:     {
 1039:       /* This is highly odd, there is no backlink index
 1040:        * there should be due to the ospf_spf_has_link() check
 1041:        * in SPF. Lets warn and try pick a link anyway.
 1042:        */
 1043:       zlog_warn ("ospf_vl_set_params: No backlink for %s!",
 1044:                  vl_data->vl_oi->ifp->name);
 1045:       for (i = 0; i < ntohs (rl->links); i++)
 1046:         {
 1047:           switch (rl->link[i].type)
 1048:             {
 1049:               case LSA_LINK_TYPE_VIRTUALLINK:
 1050:                 if (IS_DEBUG_OSPF_EVENT)
 1051:                   zlog_debug ("found back link through VL");
 1052:               case LSA_LINK_TYPE_TRANSIT:
 1053:               case LSA_LINK_TYPE_POINTOPOINT:
 1054:                 if (!IPV4_ADDR_SAME (&vl_data->peer_addr,
 1055:                                      &rl->link[i].link_data))
 1056:                   changed = 1;
 1057:                 vl_data->peer_addr = rl->link[i].link_data;
 1058:             }
 1059:         }
 1060:     }
 1061:     
 1062:   if (IS_DEBUG_OSPF_EVENT)
 1063:     zlog_debug ("%s: %s peer address: %s, cost: %d,%schanged", __func__,
 1064:                vl_data->vl_oi->ifp->name,
 1065:                inet_ntoa(vl_data->peer_addr),
 1066:                voi->output_cost,
 1067:                (changed ? " " : " un"));
 1068:                
 1069:   return changed;
 1070: }
 1071: 
 1072: 
 1073: void
 1074: ospf_vl_up_check (struct ospf_area *area, struct in_addr rid,
 1075:                   struct vertex *v)
 1076: {
 1077:   struct ospf *ospf = area->ospf;
 1078:   struct listnode *node;
 1079:   struct ospf_vl_data *vl_data;
 1080:   struct ospf_interface *oi;
 1081: 
 1082:   if (IS_DEBUG_OSPF_EVENT)
 1083:     {
 1084:       zlog_debug ("ospf_vl_up_check(): Start");
 1085:       zlog_debug ("ospf_vl_up_check(): Router ID is %s", inet_ntoa (rid));
 1086:       zlog_debug ("ospf_vl_up_check(): Area is %s", inet_ntoa (area->area_id));
 1087:     }
 1088: 
 1089:   for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
 1090:     {
 1091:       if (IS_DEBUG_OSPF_EVENT)
 1092: 	{
 1093: 	  zlog_debug ("%s: considering VL, %s in area %s", __func__,
 1094: 		     vl_data->vl_oi->ifp->name,
 1095: 		     inet_ntoa (vl_data->vl_area_id));
 1096: 	  zlog_debug ("%s: peer ID: %s", __func__,
 1097: 		     inet_ntoa (vl_data->vl_peer));
 1098: 	}
 1099: 
 1100:       if (IPV4_ADDR_SAME (&vl_data->vl_peer, &rid) &&
 1101:           IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
 1102:         {
 1103:           oi = vl_data->vl_oi;
 1104:           SET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED);
 1105: 
 1106: 	  if (IS_DEBUG_OSPF_EVENT)
 1107: 	    zlog_debug ("ospf_vl_up_check(): this VL matched");
 1108: 
 1109:           if (oi->state == ISM_Down)
 1110:             {
 1111: 	      if (IS_DEBUG_OSPF_EVENT)
 1112: 		zlog_debug ("ospf_vl_up_check(): VL is down, waking it up");
 1113:               SET_FLAG (oi->ifp->flags, IFF_UP);
 1114:               OSPF_ISM_EVENT_EXECUTE(oi,ISM_InterfaceUp);
 1115:             }
 1116: 
 1117:          if (ospf_vl_set_params (vl_data, v))
 1118:            {
 1119:              if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
 1120:                zlog_debug ("ospf_vl_up_check: VL cost change,"
 1121:                           " scheduling router lsa refresh");
 1122:              if (ospf->backbone)
 1123:                ospf_router_lsa_update_area (ospf->backbone);
 1124:              else if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
 1125:                zlog_debug ("ospf_vl_up_check: VL cost change, no backbone!");
 1126:            }
 1127:         }
 1128:     }
 1129: }
 1130: 
 1131: void
 1132: ospf_vl_unapprove (struct ospf *ospf)
 1133: {
 1134:   struct listnode *node;
 1135:   struct ospf_vl_data *vl_data;
 1136: 
 1137:   for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
 1138:     UNSET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED);
 1139: }
 1140: 
 1141: void
 1142: ospf_vl_shut_unapproved (struct ospf *ospf)
 1143: {
 1144:   struct listnode *node, *nnode;
 1145:   struct ospf_vl_data *vl_data;
 1146: 
 1147:   for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
 1148:     if (!CHECK_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED))
 1149:       ospf_vl_shutdown (vl_data);
 1150: }
 1151: 
 1152: int
 1153: ospf_full_virtual_nbrs (struct ospf_area *area)
 1154: {
 1155:   if (IS_DEBUG_OSPF_EVENT)
 1156:     {
 1157:       zlog_debug ("counting fully adjacent virtual neighbors in area %s",
 1158: 		 inet_ntoa (area->area_id));
 1159:       zlog_debug ("there are %d of them", area->full_vls);
 1160:     }
 1161: 
 1162:   return area->full_vls;
 1163: }
 1164: 
 1165: int
 1166: ospf_vls_in_area (struct ospf_area *area)
 1167: {
 1168:   struct listnode *node;
 1169:   struct ospf_vl_data *vl_data;
 1170:   int c = 0;
 1171: 
 1172:   for (ALL_LIST_ELEMENTS_RO (area->ospf->vlinks, node, vl_data))
 1173:     if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
 1174:       c++;
 1175: 
 1176:   return c;
 1177: }
 1178: 
 1179: 
 1180: struct crypt_key *
 1181: ospf_crypt_key_new ()
 1182: {
 1183:   return XCALLOC (MTYPE_OSPF_CRYPT_KEY, sizeof (struct crypt_key));
 1184: }
 1185: 
 1186: void
 1187: ospf_crypt_key_add (struct list *crypt, struct crypt_key *ck)
 1188: {
 1189:   listnode_add (crypt, ck);
 1190: }
 1191: 
 1192: struct crypt_key *
 1193: ospf_crypt_key_lookup (struct list *auth_crypt, u_char key_id)
 1194: {
 1195:   struct listnode *node;
 1196:   struct crypt_key *ck;
 1197: 
 1198:   for (ALL_LIST_ELEMENTS_RO (auth_crypt, node, ck))
 1199:     if (ck->key_id == key_id)
 1200:       return ck;
 1201: 
 1202:   return NULL;
 1203: }
 1204: 
 1205: int
 1206: ospf_crypt_key_delete (struct list *auth_crypt, u_char key_id)
 1207: {
 1208:   struct listnode *node, *nnode;
 1209:   struct crypt_key *ck;
 1210: 
 1211:   for (ALL_LIST_ELEMENTS (auth_crypt, node, nnode, ck))
 1212:     {
 1213:       if (ck->key_id == key_id)
 1214:         {
 1215:           listnode_delete (auth_crypt, ck);
 1216:           XFREE (MTYPE_OSPF_CRYPT_KEY, ck);
 1217:           return 1;
 1218:         }
 1219:     }
 1220: 
 1221:   return 0;
 1222: }
 1223: 
 1224: u_char
 1225: ospf_default_iftype(struct interface *ifp)
 1226: {
 1227:   if (if_is_pointopoint (ifp))
 1228:     return OSPF_IFTYPE_POINTOPOINT;
 1229:   else if (if_is_loopback (ifp))
 1230:     return OSPF_IFTYPE_LOOPBACK;
 1231:   else
 1232:     return OSPF_IFTYPE_BROADCAST;
 1233: }
 1234: 
 1235: void
 1236: ospf_if_init ()
 1237: {
 1238:   /* Initialize Zebra interface data structure. */
 1239:   if_init ();
 1240:   om->iflist = iflist;
 1241:   if_add_hook (IF_NEW_HOOK, ospf_if_new_hook);
 1242:   if_add_hook (IF_DELETE_HOOK, ospf_if_delete_hook);
 1243: }

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