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

    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:   ospf_opaque_type9_lsa_init (oi);
  245: 
  246:   oi->ospf = ospf;
  247:   
  248:   return oi;
  249: }
  250: 
  251: /* Restore an interface to its pre UP state
  252:    Used from ism_interface_down only */
  253: void
  254: ospf_if_cleanup (struct ospf_interface *oi)
  255: {
  256:   struct route_node *rn;
  257:   struct listnode *node, *nnode;
  258:   struct ospf_neighbor *nbr;
  259:   struct ospf_nbr_nbma *nbr_nbma;
  260:   struct ospf_lsa *lsa;
  261: 
  262:   /* oi->nbrs and oi->nbr_nbma should be deleted on InterfaceDown event */
  263:   /* delete all static neighbors attached to this interface */
  264:   for (ALL_LIST_ELEMENTS (oi->nbr_nbma, node, nnode, nbr_nbma))
  265:     {
  266:       OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
  267: 
  268:       if (nbr_nbma->nbr)
  269: 	{
  270: 	  nbr_nbma->nbr->nbr_nbma = NULL;
  271: 	  nbr_nbma->nbr = NULL;
  272: 	}
  273: 
  274:       nbr_nbma->oi = NULL;
  275:       
  276:       listnode_delete (oi->nbr_nbma, nbr_nbma);
  277:     }
  278: 
  279:   /* send Neighbor event KillNbr to all associated neighbors. */
  280:   for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
  281:     if ((nbr = rn->info) != NULL)
  282:       if (nbr != oi->nbr_self)
  283: 	OSPF_NSM_EVENT_EXECUTE (nbr, NSM_KillNbr);
  284: 
  285:   /* Cleanup Link State Acknowlegdment list. */
  286:   for (ALL_LIST_ELEMENTS (oi->ls_ack, node, nnode, lsa))
  287:     ospf_lsa_unlock (&lsa); /* oi->ls_ack */
  288:   list_delete_all_node (oi->ls_ack);
  289: 
  290:   oi->crypt_seqnum = 0;
  291:   
  292:   /* Empty link state update queue */
  293:   ospf_ls_upd_queue_empty (oi);
  294:   
  295:   /* Reset pseudo neighbor. */
  296:   ospf_nbr_self_reset (oi);
  297: }
  298: 
  299: void
  300: ospf_if_free (struct ospf_interface *oi)
  301: {
  302:   ospf_if_down (oi);
  303: 
  304:   assert (oi->state == ISM_Down);
  305: 
  306:   ospf_opaque_type9_lsa_term (oi);
  307: 
  308:   /* Free Pseudo Neighbour */
  309:   ospf_nbr_delete (oi->nbr_self);
  310:   
  311:   route_table_finish (oi->nbrs);
  312:   route_table_finish (oi->ls_upd_queue);
  313:   
  314:   /* Free any lists that should be freed */
  315:   list_free (oi->nbr_nbma);
  316:   
  317:   list_free (oi->ls_ack);
  318:   list_free (oi->ls_ack_direct.ls_ack);
  319:   
  320:   ospf_delete_from_if (oi->ifp, oi);
  321: 
  322:   listnode_delete (oi->ospf->oiflist, oi);
  323:   listnode_delete (oi->area->oiflist, oi);
  324: 
  325:   thread_cancel_event (master, oi);
  326: 
  327:   memset (oi, 0, sizeof (*oi));
  328:   XFREE (MTYPE_OSPF_IF, oi);
  329: }
  330: 
  331: 
  332: /*
  333: *  check if interface with given address is configured and
  334: *  return it if yes.  special treatment for PtP networks.
  335: */
  336: struct ospf_interface *
  337: ospf_if_is_configured (struct ospf *ospf, struct in_addr *address)
  338: {
  339:   struct listnode *node, *nnode;
  340:   struct ospf_interface *oi;
  341:   struct prefix_ipv4 addr;
  342: 
  343:   addr.family = AF_INET;
  344:   addr.prefix = *address;
  345:   addr.prefixlen = IPV4_MAX_PREFIXLEN;
  346: 
  347:   for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
  348:     if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
  349:       {
  350:         if (oi->type == OSPF_IFTYPE_POINTOPOINT)
  351: 	  {
  352: 	    /* special leniency: match if addr is anywhere on peer subnet */
  353: 	    if (prefix_match(CONNECTED_PREFIX(oi->connected),
  354: 			     (struct prefix *)&addr))
  355: 	      return oi;
  356: 	  }
  357:         else
  358: 	  {
  359: 	    if (IPV4_ADDR_SAME (address, &oi->address->u.prefix4))
  360: 	      return oi;
  361: 	  }
  362:       }
  363:   return NULL;
  364: }
  365: 
  366: int
  367: ospf_if_is_up (struct ospf_interface *oi)
  368: {
  369:   return if_is_up (oi->ifp);
  370: }
  371: 
  372: struct ospf_interface *
  373: ospf_if_exists (struct ospf_interface *oic)
  374: { 
  375:   struct listnode *node;
  376:   struct ospf *ospf;
  377:   struct ospf_interface *oi;
  378: 
  379:   if ((ospf = ospf_lookup ()) == NULL)
  380:     return NULL;
  381: 
  382:   for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
  383:     if (oi == oic)
  384:       return oi;
  385: 
  386:   return NULL;
  387: }
  388: 
  389: /* Lookup OSPF interface by router LSA posistion */
  390: struct ospf_interface *
  391: ospf_if_lookup_by_lsa_pos (struct ospf_area *area, int lsa_pos)
  392: {
  393:   struct listnode *node;
  394:   struct ospf_interface *oi;
  395: 
  396:   for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
  397:     {
  398:       if (lsa_pos >= oi->lsa_pos_beg && lsa_pos < oi->lsa_pos_end)
  399: 	return oi;
  400:     }
  401:   return NULL;
  402: }
  403: 
  404: struct ospf_interface *
  405: ospf_if_lookup_by_local_addr (struct ospf *ospf,
  406: 			      struct interface *ifp, struct in_addr address)
  407: {
  408:   struct listnode *node;
  409:   struct ospf_interface *oi;
  410:   
  411:   for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
  412:     if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
  413:       {
  414: 	if (ifp && oi->ifp != ifp)
  415: 	  continue;
  416: 	
  417: 	if (IPV4_ADDR_SAME (&address, &oi->address->u.prefix4))
  418: 	  return oi;
  419:       }
  420: 
  421:   return NULL;
  422: }
  423: 
  424: struct ospf_interface *
  425: ospf_if_lookup_by_prefix (struct ospf *ospf, struct prefix_ipv4 *p)
  426: {
  427:   struct listnode *node;
  428:   struct ospf_interface *oi;
  429:   
  430:   /* Check each Interface. */
  431:   for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
  432:     {
  433:       if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
  434: 	{
  435: 	  struct prefix ptmp;
  436: 
  437: 	  prefix_copy (&ptmp, CONNECTED_PREFIX(oi->connected));
  438: 	  apply_mask (&ptmp);
  439: 	  if (prefix_same (&ptmp, (struct prefix *) p))
  440: 	    return oi;
  441: 	}
  442:     }
  443:   return NULL;
  444: }
  445: 
  446: /* determine receiving interface by ifp and source address */
  447: struct ospf_interface *
  448: ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr src,
  449: 			struct interface *ifp)
  450: {
  451:   struct route_node *rn;
  452:   struct prefix_ipv4 addr;
  453:   struct ospf_interface *oi, *match;
  454: 
  455:   addr.family = AF_INET;
  456:   addr.prefix = src;
  457:   addr.prefixlen = IPV4_MAX_BITLEN;
  458: 
  459:   match = NULL;
  460: 
  461:   for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
  462:     {
  463:       oi = rn->info;
  464: 
  465:       if (!oi) /* oi can be NULL for PtP aliases */
  466: 	continue;
  467: 
  468:       if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
  469: 	continue;
  470: 
  471:       if (if_is_loopback (oi->ifp))
  472:         continue;
  473: 
  474:       if (prefix_match (CONNECTED_PREFIX(oi->connected),
  475:       			(struct prefix *) &addr))
  476: 	{
  477: 	  if ( (match == NULL) || 
  478: 	       (match->address->prefixlen < oi->address->prefixlen)
  479: 	     )
  480: 	    match = oi;
  481: 	}
  482:     }
  483: 
  484:   return match;
  485: }
  486: 
  487: void
  488: ospf_if_stream_set (struct ospf_interface *oi)
  489: {
  490:   /* set output fifo queue. */
  491:   if (oi->obuf == NULL) 
  492:     oi->obuf = ospf_fifo_new ();
  493: }
  494: 
  495: void
  496: ospf_if_stream_unset (struct ospf_interface *oi)
  497: {
  498:   struct ospf *ospf = oi->ospf;
  499: 
  500:   if (oi->obuf)
  501:     {
  502:      ospf_fifo_free (oi->obuf);
  503:      oi->obuf = NULL;
  504: 
  505:      if (oi->on_write_q)
  506:        {
  507: 	 listnode_delete (ospf->oi_write_q, oi);
  508:          if (list_isempty(ospf->oi_write_q))
  509:            OSPF_TIMER_OFF (ospf->t_write);
  510: 	 oi->on_write_q = 0;
  511:        }
  512:     }
  513: }
  514: 
  515: 
  516: static struct ospf_if_params *
  517: ospf_new_if_params (void)
  518: {
  519:   struct ospf_if_params *oip;
  520: 
  521:   oip = XCALLOC (MTYPE_OSPF_IF_PARAMS, sizeof (struct ospf_if_params));
  522: 
  523:   if (!oip)
  524:     return NULL;
  525: 
  526:   UNSET_IF_PARAM (oip, output_cost_cmd);
  527:   UNSET_IF_PARAM (oip, transmit_delay);
  528:   UNSET_IF_PARAM (oip, retransmit_interval);
  529:   UNSET_IF_PARAM (oip, passive_interface);
  530:   UNSET_IF_PARAM (oip, v_hello);
  531:   UNSET_IF_PARAM (oip, fast_hello);
  532:   UNSET_IF_PARAM (oip, v_wait);
  533:   UNSET_IF_PARAM (oip, priority);
  534:   UNSET_IF_PARAM (oip, type);
  535:   UNSET_IF_PARAM (oip, auth_simple);
  536:   UNSET_IF_PARAM (oip, auth_crypt);
  537:   UNSET_IF_PARAM (oip, auth_type);
  538: 
  539:   oip->auth_crypt = list_new ();
  540:   
  541:   oip->network_lsa_seqnum = htonl(OSPF_INITIAL_SEQUENCE_NUMBER);
  542: 
  543:   return oip;
  544: }
  545: 
  546: void
  547: ospf_del_if_params (struct ospf_if_params *oip)
  548: {
  549:   list_delete (oip->auth_crypt);
  550:   XFREE (MTYPE_OSPF_IF_PARAMS, oip);
  551: }
  552: 
  553: void
  554: ospf_free_if_params (struct interface *ifp, struct in_addr addr)
  555: {
  556:   struct ospf_if_params *oip;
  557:   struct prefix_ipv4 p;
  558:   struct route_node *rn;
  559: 
  560:   p.family = AF_INET;
  561:   p.prefixlen = IPV4_MAX_PREFIXLEN;
  562:   p.prefix = addr;
  563:   rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
  564:   if (!rn || !rn->info)
  565:     return;
  566: 
  567:   oip = rn->info;
  568:   route_unlock_node (rn);
  569:   
  570:   if (!OSPF_IF_PARAM_CONFIGURED (oip, output_cost_cmd) &&
  571:       !OSPF_IF_PARAM_CONFIGURED (oip, transmit_delay) &&
  572:       !OSPF_IF_PARAM_CONFIGURED (oip, retransmit_interval) &&
  573:       !OSPF_IF_PARAM_CONFIGURED (oip, passive_interface) &&
  574:       !OSPF_IF_PARAM_CONFIGURED (oip, v_hello) &&
  575:       !OSPF_IF_PARAM_CONFIGURED (oip, fast_hello) &&
  576:       !OSPF_IF_PARAM_CONFIGURED (oip, v_wait) &&
  577:       !OSPF_IF_PARAM_CONFIGURED (oip, priority) &&
  578:       !OSPF_IF_PARAM_CONFIGURED (oip, type) &&
  579:       !OSPF_IF_PARAM_CONFIGURED (oip, auth_simple) &&
  580:       !OSPF_IF_PARAM_CONFIGURED (oip, auth_type) &&
  581:       listcount (oip->auth_crypt) == 0 &&
  582:       ntohl (oip->network_lsa_seqnum) != OSPF_INITIAL_SEQUENCE_NUMBER)
  583:     {
  584:       ospf_del_if_params (oip);
  585:       rn->info = NULL;
  586:       route_unlock_node (rn);
  587:     }
  588: }
  589: 
  590: struct ospf_if_params *
  591: ospf_lookup_if_params (struct interface *ifp, struct in_addr addr)
  592: {
  593:   struct prefix_ipv4 p;
  594:   struct route_node *rn;
  595: 
  596:   p.family = AF_INET;
  597:   p.prefixlen = IPV4_MAX_PREFIXLEN;
  598:   p.prefix = addr;
  599: 
  600:   rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
  601:   
  602:   if (rn)
  603:     {
  604:       route_unlock_node (rn);
  605:       return rn->info;
  606:     }
  607: 
  608:   return NULL;
  609: }
  610: 
  611: struct ospf_if_params *
  612: ospf_get_if_params (struct interface *ifp, struct in_addr addr)
  613: {
  614:   struct prefix_ipv4 p;
  615:   struct route_node *rn;
  616: 
  617:   p.family = AF_INET;
  618:   p.prefixlen = IPV4_MAX_PREFIXLEN;
  619:   p.prefix = addr;
  620: 
  621:   rn = route_node_get (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
  622:   
  623:   if (rn->info == NULL)
  624:     rn->info = ospf_new_if_params ();
  625:   else
  626:     route_unlock_node (rn);
  627:   
  628:   return rn->info;
  629: }
  630: 
  631: void
  632: ospf_if_update_params (struct interface *ifp, struct in_addr addr)
  633: {
  634:   struct route_node *rn;
  635:   struct ospf_interface *oi;
  636:   
  637:   for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
  638:     {
  639:       if ((oi = rn->info) == NULL)
  640: 	continue;
  641: 
  642:       if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &addr))
  643: 	oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
  644:     }
  645: }
  646: 
  647: int
  648: ospf_if_new_hook (struct interface *ifp)
  649: {
  650:   int rc = 0;
  651: 
  652:   ifp->info = XCALLOC (MTYPE_OSPF_IF_INFO, sizeof (struct ospf_if_info));
  653:   
  654:   IF_OIFS (ifp) = route_table_init ();
  655:   IF_OIFS_PARAMS (ifp) = route_table_init ();
  656:   
  657:   IF_DEF_PARAMS (ifp) = ospf_new_if_params ();
  658:   
  659:   SET_IF_PARAM (IF_DEF_PARAMS (ifp), transmit_delay);
  660:   IF_DEF_PARAMS (ifp)->transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT;
  661:   
  662:   SET_IF_PARAM (IF_DEF_PARAMS (ifp), retransmit_interval);
  663:   IF_DEF_PARAMS (ifp)->retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
  664: 
  665:   SET_IF_PARAM (IF_DEF_PARAMS (ifp), priority);
  666:   IF_DEF_PARAMS (ifp)->priority = OSPF_ROUTER_PRIORITY_DEFAULT;
  667: 
  668:   IF_DEF_PARAMS (ifp)->mtu_ignore = OSPF_MTU_IGNORE_DEFAULT;
  669: 
  670:   SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_hello);
  671:   IF_DEF_PARAMS (ifp)->v_hello = OSPF_HELLO_INTERVAL_DEFAULT;
  672: 
  673:   SET_IF_PARAM (IF_DEF_PARAMS (ifp), fast_hello);
  674:   IF_DEF_PARAMS (ifp)->fast_hello = OSPF_FAST_HELLO_DEFAULT;
  675: 
  676:   SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_wait);
  677:   IF_DEF_PARAMS (ifp)->v_wait = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
  678: 
  679:   SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_simple);
  680:   memset (IF_DEF_PARAMS (ifp)->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE);
  681:   
  682:   SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_type);
  683:   IF_DEF_PARAMS (ifp)->auth_type = OSPF_AUTH_NOTSET;
  684:   
  685:   rc = ospf_opaque_new_if (ifp);
  686:   return rc;
  687: }
  688: 
  689: static int
  690: ospf_if_delete_hook (struct interface *ifp)
  691: {
  692:   int rc = 0;
  693:   struct route_node *rn;
  694:   rc = ospf_opaque_del_if (ifp);
  695: 
  696:   route_table_finish (IF_OIFS (ifp));
  697: 
  698:   for (rn = route_top (IF_OIFS_PARAMS (ifp)); rn; rn = route_next (rn))
  699:     if (rn->info)
  700:       ospf_del_if_params (rn->info);
  701:   route_table_finish (IF_OIFS_PARAMS (ifp));
  702: 
  703:   ospf_del_if_params ((struct ospf_if_params *) IF_DEF_PARAMS (ifp));
  704:   XFREE (MTYPE_OSPF_IF_INFO, ifp->info);
  705:   ifp->info = NULL;
  706: 
  707:   return rc;
  708: }
  709: 
  710: int
  711: ospf_if_is_enable (struct ospf_interface *oi)
  712: {
  713:   if (!if_is_loopback (oi->ifp))
  714:     if (if_is_up (oi->ifp))
  715: 	return 1;
  716: 
  717:   return 0;
  718: }
  719: 
  720: void
  721: ospf_if_set_multicast(struct ospf_interface *oi)
  722: {
  723:   if ((oi->state > ISM_Loopback) &&
  724:       (oi->type != OSPF_IFTYPE_LOOPBACK) &&
  725:       (oi->type != OSPF_IFTYPE_VIRTUALLINK) &&
  726:       (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE))
  727:     {
  728:       /* The interface should belong to the OSPF-all-routers group. */
  729:       if (!OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS) &&
  730: 	  (ospf_if_add_allspfrouters(oi->ospf, oi->address,
  731: 				     oi->ifp->ifindex) >= 0))
  732: 	  /* Set the flag only if the system call to join succeeded. */
  733: 	  OI_MEMBER_JOINED(oi, MEMBER_ALLROUTERS);
  734:     }
  735:   else
  736:     {
  737:       /* The interface should NOT belong to the OSPF-all-routers group. */
  738:       if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS))
  739:         {
  740:           /* Only actually drop if this is the last reference */
  741:           if (OI_MEMBER_COUNT(oi, MEMBER_ALLROUTERS) == 1)
  742: 	    ospf_if_drop_allspfrouters (oi->ospf, oi->address,
  743: 	                                oi->ifp->ifindex);
  744: 	  /* Unset the flag regardless of whether the system call to leave
  745: 	     the group succeeded, since it's much safer to assume that
  746: 	     we are not a member. */
  747:           OI_MEMBER_LEFT(oi,MEMBER_ALLROUTERS);
  748:         }
  749:     }
  750: 
  751:   if (((oi->type == OSPF_IFTYPE_BROADCAST) ||
  752:        (oi->type == OSPF_IFTYPE_POINTOPOINT)) &&
  753:       ((oi->state == ISM_DR) || (oi->state == ISM_Backup)) &&
  754:       (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_ACTIVE))
  755:     {
  756:       /* The interface should belong to the OSPF-designated-routers group. */
  757:       if (!OI_MEMBER_CHECK(oi, MEMBER_DROUTERS) &&
  758: 	  (ospf_if_add_alldrouters(oi->ospf, oi->address,
  759: 	  			   oi->ifp->ifindex) >= 0))
  760: 	/* Set the flag only if the system call to join succeeded. */
  761: 	OI_MEMBER_JOINED(oi, MEMBER_DROUTERS);
  762:     }
  763:   else
  764:     {
  765:       /* The interface should NOT belong to the OSPF-designated-routers group */
  766:       if (OI_MEMBER_CHECK(oi, MEMBER_DROUTERS))
  767:         {
  768:           /* drop only if last reference */
  769:           if (OI_MEMBER_COUNT(oi, MEMBER_DROUTERS) == 1)
  770: 	    ospf_if_drop_alldrouters(oi->ospf, oi->address, oi->ifp->ifindex);
  771:           
  772: 	  /* Unset the flag regardless of whether the system call to leave
  773: 	     the group succeeded, since it's much safer to assume that
  774: 	     we are not a member. */
  775:           OI_MEMBER_LEFT(oi, MEMBER_DROUTERS);
  776:         }
  777:     }
  778: }
  779: 
  780: int
  781: ospf_if_up (struct ospf_interface *oi)
  782: {
  783:   if (oi == NULL)
  784:     return 0;
  785: 
  786:   if (oi->type == OSPF_IFTYPE_LOOPBACK)
  787:     OSPF_ISM_EVENT_SCHEDULE (oi, ISM_LoopInd);
  788:   else
  789:     {
  790:       struct ospf *ospf = ospf_lookup ();
  791:       if (ospf != NULL)
  792:         ospf_adjust_sndbuflen (ospf, oi->ifp->mtu);
  793:       else
  794:         zlog_warn ("%s: ospf_lookup() returned NULL", __func__);
  795:       ospf_if_stream_set (oi);
  796:       OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceUp);
  797:     }
  798: 
  799:   return 1;
  800: }
  801: 
  802: int
  803: ospf_if_down (struct ospf_interface *oi)
  804: {
  805:   if (oi == NULL)
  806:     return 0;
  807: 
  808:   OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown);
  809:   /* delete position in router LSA */
  810:   oi->lsa_pos_beg = 0;
  811:   oi->lsa_pos_end = 0;
  812:   /* Shutdown packet reception and sending */
  813:   ospf_if_stream_unset (oi);
  814: 
  815:   return 1;
  816: }
  817: 
  818: 
  819: /* Virtual Link related functions. */
  820: 
  821: struct ospf_vl_data *
  822: ospf_vl_data_new (struct ospf_area *area, struct in_addr vl_peer)
  823: {
  824:   struct ospf_vl_data *vl_data;
  825: 
  826:   vl_data = XCALLOC (MTYPE_OSPF_VL_DATA, sizeof (struct ospf_vl_data));
  827: 
  828:   vl_data->vl_peer.s_addr = vl_peer.s_addr;
  829:   vl_data->vl_area_id = area->area_id;
  830:   vl_data->format = area->format;
  831: 
  832:   return vl_data;
  833: }
  834: 
  835: void
  836: ospf_vl_data_free (struct ospf_vl_data *vl_data)
  837: {
  838:   XFREE (MTYPE_OSPF_VL_DATA, vl_data);
  839: }
  840: 
  841: u_int vlink_count = 0;
  842: 
  843: struct ospf_interface * 
  844: ospf_vl_new (struct ospf *ospf, struct ospf_vl_data *vl_data)
  845: {
  846:   struct ospf_interface * voi;
  847:   struct interface * vi;
  848:   char   ifname[INTERFACE_NAMSIZ + 1];
  849:   struct ospf_area *area;
  850:   struct in_addr area_id;
  851:   struct connected *co;
  852:   struct prefix_ipv4 *p;
  853:   
  854:   if (IS_DEBUG_OSPF_EVENT)
  855:     zlog_debug ("ospf_vl_new(): Start");
  856:   if (vlink_count == OSPF_VL_MAX_COUNT)
  857:     {
  858:       if (IS_DEBUG_OSPF_EVENT)
  859: 	zlog_debug ("ospf_vl_new(): Alarm: "
  860: 		   "cannot create more than OSPF_MAX_VL_COUNT virtual links");
  861:       return NULL;
  862:     }
  863: 
  864:   if (IS_DEBUG_OSPF_EVENT)
  865:     zlog_debug ("ospf_vl_new(): creating pseudo zebra interface");
  866: 
  867:   snprintf (ifname, sizeof(ifname), "VLINK%d", vlink_count);
  868:   vi = if_create (ifname, strnlen(ifname, sizeof(ifname)));
  869:   co = connected_new ();
  870:   co->ifp = vi;
  871:   listnode_add (vi->connected, co);
  872: 
  873:   p = prefix_ipv4_new ();
  874:   p->family = AF_INET;
  875:   p->prefix.s_addr = 0;
  876:   p->prefixlen = 0;
  877:  
  878:   co->address = (struct prefix *)p;
  879:   
  880:   voi = ospf_if_new (ospf, vi, co->address);
  881:   if (voi == NULL)
  882:     {
  883:       if (IS_DEBUG_OSPF_EVENT)
  884: 	zlog_debug ("ospf_vl_new(): Alarm: OSPF int structure is not created");
  885:       return NULL;
  886:     }
  887:   voi->connected = co;
  888:   voi->vl_data = vl_data;
  889:   voi->ifp->mtu = OSPF_VL_MTU;
  890:   voi->type = OSPF_IFTYPE_VIRTUALLINK;
  891: 
  892:   vlink_count++;
  893:   if (IS_DEBUG_OSPF_EVENT)
  894:     zlog_debug ("ospf_vl_new(): Created name: %s", ifname);
  895:   if (IS_DEBUG_OSPF_EVENT)
  896:     zlog_debug ("ospf_vl_new(): set if->name to %s", vi->name);
  897: 
  898:   area_id.s_addr = 0;
  899:   area = ospf_area_get (ospf, area_id, OSPF_AREA_ID_FORMAT_ADDRESS);
  900:   voi->area = area;
  901: 
  902:   if (IS_DEBUG_OSPF_EVENT)
  903:     zlog_debug ("ospf_vl_new(): set associated area to the backbone");
  904: 
  905:   ospf_nbr_add_self (voi);
  906:   ospf_area_add_if (voi->area, voi);
  907: 
  908:   ospf_if_stream_set (voi);
  909: 
  910:   if (IS_DEBUG_OSPF_EVENT)
  911:     zlog_debug ("ospf_vl_new(): Stop");
  912:   return voi;
  913: }
  914: 
  915: static void
  916: ospf_vl_if_delete (struct ospf_vl_data *vl_data)
  917: {
  918:   struct interface *ifp = vl_data->vl_oi->ifp;
  919:   vl_data->vl_oi->address->u.prefix4.s_addr = 0;
  920:   vl_data->vl_oi->address->prefixlen = 0;
  921:   ospf_if_free (vl_data->vl_oi);
  922:   if_delete (ifp);
  923:   vlink_count--;
  924: }
  925: 
  926: /* Look up vl_data for given peer, optionally qualified to be in the
  927:  * specified area. NULL area returns first found..
  928:  */
  929: struct ospf_vl_data *
  930: ospf_vl_lookup (struct ospf *ospf, struct ospf_area *area,
  931:                 struct in_addr vl_peer)
  932: {
  933:   struct ospf_vl_data *vl_data;
  934:   struct listnode *node;
  935:   
  936:   if (IS_DEBUG_OSPF_EVENT)
  937:     {
  938:       zlog_debug ("%s: Looking for %s", __func__, inet_ntoa (vl_peer));
  939:       if (area)
  940:         zlog_debug ("%s: in area %s", __func__, inet_ntoa (area->area_id));
  941:     }
  942:   
  943:   for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
  944:     {
  945:       if (IS_DEBUG_OSPF_EVENT)
  946:         zlog_debug ("%s: VL %s, peer %s", __func__,
  947:                     vl_data->vl_oi->ifp->name,
  948:                     inet_ntoa (vl_data->vl_peer));
  949:       
  950:       if (area && !IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
  951:         continue;
  952:       
  953:       if (IPV4_ADDR_SAME (&vl_data->vl_peer, &vl_peer))
  954:         return vl_data;
  955:     }
  956: 
  957:   return NULL;
  958: }
  959: 
  960: static void 
  961: ospf_vl_shutdown (struct ospf_vl_data *vl_data)
  962: {
  963:   struct ospf_interface *oi;
  964: 
  965:   if ((oi = vl_data->vl_oi) == NULL)
  966:     return;
  967: 
  968:   oi->address->u.prefix4.s_addr = 0;
  969:   oi->address->prefixlen = 0;
  970: 
  971:   UNSET_FLAG (oi->ifp->flags, IFF_UP);
  972:   /* OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceDown); */
  973:   OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown);
  974: }
  975: 
  976: void
  977: ospf_vl_add (struct ospf *ospf, struct ospf_vl_data *vl_data)
  978: {
  979:   listnode_add (ospf->vlinks, vl_data);
  980: #ifdef HAVE_SNMP
  981:   ospf_snmp_vl_add (vl_data);
  982: #endif /* HAVE_SNMP */
  983: }
  984: 
  985: void
  986: ospf_vl_delete (struct ospf *ospf, struct ospf_vl_data *vl_data)
  987: {
  988:   ospf_vl_shutdown (vl_data);
  989:   ospf_vl_if_delete (vl_data);
  990: 
  991: #ifdef HAVE_SNMP
  992:   ospf_snmp_vl_delete (vl_data);
  993: #endif /* HAVE_SNMP */
  994:   listnode_delete (ospf->vlinks, vl_data);
  995: 
  996:   ospf_vl_data_free (vl_data);
  997: }
  998: 
  999: static int
 1000: ospf_vl_set_params (struct ospf_vl_data *vl_data, struct vertex *v)
 1001: {
 1002:   int changed = 0;
 1003:   struct ospf_interface *voi;
 1004:   struct listnode *node;
 1005:   struct vertex_parent *vp = NULL;
 1006:   unsigned int i;
 1007:   struct router_lsa *rl;
 1008: 
 1009:   voi = vl_data->vl_oi;
 1010: 
 1011:   if (voi->output_cost != v->distance)
 1012:     {
 1013:      
 1014:       voi->output_cost = v->distance;
 1015:       changed = 1;
 1016:     }
 1017: 
 1018:   for (ALL_LIST_ELEMENTS_RO (v->parents, node, vp))
 1019:     {
 1020:       vl_data->nexthop.oi = vp->nexthop->oi;
 1021:       vl_data->nexthop.router = vp->nexthop->router;
 1022:       
 1023:       if (!IPV4_ADDR_SAME(&voi->address->u.prefix4,
 1024:                           &vl_data->nexthop.oi->address->u.prefix4))
 1025:         changed = 1;
 1026:         
 1027:       voi->address->u.prefix4 = vl_data->nexthop.oi->address->u.prefix4;
 1028:       voi->address->prefixlen = vl_data->nexthop.oi->address->prefixlen;
 1029: 
 1030:       break; /* We take the first interface. */
 1031:     }
 1032: 
 1033:   rl = (struct router_lsa *)v->lsa;
 1034: 
 1035:   /* use SPF determined backlink index in struct vertex
 1036:    * for virtual link destination address
 1037:    */
 1038:   if (vp && vp->backlink >= 0)
 1039:     {
 1040:       if (!IPV4_ADDR_SAME (&vl_data->peer_addr,
 1041:                            &rl->link[vp->backlink].link_data))
 1042:         changed = 1;
 1043:       vl_data->peer_addr = rl->link[vp->backlink].link_data;
 1044:     }
 1045:   else
 1046:     {
 1047:       /* This is highly odd, there is no backlink index
 1048:        * there should be due to the ospf_spf_has_link() check
 1049:        * in SPF. Lets warn and try pick a link anyway.
 1050:        */
 1051:       zlog_warn ("ospf_vl_set_params: No backlink for %s!",
 1052:                  vl_data->vl_oi->ifp->name);
 1053:       for (i = 0; i < ntohs (rl->links); i++)
 1054:         {
 1055:           switch (rl->link[i].type)
 1056:             {
 1057:               case LSA_LINK_TYPE_VIRTUALLINK:
 1058:                 if (IS_DEBUG_OSPF_EVENT)
 1059:                   zlog_debug ("found back link through VL");
 1060:               case LSA_LINK_TYPE_TRANSIT:
 1061:               case LSA_LINK_TYPE_POINTOPOINT:
 1062:                 if (!IPV4_ADDR_SAME (&vl_data->peer_addr,
 1063:                                      &rl->link[i].link_data))
 1064:                   changed = 1;
 1065:                 vl_data->peer_addr = rl->link[i].link_data;
 1066:             }
 1067:         }
 1068:     }
 1069:     
 1070:   if (IS_DEBUG_OSPF_EVENT)
 1071:     zlog_debug ("%s: %s peer address: %s, cost: %d,%schanged", __func__,
 1072:                vl_data->vl_oi->ifp->name,
 1073:                inet_ntoa(vl_data->peer_addr),
 1074:                voi->output_cost,
 1075:                (changed ? " " : " un"));
 1076:                
 1077:   return changed;
 1078: }
 1079: 
 1080: 
 1081: void
 1082: ospf_vl_up_check (struct ospf_area *area, struct in_addr rid,
 1083:                   struct vertex *v)
 1084: {
 1085:   struct ospf *ospf = area->ospf;
 1086:   struct listnode *node;
 1087:   struct ospf_vl_data *vl_data;
 1088:   struct ospf_interface *oi;
 1089: 
 1090:   if (IS_DEBUG_OSPF_EVENT)
 1091:     {
 1092:       zlog_debug ("ospf_vl_up_check(): Start");
 1093:       zlog_debug ("ospf_vl_up_check(): Router ID is %s", inet_ntoa (rid));
 1094:       zlog_debug ("ospf_vl_up_check(): Area is %s", inet_ntoa (area->area_id));
 1095:     }
 1096: 
 1097:   for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
 1098:     {
 1099:       if (IS_DEBUG_OSPF_EVENT)
 1100: 	{
 1101: 	  zlog_debug ("%s: considering VL, %s in area %s", __func__,
 1102: 		     vl_data->vl_oi->ifp->name,
 1103: 		     inet_ntoa (vl_data->vl_area_id));
 1104: 	  zlog_debug ("%s: peer ID: %s", __func__,
 1105: 		     inet_ntoa (vl_data->vl_peer));
 1106: 	}
 1107: 
 1108:       if (IPV4_ADDR_SAME (&vl_data->vl_peer, &rid) &&
 1109:           IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
 1110:         {
 1111:           oi = vl_data->vl_oi;
 1112:           SET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED);
 1113: 
 1114: 	  if (IS_DEBUG_OSPF_EVENT)
 1115: 	    zlog_debug ("ospf_vl_up_check(): this VL matched");
 1116: 
 1117:           if (oi->state == ISM_Down)
 1118:             {
 1119: 	      if (IS_DEBUG_OSPF_EVENT)
 1120: 		zlog_debug ("ospf_vl_up_check(): VL is down, waking it up");
 1121:               SET_FLAG (oi->ifp->flags, IFF_UP);
 1122:               OSPF_ISM_EVENT_EXECUTE(oi,ISM_InterfaceUp);
 1123:             }
 1124: 
 1125:          if (ospf_vl_set_params (vl_data, v))
 1126:            {
 1127:              if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
 1128:                zlog_debug ("ospf_vl_up_check: VL cost change,"
 1129:                           " scheduling router lsa refresh");
 1130:              if (ospf->backbone)
 1131:                ospf_router_lsa_update_area (ospf->backbone);
 1132:              else if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
 1133:                zlog_debug ("ospf_vl_up_check: VL cost change, no backbone!");
 1134:            }
 1135:         }
 1136:     }
 1137: }
 1138: 
 1139: void
 1140: ospf_vl_unapprove (struct ospf *ospf)
 1141: {
 1142:   struct listnode *node;
 1143:   struct ospf_vl_data *vl_data;
 1144: 
 1145:   for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data))
 1146:     UNSET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED);
 1147: }
 1148: 
 1149: void
 1150: ospf_vl_shut_unapproved (struct ospf *ospf)
 1151: {
 1152:   struct listnode *node, *nnode;
 1153:   struct ospf_vl_data *vl_data;
 1154: 
 1155:   for (ALL_LIST_ELEMENTS (ospf->vlinks, node, nnode, vl_data))
 1156:     if (!CHECK_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED))
 1157:       ospf_vl_shutdown (vl_data);
 1158: }
 1159: 
 1160: int
 1161: ospf_full_virtual_nbrs (struct ospf_area *area)
 1162: {
 1163:   if (IS_DEBUG_OSPF_EVENT)
 1164:     {
 1165:       zlog_debug ("counting fully adjacent virtual neighbors in area %s",
 1166: 		 inet_ntoa (area->area_id));
 1167:       zlog_debug ("there are %d of them", area->full_vls);
 1168:     }
 1169: 
 1170:   return area->full_vls;
 1171: }
 1172: 
 1173: int
 1174: ospf_vls_in_area (struct ospf_area *area)
 1175: {
 1176:   struct listnode *node;
 1177:   struct ospf_vl_data *vl_data;
 1178:   int c = 0;
 1179: 
 1180:   for (ALL_LIST_ELEMENTS_RO (area->ospf->vlinks, node, vl_data))
 1181:     if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
 1182:       c++;
 1183: 
 1184:   return c;
 1185: }
 1186: 
 1187: 
 1188: struct crypt_key *
 1189: ospf_crypt_key_new ()
 1190: {
 1191:   return XCALLOC (MTYPE_OSPF_CRYPT_KEY, sizeof (struct crypt_key));
 1192: }
 1193: 
 1194: void
 1195: ospf_crypt_key_add (struct list *crypt, struct crypt_key *ck)
 1196: {
 1197:   listnode_add (crypt, ck);
 1198: }
 1199: 
 1200: struct crypt_key *
 1201: ospf_crypt_key_lookup (struct list *auth_crypt, u_char key_id)
 1202: {
 1203:   struct listnode *node;
 1204:   struct crypt_key *ck;
 1205: 
 1206:   for (ALL_LIST_ELEMENTS_RO (auth_crypt, node, ck))
 1207:     if (ck->key_id == key_id)
 1208:       return ck;
 1209: 
 1210:   return NULL;
 1211: }
 1212: 
 1213: int
 1214: ospf_crypt_key_delete (struct list *auth_crypt, u_char key_id)
 1215: {
 1216:   struct listnode *node, *nnode;
 1217:   struct crypt_key *ck;
 1218: 
 1219:   for (ALL_LIST_ELEMENTS (auth_crypt, node, nnode, ck))
 1220:     {
 1221:       if (ck->key_id == key_id)
 1222:         {
 1223:           listnode_delete (auth_crypt, ck);
 1224:           XFREE (MTYPE_OSPF_CRYPT_KEY, ck);
 1225:           return 1;
 1226:         }
 1227:     }
 1228: 
 1229:   return 0;
 1230: }
 1231: 
 1232: u_char
 1233: ospf_default_iftype(struct interface *ifp)
 1234: {
 1235:   if (if_is_pointopoint (ifp))
 1236:     return OSPF_IFTYPE_POINTOPOINT;
 1237:   else if (if_is_loopback (ifp))
 1238:     return OSPF_IFTYPE_LOOPBACK;
 1239:   else
 1240:     return OSPF_IFTYPE_BROADCAST;
 1241: }
 1242: 
 1243: void
 1244: ospf_if_init ()
 1245: {
 1246:   /* Initialize Zebra interface data structure. */
 1247:   om->iflist = iflist;
 1248:   if_add_hook (IF_NEW_HOOK, ospf_if_new_hook);
 1249:   if_add_hook (IF_DELETE_HOOK, ospf_if_delete_hook);
 1250: }

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