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