]> git.sommitrealweird.co.uk Git - quagga-debian.git/blob - ospfd/ospf_interface.c
New upstream version 1.2.4
[quagga-debian.git] / ospfd / ospf_interface.c
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 void
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 *
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
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
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 *
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
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
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 *
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
390 ospf_if_is_up (struct ospf_interface *oi)
391 {
392   return if_is_up (oi->ifp);
393 }
394
395 struct ospf_interface *
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 *
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 *
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 *
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 *
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
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
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 *
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
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
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 *
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 *
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
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
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
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
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
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
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
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 *
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
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 * 
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
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 *
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 
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
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
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
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
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
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
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
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
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 *
1217 ospf_crypt_key_new ()
1218 {
1219   return XCALLOC (MTYPE_OSPF_CRYPT_KEY, sizeof (struct crypt_key));
1220 }
1221
1222 void
1223 ospf_crypt_key_add (struct list *crypt, struct crypt_key *ck)
1224 {
1225   listnode_add (crypt, ck);
1226 }
1227
1228 struct crypt_key *
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
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
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
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 }