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