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