ospf_interface.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:25k
源码类别:

网络

开发平台:

Unix_Linux

  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. #include <zebra.h>
  23. #include "thread.h"
  24. #include "linklist.h"
  25. #include "prefix.h"
  26. #include "if.h"
  27. #include "table.h"
  28. #include "memory.h"
  29. #include "command.h"
  30. #include "stream.h"
  31. #include "log.h"
  32. #include "ospfd/ospfd.h"
  33. #include "ospfd/ospf_spf.h"
  34. #include "ospfd/ospf_interface.h"
  35. #include "ospfd/ospf_ism.h"
  36. #include "ospfd/ospf_asbr.h"
  37. #include "ospfd/ospf_lsa.h"
  38. #include "ospfd/ospf_lsdb.h"
  39. #include "ospfd/ospf_neighbor.h"
  40. #include "ospfd/ospf_nsm.h"
  41. #include "ospfd/ospf_packet.h"
  42. #include "ospfd/ospf_abr.h"
  43. #include "ospfd/ospf_network.h"
  44. #include "ospfd/ospf_dump.h"
  45. #ifdef HAVE_SNMP
  46. #include "ospfd/ospf_snmp.h"
  47. #endif /* HAVE_SNMP */
  48. int
  49. ospf_if_get_output_cost (struct ospf_interface *oi)
  50. {
  51.   /* If all else fails, use default OSPF cost */
  52.   u_int32_t cost;
  53.   u_int32_t bw, refbw;
  54.   bw = oi->ifp->bandwidth ? oi->ifp->bandwidth : OSPF_DEFAULT_BANDWIDTH;
  55.   refbw = oi->ospf->ref_bandwidth;
  56.   /* A specifed ip ospf cost overrides a calculated one. */
  57.   if (OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (oi->ifp), output_cost_cmd) ||
  58.       OSPF_IF_PARAM_CONFIGURED (oi->params, output_cost_cmd))
  59.     cost = OSPF_IF_PARAM (oi, output_cost_cmd);
  60.   /* See if a cost can be calculated from the zebra processes
  61.      interface bandwidth field. */
  62.   else
  63.     {
  64.       cost = (u_int32_t) ((double)refbw / (double)bw + (double)0.5);
  65.       if (cost < 1)
  66. cost = 1;
  67.       else if (cost > 65535)
  68. cost = 65535;
  69.     }
  70.   return cost;
  71. }
  72. void
  73. ospf_if_recalculate_output_cost (struct interface *ifp)
  74. {
  75.   u_int32_t newcost;
  76.   struct route_node *rn;
  77.   
  78.   for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
  79.     {
  80.       struct ospf_interface *oi;
  81.       
  82.       if ( (oi = rn->info) == NULL)
  83. continue;
  84.       newcost = ospf_if_get_output_cost (oi);
  85.       /* Is actual output cost changed? */
  86.       if (oi->output_cost != newcost)
  87. {
  88.   oi->output_cost = newcost;
  89.   ospf_router_lsa_timer_add (oi->area);
  90. }
  91.     }
  92. }
  93. void
  94. ospf_if_reset_variables (struct ospf_interface *oi)
  95. {
  96.   /* Set default values. */
  97.   /* don't clear this flag.  oi->flag = OSPF_IF_DISABLE; */
  98.   if (oi->vl_data)
  99.     oi->type = OSPF_IFTYPE_VIRTUALLINK;
  100.   else 
  101.   /* preserve network-type */
  102.   if (oi->type != OSPF_IFTYPE_NBMA)
  103.     oi->type = OSPF_IFTYPE_BROADCAST;
  104.   oi->state = ISM_Down;
  105.   oi->crypt_seqnum = 0;
  106.   /* This must be short, (less than RxmtInterval) 
  107.      - RFC 2328 Section 13.5 para 3.  Set to 1 second to avoid Acks being
  108.        held back for too long - MAG */
  109.   oi->v_ls_ack = 1;  
  110. }
  111. void
  112. ospf_add_to_if (struct interface *ifp, struct ospf_interface *oi)
  113. {
  114.   struct route_node *rn;
  115.   struct prefix p;
  116.   p = *oi->address;
  117.   p.prefixlen = IPV4_MAX_PREFIXLEN;
  118.   rn = route_node_get (IF_OIFS (ifp), &p);
  119.   assert (! rn->info);
  120.   rn->info = oi;
  121. }
  122. void
  123. ospf_delete_from_if (struct interface *ifp, struct ospf_interface *oi)
  124. {
  125.   struct route_node *rn;
  126.   struct prefix p;
  127.   p = *oi->address;
  128.   p.prefixlen = IPV4_MAX_PREFIXLEN;
  129.   rn = route_node_lookup (IF_OIFS (oi->ifp), &p);
  130.   assert (rn);
  131.   assert (rn->info);
  132.   rn->info = NULL;
  133.   route_unlock_node (rn);
  134.   route_unlock_node (rn);
  135. }
  136. struct ospf_interface *
  137. ospf_if_new (struct ospf *ospf, struct interface *ifp, struct prefix *p)
  138. {
  139.   struct ospf_interface *oi;
  140.   oi = XCALLOC (MTYPE_OSPF_IF, sizeof (struct ospf_interface));
  141.   memset (oi, 0, sizeof (struct ospf_interface));
  142.   /* Set zebra interface pointer. */
  143.   oi->ifp = ifp;
  144.   oi->address = p;
  145.   
  146.   ospf_add_to_if (ifp, oi);
  147.   listnode_add (ospf->oiflist, oi);
  148.   
  149.   /* Clear self-originated network-LSA. */
  150.   oi->network_lsa_self = NULL;
  151.   /* Initialize neighbor list. */
  152.   oi->nbrs = route_table_init ();
  153.   /* Initialize static neighbor list. */
  154.   oi->nbr_nbma = list_new ();
  155.   /* Initialize Link State Acknowledgment list. */
  156.   oi->ls_ack = list_new ();
  157.   oi->ls_ack_direct.ls_ack = list_new ();
  158.   /* Set default values. */
  159.   ospf_if_reset_variables (oi);
  160.   /* Add pseudo neighbor. */
  161.   oi->nbr_self = ospf_nbr_new (oi);
  162.   oi->nbr_self->state = NSM_TwoWay;
  163.   oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority);
  164.   oi->nbr_self->options = OSPF_OPTION_E;
  165.   oi->ls_upd_queue = route_table_init ();
  166.   oi->t_ls_upd_event = NULL;
  167.   oi->t_ls_ack_direct = NULL;
  168.   oi->crypt_seqnum = time (NULL);
  169. #ifdef HAVE_OPAQUE_LSA
  170.   ospf_opaque_type9_lsa_init (oi);
  171. #endif /* HAVE_OPAQUE_LSA */
  172.   oi->ospf = ospf;
  173.   
  174.   return oi;
  175. }
  176. /* Restore an interface to its pre UP state
  177.    Used from ism_interface_down only */
  178. void
  179. ospf_if_cleanup (struct ospf_interface *oi)
  180. {
  181.   struct route_node *rn;
  182.   listnode node;
  183.   struct ospf_neighbor *nbr;
  184.   /* oi->nbrs and oi->nbr_nbma should be deletete on InterafceDown event */
  185.   /* delete all static neighbors attached to this interface */
  186.   for (node = listhead (oi->nbr_nbma); node; )
  187.     {
  188.       struct ospf_nbr_nbma *nbr_nbma = getdata (node);
  189.       nextnode (node);
  190.       OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);
  191.       if (nbr_nbma->nbr)
  192. {
  193.   nbr_nbma->nbr->nbr_nbma = NULL;
  194.   nbr_nbma->nbr = NULL;
  195. }
  196.       nbr_nbma->oi = NULL;
  197.       
  198.       listnode_delete (oi->nbr_nbma, nbr_nbma);
  199.     }
  200.   /* send Neighbor event KillNbr to all associated neighbors. */
  201.   for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
  202.     if ((nbr = rn->info) != NULL)
  203.       if (nbr != oi->nbr_self)
  204. OSPF_NSM_EVENT_EXECUTE (nbr, NSM_KillNbr);
  205.   /* Cleanup Link State Acknowlegdment list. */
  206.   for (node = listhead (oi->ls_ack); node; nextnode (node))
  207.     ospf_lsa_unlock (node->data);
  208.   list_delete_all_node (oi->ls_ack);
  209.   oi->crypt_seqnum = 0;
  210.   
  211.   /* Empty link state update queue */
  212.   ospf_ls_upd_queue_empty (oi);
  213.   
  214.  /* Handle pseudo neighbor. */
  215.   ospf_nbr_delete (oi->nbr_self);
  216.   oi->nbr_self = ospf_nbr_new (oi);
  217.   oi->nbr_self->state = NSM_TwoWay;
  218.   oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority);
  219.   oi->nbr_self->router_id = oi->ospf->router_id;
  220.   oi->nbr_self->src = oi->address->u.prefix4;
  221.   oi->nbr_self->address = *oi->address;
  222.   switch (oi->area->external_routing)
  223.     {
  224.     case OSPF_AREA_DEFAULT:
  225.       SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
  226.       break;
  227.     case OSPF_AREA_STUB:
  228.       UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
  229.       break;
  230. #ifdef HAVE_NSSA
  231.     case OSPF_AREA_NSSA:
  232.       UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E);
  233.       SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP);
  234.       break;
  235. #endif /* HAVE_NSSA */
  236.     }
  237.   ospf_nbr_add_self (oi);
  238.   ospf_lsa_unlock (oi->network_lsa_self);
  239.   oi->network_lsa_self = NULL;
  240.   OSPF_TIMER_OFF (oi->t_network_lsa_self);
  241. }
  242. void
  243. ospf_if_free (struct ospf_interface *oi)
  244. {
  245.   ospf_if_down (oi);
  246.   assert (oi->state == ISM_Down);
  247. #ifdef HAVE_OPAQUE_LSA
  248.   ospf_opaque_type9_lsa_term (oi);
  249. #endif /* HAVE_OPAQUE_LSA */
  250.   /* Free Pseudo Neighbour */
  251.   ospf_nbr_delete (oi->nbr_self);
  252.   
  253.   route_table_finish (oi->nbrs);
  254.   route_table_finish (oi->ls_upd_queue);
  255.   
  256.   /* Free any lists that should be freed */
  257.   list_free (oi->nbr_nbma);
  258.   
  259.   list_free (oi->ls_ack);
  260.   list_free (oi->ls_ack_direct.ls_ack);
  261.   
  262.   ospf_delete_from_if (oi->ifp, oi);
  263.   listnode_delete (oi->ospf->oiflist, oi);
  264.   listnode_delete (oi->area->oiflist, oi);
  265.   memset (oi, 0, sizeof (*oi));
  266.   XFREE (MTYPE_OSPF_IF, oi);
  267. }
  268. /*
  269. *  check if interface with given address is configured and
  270. *  return it if yes.
  271. */
  272. struct ospf_interface *
  273. ospf_if_is_configured (struct ospf *ospf, struct in_addr *address)
  274. {
  275.   listnode node;
  276.   struct ospf_interface *oi;
  277.   struct prefix *addr;
  278.   
  279.   for (node = listhead (ospf->oiflist); node; nextnode (node))
  280.     if ((oi = getdata (node)) != NULL && oi->type != OSPF_IFTYPE_VIRTUALLINK)
  281.       {
  282. if (oi->type == OSPF_IFTYPE_POINTOPOINT)
  283.   addr = oi->connected->destination;
  284. else
  285.   addr = oi->address;
  286. if (IPV4_ADDR_SAME (address, &addr->u.prefix4))
  287.   return oi;
  288.       }
  289.   return NULL;
  290. }
  291. int
  292. ospf_if_is_up (struct ospf_interface *oi)
  293. {
  294.   return if_is_up (oi->ifp);
  295. }
  296. struct ospf_interface *
  297. ospf_if_lookup_by_local_addr (struct ospf *ospf,
  298.       struct interface *ifp, struct in_addr address)
  299. {
  300.   listnode node;
  301.   struct ospf_interface *oi;
  302.   
  303.   for (node = listhead (ospf->oiflist); node; nextnode (node))
  304.     if ((oi = getdata (node)) != NULL && oi->type != OSPF_IFTYPE_VIRTUALLINK)
  305.       {
  306. if (ifp && oi->ifp != ifp)
  307.   continue;
  308. if (IPV4_ADDR_SAME (&address, &oi->address->u.prefix4))
  309.   return oi;
  310.       }
  311.   return NULL;
  312. }
  313. struct ospf_interface *
  314. ospf_if_lookup_by_prefix (struct ospf *ospf, struct prefix_ipv4 *p)
  315. {
  316.   listnode node;
  317.   struct ospf_interface *oi;
  318.   struct prefix ptmp;
  319.   
  320.   /* Check each Interface. */
  321.   for (node = listhead (ospf->oiflist); node; nextnode (node))
  322.     {
  323.       if ((oi = getdata (node)) != NULL && oi->type != OSPF_IFTYPE_VIRTUALLINK)
  324. {
  325.   if (oi->type == OSPF_IFTYPE_POINTOPOINT)
  326.     {
  327.       prefix_copy (&ptmp, oi->connected->destination);
  328.       ptmp.prefixlen = IPV4_MAX_BITLEN;
  329.     }
  330.   else
  331.     prefix_copy (&ptmp, oi->address);
  332.   apply_mask (&ptmp);
  333.   if (prefix_same (&ptmp, (struct prefix *) p))
  334.     return oi;
  335. }
  336.     }
  337.   return NULL;
  338. }
  339. /* determine receiving interface by source of packet */
  340. struct ospf_interface *
  341. ospf_if_lookup_recv_if (struct ospf *ospf, struct in_addr src)
  342. {
  343.   listnode node;
  344.   struct prefix_ipv4 addr;
  345.   struct ospf_interface *oi, *match;
  346.   addr.family = AF_INET;
  347.   addr.prefix = src;
  348.   addr.prefixlen = IPV4_MAX_BITLEN;
  349.   match = NULL;
  350.   for (node = listhead (ospf->oiflist); node; nextnode (node))
  351.     {
  352.       oi = getdata (node);
  353.       
  354.       if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
  355. continue;
  356.       
  357.       if (oi->type == OSPF_IFTYPE_POINTOPOINT)
  358. {
  359.   if (IPV4_ADDR_SAME (&oi->connected->destination->u.prefix4, &src))
  360.     return oi;
  361. }
  362.       else
  363. {
  364.   if (prefix_match (oi->address, (struct prefix *) &addr))
  365.     match = oi;
  366. }
  367.     }
  368.   return match;
  369. }
  370. void
  371. ospf_if_stream_set (struct ospf_interface *oi)
  372. {
  373.   /* set output fifo queue. */
  374.   if (oi->obuf == NULL) 
  375.     oi->obuf = ospf_fifo_new ();
  376. }
  377. void
  378. ospf_if_stream_unset (struct ospf_interface *oi)
  379. {
  380.   struct ospf *ospf = oi->ospf;
  381.   if (oi->obuf)
  382.     {
  383.      ospf_fifo_free (oi->obuf);
  384.      oi->obuf = NULL;
  385.      if (oi->on_write_q)
  386.        {
  387.  listnode_delete (ospf->oi_write_q, oi);
  388.          if (list_isempty(ospf->oi_write_q))
  389.            OSPF_TIMER_OFF (ospf->t_write);
  390.  oi->on_write_q = 0;
  391.        }
  392.     }
  393. }
  394. struct ospf_if_params *
  395. ospf_new_if_params ()
  396. {
  397.   struct ospf_if_params *oip;
  398.   oip = XMALLOC (MTYPE_OSPF_IF_PARAMS, sizeof (struct ospf_if_params));
  399.   memset (oip, 0, sizeof (struct ospf_if_params));
  400.   if (!oip)
  401.     return NULL;
  402.   memset (oip, 0, sizeof (struct ospf_if_params));
  403.   UNSET_IF_PARAM (oip, output_cost_cmd);
  404.   UNSET_IF_PARAM (oip, transmit_delay);
  405.   UNSET_IF_PARAM (oip, retransmit_interval);
  406.   UNSET_IF_PARAM (oip, passive_interface);
  407.   UNSET_IF_PARAM (oip, v_hello);
  408.   UNSET_IF_PARAM (oip, v_wait);
  409.   UNSET_IF_PARAM (oip, priority);
  410.   UNSET_IF_PARAM (oip, type);
  411.   UNSET_IF_PARAM (oip, auth_simple);
  412.   UNSET_IF_PARAM (oip, auth_crypt);
  413.   UNSET_IF_PARAM (oip, auth_type);
  414.   
  415.   oip->auth_crypt = list_new ();
  416.   return oip;
  417. }
  418. void
  419. ospf_del_if_params (struct ospf_if_params *oip)
  420. {
  421.   list_delete (oip->auth_crypt);
  422.   XFREE (MTYPE_OSPF_IF_PARAMS, oip);
  423. }
  424. void
  425. ospf_free_if_params (struct interface *ifp, struct in_addr addr)
  426. {
  427.   struct ospf_if_params *oip;
  428.   struct prefix_ipv4 p;
  429.   struct route_node *rn;
  430.   p.prefixlen = IPV4_MAX_PREFIXLEN;
  431.   p.prefix = addr;
  432.   rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
  433.   if (!rn || !rn->info)
  434.     return;
  435.   oip = rn->info;
  436.   route_unlock_node (rn);
  437.   
  438.   if (!OSPF_IF_PARAM_CONFIGURED (oip, output_cost_cmd) &&
  439.       !OSPF_IF_PARAM_CONFIGURED (oip, transmit_delay) &&
  440.       !OSPF_IF_PARAM_CONFIGURED (oip, retransmit_interval) &&
  441.       !OSPF_IF_PARAM_CONFIGURED (oip, passive_interface) &&
  442.       !OSPF_IF_PARAM_CONFIGURED (oip, v_hello) &&
  443.       !OSPF_IF_PARAM_CONFIGURED (oip, v_wait) &&
  444.       !OSPF_IF_PARAM_CONFIGURED (oip, priority) &&
  445.       !OSPF_IF_PARAM_CONFIGURED (oip, type) &&
  446.       !OSPF_IF_PARAM_CONFIGURED (oip, auth_simple) &&
  447.       !OSPF_IF_PARAM_CONFIGURED (oip, auth_type) &&
  448.       listcount (oip->auth_crypt) == 0)
  449.     {
  450.       ospf_del_if_params (oip);
  451.       rn->info = NULL;
  452.       route_unlock_node (rn);
  453.     }
  454. }
  455. struct ospf_if_params *
  456. ospf_lookup_if_params (struct interface *ifp, struct in_addr addr)
  457. {
  458.   struct prefix_ipv4 p;
  459.   struct route_node *rn;
  460.   p.prefixlen = IPV4_MAX_PREFIXLEN;
  461.   p.prefix = addr;
  462.   rn = route_node_lookup (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
  463.   
  464.   if (rn)
  465.     {
  466.       route_unlock_node (rn);
  467.       return rn->info;
  468.     }
  469.   return NULL;
  470. }
  471. struct ospf_if_params *
  472. ospf_get_if_params (struct interface *ifp, struct in_addr addr)
  473. {
  474.   struct prefix_ipv4 p;
  475.   struct route_node *rn;
  476.   p.family = AF_INET;
  477.   p.prefixlen = IPV4_MAX_PREFIXLEN;
  478.   p.prefix = addr;
  479.   rn = route_node_get (IF_OIFS_PARAMS (ifp), (struct prefix*)&p);
  480.   
  481.   if (rn->info == NULL)
  482.     rn->info = ospf_new_if_params ();
  483.   else
  484.     route_unlock_node (rn);
  485.   
  486.   return rn->info;
  487. }
  488. void
  489. ospf_if_update_params (struct interface *ifp, struct in_addr addr)
  490. {
  491.   struct route_node *rn;
  492.   struct ospf_interface *oi;
  493.   
  494.   for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
  495.     {
  496.       if ((oi = rn->info) == NULL)
  497. continue;
  498.       if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &addr))
  499. oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4);
  500.     }
  501. }
  502. int
  503. ospf_if_new_hook (struct interface *ifp)
  504. {
  505.   int rc = 0;
  506.   ifp->info = XMALLOC (MTYPE_OSPF_IF_INFO, sizeof (struct ospf_if_info));
  507.   memset (ifp->info, 0, sizeof (struct ospf_if_info));
  508.   
  509.   IF_OIFS (ifp) = route_table_init ();
  510.   IF_OIFS_PARAMS (ifp) = route_table_init ();
  511.   
  512.   IF_DEF_PARAMS (ifp) = ospf_new_if_params ();
  513.   
  514.   SET_IF_PARAM (IF_DEF_PARAMS (ifp), transmit_delay);
  515.   IF_DEF_PARAMS (ifp)->transmit_delay = OSPF_TRANSMIT_DELAY_DEFAULT;
  516.   
  517.   SET_IF_PARAM (IF_DEF_PARAMS (ifp), retransmit_interval);
  518.   IF_DEF_PARAMS (ifp)->retransmit_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
  519.   SET_IF_PARAM (IF_DEF_PARAMS (ifp), priority);
  520.   IF_DEF_PARAMS (ifp)->priority = OSPF_ROUTER_PRIORITY_DEFAULT;
  521.   SET_IF_PARAM (IF_DEF_PARAMS (ifp), passive_interface);
  522.   IF_DEF_PARAMS (ifp)->passive_interface = OSPF_IF_ACTIVE;
  523.   SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_hello);
  524.   IF_DEF_PARAMS (ifp)->v_hello = OSPF_HELLO_INTERVAL_DEFAULT;
  525.   SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_wait);
  526.   IF_DEF_PARAMS (ifp)->v_wait = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
  527.   SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_simple);
  528.   memset (IF_DEF_PARAMS (ifp)->auth_simple, 0, OSPF_AUTH_SIMPLE_SIZE);
  529.   
  530.   SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_crypt);
  531.   IF_DEF_PARAMS (ifp)->auth_crypt = list_new ();
  532.   SET_IF_PARAM (IF_DEF_PARAMS (ifp), auth_type);
  533.   IF_DEF_PARAMS (ifp)->auth_type = OSPF_AUTH_NOTSET;
  534.   
  535. #ifdef HAVE_OPAQUE_LSA
  536.   rc = ospf_opaque_new_if (ifp);
  537. #endif /* HAVE_OPAQUE_LSA */
  538.   return rc;
  539. }
  540. int
  541. ospf_if_delete_hook (struct interface *ifp)
  542. {
  543.   int rc = 0;
  544. #ifdef HAVE_OPAQUE_LSA
  545.   rc = ospf_opaque_del_if (ifp);
  546. #endif /* HAVE_OPAQUE_LSA */
  547.   route_table_finish (IF_OIFS (ifp));
  548.   route_table_finish (IF_OIFS_PARAMS (ifp));
  549.   XFREE (MTYPE_OSPF_IF_INFO, ifp->info);
  550.   ifp->info = NULL;
  551.   return rc;
  552. }
  553. int
  554. ospf_if_is_enable (struct ospf_interface *oi)
  555. {
  556.   if (!if_is_loopback (oi->ifp))
  557.     if (if_is_up (oi->ifp))
  558. return 1;
  559.   return 0;
  560. }
  561. int
  562. ospf_if_up (struct ospf_interface *oi)
  563. {
  564.   if (oi == NULL)
  565.     return 0;
  566.   if (oi->type == OSPF_IFTYPE_LOOPBACK)
  567.     OSPF_ISM_EVENT_SCHEDULE (oi, ISM_LoopInd);
  568.   else
  569.     {
  570.       if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
  571. ospf_if_add_allspfrouters (oi->ospf, oi->address, oi->ifp->ifindex);
  572.       ospf_if_stream_set (oi);
  573.       OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceUp);
  574.     }
  575.   return 1;
  576. }
  577. int
  578. ospf_if_down (struct ospf_interface *oi)
  579. {
  580.   if (oi == NULL)
  581.     return 0;
  582.   OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown);
  583.   /* Shutdown packet reception and sending */
  584.   ospf_if_stream_unset (oi);
  585.   if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
  586.     ospf_if_drop_allspfrouters (oi->ospf, oi->address, oi->ifp->ifindex);
  587.   return 1;
  588. }
  589. /* Virtual Link related functions. */
  590. struct ospf_vl_data *
  591. ospf_vl_data_new (struct ospf_area *area, struct in_addr vl_peer)
  592. {
  593.   struct ospf_vl_data *vl_data;
  594.   vl_data = XMALLOC (MTYPE_OSPF_VL_DATA, sizeof (struct ospf_vl_data));
  595.   memset (vl_data, 0, sizeof (struct ospf_vl_data));
  596.   vl_data->vl_peer.s_addr = vl_peer.s_addr;
  597.   vl_data->vl_area_id = area->area_id;
  598.   vl_data->format = area->format;
  599.   return vl_data;
  600. }
  601. void
  602. ospf_vl_data_free (struct ospf_vl_data *vl_data)
  603. {
  604.   XFREE (MTYPE_OSPF_VL_DATA, vl_data);
  605. }
  606. u_int vlink_count = 0;
  607. struct ospf_interface * 
  608. ospf_vl_new (struct ospf *ospf, struct ospf_vl_data *vl_data)
  609. {
  610.   struct ospf_interface * voi;
  611.   struct interface * vi;
  612.   char   ifname[INTERFACE_NAMSIZ + 1];
  613.   struct ospf_area *area;
  614.   struct in_addr area_id;
  615.   struct connected *co;
  616.   struct prefix_ipv4 *p;
  617.   
  618.   if (IS_DEBUG_OSPF_EVENT)
  619.     zlog_info ("ospf_vl_new(): Start");
  620.   if (vlink_count == OSPF_VL_MAX_COUNT)
  621.     {
  622.       if (IS_DEBUG_OSPF_EVENT)
  623. zlog_info ("ospf_vl_new(): Alarm: "
  624.    "cannot create more than OSPF_MAX_VL_COUNT virtual links");
  625.       return NULL;
  626.     }
  627.   if (IS_DEBUG_OSPF_EVENT)
  628.     zlog_info ("ospf_vl_new(): creating pseudo zebra interface");
  629.   vi = if_create ();
  630.   co = connected_new ();
  631.   co->ifp = vi;
  632.   listnode_add (vi->connected, co);
  633.   p = prefix_ipv4_new ();
  634.   p->family = AF_INET;
  635.   p->prefix.s_addr = 0;
  636.   p->prefixlen = 0;
  637.  
  638.   co->address = (struct prefix *)p;
  639.   
  640.   voi = ospf_if_new (ospf, vi, co->address);
  641.   if (voi == NULL)
  642.     {
  643.       if (IS_DEBUG_OSPF_EVENT)
  644. zlog_info ("ospf_vl_new(): Alarm: OSPF int structure is not created");
  645.       return NULL;
  646.     }
  647.   voi->connected = co;
  648.   voi->vl_data = vl_data;
  649.   voi->ifp->mtu = OSPF_VL_MTU;
  650.   voi->type = OSPF_IFTYPE_VIRTUALLINK;
  651.   sprintf (ifname, "VLINK%d", vlink_count++);
  652.   if (IS_DEBUG_OSPF_EVENT)
  653.     zlog_info ("ospf_vl_new(): Created name: %s", ifname);
  654.   strncpy (vi->name, ifname, IFNAMSIZ);
  655.   if (IS_DEBUG_OSPF_EVENT)
  656.     zlog_info ("ospf_vl_new(): set if->name to %s", vi->name);
  657.   area_id.s_addr = 0;
  658.   area = ospf_area_get (ospf, area_id, OSPF_AREA_ID_FORMAT_ADDRESS);
  659.   voi->area = area;
  660.   if (IS_DEBUG_OSPF_EVENT)
  661.     zlog_info ("ospf_vl_new(): set associated area to the backbone");
  662.   ospf_area_add_if (voi->area, voi);
  663.   ospf_if_stream_set (voi);
  664.   if (IS_DEBUG_OSPF_EVENT)
  665.     zlog_info ("ospf_vl_new(): Stop");
  666.   return voi;
  667. }
  668. void
  669. ospf_vl_if_delete (struct ospf_vl_data *vl_data)
  670. {
  671.   struct interface *ifp = vl_data->vl_oi->ifp;
  672.   vl_data->vl_oi->address->u.prefix4.s_addr = 0;
  673.   vl_data->vl_oi->address->prefixlen = 0;
  674.   ospf_if_free (vl_data->vl_oi);
  675.   if_delete (ifp);
  676.   vlink_count--;
  677. }
  678. struct ospf_vl_data *
  679. ospf_vl_lookup (struct ospf_area *area, struct in_addr vl_peer)
  680. {
  681.   struct ospf_vl_data *vl_data;
  682.   listnode node;
  683.   for (node = listhead (area->ospf->vlinks); node; nextnode (node))
  684.     if ((vl_data = getdata (node)) != NULL)
  685.       if (vl_data->vl_peer.s_addr == vl_peer.s_addr &&
  686.           IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
  687.         return vl_data;
  688.   return NULL;
  689. }
  690. void 
  691. ospf_vl_shutdown (struct ospf_vl_data *vl_data)
  692. {
  693.   struct ospf_interface *oi;
  694.   if ((oi = vl_data->vl_oi) == NULL)
  695.     return;
  696.   oi->address->u.prefix4.s_addr = 0;
  697.   oi->address->prefixlen = 0;
  698.   UNSET_FLAG (oi->ifp->flags, IFF_UP);
  699.   /* OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceDown); */
  700.   OSPF_ISM_EVENT_EXECUTE (oi, ISM_InterfaceDown);
  701. }
  702. void
  703. ospf_vl_add (struct ospf *ospf, struct ospf_vl_data *vl_data)
  704. {
  705.   listnode_add (ospf->vlinks, vl_data);
  706. #ifdef HAVE_SNMP
  707.   ospf_snmp_vl_add (vl_data);
  708. #endif /* HAVE_SNMP */
  709. }
  710. void
  711. ospf_vl_delete (struct ospf *ospf, struct ospf_vl_data *vl_data)
  712. {
  713.   ospf_vl_shutdown (vl_data);
  714.   ospf_vl_if_delete (vl_data);
  715. #ifdef HAVE_SNMP
  716.   ospf_snmp_vl_delete (vl_data);
  717. #endif /* HAVE_SNMP */
  718.   listnode_delete (ospf->vlinks, vl_data);
  719.   ospf_vl_data_free (vl_data);
  720. }
  721. void
  722. ospf_vl_set_params (struct ospf_vl_data *vl_data, struct vertex *v)
  723. {
  724.   int changed = 0;
  725.   struct ospf_interface *voi;
  726.   listnode node;
  727.   struct vertex_nexthop *nh;
  728.   int i;
  729.   struct router_lsa *rl;
  730.   voi = vl_data->vl_oi;
  731.   if (voi->output_cost != v->distance)
  732.     {
  733.       voi->output_cost = v->distance;
  734.       changed = 1;
  735.     }
  736.   for (node = listhead (v->nexthop); node; nextnode (node))
  737.     if ((nh = getdata (node)) != NULL)
  738.       {
  739. vl_data->out_oi = (struct ospf_interface *) nh->oi;
  740. voi->address->u.prefix4 = vl_data->out_oi->address->u.prefix4;
  741. voi->address->prefixlen = vl_data->out_oi->address->prefixlen;
  742. break; /* We take the first interface. */
  743.       }
  744.   rl = (struct router_lsa *)v->lsa;
  745.   
  746.   for (i = 0; i < ntohs (rl->links); i++)
  747.     {
  748.       switch (rl->link[i].type)
  749. {
  750. case LSA_LINK_TYPE_VIRTUALLINK:
  751.   if (IS_DEBUG_OSPF_EVENT)
  752.     zlog_info ("found back link through VL");
  753. case LSA_LINK_TYPE_TRANSIT:
  754. case LSA_LINK_TYPE_POINTOPOINT:
  755.   vl_data->peer_addr = rl->link[i].link_data;
  756.   if (IS_DEBUG_OSPF_EVENT)
  757.     zlog_info ("%s peer address is %sn",
  758.        vl_data->vl_oi->ifp->name, inet_ntoa(vl_data->peer_addr));
  759.   return;
  760. }
  761.     }
  762. }
  763. void
  764. ospf_vl_up_check (struct ospf_area *area, struct in_addr rid,
  765.                   struct vertex *v)
  766. {
  767.   struct ospf *ospf = area->ospf;
  768.   listnode node;
  769.   struct ospf_vl_data *vl_data;
  770.   struct ospf_interface *oi;
  771.   if (IS_DEBUG_OSPF_EVENT)
  772.     {
  773.       zlog_info ("ospf_vl_up_check(): Start");
  774.       zlog_info ("ospf_vl_up_check(): Router ID is %s", inet_ntoa (rid));
  775.       zlog_info ("ospf_vl_up_check(): Area is %s", inet_ntoa (area->area_id));
  776.     }
  777.   for (node = listhead (ospf->vlinks); node; nextnode (node))
  778.     {
  779.       if ((vl_data = getdata (node)) == NULL)
  780.         continue;
  781.   
  782.       if (IS_DEBUG_OSPF_EVENT)
  783. {
  784.   zlog_info ("ospf_vl_up_check(): considering VL, name: %s", 
  785.      vl_data->vl_oi->ifp->name);
  786.   zlog_info ("ospf_vl_up_check(): VL area: %s, peer ID: %s", 
  787.      inet_ntoa (vl_data->vl_area_id),
  788.      inet_ntoa (vl_data->vl_peer));
  789. }
  790.       if (IPV4_ADDR_SAME (&vl_data->vl_peer, &rid) &&
  791.           IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
  792.         {
  793.           oi = vl_data->vl_oi;
  794.           SET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED);
  795.   if (IS_DEBUG_OSPF_EVENT)
  796.     zlog_info ("ospf_vl_up_check(): this VL matched");
  797.           if (oi->state == ISM_Down)
  798.             {
  799.       if (IS_DEBUG_OSPF_EVENT)
  800. zlog_info ("ospf_vl_up_check(): VL is down, waking it up");
  801.               SET_FLAG (oi->ifp->flags, IFF_UP);
  802.               OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceUp);
  803.             }
  804.           ospf_vl_set_params (vl_data, v);
  805.         }
  806.     }
  807. }
  808. void
  809. ospf_vl_unapprove (struct ospf *ospf)
  810. {
  811.   listnode node;
  812.   struct ospf_vl_data *vl_data;
  813.   for (node = listhead (ospf->vlinks); node; nextnode (node))
  814.     if ((vl_data = getdata (node)) != NULL)
  815.       UNSET_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED);
  816. }
  817. void
  818. ospf_vl_shut_unapproved (struct ospf *ospf)
  819. {
  820.   listnode node;
  821.   struct ospf_vl_data *vl_data;
  822.   for (node = listhead (ospf->vlinks); node; nextnode (node))
  823.     if ((vl_data = getdata (node)) != NULL)
  824.       if (!CHECK_FLAG (vl_data->flags, OSPF_VL_FLAG_APPROVED))
  825.         ospf_vl_shutdown (vl_data);
  826. }
  827. int
  828. ospf_full_virtual_nbrs (struct ospf_area *area)
  829. {
  830.   if (IS_DEBUG_OSPF_EVENT)
  831.     {
  832.       zlog_info ("counting fully adjacent virtual neighbors in area %s",
  833.  inet_ntoa (area->area_id));
  834.       zlog_info ("there are %d of them", area->full_vls);
  835.     }
  836.   return area->full_vls;
  837. }
  838. int
  839. ospf_vls_in_area (struct ospf_area *area)
  840. {
  841.   listnode node;
  842.   struct ospf_vl_data *vl_data;
  843.   int c = 0;
  844.   for (node = listhead (area->ospf->vlinks); node; nextnode (node))
  845.     if ((vl_data = getdata (node)) != NULL)
  846.       if (IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id))
  847.         c++;
  848.   return c;
  849. }
  850. struct crypt_key *
  851. ospf_crypt_key_new ()
  852. {
  853.   struct crypt_key *ck;
  854.   ck = XMALLOC (MTYPE_OSPF_CRYPT_KEY, sizeof (struct crypt_key));
  855.   memset (ck, 0, sizeof (struct crypt_key));
  856.   return ck;
  857. }
  858. void
  859. ospf_crypt_key_add (list crypt, struct crypt_key *ck)
  860. {
  861.   listnode_add (crypt, ck);
  862. }
  863. struct crypt_key *
  864. ospf_crypt_key_lookup (list auth_crypt, u_char key_id)
  865. {
  866.   listnode node;
  867.   struct crypt_key *ck;
  868.   for (node = listhead (auth_crypt); node; nextnode (node))
  869.     {
  870.       ck = getdata (node);
  871.       if (ck->key_id == key_id)
  872.         return ck;
  873.     }
  874.   return NULL;
  875. }
  876. int
  877. ospf_crypt_key_delete (list auth_crypt, u_char key_id)
  878. {
  879.   listnode node;
  880.   struct crypt_key *ck;
  881.   for (node = listhead (auth_crypt); node; nextnode (node))
  882.     {
  883.       ck = getdata (node);
  884.       if (ck->key_id == key_id)
  885.         {
  886.           listnode_delete (auth_crypt, ck);
  887.           return 1;
  888.         }
  889.     }
  890.   return 0;
  891. }
  892. void
  893. ospf_if_init ()
  894. {
  895.   /* Initialize Zebra interface data structure. */
  896.   if_init ();
  897.   om->iflist = iflist;
  898.   if_add_hook (IF_NEW_HOOK, ospf_if_new_hook);
  899.   if_add_hook (IF_DELETE_HOOK, ospf_if_delete_hook);
  900. }