]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospf_lsa.c
Kevin C Miller <kevinm@andrew.cmu.edu>
[mirror_frr.git] / ospfd / ospf_lsa.c
CommitLineData
718e3744 1/*
2 * OSPF Link State Advertisement
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 it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * 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 Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "linklist.h"
26#include "prefix.h"
27#include "if.h"
28#include "table.h"
29#include "memory.h"
30#include "stream.h"
31#include "log.h"
32#include "thread.h"
33#include "hash.h"
34#include "sockunion.h" /* for inet_aton() */
35
36#include "ospfd/ospfd.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_flood.h"
45#include "ospfd/ospf_packet.h"
46#include "ospfd/ospf_spf.h"
47#include "ospfd/ospf_dump.h"
48#include "ospfd/ospf_route.h"
49#include "ospfd/ospf_ase.h"
50#include "ospfd/ospf_zebra.h"
51
52\f
53u_int32_t
54get_metric (u_char *metric)
55{
56 u_int32_t m;
57 m = metric[0];
58 m = (m << 8) + metric[1];
59 m = (m << 8) + metric[2];
60 return m;
61}
62
63\f
64struct timeval
65tv_adjust (struct timeval a)
66{
67 while (a.tv_usec >= 1000000)
68 {
69 a.tv_usec -= 1000000;
70 a.tv_sec++;
71 }
72
73 while (a.tv_usec < 0)
74 {
75 a.tv_usec += 1000000;
76 a.tv_sec--;
77 }
78
79 return a;
80}
81
82int
83tv_ceil (struct timeval a)
84{
85 a = tv_adjust (a);
86
87 return (a.tv_usec ? a.tv_sec + 1 : a.tv_sec);
88}
89
90int
91tv_floor (struct timeval a)
92{
93 a = tv_adjust (a);
94
95 return a.tv_sec;
96}
97
98struct timeval
99int2tv (int a)
100{
101 struct timeval ret;
102
103 ret.tv_sec = a;
104 ret.tv_usec = 0;
105
106 return ret;
107}
108
109struct timeval
110tv_add (struct timeval a, struct timeval b)
111{
112 struct timeval ret;
113
114 ret.tv_sec = a.tv_sec + b.tv_sec;
115 ret.tv_usec = a.tv_usec + b.tv_usec;
116
117 return tv_adjust (ret);
118}
119
120struct timeval
121tv_sub (struct timeval a, struct timeval b)
122{
123 struct timeval ret;
124
125 ret.tv_sec = a.tv_sec - b.tv_sec;
126 ret.tv_usec = a.tv_usec - b.tv_usec;
127
128 return tv_adjust (ret);
129}
130
131int
132tv_cmp (struct timeval a, struct timeval b)
133{
134 return (a.tv_sec == b.tv_sec ?
135 a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
136}
137
138int
139ospf_lsa_refresh_delay (struct ospf_lsa *lsa)
140{
141 struct timeval delta, now;
142 int delay = 0;
143
144 gettimeofday (&now, NULL);
145 delta = tv_sub (now, lsa->tv_orig);
146
147 if (tv_cmp (delta, int2tv (OSPF_MIN_LS_INTERVAL)) < 0)
148 {
149 delay = tv_ceil (tv_sub (int2tv (OSPF_MIN_LS_INTERVAL), delta));
150
151 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
152 zlog_info ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
153 lsa->data->type, inet_ntoa (lsa->data->id), delay);
154
155 assert (delay > 0);
156 }
157
158 return delay;
159}
160
161\f
162int
163get_age (struct ospf_lsa *lsa)
164{
165 int age;
166 struct timeval now;
167
168 gettimeofday (&now, NULL);
169 age = ntohs (lsa->data->ls_age) + tv_floor (tv_sub (now, lsa->tv_recv));
170
171 return age;
172}
173
174\f
175/* Fletcher Checksum -- Refer to RFC1008. */
176#define MODX 4102
177#define LSA_CHECKSUM_OFFSET 15
178
179u_int16_t
180ospf_lsa_checksum (struct lsa_header *lsa)
181{
182 u_char *sp, *ep, *p, *q;
183 int c0 = 0, c1 = 0;
184 int x, y;
185 u_int16_t length;
186
187 lsa->checksum = 0;
188 length = ntohs (lsa->length) - 2;
189 sp = (char *) &lsa->options;
190
191 for (ep = sp + length; sp < ep; sp = q)
192 {
193 q = sp + MODX;
194 if (q > ep)
195 q = ep;
196 for (p = sp; p < q; p++)
197 {
198 c0 += *p;
199 c1 += c0;
200 }
201 c0 %= 255;
202 c1 %= 255;
203 }
204
205 x = ((length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255;
206 if (x <= 0)
207 x += 255;
208 y = 510 - c0 - x;
209 if (y > 255)
210 y -= 255;
211
212 /* take care endian issue. */
213 lsa->checksum = htons ((x << 8) + y);
214
215 return (lsa->checksum);
216}
217
218
219\f
220/* Create OSPF LSA. */
221struct ospf_lsa *
222ospf_lsa_new ()
223{
224 struct ospf_lsa *new;
225
226 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
227 memset (new, 0, sizeof (struct ospf_lsa));
228
229 new->flags = 0;
230 new->lock = 1;
231 new->retransmit_counter = 0;
232 gettimeofday (&new->tv_recv, NULL);
233 new->tv_orig = new->tv_recv;
234 new->refresh_list = -1;
235
236 return new;
237}
238
239/* Duplicate OSPF LSA. */
240struct ospf_lsa *
241ospf_lsa_dup (struct ospf_lsa *lsa)
242{
243 struct ospf_lsa *new;
244
245 if (lsa == NULL)
246 return NULL;
247
248 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
249
250 memcpy (new, lsa, sizeof (struct ospf_lsa));
251 UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
252 new->lock = 1;
253 new->retransmit_counter = 0;
254 new->data = ospf_lsa_data_dup (lsa->data);
255
f2c80652 256 /* kevinm: Clear the refresh_list, otherwise there are going
257 to be problems when we try to remove the LSA from the
258 queue (which it's not a member of.)
259 XXX: Should we add the LSA to the refresh_list queue? */
260 new->refresh_list = -1;
261
262 if (IS_DEBUG_OSPF (lsa, LSA))
263 zlog_info ("LSA: duplicated %p (new: %p)", lsa, new);
264
718e3744 265 return new;
266}
267
268/* Free OSPF LSA. */
269void
270ospf_lsa_free (struct ospf_lsa *lsa)
271{
272 assert (lsa->lock == 0);
273
274 if (IS_DEBUG_OSPF (lsa, LSA))
275 zlog_info ("LSA: freed %p", lsa);
276
277 /* Delete LSA data. */
278 if (lsa->data != NULL)
279 ospf_lsa_data_free (lsa->data);
280
281 assert (lsa->refresh_list < 0);
282
283 memset (lsa, 0, sizeof (struct ospf_lsa));
284 XFREE (MTYPE_OSPF_LSA, lsa);
285}
286
287/* Lock LSA. */
288struct ospf_lsa *
289ospf_lsa_lock (struct ospf_lsa *lsa)
290{
291 lsa->lock++;
292 return lsa;
293}
294
295/* Unlock LSA. */
296void
297ospf_lsa_unlock (struct ospf_lsa *lsa)
298{
299 /* This is sanity check. */
300 if (!lsa)
301 return;
302
303 lsa->lock--;
304
305 assert (lsa->lock >= 0);
306
307 if (lsa->lock == 0)
308 {
309 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD));
310 ospf_lsa_free (lsa);
311 }
312}
313
314/* Check discard flag. */
315void
316ospf_lsa_discard (struct ospf_lsa *lsa)
317{
318 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
319 {
320 SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
321 ospf_lsa_unlock (lsa);
322 }
323}
324
325/* Create LSA data. */
326struct lsa_header *
327ospf_lsa_data_new (size_t size)
328{
329 struct lsa_header *new;
330
331 new = (struct lsa_header *) XMALLOC (MTYPE_OSPF_LSA_DATA, size);
332 memset (new, 0, size);
333
334 return new;
335}
336
337/* Duplicate LSA data. */
338struct lsa_header *
339ospf_lsa_data_dup (struct lsa_header *lsah)
340{
341 struct lsa_header *new;
342
343 new = ospf_lsa_data_new (ntohs (lsah->length));
344 memcpy (new, lsah, ntohs (lsah->length));
345
346 return new;
347}
348
349/* Free LSA data. */
350void
351ospf_lsa_data_free (struct lsa_header *lsah)
352{
353 if (IS_DEBUG_OSPF (lsa, LSA))
354 zlog_info ("LSA[Type%d:%s]: data freed %p",
355 lsah->type, inet_ntoa (lsah->id), lsah);
356
357 XFREE (MTYPE_OSPF_LSA_DATA, lsah);
358}
359
360\f
361/* LSA general functions. */
362
363const char *
364dump_lsa_key (struct ospf_lsa *lsa)
365{
366 static char buf[] = {
367 "Type255,id(255.255.255.255),ar(255.255.255.255)",
368 };
369 struct lsa_header *lsah;
370
371 if (lsa != NULL && (lsah = lsa->data) != NULL)
372 {
373 char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
374 strcpy (id, inet_ntoa (lsah->id));
375 strcpy (ar, inet_ntoa (lsah->adv_router));
376
377 sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
378 }
379 else
380 strcpy (buf, "NULL");
381
382 return buf;
383}
384
385u_int32_t
386lsa_seqnum_increment (struct ospf_lsa *lsa)
387{
388 u_int32_t seqnum;
389
390 seqnum = ntohl (lsa->data->ls_seqnum) + 1;
391
392 return htonl (seqnum);
393}
394
395void
396lsa_header_set (struct stream *s, u_char options,
397 u_char type, struct in_addr id)
398{
399 struct lsa_header *lsah;
400
401 lsah = (struct lsa_header *) STREAM_DATA (s);
402
403 lsah->ls_age = htons (0);
404 lsah->options = options;
405 lsah->type = type;
406 lsah->id = id;
407 lsah->adv_router = ospf_top->router_id;
408 lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
409
410 ospf_output_forward (s, OSPF_LSA_HEADER_SIZE);
411}
412\f
413/* router-LSA related functions. */
414/* Get router-LSA flags. */
415u_char
416router_lsa_flags (struct ospf_area *area)
417{
418 u_char flags;
419
420 flags = ospf_top->flags;
421
422 /* Set virtual link flag. */
423 if (ospf_full_virtual_nbrs (area))
424 SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
425 else
426 /* Just sanity check */
427 UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);
428
429 /* Set Shortcut ABR behabiour flag. */
430 UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
431 if (ospf_top->abr_type == OSPF_ABR_SHORTCUT)
432 if (!OSPF_IS_AREA_BACKBONE (area))
433 if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
434 !ospf_top->backbone) ||
435 area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
436 SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
437
438 /* ASBR can't exit in stub area. */
439 if (area->external_routing == OSPF_AREA_STUB)
440 UNSET_FLAG (flags, OSPF_FLAG_ASBR);
441
442 return flags;
443}
444
445/* Lookup neighbor other than myself.
446 And check neighbor count,
447 Point-to-Point link must have only 1 neighbor. */
448struct ospf_neighbor *
449ospf_nbr_lookup_ptop (struct route_table *nbrs, struct in_addr router_id)
450{
451 struct route_node *rn;
452 struct ospf_neighbor *nbr = NULL;
453
454 /* Search neighbor, there must be one of two nbrs. */
455 for (rn = route_top (nbrs); rn; rn = route_next (rn))
456 if ((nbr = rn->info) != NULL)
457 /* Ignore myself. */
458 if (!IPV4_ADDR_SAME (&nbr->router_id, &ospf_top->router_id))
459 if (nbr->state == NSM_Full)
460 break;
461
462 /* PtoP link must have only 1 neighbor. */
463 if (ospf_nbr_count (nbrs, 0) > 1)
464 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
465
466 return nbr;
467}
468
469/* Set a link information. */
470void
471link_info_set (struct stream *s, struct in_addr id,
472 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
473{
474 /* TOS based routing is not supported. */
475 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
476 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
477 stream_putc (s, type); /* Link Type. */
478 stream_putc (s, tos); /* TOS = 0. */
479 stream_putw (s, cost); /* Link Cost. */
480}
481
482/* Describe Point-to-Point link. */
483int
484lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
485{
486 int links = 0;
487 struct ospf_neighbor *nbr;
488 struct in_addr id, mask;
489
490 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
491 zlog_info ("LSA[Type1]: Set link Point-to-Point");
492
493 if ((nbr = ospf_nbr_lookup_ptop (oi->nbrs, ospf_top->router_id)))
494 if (nbr->state == NSM_Full)
495 {
496 /* For unnumbered point-to-point networks, the Link Data field
497 should specify the interface's MIB-II ifIndex value. */
498 link_info_set (s, nbr->router_id, oi->address->u.prefix4,
499 LSA_LINK_TYPE_POINTOPOINT, 0, oi->output_cost);
500 links++;
501 }
502
503 if (oi->connected->destination != NULL)
504 {
505 /* Option 1:
506 link_type = LSA_LINK_TYPE_STUB;
507 link_id = nbr->address.u.prefix4;
508 link_data.s_addr = 0xffffffff;
509 link_cost = o->output_cost; */
510
511 id.s_addr = oi->connected->destination->u.prefix4.s_addr;
512 mask.s_addr = 0xffffffff;
513 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
514 }
515 else
516 {
517 /* Option 2: We need to include link to a stub
518 network regardless of the state of the neighbor */
519 masklen2ip (oi->address->prefixlen, &mask);
520 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
521 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
522 }
523 links++;
524
525 return links;
526}
527
528/* Describe Broadcast Link. */
529int
530lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
531{
532 struct ospf_neighbor *dr;
533 struct in_addr id, mask;
534
535 /* Describe Type 3 Link. */
536 if (oi->state == ISM_Waiting)
537 {
538 masklen2ip (oi->address->prefixlen, &mask);
539 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
540 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
541 return 1;
542 }
543
544 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
545 /* Describe Type 2 link. */
546 if (dr && (dr->state == NSM_Full ||
547 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
548 ospf_nbr_count (oi->nbrs, NSM_Full) > 0)
549 {
550 link_info_set (s, DR (oi), oi->address->u.prefix4,
551 LSA_LINK_TYPE_TRANSIT, 0, oi->output_cost);
552 }
553 /* Describe type 3 link. */
554 else
555 {
556 masklen2ip (oi->address->prefixlen, &mask);
557 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
558 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
559 }
560 return 1;
561}
562
563int
564lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
565{
566 struct in_addr id, mask;
567
568 /* Describe Type 3 Link. */
569 if (oi->state != ISM_Loopback)
570 return 0;
571
572 mask.s_addr = 0xffffffff;
573 id.s_addr = oi->address->u.prefix4.s_addr;
574 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
575 return 1;
576}
577
578/* Describe Virtual Link. */
579int
580lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
581{
582 struct ospf_neighbor *nbr;
583
584 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
585 zlog_info ("LSA[Type1]: Set link type VL, state %d", oi->state);
586
587 if (oi->state == ISM_PointToPoint)
588 if ((nbr = ospf_nbr_lookup_ptop (oi->nbrs, ospf_top->router_id)))
589 if (nbr->state == NSM_Full)
590 {
591 link_info_set (s, nbr->router_id, oi->address->u.prefix4,
592 LSA_LINK_TYPE_VIRTUALLINK, 0, oi->output_cost);
593 return 1;
594 }
595
596 return 0;
597}
598
599#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
600
7afa08da 601/* this function add for support point-to-multipoint ,see rfc2328
60212.4.1.4.*/
603/* from "edward rrr" <edward_rrr@hotmail.com>
604 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
605int lsa_link_ptomultip_set (struct stream *s, struct ospf_interface *oi)
606{
607 int links = 0;
608 struct route_node *rn;
609 struct ospf_neighbor *nbr = NULL;
610 struct in_addr id, mask;
611
612 mask.s_addr = 0xffffffff;
613 id.s_addr = oi->address->u.prefix4.s_addr;
614 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
615 links++;
616
617 zlog_info ("PointToMultipoint: running ptomultip_set");
618
619 /* Search neighbor, */
620 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
621 if ((nbr = rn->info) != NULL)
622 /* Ignore myself. */
623 if (!IPV4_ADDR_SAME (&nbr->router_id, &ospf_top->router_id))
624 if (nbr->state == NSM_Full)
625
626 {
627
628 link_info_set (s, nbr->router_id, oi->address->u.prefix4,
629 LSA_LINK_TYPE_POINTOPOINT, 0, oi->output_cost);
630 links++;
631 zlog_info ("PointToMultipoint: set link to %s",
632 inet_ntoa(oi->address->u.prefix4));
633 }
634
635 return links;
636
637}
638
718e3744 639/* Set router-LSA link information. */
640int
641router_lsa_link_set (struct stream *s, struct ospf_area *area)
642{
643 listnode node;
644 int links = 0;
645
646 for (node = listhead (area->oiflist); node; node = nextnode (node))
647 {
648 struct ospf_interface *oi = node->data;
649 struct interface *ifp = oi->ifp;
650
651 /* Check interface is up, OSPF is enable. */
2e3b2e47 652 if (if_is_operative (ifp))
718e3744 653 {
654 if (oi->state != ISM_Down)
655 {
656 /* Describe each link. */
657 switch (oi->type)
658 {
659 case OSPF_IFTYPE_POINTOPOINT:
660 links += lsa_link_ptop_set (s, oi);
661 break;
662 case OSPF_IFTYPE_BROADCAST:
663 links += lsa_link_broadcast_set (s, oi);
664 break;
665 case OSPF_IFTYPE_NBMA:
666 links += lsa_link_nbma_set (s, oi);
667 break;
668 case OSPF_IFTYPE_POINTOMULTIPOINT:
7afa08da 669 links += lsa_link_ptomultip_set (s, oi);
718e3744 670 break;
671 case OSPF_IFTYPE_VIRTUALLINK:
672 links += lsa_link_virtuallink_set (s, oi);
673 break;
674 case OSPF_IFTYPE_LOOPBACK:
675 links += lsa_link_loopback_set (s, oi);
676 }
677 }
678 }
679 }
680
681 return links;
682}
683
684/* Set router-LSA body. */
685void
686ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
687{
688 unsigned long putp;
689 u_int16_t cnt;
690
691 /* Set flags. */
692 stream_putc (s, router_lsa_flags (area));
693
694 /* Set Zero fields. */
695 stream_putc (s, 0);
696
697 /* Keep pointer to # links. */
698 putp = s->putp;
699
700 /* Forward word */
701 stream_putw(s, 0);
702
703 /* Set all link information. */
704 cnt = router_lsa_link_set (s, area);
705
706 /* Set # of links here. */
707 stream_putw_at (s, putp, cnt);
708}
709
710/* Create new router-LSA. */
711struct ospf_lsa *
712ospf_router_lsa_new (struct ospf_area *area)
713{
714 struct stream *s;
715 struct lsa_header *lsah;
716 struct ospf_lsa *new;
717 int length;
718
719 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
720 zlog_info ("LSA[Type1]: Create router-LSA instance");
721
722 /* Create a stream for LSA. */
723 s = stream_new (OSPF_MAX_LSA_SIZE);
724 lsah = (struct lsa_header *) STREAM_DATA (s);
725
726#ifdef HAVE_NSSA
727 /* Set LSA common header fields. */
728 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_NSSA_GET (area),
729 OSPF_ROUTER_LSA, ospf_top->router_id);
730#else /* ! HAVE_NSSA */
731 /* Set LSA common header fields. */
732 lsa_header_set (s, LSA_OPTIONS_GET (area),
733 OSPF_ROUTER_LSA, ospf_top->router_id);
734#endif /* HAVE_NSSA */
735
736 /* Set router-LSA body fields. */
737 ospf_router_lsa_body_set (s, area);
738
739 /* Set length. */
740 length = stream_get_endp (s);
741 lsah->length = htons (length);
742
743 /* Now, create OSPF LSA instance. */
744 new = ospf_lsa_new ();
745 new->area = area;
746 SET_FLAG (new->flags, OSPF_LSA_SELF);
747
748 /* Copy LSA data to store, discard stream. */
749 new->data = ospf_lsa_data_new (length);
750 memcpy (new->data, lsah, length);
751 stream_free (s);
752
753 return new;
754}
755
756/* Originate Router-LSA. */
757struct ospf_lsa *
758ospf_router_lsa_originate (struct ospf_area *area)
759{
760 struct ospf_lsa *new;
761
762 /* Create new router-LSA instance. */
763 new = ospf_router_lsa_new (area);
764
765 /* Sanity check. */
766 if (new->data->adv_router.s_addr == 0)
767 {
768 if (IS_DEBUG_OSPF_EVENT)
769 zlog_info ("LSA[Type1]: AdvRouter is 0, discard");
770 ospf_lsa_discard (new);
771 return NULL;
772 }
773
774 /* Install LSA to LSDB. */
775 new = ospf_lsa_install (NULL, new);
776
777 /* Update LSA origination count. */
778 ospf_top->lsa_originate_count++;
779
780 /* Flooding new LSA through area. */
781 ospf_flood_through_area (area, NULL, new);
782
783 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
784 {
785 zlog_info ("LSA[Type%d:%s]: Originate router-LSA %p",
786 new->data->type, inet_ntoa (new->data->id), new);
787 ospf_lsa_header_dump (new->data);
788 }
789
790 return new;
791}
792
793/* Refresh router-LSA. */
794struct ospf_lsa *
795ospf_router_lsa_refresh (struct ospf_lsa *lsa)
796{
797 struct ospf_area *area = lsa->area;
798 struct ospf_lsa *new;
799
800 /* Sanity check. */
801 assert (lsa->data);
802
803 /* Delete LSA from neighbor retransmit-list. */
804 ospf_ls_retransmit_delete_nbr_all (area, lsa);
805
806 /* Create new router-LSA instance. */
807 new = ospf_router_lsa_new (area);
808 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
809
810 ospf_lsa_install (NULL, new);
811
812 /* Flood LSA through area. */
813 ospf_flood_through_area (area, NULL, new);
814
815 /* Debug logging. */
816 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
817 {
818 zlog_info ("LSA[Type%d:%s]: router-LSA refresh",
819 new->data->type, inet_ntoa (new->data->id));
820 ospf_lsa_header_dump (new->data);
821 }
822
823 return NULL;
824}
825
826int
827ospf_router_lsa_timer (struct thread *t)
828{
829 struct ospf_area *area;
830
831 if (IS_DEBUG_OSPF_EVENT)
832 zlog_info ("Timer[router-LSA]: (router-LSA Refresh expire)");
833
834 area = THREAD_ARG (t);
835 area->t_router_lsa_self = NULL;
836
837 /* Now refresh router-LSA. */
838 if (area->router_lsa_self)
839 ospf_router_lsa_refresh (area->router_lsa_self);
840 /* Newly originate router-LSA. */
841 else
842 ospf_router_lsa_originate (area);
843
844 return 0;
845}
846
847void
848ospf_router_lsa_timer_add (struct ospf_area *area)
849{
850 /* Keep area's self-originated router-LSA. */
851 struct ospf_lsa *lsa = area->router_lsa_self;
852
853 /* Cancel previously scheduled router-LSA timer. */
854 if (area->t_router_lsa_self)
855 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
856 zlog_info ("LSA[Type1]: Cancel previous router-LSA timer");
857
858 OSPF_TIMER_OFF (area->t_router_lsa_self);
859
860 /* If router-LSA is originated previously, check the interval time. */
861 if (lsa)
862 {
863 int delay;
864 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
865 {
866 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
867 ospf_router_lsa_timer, delay);
868 return;
869 }
870 }
871
872 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
873 zlog_info ("LSA[Type1]: Scheduling router-LSA origination right away");
874
875 /* Immediately refresh router-LSA. */
876 OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
877}
878
879int
880ospf_router_lsa_update_timer (struct thread *t)
881{
882 listnode node;
883
884 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
885 zlog_info ("Timer[router-LSA Update]: (timer expire)");
886
887 ospf_top->t_router_lsa_update = NULL;
888
889 for (node = listhead (ospf_top->areas); node; nextnode (node))
890 {
891 struct ospf_area *area = getdata (node);
892 struct ospf_lsa *lsa = area->router_lsa_self;
893 struct router_lsa *rl;
894 char *area_str;
895
896 /* Keep Area ID string. */
897 area_str = AREA_NAME (area);
898
899 /* If LSA not exist in this Area, originate new. */
900 if (lsa == NULL)
901 {
902 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
903 zlog_info("LSA[Type1]: Create router-LSA for Area %s", area_str);
904
905 ospf_router_lsa_originate (area);
906 }
907 /* If router-ID is changed, Link ID must change.
908 First flush old LSA, then originate new. */
909 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf_top->router_id))
910 {
911 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
912 zlog_info("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
913 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
914 ospf_lsa_flush_area (lsa, area);
915 ospf_lsa_unlock (area->router_lsa_self);
916 area->router_lsa_self = NULL;
917
918 /* Refresh router-LSA, (not install) and flood through area. */
919 ospf_router_lsa_timer_add (area);
920 }
921 else
922 {
923 rl = (struct router_lsa *) lsa->data;
924 /* Refresh router-LSA, (not install) and flood through area. */
925 if (rl->flags != ospf_top->flags)
926 ospf_router_lsa_timer_add (area);
927 }
928 }
929
930 return 0;
931}
932
933\f
934/* network-LSA related functions. */
935/* Originate Network-LSA. */
936void
937ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
938{
939 struct in_addr mask;
940 struct route_node *rn;
941 struct ospf_neighbor *nbr;
942
943 masklen2ip (oi->address->prefixlen, &mask);
944 stream_put_ipv4 (s, mask.s_addr);
945
946 /* The network-LSA lists those routers that are fully adjacent to
947 the Designated Router; each fully adjacent router is identified by
948 its OSPF Router ID. The Designated Router includes itself in this
949 list. RFC2328, Section 12.4.2 */
950
951 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
952 if ((nbr = rn->info) != NULL)
953 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
954 stream_put_ipv4 (s, nbr->router_id.s_addr);
955}
956
957struct ospf_lsa *
958ospf_network_lsa_new (struct ospf_interface *oi)
959{
960 struct stream *s;
961 struct ospf_lsa *new;
962 struct lsa_header *lsah;
963 int length;
964
965 /* If there are no neighbours on this network (the net is stub),
966 the router does not originate network-LSA (see RFC 12.4.2) */
967 if (oi->full_nbrs == 0)
968 return NULL;
969
970 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
971 zlog_info ("LSA[Type2]: Create network-LSA instance");
972
973 /* Create new stream for LSA. */
974 s = stream_new (OSPF_MAX_LSA_SIZE);
975 lsah = (struct lsa_header *) STREAM_DATA (s);
976
977 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
978 OSPF_NETWORK_LSA, DR (oi));
979
980 /* Set network-LSA body fields. */
981 ospf_network_lsa_body_set (s, oi);
982
983 /* Set length. */
984 length = stream_get_endp (s);
985 lsah->length = htons (length);
986
987 /* Create OSPF LSA instance. */
988 new = ospf_lsa_new ();
989 new->area = oi->area;
990 SET_FLAG (new->flags, OSPF_LSA_SELF);
991
992 /* Copy LSA to store. */
993 new->data = ospf_lsa_data_new (length);
994 memcpy (new->data, lsah, length);
995 stream_free (s);
996
997 return new;
998}
999
1000/* Originate network-LSA. */
1001struct ospf_lsa *
1002ospf_network_lsa_originate (struct ospf_interface *oi)
1003{
1004 struct ospf_lsa *new;
1005
1006 /* Create new network-LSA instance. */
1007 new = ospf_network_lsa_new (oi);
1008 if (new == NULL)
1009 return NULL;
1010
1011 /* Install LSA to LSDB. */
1012 new = ospf_lsa_install (oi, new);
1013
1014 /* Update LSA origination count. */
1015 ospf_top->lsa_originate_count++;
1016
1017 /* Flooding new LSA through area. */
1018 ospf_flood_through_area (oi->area, NULL, new);
1019
1020 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1021 {
1022 zlog_info ("LSA[Type%d:%s]: Originate network-LSA %p",
1023 new->data->type, inet_ntoa (new->data->id), new);
1024 ospf_lsa_header_dump (new->data);
1025 }
1026
1027 return new;
1028}
1029
1030int
1031ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1032{
1033 struct ospf_area *area = lsa->area;
1034 struct ospf_lsa *new;
1035
1036 assert (lsa->data);
1037
1038 /* Delete LSA from neighbor retransmit-list. */
1039 ospf_ls_retransmit_delete_nbr_all (area, lsa);
1040
1041 /* Create new network-LSA instance. */
1042 new = ospf_network_lsa_new (oi);
1043 if (new == NULL)
1044 return -1;
1045 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1046
1047 ospf_lsa_install (oi, new);
1048
1049 /* Flood LSA through aera. */
1050 ospf_flood_through_area (area, NULL, new);
1051
1052 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1053 {
1054 zlog_info ("LSA[Type%d:%s]: network-LSA refresh",
1055 new->data->type, inet_ntoa (new->data->id));
1056 ospf_lsa_header_dump (new->data);
1057 }
1058
1059 return 0;
1060}
1061
1062int
1063ospf_network_lsa_refresh_timer (struct thread *t)
1064{
1065 struct ospf_interface *oi;
1066
1067 oi = THREAD_ARG (t);
1068 oi->t_network_lsa_self = NULL;
1069
1070 if (oi->network_lsa_self)
1071 /* Now refresh network-LSA. */
1072 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1073 else
1074 /* Newly create network-LSA. */
1075 ospf_network_lsa_originate (oi);
1076
1077 return 0;
1078}
1079
1080void
1081ospf_network_lsa_timer_add (struct ospf_interface *oi)
1082{
1083 /* Keep interface's self-originated network-LSA. */
1084 struct ospf_lsa *lsa = oi->network_lsa_self;
1085
1086 /* Cancel previously schedules network-LSA timer. */
1087 if (oi->t_network_lsa_self)
1088 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1089 zlog_info ("LSA[Type2]: Cancel previous network-LSA timer");
1090 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1091
1092 /* If network-LSA is originated previously, check the interval time. */
1093 if (lsa)
1094 {
1095 int delay;
1096 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1097 {
1098 oi->t_network_lsa_self =
1099 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1100 oi, delay);
1101 return;
1102 }
1103 }
1104
1105 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1106 zlog_info ("Scheduling network-LSA origination right away");
1107
1108 /* Immediately refresh network-LSA. */
1109 oi->t_network_lsa_self =
1110 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1111}
1112
1113\f
1114void
1115stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1116{
1117 u_int32_t metric;
1118 char *mp;
1119
1120 /* Put 0 metric. TOS metric is not supported. */
1121 metric = htonl (metric_value);
1122 mp = (char *) &metric;
1123 mp++;
1124 stream_put (s, mp, 3);
1125}
1126
1127/* summary-LSA related functions. */
1128void
1129ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1130 u_int32_t metric)
1131{
1132 struct in_addr mask;
1133
1134 masklen2ip (p->prefixlen, &mask);
1135
1136 /* Put Network Mask. */
1137 stream_put_ipv4 (s, mask.s_addr);
1138
1139 /* Set # TOS. */
1140 stream_putc (s, (u_char) 0);
1141
1142 /* Set metric. */
1143 stream_put_ospf_metric (s, metric);
1144}
1145
1146struct ospf_lsa *
1147ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1148 u_int32_t metric, struct in_addr id)
1149{
1150 struct stream *s;
1151 struct ospf_lsa *new;
1152 struct lsa_header *lsah;
1153 int length;
1154
1155 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1156 zlog_info ("LSA[Type3]: Create summary-LSA instance");
1157
1158 /* Create new stream for LSA. */
1159 s = stream_new (OSPF_MAX_LSA_SIZE);
1160 lsah = (struct lsa_header *) STREAM_DATA (s);
1161
1162 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA, id);
1163
1164 /* Set summary-LSA body fields. */
1165 ospf_summary_lsa_body_set (s, p, metric);
1166
1167 /* Set length. */
1168 length = stream_get_endp (s);
1169 lsah->length = htons (length);
1170
1171 /* Create OSPF LSA instance. */
1172 new = ospf_lsa_new ();
1173 new->area = area;
1174 SET_FLAG (new->flags, OSPF_LSA_SELF);
1175
1176 /* Copy LSA to store. */
1177 new->data = ospf_lsa_data_new (length);
1178 memcpy (new->data, lsah, length);
1179 stream_free (s);
1180
1181 return new;
1182}
1183
1184/* Originate Summary-LSA. */
1185struct ospf_lsa *
1186ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1187 struct ospf_area *area)
1188{
1189 struct ospf_lsa *new;
1190 struct in_addr id;
1191
1192 id = ospf_lsa_unique_id (area->lsdb, OSPF_SUMMARY_LSA, p);
1193
1194 /* Create new summary-LSA instance. */
1195 new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id);
1196
1197 /* Instlal LSA to LSDB. */
1198 new = ospf_lsa_install (NULL, new);
1199
1200 /* Update LSA origination count. */
1201 ospf_top->lsa_originate_count++;
1202
1203 /* Flooding new LSA through area. */
1204 ospf_flood_through_area (area, NULL, new);
1205
1206 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1207 {
1208 zlog_info ("LSA[Type%d:%s]: Originate summary-LSA %p",
1209 new->data->type, inet_ntoa (new->data->id), new);
1210 ospf_lsa_header_dump (new->data);
1211 }
1212
1213 return new;
1214}
1215
1216struct ospf_lsa*
1217ospf_summary_lsa_refresh (struct ospf_lsa *lsa)
1218{
1219 struct ospf_lsa *new;
1220 struct summary_lsa *sl;
1221 struct prefix p;
1222
1223 /* Sanity check. */
1224 assert (lsa->data);
1225
1226 sl = (struct summary_lsa *)lsa->data;
1227 p.prefixlen = ip_masklen (sl->mask);
1228 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1229 sl->header.id);
1230
1231 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1232
1233 /* Re-calculate checksum. */
1234 ospf_lsa_checksum (new->data);
1235
1236 ospf_lsa_install (NULL, new);
1237
1238 /* Flood LSA through AS. */
1239 ospf_flood_through_area (new->area, NULL, new);
1240
1241 /* Debug logging. */
1242 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1243 {
1244 zlog_info ("LSA[Type%d:%s]: summary-LSA refresh",
1245 new->data->type, inet_ntoa (new->data->id));
1246 ospf_lsa_header_dump (new->data);
1247 }
1248
1249 return new;
1250}
1251
1252\f
1253/* summary-ASBR-LSA related functions. */
1254void
1255ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1256 u_int32_t metric)
1257{
1258 struct in_addr mask;
1259
1260 masklen2ip (p->prefixlen, &mask);
1261
1262 /* Put Network Mask. */
1263 stream_put_ipv4 (s, mask.s_addr);
1264
1265 /* Set # TOS. */
1266 stream_putc (s, (u_char) 0);
1267
1268 /* Set metric. */
1269 stream_put_ospf_metric (s, metric);
1270}
1271
1272struct ospf_lsa *
1273ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1274 u_int32_t metric, struct in_addr id)
1275{
1276 struct stream *s;
1277 struct ospf_lsa *new;
1278 struct lsa_header *lsah;
1279 int length;
1280
1281 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1282 zlog_info ("LSA[Type3]: Create summary-LSA instance");
1283
1284 /* Create new stream for LSA. */
1285 s = stream_new (OSPF_MAX_LSA_SIZE);
1286 lsah = (struct lsa_header *) STREAM_DATA (s);
1287
1288 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA, id);
1289
1290 /* Set summary-LSA body fields. */
1291 ospf_summary_asbr_lsa_body_set (s, p, metric);
1292
1293 /* Set length. */
1294 length = stream_get_endp (s);
1295 lsah->length = htons (length);
1296
1297 /* Create OSPF LSA instance. */
1298 new = ospf_lsa_new ();
1299 new->area = area;
1300 SET_FLAG (new->flags, OSPF_LSA_SELF);
1301
1302 /* Copy LSA to store. */
1303 new->data = ospf_lsa_data_new (length);
1304 memcpy (new->data, lsah, length);
1305 stream_free (s);
1306
1307 return new;
1308}
1309
1310/* Originate summary-ASBR-LSA. */
1311struct ospf_lsa *
1312ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1313 struct ospf_area *area)
1314{
1315 struct ospf_lsa *new;
1316 struct in_addr id;
1317
1318 id = ospf_lsa_unique_id (area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
1319
1320 /* Create new summary-LSA instance. */
1321 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
1322
1323 /* Install LSA to LSDB. */
1324 new = ospf_lsa_install (NULL, new);
1325
1326 /* Update LSA origination count. */
1327 ospf_top->lsa_originate_count++;
1328
1329 /* Flooding new LSA through area. */
1330 ospf_flood_through_area (area, NULL, new);
1331
1332 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1333 {
1334 zlog_info ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
1335 new->data->type, inet_ntoa (new->data->id), new);
1336 ospf_lsa_header_dump (new->data);
1337 }
1338
1339 return new;
1340}
1341
1342struct ospf_lsa*
1343ospf_summary_asbr_lsa_refresh (struct ospf_lsa *lsa)
1344{
1345 struct ospf_lsa *new;
1346 struct summary_lsa *sl;
1347 struct prefix p;
1348
1349 /* Sanity check. */
1350 assert (lsa->data);
1351
1352 sl = (struct summary_lsa *)lsa->data;
1353 p.prefixlen = ip_masklen (sl->mask);
1354 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1355 sl->header.id);
1356
1357 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1358
1359 /* Re-calculate checksum. */
1360 ospf_lsa_checksum (new->data);
1361
1362 ospf_lsa_install (NULL, new);
1363
1364 /* Flood LSA through area. */
1365 ospf_flood_through_area (new->area, NULL, new);
1366
1367 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1368 {
1369 zlog_info ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
1370 new->data->type, inet_ntoa (new->data->id));
1371 ospf_lsa_header_dump (new->data);
1372 }
1373
1374 return new;
1375}
1376
1377/* AS-external-LSA related functions. */
1378
1379/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1380 is connected, else 0*/
1381struct in_addr
1382ospf_external_lsa_nexthop_get (struct in_addr nexthop)
1383{
1384 struct in_addr fwd;
1385 struct prefix nh;
1386 /* struct route_node *rn; */
1387 listnode n1;
1388
1389 fwd.s_addr = 0;
1390
1391 if (!nexthop.s_addr)
1392 return fwd;
1393
1394 /* Check whether nexthop is covered by OSPF network. */
1395 nh.family = AF_INET;
1396 nh.u.prefix4 = nexthop;
1397 nh.prefixlen = IPV4_MAX_BITLEN;
1398
1399 for (n1 = listhead (ospf_top->oiflist); n1; nextnode (n1))
1400 {
1401 struct ospf_interface *oi = getdata (n1);
1402
2e3b2e47 1403 if (if_is_operative (oi->ifp))
718e3744 1404 if (oi->address->family == AF_INET)
1405 if (prefix_match (oi->address, &nh))
1406 return nexthop;
1407 }
1408
1409 return fwd;
1410}
1411
1412#ifdef HAVE_NSSA
1413/* NSSA-external-LSA related functions. */
1414
1415/* Get 1st IP connection for Forward Addr */
1416
1417struct in_addr
1418ospf_get_ip_from_ifp (struct ospf_interface *oi)
1419{
1420 struct in_addr fwd;
1421
1422 fwd.s_addr = 0;
1423
2e3b2e47 1424 if (if_is_operative (oi->ifp))
718e3744 1425 return oi->address->u.prefix4;
1426
1427 return fwd;
1428}
1429
1430/* Get 1st IP connection for Forward Addr */
1431struct in_addr
f2c80652 1432ospf_get_nssa_ip (struct ospf_area *area)
718e3744 1433{
1434 struct in_addr fwd;
f2c80652 1435 struct in_addr best_default;
718e3744 1436 listnode n1;
1437
1438 fwd.s_addr = 0;
f2c80652 1439 best_default.s_addr = 0;
718e3744 1440
1441
1442 for (n1 = listhead (ospf_top->oiflist); n1; nextnode (n1))
1443 {
1444 struct ospf_interface *oi = getdata (n1);
1445
2e3b2e47 1446 if (if_is_operative (oi->ifp))
718e3744 1447 if (oi->area->external_routing == OSPF_AREA_NSSA)
f2c80652 1448 if (oi->address && oi->address->family == AF_INET) {
1449 if (best_default.s_addr == 0) {
1450 best_default = oi->address->u.prefix4;
1451 }
1452 if (oi->area == area)
1453 return (oi->address->u.prefix4);
1454 }
718e3744 1455 }
f2c80652 1456 if (best_default.s_addr != 0)
1457 return best_default;
718e3744 1458
1459 return fwd;
1460}
1461#endif /* HAVE_NSSA */
1462\f
1463#define DEFAULT_DEFAULT_METRIC 20
1464#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1465#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1466
1467#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1468
1469int
1470metric_type (u_char src)
1471{
1472 return (ospf_top->dmetric[src].type < 0 ?
1473 DEFAULT_METRIC_TYPE : ospf_top->dmetric[src].type);
1474}
1475
1476int
1477metric_value (u_char src)
1478{
1479 if (ospf_top->dmetric[src].value < 0)
1480 {
1481 if (src == DEFAULT_ROUTE)
1482 {
1483 if (ospf_top->default_originate == DEFAULT_ORIGINATE_ZEBRA)
1484 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1485 else
1486 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1487 }
1488 else if (ospf_top->default_metric < 0)
1489 return DEFAULT_DEFAULT_METRIC;
1490 else
1491 return ospf_top->default_metric;
1492 }
1493
1494 return ospf_top->dmetric[src].value;
1495}
1496
1497/* Set AS-external-LSA body. */
1498void
1499ospf_external_lsa_body_set (struct stream *s, struct external_info *ei)
1500{
1501 struct prefix_ipv4 *p = &ei->p;
1502 struct in_addr mask, fwd_addr;
1503 u_int32_t mvalue;
1504 int mtype;
1505 int type;
1506
1507 /* Put Network Mask. */
1508 masklen2ip (p->prefixlen, &mask);
1509 stream_put_ipv4 (s, mask.s_addr);
1510
1511 /* If prefix is default, specify DEFAULT_ROUTE. */
1512 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1513
1514 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
1515 ROUTEMAP_METRIC_TYPE (ei) : metric_type (type);
1516
1517 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
1518 ROUTEMAP_METRIC (ei) : metric_value (type);
1519
1520 /* Put type of external metric. */
1521 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1522
1523 /* Put 0 metric. TOS metric is not supported. */
1524 stream_put_ospf_metric (s, mvalue);
1525
1526 /* Get forwarding address to nexthop if on the Connection List, else 0. */
1527 fwd_addr = ospf_external_lsa_nexthop_get (ei->nexthop);
1528
1529 /* Put forwarding address. */
1530 stream_put_ipv4 (s, fwd_addr.s_addr);
1531
1532 /* Put route tag -- This value should be introduced from configuration. */
1533 stream_putl (s, 0);
1534}
1535
1536/* Create new external-LSA. */
1537struct ospf_lsa *
1538ospf_external_lsa_new (struct external_info *ei, struct in_addr *old_id)
1539{
1540 struct stream *s;
1541 struct lsa_header *lsah;
1542 struct ospf_lsa *new;
1543 struct in_addr id;
1544 int length;
1545
1546 if (ei == NULL)
1547 {
1548 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1549 zlog_warn ("LSA[Type5]: External info is NULL, could not originated");
1550 return NULL;
1551 }
1552
1553 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1554 zlog_info ("LSA[Type5]: Originate AS-external-LSA instance");
1555
1556 /* If old Link State ID is specified, refresh LSA with same ID. */
1557 if (old_id)
1558 id = *old_id;
1559 /* Get Link State with unique ID. */
1560 else
1561 {
1562 id = ospf_lsa_unique_id (ospf_top->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
1563 if (id.s_addr == 0xffffffff)
1564 {
1565 /* Maybe Link State ID not available. */
1566 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1567 zlog_info ("LSA[Type5]: Link ID not available, can't originate");
1568 return NULL;
1569 }
1570 }
1571
1572 /* Create new stream for LSA. */
1573 s = stream_new (OSPF_MAX_LSA_SIZE);
1574 lsah = (struct lsa_header *) STREAM_DATA (s);
1575
1576 /* Set LSA common header fields. */
1577 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA, id);
1578
1579 /* Set AS-external-LSA body fields. */
1580 ospf_external_lsa_body_set (s, ei);
1581
1582 /* Set length. */
1583 length = stream_get_endp (s);
1584 lsah->length = htons (length);
1585
1586 /* Now, create OSPF LSA instance. */
1587 new = ospf_lsa_new ();
1588 new->area = NULL;
1589 SET_FLAG (new->flags, OSPF_LSA_SELF|OSPF_LSA_APPROVED);
1590
1591 /* Copy LSA data to store, discard stream. */
1592 new->data = ospf_lsa_data_new (length);
1593 memcpy (new->data, lsah, length);
1594 stream_free (s);
1595
1596 return new;
1597}
1598
1599#ifdef HAVE_NSSA
1600/* Set AS-external-LSA body test. */
1601void
1602ospf_external_lsa_body_test (struct stream *s)
1603{
1604 struct in_addr mask, fwd_addr;
1605 u_int32_t mvalue = 0;
1606 /* int mtype;
1607 int type; */
1608
1609 mask.s_addr = 0;
1610 fwd_addr.s_addr = 0;
1611
1612 /* Put Network Mask. */
1613 /* masklen2ip (p->prefixlen, &mask); */
1614 stream_put_ipv4 (s, mask.s_addr);
1615
1616 /* If prefix is default, specify DEFAULT_ROUTE. */
1617 /* type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1618
1619 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
1620 ROUTEMAP_METRIC_TYPE (ei) : metric_type (type);
1621
1622 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
1623 ROUTEMAP_METRIC (ei) : metric_value (type); */
1624
1625 /* Put type of external metric. */
1626 stream_putc (s, 0);
1627
1628 /* Put 0 metric. TOS metric is not supported. */
1629 stream_put_ospf_metric (s, mvalue);
1630
1631
1632 /* fwd_addr = ospf_top->router_id; */
1633
1634 /* OLD == ospf_external_lsa_nexthop_get (ei->nexthop); */
1635
1636 /* Put forwarding address. */
1637 /* stream_put_ipv4 (s, fwd_addr.s_addr); */
1638 stream_put_ipv4 (s, ospf_top->router_id.s_addr);
1639
1640 /* Put route tag -- This value should be introduced from configuration. */
1641 stream_putl (s, 0);
1642}
1643
1644/* As Type-7 */
1645void
1646ospf_install_flood_nssa (struct ospf_lsa *lsa, struct external_info *ei)
1647{
1648 struct ospf_lsa *new2;
f2c80652 1649 struct as_external_lsa *extlsa, *newextlsa;
1650 listnode node;
718e3744 1651
1652 /* NSSA Originate or Refresh (If anyNSSA)
1653
1654 LSA is self-originated. And just installed as Type-5.
1655 Additionally, install as Type-7 LSDB for every attached NSSA.
1656
1657 P-Bit controls which ABR performs translation to outside world; If
1658 we are an ABR....do not set the P-bit, because we send the Type-5,
1659 not as the ABR Translator, but as the ASBR owner within the AS!
1660
1661 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1662 elected ABR Translator will see the P-bit, Translate, and re-flood.
1663
1664 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1665 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1666
f2c80652 1667 for (node = listhead (ospf_top->areas); node; nextnode (node)) {
1668
1669 struct ospf_area *area = getdata (node);
718e3744 1670
f2c80652 1671 /* make lsa duplicate, lock=1 */
1672 new2 = ospf_lsa_dup(lsa);
718e3744 1673
f2c80652 1674 /* make type-7 */
1675 new2->data->type = OSPF_AS_NSSA_LSA;
718e3744 1676
f2c80652 1677 /* set P-bit if not ABR */
1678 if (! OSPF_IS_ABR)
1679 {
1680 SET_FLAG(new2->data->options, OSPF_OPTION_NP);
1681
1682 /* set non-zero FWD ADDR
1683
1684 draft-ietf-ospf-nssa-update-09.txt
1685
1686 if the network between the NSSA AS boundary router and the
1687 adjacent AS is advertised into OSPF as an internal OSPF route,
1688 the forwarding address should be the next op address as is cu
1689 currently done with type-5 LSAs. If the intervening network is
1690 not adversited into OSPF as an internal OSPF route and the
1691 type-7 LSA's P-bit is set a forwarding address should be
1692 selected from one of the router's active OSPF inteface addresses
1693 which belong to the NSSA. If no such addresses exist, then
1694 no type-7 LSA's with the P-bit set should originate from this
1695 router. */
1696
1697 /* not updating lsa anymore, just new2 */
1698 extlsa = (struct as_external_lsa *)(new2->data);
1699
1700 if (extlsa->e[0].fwd_addr.s_addr == 0)
1701 /* this NSSA area in ifp */
1702 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area);
1703
1704 if (IS_DEBUG_OSPF_NSSA)
1705 if (extlsa->e[0].fwd_addr.s_addr == 0)
1706 {
1707 zlog_info ("LSA[Type-7]: Could not build FWD-ADDR");
1708 ospf_lsa_discard(new2);
1709 return;
1710 }
1711 }
718e3744 1712
f2c80652 1713 /* Re-calculate checksum. */
1714 ospf_lsa_checksum (new2->data);
718e3744 1715
f2c80652 1716 /* install also as Type-7 */
1717 ospf_lsa_install (NULL, new2); /* Remove Old, Lock New = 2 */
718e3744 1718
f2c80652 1719 /* will send each copy, lock=2+n */
1720 ospf_flood_through_as (NULL, new2); /* all attached NSSA's, no AS/STUBs */
1721 }
718e3744 1722
1723 /* last send, lock=2 LSA is now permanent in Type-7 LSDB */
1724 /* It has the same ID as it's Type-5 Counter-Part */
1725
1726}
1727#endif /* HAVE_NSSA */
1728
1729int
1730is_prefix_default (struct prefix_ipv4 *p)
1731{
1732 struct prefix_ipv4 q;
1733
1734 q.family = AF_INET;
1735 q.prefix.s_addr = 0;
1736 q.prefixlen = 0;
1737
1738 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
1739}
1740
1741/* Originate an AS-external-LSA, install and flood. */
1742struct ospf_lsa *
1743ospf_external_lsa_originate (struct external_info *ei)
1744{
1745 struct ospf_lsa *new;
1746
1747 /* Added for NSSA project....
1748
1749 External LSAs are originated in ASBRs as usual, but for NSSA systems.
1750 there is the global Type-5 LSDB and a Type-7 LSDB installed for
1751 every area. The Type-7's are flooded to every IR and every ABR; We
1752 install the Type-5 LSDB so that the normal "refresh" code operates
1753 as usual, and flag them as not used during ASE calculations. The
1754 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
1755 Address of non-zero.
1756
1757 If an ABR is the elected NSSA translator, following SPF and during
1758 the ABR task it will translate all the scanned Type-7's, with P-bit
1759 ON and not-self generated, and translate to Type-5's throughout the
1760 non-NSSA/STUB AS.
1761
1762 A difference in operation depends whether this ASBR is an ABR
1763 or not. If not an ABR, the P-bit is ON, to indicate that any
1764 elected NSSA-ABR can perform its translation.
1765
1766 If an ABR, the P-bit is OFF; No ABR will perform translation and
1767 this ASBR will flood the Type-5 LSA as usual.
1768
1769 For the case where this ASBR is not an ABR, the ASE calculations
1770 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
1771 demonstrate to the user that there are LSA's that belong to any
1772 attached NSSA.
1773
1774 Finally, it just so happens that when the ABR is translating every
1775 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
1776 approved Type-5 (translated from Type-7); at the end of translation
1777 if any Translated Type-5's remain unapproved, then they must be
1778 flushed from the AS.
1779
1780 */
1781
1782 /* Check the AS-external-LSA should be originated. */
1783 if (!ospf_redistribute_check (ei, NULL))
1784 return NULL;
1785
1786 /* Create new AS-external-LSA instance. */
1787 if ((new = ospf_external_lsa_new (ei, NULL)) == NULL)
1788 {
1789 if (IS_DEBUG_OSPF_EVENT)
1790 zlog_info ("LSA[Type5:%s]: Could not originate AS-external-LSA",
1791 inet_ntoa (ei->p.prefix));
1792 return NULL;
1793 }
1794
1795 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
1796 ospf_lsa_install (NULL, new);
1797
1798 /* Update LSA origination count. */
1799 ospf_top->lsa_originate_count++;
1800
1801 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
1802 ospf_flood_through_as (NULL, new);
1803
1804#ifdef HAVE_NSSA
1805 /* If there is any attached NSSA, do special handling */
1806 if (ospf_top->anyNSSA)
1807 ospf_install_flood_nssa (new, ei); /* Install/Flood Type-7 to all NSSAs */
1808#endif /* HAVE_NSSA */
1809
1810 /* Debug logging. */
1811 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1812 {
1813 zlog_info ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
1814 new->data->type, inet_ntoa (new->data->id), new);
1815 ospf_lsa_header_dump (new->data);
1816 }
1817
1818 return new;
1819}
1820
1821/* Originate AS-external-LSA from external info with initial flag. */
1822int
1823ospf_external_lsa_originate_timer (struct thread *t)
1824{
1825 struct route_node *rn;
1826 struct external_info *ei;
1827 struct route_table *rt;
1828 int type;
1829
1830 ospf_top->t_external_lsa = NULL;
1831 type = THREAD_VAL (t);
1832
1833 /* Originate As-external-LSA from all type of distribute source. */
1834 if ((rt = EXTERNAL_INFO (type)))
1835 for (rn = route_top (rt); rn; rn = route_next (rn))
1836 if ((ei = rn->info) != NULL)
1837 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
1838 if (!ospf_external_lsa_originate (ei))
1839 zlog_warn ("LSA: AS-external-LSA was not originated.");
1840
1841 return 0;
1842}
1843
1844struct external_info *
1845ospf_default_external_info ()
1846{
1847 int type;
1848 struct route_node *rn;
1849 struct prefix_ipv4 p;
1850
1851 p.family = AF_INET;
1852 p.prefix.s_addr = 0;
1853 p.prefixlen = 0;
1854
1855 /* First, lookup redistributed default route. */
1856 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
1857 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
1858 {
1859 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
1860 if (rn != NULL)
1861 {
1862 route_unlock_node (rn);
1863 assert (rn->info);
1864 if (ospf_redistribute_check (rn->info, NULL))
1865 return rn->info;
1866 }
1867 }
1868
1869 return NULL;
1870}
1871
1872int
1873ospf_default_originate_timer (struct thread *t)
1874{
1875 int *origin;
1876 struct prefix_ipv4 p;
1877 struct in_addr nexthop;
1878 struct external_info *ei;
1879
1880 /* Get originate flags. */
1881 origin = THREAD_ARG (t);
1882
1883 p.family = AF_INET;
1884 p.prefix.s_addr = 0;
1885 p.prefixlen = 0;
1886
1887 if (*origin == DEFAULT_ORIGINATE_ALWAYS)
1888 {
1889 /* If there is no default route via redistribute,
1890 then originate AS-external-LSA with nexthop 0 (self). */
1891 nexthop.s_addr = 0;
1892 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
1893 }
1894
1895 if ((ei = ospf_default_external_info ()))
1896 ospf_external_lsa_originate (ei);
1897
1898 return 0;
1899}
1900
1901/* Flush an AS-external-LSA from LSDB and routing domain. */
1902void
1903ospf_external_lsa_flush (u_char type, struct prefix_ipv4 *p,
1904 unsigned int ifindex, struct in_addr nexthop)
1905{
1906 struct ospf_lsa *lsa;
1907
1908 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
1909 zlog_info ("LSA: Flushing AS-external-LSA %s/%d",
1910 inet_ntoa (p->prefix), p->prefixlen);
1911
1912 /* First lookup LSA from LSDB. */
1913 if (!(lsa = ospf_external_info_find_lsa (p)))
1914 {
1915 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
1916 zlog_warn ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
1917 inet_ntoa (p->prefix), p->prefixlen);
1918 return;
1919 }
1920
1921 /* Sweep LSA from Link State Retransmit List. */
1922 ospf_ls_retransmit_delete_nbr_all (NULL, lsa);
1923
1924 /* There must be no self-originated LSA in rtrs_external. */
1925#if 0
1926 /* Remove External route from Zebra. */
1927 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
1928#endif
1929
1930 if (!IS_LSA_MAXAGE (lsa))
1931 {
1932 /* Unregister LSA from Refresh queue. */
1933 ospf_refresher_unregister_lsa (ospf_top, lsa);
1934
1935 /* Flush AS-external-LSA through AS. */
1936 ospf_flush_through_as (lsa);
1937 }
1938
1939 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
1940 zlog_info ("ospf_external_lsa_flush(): stop");
1941}
1942
1943void
1944ospf_external_lsa_refresh_default ()
1945{
1946 struct prefix_ipv4 p;
1947 struct external_info *ei;
1948 struct ospf_lsa *lsa;
1949
1950 p.family = AF_INET;
1951 p.prefixlen = 0;
1952 p.prefix.s_addr = 0;
1953
1954 ei = ospf_default_external_info ();
1955 lsa = ospf_external_info_find_lsa (&p);
1956
1957 if (ei)
1958 {
1959 if (lsa)
1960 {
1961 if (IS_DEBUG_OSPF_EVENT)
1962 zlog_info ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
1963 ospf_external_lsa_refresh (lsa, ei, LSA_REFRESH_FORCE);
1964 }
1965 else
1966 {
1967 if (IS_DEBUG_OSPF_EVENT)
1968 zlog_info ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
1969 ospf_external_lsa_originate (ei);
1970 }
1971 }
1972 else
1973 {
1974 if (lsa)
1975 {
1976 if (IS_DEBUG_OSPF_EVENT)
1977 zlog_info ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
1978 ospf_lsa_flush_as (lsa);
1979 }
1980 }
1981}
1982
1983void
1984ospf_external_lsa_refresh_type (u_char type, int force)
1985{
1986 struct route_node *rn;
1987 struct external_info *ei;
1988
1989 if (type != DEFAULT_ROUTE)
1990 if (EXTERNAL_INFO(type))
1991 /* Refresh each redistributed AS-external-LSAs. */
1992 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
1993 if ((ei = rn->info))
1994 if (!is_prefix_default (&ei->p))
1995 {
1996 struct ospf_lsa *lsa;
1997
1998 if ((lsa = ospf_external_info_find_lsa (&ei->p)))
1999 ospf_external_lsa_refresh (lsa, ei, force);
2000 else
2001 ospf_external_lsa_originate (ei);
2002 }
2003}
2004
2005/* Refresh AS-external-LSA. */
2006void
2007ospf_external_lsa_refresh (struct ospf_lsa *lsa,
2008 struct external_info *ei, int force)
2009{
2010 struct ospf_lsa *new;
2011 int changed;
2012
2013 /* Check the AS-external-LSA should be originated. */
2014 if (!ospf_redistribute_check (ei, &changed))
2015 {
2016 ospf_external_lsa_flush (ei->type, &ei->p, ei->ifindex, ei->nexthop);
2017 return;
2018 }
2019
2020 if (!changed && !force)
2021 return;
2022
2023 /* Delete LSA from neighbor retransmit-list. */
2024 ospf_ls_retransmit_delete_nbr_all (NULL, lsa);
2025
2026 /* Unregister AS-external-LSA from refresh-list. */
2027 ospf_refresher_unregister_lsa (ospf_top, lsa);
2028
2029 new = ospf_external_lsa_new (ei, &lsa->data->id);
2030
2031 if (new == NULL)
2032 {
2033 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2034 zlog_warn ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
2035 inet_ntoa (lsa->data->id));
2036 return;
2037 }
2038
2039 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2040
2041 /* Record timestamp. */
2042 gettimeofday (&new->tv_orig, NULL);
2043
2044 /* Re-calculate checksum. */
2045 ospf_lsa_checksum (new->data);
2046
2047 ospf_lsa_install (NULL, new); /* As type-5. */
2048
2049 /* Flood LSA through AS. */
2050 ospf_flood_through_as (NULL, new);
2051
2052#ifdef HAVE_NSSA
2053 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
2054 if (ospf_top->anyNSSA)
2055 ospf_install_flood_nssa (new, ei); /* Install/Flood per new rules */
2056#endif /* HAVE_NSSA */
2057
2058 /* Register slef-originated LSA to refresh queue. */
2059 ospf_refresher_register_lsa (ospf_top, new);
2060
2061 /* Debug logging. */
2062 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2063 {
2064 zlog_info ("LSA[Type%d:%s]: AS-external-LSA refresh",
2065 new->data->type, inet_ntoa (new->data->id));
2066 ospf_lsa_header_dump (new->data);
2067 }
2068
2069 return;
2070}
2071
2072\f
2073/* LSA installation functions. */
2074
2075/* Install router-LSA to an area. */
2076struct ospf_lsa *
2077ospf_router_lsa_install (struct ospf_lsa *new, int rt_recalc)
2078{
2079 struct ospf_area *area = new->area;
2080
2081 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2082 The entire routing table must be recalculated, starting with
2083 the shortest path calculations for each area (not just the
2084 area whose link-state database has changed).
2085 */
2086 if (rt_recalc)
2087 ospf_spf_calculate_schedule();
2088
2089 if (IS_LSA_SELF (new))
2090 {
2091 /* Set router-LSA refresh timer. */
2092 OSPF_TIMER_OFF (area->t_router_lsa_self);
2093 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
2094 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
2095
2096 /* Set self-originated router-LSA. */
2097 ospf_lsa_unlock (area->router_lsa_self);
2098 area->router_lsa_self = ospf_lsa_lock (new);
2099
2100 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2101 zlog_info("LSA[Type%d]: ID %s is self-originated",
2102 new->data->type, inet_ntoa (new->data->id));
2103 }
2104
2105 return new;
2106}
2107
2108#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2109 if (!(T)) \
2110 (T) = thread_add_timer (master, (F), oi, (V))
2111
2112/* Install network-LSA to an area. */
2113struct ospf_lsa *
2114ospf_network_lsa_install (struct ospf_interface *oi,
2115 struct ospf_lsa *new,
2116 int rt_recalc)
2117{
2118
2119 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2120 The entire routing table must be recalculated, starting with
2121 the shortest path calculations for each area (not just the
2122 area whose link-state database has changed).
2123 */
2124 if (rt_recalc)
2125 ospf_spf_calculate_schedule();
2126
2127 /* We supposed that when LSA is originated by us, we pass the int
2128 for which it was originated. If LSA was received by flooding,
2129 the RECEIVED flag is set, so we do not link the LSA to the int. */
2130 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2131 {
2132 /* Set LSRefresh timer. */
2133 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2134
2135 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2136 ospf_network_lsa_refresh_timer,
2137 OSPF_LS_REFRESH_TIME);
2138
2139 ospf_lsa_unlock (oi->network_lsa_self);
2140 oi->network_lsa_self = ospf_lsa_lock (new);
2141 }
2142
2143 return new;
2144}
2145
2146/* Install summary-LSA to an area. */
2147struct ospf_lsa *
2148ospf_summary_lsa_install (struct ospf_lsa *new, int rt_recalc)
2149{
2150
2151 if (rt_recalc && !IS_LSA_SELF (new))
2152 {
2153 /* RFC 2328 Section 13.2 Summary-LSAs
2154 The best route to the destination described by the summary-
2155 LSA must be recalculated (see Section 16.5). If this
2156 destination is an AS boundary router, it may also be
2157 necessary to re-examine all the AS-external-LSAs.
2158 */
2159
2160#if 0
2161 /* This doesn't exist yet... */
2162 ospf_summary_incremental_update(new); */
2163#else /* #if 0 */
2164 ospf_spf_calculate_schedule();
2165#endif /* #if 0 */
2166
2167 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2168 zlog_info ("ospf_summary_lsa_install(): SPF scheduled");
2169 }
2170
2171 if (IS_LSA_SELF (new))
2172 ospf_refresher_register_lsa (ospf_top, new);
2173
2174 return new;
2175}
2176
2177/* Install ASBR-summary-LSA to an area. */
2178struct ospf_lsa *
2179ospf_summary_asbr_lsa_install (struct ospf_lsa *new, int rt_recalc)
2180{
2181 if (rt_recalc && !IS_LSA_SELF (new))
2182 {
2183 /* RFC 2328 Section 13.2 Summary-LSAs
2184 The best route to the destination described by the summary-
2185 LSA must be recalculated (see Section 16.5). If this
2186 destination is an AS boundary router, it may also be
2187 necessary to re-examine all the AS-external-LSAs.
2188 */
2189#if 0
2190 /* These don't exist yet... */
2191 ospf_summary_incremental_update(new);
2192 /* Isn't this done by the above call?
2193 - RFC 2328 Section 16.5 implies it should be */
2194 /* ospf_ase_calculate_schedule(); */
2195#else /* #if 0 */
2196 ospf_spf_calculate_schedule();
2197#endif /* #if 0 */
2198 }
2199
2200 /* register LSA to refresh-list. */
2201 if (IS_LSA_SELF (new))
2202 ospf_refresher_register_lsa (ospf_top, new);
2203
2204 return new;
2205}
2206
2207/* Install AS-external-LSA. */
2208struct ospf_lsa *
2209ospf_external_lsa_install (struct ospf_lsa *new, int rt_recalc)
2210{
2211 ospf_ase_register_external_lsa (new, ospf_top);
2212 /* If LSA is not self-originated, calculate an external route. */
2213 if (rt_recalc)
2214 {
2215 /* RFC 2328 Section 13.2 AS-external-LSAs
2216 The best route to the destination described by the AS-
2217 external-LSA must be recalculated (see Section 16.6).
2218 */
2219
2220 if (!IS_LSA_SELF (new))
2221 ospf_ase_incremental_update (new, ospf_top);
2222 }
2223
2224 /* Register self-originated LSA to refresh queue. */
2225 if (IS_LSA_SELF (new))
2226 ospf_refresher_register_lsa (ospf_top, new);
2227
2228 return new;
2229}
2230
2231void
2232ospf_discard_from_db (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
2233{
2234 struct ospf_lsa *old;
2235
2236 old = ospf_lsdb_lookup (lsdb, lsa);
2237
2238 if (!old)
2239 return;
2240
2241 if (old->refresh_list >= 0)
2242 ospf_refresher_unregister_lsa (ospf_top, old);
2243
2244 ospf_ls_retransmit_delete_nbr_all (old->area, old);
2245
2246 switch (old->data->type)
2247 {
2248 case OSPF_AS_EXTERNAL_LSA:
2249#ifdef HAVE_OPAQUE_LSA
2250 case OSPF_OPAQUE_AS_LSA:
2251#endif /* HAVE_OPAQUE_LSA */
2252 ospf_ase_unregister_external_lsa (old, ospf_top);
2253 break;
2254 default:
2255 break;
2256 }
2257
2258 ospf_lsa_maxage_delete (old);
2259 ospf_lsa_discard (old);
2260}
2261
2262/* callback for foreach_lsa */
2263int
2264ospf_lsa_discard_callback (struct ospf_lsa *lsa, void *p, int i)
2265{
2266#ifdef HAVE_NSSA
2267 /* Removed: Stay away from any Local Translated Type-7 LSAs */
2268 /* if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2269 return 0; */
2270#endif /* HAVE_NSSA */
2271 ospf_discard_from_db ((struct ospf_lsdb *)p, lsa);
2272 return 0;
2273}
2274
2275struct ospf_lsa *
2276ospf_lsa_install (struct ospf_interface *oi, struct ospf_lsa *lsa)
2277{
2278 struct ospf_lsa *new = NULL;
2279 struct ospf_lsa *old = NULL;
2280 struct ospf_lsdb *lsdb = NULL;
2281 int rt_recalc;
2282
2283 /* Set LSDB. */
2284 switch (lsa->data->type)
2285 {
f2c80652 2286 /* kevinm */
2287 case OSPF_AS_NSSA_LSA:
2288 if (lsa->area)
2289 lsdb = lsa->area->lsdb;
2290 else
2291 lsdb = ospf_top->lsdb;
2292 break;
718e3744 2293 case OSPF_AS_EXTERNAL_LSA:
2294#ifdef HAVE_OPAQUE_LSA
2295 case OSPF_OPAQUE_AS_LSA:
2296#endif /* HAVE_OPAQUE_LSA */
2297 lsdb = ospf_top->lsdb;
2298 break;
2299 default:
2300 lsdb = lsa->area->lsdb;
2301 break;
2302 }
2303
2304#ifdef HAVE_NSSA
2305 if (IS_DEBUG_OSPF_NSSA)
2306 {
2307 zlog_info ("LSA[Installing]: Type-%d ", lsa->data->type);
2308
2309 if (lsa->data->type == OSPF_AS_NSSA_LSA )
2310 zlog_info ("NSSA LSA AREA = %s", inet_ntoa (lsa->area->area_id));
2311 }
2312#endif /* HAVE_NSSA */
2313
2314 assert (lsdb);
2315
2316 /* RFC 2328 13.2. Installing LSAs in the database
2317
2318 Installing a new LSA in the database, either as the result of
2319 flooding or a newly self-originated LSA, may cause the OSPF
2320 routing table structure to be recalculated. The contents of the
2321 new LSA should be compared to the old instance, if present. If
2322 there is no difference, there is no need to recalculate the
2323 routing table. When comparing an LSA to its previous instance,
2324 the following are all considered to be differences in contents:
2325
2326 o The LSA's Options field has changed.
2327
2328 o One of the LSA instances has LS age set to MaxAge, and
2329 the other does not.
2330
2331 o The length field in the LSA header has changed.
2332
2333 o The body of the LSA (i.e., anything outside the 20-byte
2334 LSA header) has changed. Note that this excludes changes
2335 in LS Sequence Number and LS Checksum.
2336
2337 */
2338 /* Look up old LSA and determine if any SPF calculation or incremental
2339 update is needed */
2340 old = ospf_lsdb_lookup (lsdb, lsa);
2341
2342 /* Do comparision and record if recalc needed. */
2343 rt_recalc = 0;
2344 if ( old == NULL || ospf_lsa_different(old, lsa))
2345 rt_recalc = 1;
2346
2347 /* discard old LSA from LSDB */
2348 if (old != NULL)
2349 ospf_discard_from_db (lsdb, lsa);
2350
2351 /* Insert LSA to LSDB. */
2352 ospf_lsdb_add (lsdb, lsa);
2353 lsa->lsdb = lsdb;
2354
2355 /* Calculate Checksum if self-originated?. */
2356 if (IS_LSA_SELF (lsa))
2357 ospf_lsa_checksum (lsa->data);
2358
2359 /* Do LSA specific installation process. */
2360 switch (lsa->data->type)
2361 {
2362 case OSPF_ROUTER_LSA:
2363 new = ospf_router_lsa_install (lsa, rt_recalc);
2364 break;
2365 case OSPF_NETWORK_LSA:
2366 assert (oi);
2367 new = ospf_network_lsa_install (oi, lsa, rt_recalc);
2368 break;
2369 case OSPF_SUMMARY_LSA:
2370 new = ospf_summary_lsa_install (lsa, rt_recalc);
2371 break;
2372 case OSPF_ASBR_SUMMARY_LSA:
2373 new = ospf_summary_asbr_lsa_install (lsa, rt_recalc);
2374 break;
2375 case OSPF_AS_EXTERNAL_LSA:
2376 new = ospf_external_lsa_install (lsa, rt_recalc);
2377 break;
2378#ifdef HAVE_OPAQUE_LSA
2379 case OSPF_OPAQUE_LINK_LSA:
2380 case OSPF_OPAQUE_AREA_LSA:
2381 case OSPF_OPAQUE_AS_LSA:
2382 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2383 break;
2384#endif /* HAVE_OPAQUE_LSA */
2385 default: /* NSSA, or type-6,8,9....nothing special */
2386#ifdef HAVE_NSSA
2387 new = ospf_external_lsa_install (lsa, rt_recalc);
2388#endif /* HAVE_NSSA */
2389 break;
2390 }
2391
2392 if (new == NULL)
2393 return new; /* Installation failed, cannot proceed further -- endo. */
2394
2395 /* Debug logs. */
2396 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2397 {
2398 char area_str[INET_ADDRSTRLEN];
2399
2400 switch (lsa->data->type)
2401 {
2402 case OSPF_AS_EXTERNAL_LSA:
2403#ifdef HAVE_OPAQUE_LSA
2404 case OSPF_OPAQUE_AS_LSA:
2405#endif /* HAVE_OPAQUE_LSA */
f2c80652 2406#ifdef HAVE_NSSA
2407 case OSPF_AS_NSSA_LSA:
2408#endif
718e3744 2409 zlog_info ("LSA[%s]: Install %s",
2410 dump_lsa_key (new),
2411 LOOKUP (ospf_lsa_type_msg, new->data->type));
2412 break;
2413 default:
2414 strcpy (area_str, inet_ntoa (new->area->area_id));
2415 zlog_info ("LSA[%s]: Install %s to Area %s",
2416 dump_lsa_key (new),
2417 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2418 break;
2419 }
2420 }
2421
2422 /* If received LSA' ls_age is MaxAge, set LSA on MaxAge LSA list. */
2423 if (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new))
2424 {
2425 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2426 zlog_info ("LSA[Type%d:%s]: Install LSA, MaxAge",
2427 new->data->type, inet_ntoa (new->data->id));
2428 ospf_lsa_maxage (lsa);
2429 }
2430
2431 return new;
2432}
2433
2434\f
2435int
2436ospf_check_nbr_status ()
2437{
2438 listnode node;
2439
2440 for (node = listhead (ospf_top->oiflist); node; node = nextnode (node))
2441 {
2442 struct ospf_interface *oi = getdata (node);
2443 struct route_node *rn;
2444 struct ospf_neighbor *nbr;
2445
2446 if (ospf_if_is_enable (oi))
2447 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2448 if ((nbr = rn->info) != NULL)
2449 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2450 {
2451 route_unlock_node (rn);
2452 return 0;
2453 }
2454 }
2455
2456 return 1;
2457}
2458
2459\f
2460#ifdef ORIGINAL_CODING
2461/* This function flood the maxaged LSA to DR. */
2462void
2463ospf_maxage_flood (struct ospf_lsa *lsa)
2464{
2465 switch (lsa->data->type)
2466 {
2467 case OSPF_ROUTER_LSA:
2468 case OSPF_NETWORK_LSA:
2469 case OSPF_SUMMARY_LSA:
2470 case OSPF_ASBR_SUMMARY_LSA:
2471#ifdef HAVE_NSSA
2472 case OSPF_AS_NSSA_LSA:
2473#endif /* HAVE_NSSA */
2474#ifdef HAVE_OPAQUE_LSA
2475 case OSPF_OPAQUE_LINK_LSA:
2476 case OSPF_OPAQUE_AREA_LSA:
2477#endif /* HAVE_OPAQUE_LSA */
2478 ospf_flood_through_area (lsa->area, NULL, lsa);
2479 break;
2480 case OSPF_AS_EXTERNAL_LSA:
2481#ifdef HAVE_OPAQUE_LSA
2482 case OSPF_OPAQUE_AS_LSA:
2483#endif /* HAVE_OPAQUE_LSA */
2484 ospf_flood_through_as (NULL, lsa);
2485 break;
2486 default:
2487 break;
2488 }
2489}
2490#endif /* ORIGINAL_CODING */
2491
2492int
2493ospf_maxage_lsa_remover (struct thread *thread)
2494{
2495 listnode node;
2496 listnode next;
2497 int reschedule = 0;
2498
2499 ospf_top->t_maxage = NULL;
2500
2501 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2502 zlog_info ("LSA[MaxAge]: remover Start");
2503
2504 reschedule = !ospf_check_nbr_status ();
2505
2506 if (!reschedule)
2507 for (node = listhead (ospf_top->maxage_lsa); node; node = next)
2508 {
2509 struct ospf_lsa *lsa = getdata (node);
2510 next = node->next;
2511
2512 if (lsa->retransmit_counter > 0)
2513 {
2514 reschedule = 1;
2515 continue;
2516 }
2517
2518 /* Remove LSA from the LSDB */
2519 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2520 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2521 zlog_info ("LSA[Type%d:%s]: This LSA is self-originated: ",
2522 lsa->data->type, inet_ntoa (lsa->data->id));
2523
2524 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2525 zlog_info ("LSA[Type%d:%s]: MaxAge LSA removed from list",
2526 lsa->data->type, inet_ntoa (lsa->data->id));
2527
2528 /* Flood max age LSA. */
2529#ifdef ORIGINAL_CODING
2530 ospf_maxage_flood (lsa);
2531#else /* ORIGINAL_CODING */
2532 ospf_flood_through (NULL, lsa);
2533#endif /* ORIGINAL_CODING */
2534
2535 /* Remove from lsdb. */
2536 ospf_discard_from_db (lsa->lsdb, lsa);
2537 ospf_lsdb_delete (lsa->lsdb, lsa);
2538 }
2539
2540 /* A MaxAge LSA must be removed immediately from the router's link
2541 state database as soon as both a) it is no longer contained on any
2542 neighbor Link state retransmission lists and b) none of the router's
2543 neighbors are in states Exchange or Loading. */
2544 if (reschedule)
2545 OSPF_SCHEDULE_MAXAGE (ospf_top->t_maxage, ospf_maxage_lsa_remover);
2546
2547 return 0;
2548}
2549
2550int
2551ospf_lsa_maxage_exist (struct ospf_lsa *new)
2552{
2553 listnode node;
2554
2555 for (node = listhead (ospf_top->maxage_lsa); node; nextnode (node))
2556 if (((struct ospf_lsa *) node->data) == new)
2557 return 1;
2558
2559 return 0;
2560}
2561
2562void
2563ospf_lsa_maxage_delete (struct ospf_lsa *lsa)
2564{
2565 listnode n;
2566
2567 if ((n = listnode_lookup (ospf_top->maxage_lsa, lsa)))
2568 {
2569 list_delete_node (ospf_top->maxage_lsa, n);
2570 ospf_lsa_unlock (lsa);
2571 }
2572}
2573
2574void
2575ospf_lsa_maxage (struct ospf_lsa *lsa)
2576{
2577 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2578 and schedule the MaxAge LSA remover. */
2579 if (ospf_lsa_maxage_exist (lsa))
2580 {
2581 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2582 zlog_info ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
2583 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2584 return;
2585 }
2586
2587 listnode_add (ospf_top->maxage_lsa, ospf_lsa_lock (lsa));
2588
2589 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2590 zlog_info ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
2591
2592 OSPF_SCHEDULE_MAXAGE (ospf_top->t_maxage, ospf_maxage_lsa_remover);
2593}
2594
2595int
2596ospf_lsa_maxage_walker_remover (struct ospf_lsa *lsa, void *p_arg, int int_arg)
2597{
2598#ifdef HAVE_NSSA
2599 /* Stay away from any Local Translated Type-7 LSAs */
2600 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2601 return 0;
2602#endif /* HAVE_NSSA */
2603
2604 if (IS_LSA_MAXAGE (lsa))
2605 /* Self-originated LSAs should NOT time-out instead,
2606 they're flushed and submitted to the max_age list explicitly. */
2607 if (!ospf_lsa_is_self_originated (lsa))
2608 {
2609 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2610 zlog_info("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
2611
2612 switch (lsa->data->type)
2613 {
2614 case OSPF_AS_EXTERNAL_LSA:
2615#ifdef HAVE_OPAQUE_LSA
2616 case OSPF_OPAQUE_AS_LSA:
2617#endif /* HAVE_OPAQUE_LSA */
f2c80652 2618#ifdef HAVE_NSSA
2619 case OSPF_AS_NSSA_LSA:
2620#endif
718e3744 2621 ospf_ase_incremental_update (lsa, ospf_top);
2622 break;
2623 default:
2624 ospf_spf_calculate_schedule ();
2625 break;
2626 }
2627
2628 ospf_lsa_maxage (lsa);
2629 }
2630
2631 return 0;
2632}
2633
2634/* Periodical check of MaxAge LSA. */
2635int
2636ospf_lsa_maxage_walker (struct thread *t)
2637{
2638 listnode node;
2639
2640 ospf_top->t_maxage_walker = NULL;
2641
2642 for (node = listhead (ospf_top->areas); node; nextnode (node))
2643 {
2644 struct ospf_area *area = node->data;
2645
2646 foreach_lsa (ROUTER_LSDB (area), NULL, 0,
2647 ospf_lsa_maxage_walker_remover);
2648 foreach_lsa (NETWORK_LSDB (area), NULL, 0,
2649 ospf_lsa_maxage_walker_remover);
2650 foreach_lsa (SUMMARY_LSDB (area), NULL, 0,
2651 ospf_lsa_maxage_walker_remover);
2652 foreach_lsa (ASBR_SUMMARY_LSDB (area), NULL, 0,
2653 ospf_lsa_maxage_walker_remover);
2654#ifdef HAVE_OPAQUE_LSA
2655 foreach_lsa (OPAQUE_LINK_LSDB (area), NULL, 0,
2656 ospf_lsa_maxage_walker_remover);
2657 foreach_lsa (OPAQUE_AREA_LSDB (area), NULL, 0,
2658 ospf_lsa_maxage_walker_remover);
2659#endif /* HAVE_OPAQUE_LSA */
2660 }
2661
2662 /* for AS-eternal-LSAs. */
2663 if (ospf_top->lsdb)
2664 foreach_lsa (EXTERNAL_LSDB (ospf_top), NULL, 0,
2665 ospf_lsa_maxage_walker_remover);
2666
2667#ifdef HAVE_OPAQUE_LSA
2668 if (ospf_top->lsdb)
2669 foreach_lsa (OPAQUE_AS_LSDB (ospf_top), NULL, 0,
2670 ospf_lsa_maxage_walker_remover);
2671#endif /* HAVE_OPAQUE_LSA */
2672
2673 ospf_top->t_maxage_walker =
2674 thread_add_timer (master, ospf_lsa_maxage_walker, NULL,
2675 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
2676 return 0;
2677}
2678
2679int
2680find_summary (struct ospf_lsa *lsa, void * v, int i)
2681{
2682 struct prefix_ipv4 *p, pr;
2683
2684 if ((p = (struct prefix_ipv4 *) v) != NULL)
2685 if (lsa != NULL)
2686 /* We're looking for self-originated one */
2687 if (ospf_lsa_is_self_originated (lsa))
2688 {
2689 struct summary_lsa *sl = (struct summary_lsa *) lsa->data;
2690
2691 pr.family = AF_INET;
2692 pr.prefix = sl->header.id;
2693 pr.prefixlen = ip_masklen (sl->mask);
2694 apply_mask_ipv4 (&pr);
2695
2696 if (prefix_same ((struct prefix*) &pr, (struct prefix*) p))
2697 return 1;
2698 }
2699
2700 return 0;
2701}
2702
2703int
2704find_asbr_summary (struct ospf_lsa *lsa, void * v, int i)
2705{
2706 struct prefix_ipv4 *p;
2707
2708 if ((p = (struct prefix_ipv4 *) v) != NULL)
2709 if (lsa != NULL)
2710 /* We're looking for self-originated one */
2711 if (ospf_lsa_is_self_originated (lsa))
2712 {
2713 struct summary_lsa *sl = (struct summary_lsa *) lsa->data;
2714
2715 if (IPV4_ADDR_SAME (&p->prefix, &sl->header.id))
2716 return 1;
2717 }
2718
2719 return 0;
2720}
2721
2722struct ospf_lsa *
2723ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
2724 struct in_addr id, struct in_addr adv_router)
2725{
2726 switch (type)
2727 {
2728 case OSPF_ROUTER_LSA:
2729 case OSPF_NETWORK_LSA:
2730 case OSPF_SUMMARY_LSA:
2731 case OSPF_ASBR_SUMMARY_LSA:
2732#ifdef HAVE_NSSA
2733 case OSPF_AS_NSSA_LSA:
2734#endif /* HAVE_NSSA */
2735#ifdef HAVE_OPAQUE_LSA
2736 case OSPF_OPAQUE_LINK_LSA:
2737 case OSPF_OPAQUE_AREA_LSA:
2738#endif /* HAVE_OPAQUE_LSA */
2739 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
2740 break;
2741 case OSPF_AS_EXTERNAL_LSA:
2742#ifdef HAVE_OPAQUE_LSA
2743 case OSPF_OPAQUE_AS_LSA:
2744#endif /* HAVE_OPAQUE_LSA */
2745 return ospf_lsdb_lookup_by_id (ospf_top->lsdb, type, id, adv_router);
2746 break;
2747 default:
2748 break;
2749 }
2750
2751 return NULL;
2752}
2753
2754struct ospf_lsa *
2755ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
2756 struct in_addr id)
2757{
2758 struct ospf_lsa *lsa;
2759 struct route_node *rn;
2760
2761 switch (type)
2762 {
2763 case OSPF_ROUTER_LSA:
2764 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
2765 break;
2766 case OSPF_NETWORK_LSA:
2767 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
2768 if ((lsa = rn->info))
2769 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
2770 {
2771 route_unlock_node (rn);
2772 return lsa;
2773 }
2774 break;
2775 case OSPF_SUMMARY_LSA:
2776 case OSPF_ASBR_SUMMARY_LSA:
2777 /* Currently not used. */
2778 assert (1);
2779 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
2780 break;
2781 case OSPF_AS_EXTERNAL_LSA:
2782#ifdef HAVE_OPAQUE_LSA
2783 case OSPF_OPAQUE_LINK_LSA:
2784 case OSPF_OPAQUE_AREA_LSA:
2785 case OSPF_OPAQUE_AS_LSA:
2786 /* Currently not used. */
2787 break;
2788#endif /* HAVE_OPAQUE_LSA */
2789 default:
2790 break;
2791 }
2792
2793 return NULL;
2794}
2795
2796struct ospf_lsa *
2797ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
2798{
2799 struct ospf_lsa *match;
2800
2801#ifdef HAVE_OPAQUE_LSA
2802 /*
2803 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
2804 * is redefined to have two subfields; opaque-type and opaque-id.
2805 * However, it is harmless to treat the two sub fields together, as if
2806 * they two were forming a unique LSA-ID.
2807 */
2808#endif /* HAVE_OPAQUE_LSA */
2809
2810 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
2811
2812 if (match == NULL)
2813 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
2814 zlog_info ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
2815 lsah->type, inet_ntoa (lsah->id));
2816
2817 return match;
2818}
2819
2820/* return +n, l1 is more recent.
2821 return -n, l2 is more recent.
2822 return 0, l1 and l2 is identical. */
2823int
2824ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
2825{
2826 int r;
2827 int x, y;
2828
2829 if (l1 == NULL && l2 == NULL)
2830 return 0;
2831 if (l1 == NULL)
2832 return -1;
2833 if (l2 == NULL)
2834 return 1;
2835
2836 /* compare LS sequence number. */
2837 x = (int) ntohl (l1->data->ls_seqnum);
2838 y = (int) ntohl (l2->data->ls_seqnum);
2839 if (x > y)
2840 return 1;
2841 if (x < y)
2842 return -1;
2843
2844 /* compare LS checksum. */
2845 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
2846 if (r)
2847 return r;
2848
2849 /* compare LS age. */
2850 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
2851 return 1;
2852 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
2853 return -1;
2854
2855 /* compare LS age with MaxAgeDiff. */
2856 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
2857 return -1;
2858 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
2859 return 1;
2860
2861 /* LSAs are identical. */
2862 return 0;
2863}
2864
2865/* If two LSAs are different, return 1, otherwise return 0. */
2866int
2867ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
2868{
2869 char *p1, *p2;
2870 assert (l1);
2871 assert (l2);
2872 assert (l1->data);
2873 assert (l2->data);
2874
2875 if (l1->data->options != l2->data->options)
2876 return 1;
2877
2878 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
2879 return 1;
2880
2881 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
2882 return 1;
2883
2884 if (l1->data->length != l2->data->length)
2885 return 1;
2886
2887 if (l1->data->length == 0)
2888 return 1;
2889
2890 assert (l1->data->length > OSPF_LSA_HEADER_SIZE);
2891
2892 p1 = (char *) l1->data;
2893 p2 = (char *) l2->data;
2894
2895 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
2896 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
2897 return 1;
2898
2899 return 0;
2900}
2901
2902#ifdef ORIGINAL_CODING
2903void
2904ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
2905 struct ospf_lsa *self,
2906 struct ospf_lsa *new)
2907{
2908 u_int32_t seqnum;
2909
2910 /* Adjust LS Sequence Number. */
2911 seqnum = ntohl (new->data->ls_seqnum) + 1;
2912 self->data->ls_seqnum = htonl (seqnum);
2913
2914 /* Recalculate LSA checksum. */
2915 ospf_lsa_checksum (self->data);
2916
2917 /* Reflooding LSA. */
2918 /* RFC2328 Section 13.3
2919 On non-broadcast networks, separate Link State Update
2920 packets must be sent, as unicasts, to each adjacent neighbor
2921 (i.e., those in state Exchange or greater). The destination
2922 IP addresses for these packets are the neighbors' IP
2923 addresses. */
2924 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
2925 {
2926 struct route_node *rn;
2927 struct ospf_neighbor *onbr;
2928
2929 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
2930 if ((onbr = rn->info) != NULL)
2931 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
2932 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
2933 }
2934 else
2935 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
2936
2937 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2938 zlog_info ("LSA[Type%d:%s]: Flush self-originated LSA",
2939 self->data->type, inet_ntoa (self->data->id));
2940}
2941#else /* ORIGINAL_CODING */
2942static int
2943ospf_lsa_flush_schedule (struct ospf_lsa *lsa, void *v, int i)
2944{
2945 if (lsa == NULL || !IS_LSA_SELF (lsa))
2946 return 0;
2947
2948 if (IS_DEBUG_OSPF_EVENT)
2949 zlog_info ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
2950
2951 /* Force given lsa's age to MaxAge. */
2952 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2953
2954 switch (lsa->data->type)
2955 {
2956#ifdef HAVE_OPAQUE_LSA
2957 case OSPF_OPAQUE_LINK_LSA:
2958 case OSPF_OPAQUE_AREA_LSA:
2959 case OSPF_OPAQUE_AS_LSA:
2960 ospf_opaque_lsa_refresh (lsa);
2961 break;
2962#endif /* HAVE_OPAQUE_LSA */
2963 default:
2964 ospf_lsa_maxage (lsa);
2965 break;
2966 }
2967
2968 return 0;
2969}
2970
2971void
2972ospf_flush_self_originated_lsas_now (struct ospf *top)
2973{
2974 listnode n1, n2;
2975 struct ospf_area *area;
2976 struct ospf_interface *oi;
2977 struct ospf_lsa *lsa;
2978 int need_to_flush_ase = 0;
2979
2980 for (n1 = listhead (top->areas); n1; nextnode (n1))
2981 {
2982 if ((area = getdata (n1)) == NULL)
2983 continue;
2984
2985 if ((lsa = area->router_lsa_self) != NULL)
2986 {
2987 if (IS_DEBUG_OSPF_EVENT)
2988 zlog_info ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
2989
2990 ospf_lsa_flush_area (lsa, area);
2991 ospf_lsa_unlock (area->router_lsa_self);
2992 area->router_lsa_self = NULL;
2993 OSPF_TIMER_OFF (area->t_router_lsa_self);
2994 }
2995
2996 for (n2 = listhead (area->oiflist); n2; nextnode (n2))
2997 {
2998 if ((oi = getdata (n2)) == NULL)
2999 continue;
3000
3001 if ((lsa = oi->network_lsa_self) != NULL
3002 && oi->state == ISM_DR
3003 && oi->full_nbrs > 0)
3004 {
3005 if (IS_DEBUG_OSPF_EVENT)
3006 zlog_info ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
3007
3008 ospf_lsa_flush_area (oi->network_lsa_self, area);
3009 ospf_lsa_unlock (oi->network_lsa_self);
3010 oi->network_lsa_self = NULL;
3011 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3012 }
3013
3014 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3015 && area->external_routing == OSPF_AREA_DEFAULT)
3016 need_to_flush_ase = 1;
3017 }
3018
3019 foreach_lsa (SUMMARY_LSDB (area), NULL, 0, ospf_lsa_flush_schedule);
3020 foreach_lsa (ASBR_SUMMARY_LSDB (area), NULL, 0, ospf_lsa_flush_schedule);
3021#ifdef HAVE_OPAQUE_LSA
3022 foreach_lsa (OPAQUE_LINK_LSDB (area),
3023 NULL, 0, ospf_lsa_flush_schedule);
3024 foreach_lsa (OPAQUE_AREA_LSDB (area),
3025 NULL, 0, ospf_lsa_flush_schedule);
3026#endif /* HAVE_OPAQUE_LSA */
3027 }
3028
3029 if (need_to_flush_ase)
3030 {
3031 foreach_lsa (EXTERNAL_LSDB (top), NULL, 0, ospf_lsa_flush_schedule);
3032#ifdef HAVE_OPAQUE_LSA
3033 foreach_lsa (OPAQUE_AS_LSDB (top),
3034 NULL, 0, ospf_lsa_flush_schedule);
3035#endif /* HAVE_OPAQUE_LSA */
3036 }
3037
3038 /*
3039 * Make sure that the MaxAge LSA remover is executed immediately,
3040 * without conflicting to other threads.
3041 */
3042 if (top->t_maxage != NULL)
3043 {
3044 OSPF_TIMER_OFF (top->t_maxage);
3045 thread_execute (master, ospf_maxage_lsa_remover, top, 0);
3046 }
3047
3048 return;
3049}
3050#endif /* ORIGINAL_CODING */
3051
3052/* If there is self-originated LSA, then return 1, otherwise return 0. */
3053/* An interface-independent version of ospf_lsa_is_self_originated */
3054int
3055ospf_lsa_is_self_originated (struct ospf_lsa *lsa)
3056{
3057 listnode node;
3058
3059 /* This LSA is already checked. */
3060 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3061 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3062
3063 /* Make sure LSA is self-checked. */
3064 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3065
3066 /* AdvRouter and Router ID is the same. */
3067 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf_top->router_id))
3068 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3069
3070 /* LSA is router-LSA. */
3071 else if (lsa->data->type == OSPF_ROUTER_LSA &&
3072 IPV4_ADDR_SAME (&lsa->data->id, &ospf_top->router_id))
3073 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3074
3075 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3076 else if (lsa->data->type == OSPF_NETWORK_LSA)
3077 for (node = listhead (ospf_top->oiflist); node; nextnode (node))
3078 {
3079 struct ospf_interface *oi = getdata (node);
3080
3081 /* Ignore virtual link. */
3082 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3083 if (oi->address->family == AF_INET)
3084 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3085 {
3086 /* to make it easier later */
3087 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3088 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3089 }
3090 }
3091
3092 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3093}
3094
3095/* Get unique Link State ID. */
3096struct in_addr
3097ospf_lsa_unique_id (struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
3098{
3099 struct ospf_lsa *lsa;
3100 struct in_addr mask, id;
3101
3102 id = p->prefix;
3103
3104 /* Check existence of LSA instance. */
3105 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf_top->router_id);
3106 if (lsa)
3107 {
3108 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3109 if (ip_masklen (al->mask) == p->prefixlen)
3110 {
3111 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
3112 zlog_warn ("ospf_lsa_unique_id(): "
3113 "Can't get Link State ID for %s/%d",
3114 inet_ntoa (p->prefix), p->prefixlen);
3115 /* id.s_addr = 0; */
3116 id.s_addr = 0xffffffff;
3117 return id;
3118 }
3119 /* Masklen differs, then apply wildcard mask to Link State ID. */
3120 else
3121 {
3122 masklen2ip (p->prefixlen, &mask);
3123
3124 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3125 lsa = ospf_lsdb_lookup_by_id (ospf_top->lsdb, type,
3126 id, ospf_top->router_id);
3127 if (lsa)
3128 {
3129 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
3130 zlog_warn ("ospf_lsa_unique_id(): "
3131 "Can't get Link State ID for %s/%d",
3132 inet_ntoa (p->prefix), p->prefixlen);
3133 /* id.s_addr = 0; */
3134 id.s_addr = 0xffffffff;
3135 return id;
3136 }
3137 }
3138 }
3139
3140 return id;
3141}
3142
3143\f
3144#define LSA_ACTION_ORIGN_RTR 1
3145#define LSA_ACTION_ORIGN_NET 2
3146#define LSA_ACTION_FLOOD_AREA 3
3147#define LSA_ACTION_FLOOD_AS 4
3148#define LSA_ACTION_FLUSH_AREA 5
3149#define LSA_ACTION_FLUSH_AS 6
3150
3151struct lsa_action
3152{
3153 u_char action;
3154 struct ospf_area *area;
3155 struct ospf_interface *oi;
3156 struct ospf_lsa *lsa;
3157};
3158
3159int
3160ospf_lsa_action (struct thread *t)
3161{
3162 struct lsa_action *data;
3163
3164 data = THREAD_ARG (t);
3165
3166 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
3167 zlog_info ("LSA[Action]: Performing scheduled LSA action: %d",
3168 data->action);
3169
3170 switch (data->action)
3171 {
3172 case LSA_ACTION_ORIGN_RTR:
3173 ospf_router_lsa_refresh (data->area->router_lsa_self);
3174 break;
3175 case LSA_ACTION_ORIGN_NET:
3176 ospf_network_lsa_originate (data->oi);
3177 break;
3178 case LSA_ACTION_FLOOD_AREA:
3179 ospf_flood_through_area (data->area, NULL, data->lsa);
3180 break;
3181 case LSA_ACTION_FLOOD_AS:
3182 ospf_flood_through_as (NULL, data->lsa);
3183 break;
3184 case LSA_ACTION_FLUSH_AREA:
3185 ospf_lsa_flush_area (data->lsa, data->area);
3186 break;
3187 case LSA_ACTION_FLUSH_AS:
3188 ospf_lsa_flush_as (data->lsa);
3189 break;
3190 }
3191
3192 ospf_lsa_unlock (data->lsa);
3193 XFREE (MTYPE_OSPF_MESSAGE, data);
3194 return 0;
3195}
3196
3197void
3198ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3199{
3200 struct lsa_action *data;
3201
3202 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3203 memset (data, 0, sizeof (struct lsa_action));
3204
3205 data->action = LSA_ACTION_FLOOD_AREA;
3206 data->area = area;
3207 data->lsa = ospf_lsa_lock (lsa);
3208
3209 thread_add_event (master, ospf_lsa_action, data, 0);
3210}
3211
3212void
3213ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3214{
3215 struct lsa_action *data;
3216
3217 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3218 memset (data, 0, sizeof (struct lsa_action));
3219
3220 data->action = LSA_ACTION_FLUSH_AREA;
3221 data->area = area;
3222 data->lsa = ospf_lsa_lock (lsa);
3223
3224 thread_add_event (master, ospf_lsa_action, data, 0);
3225}
3226
3227\f
3228/* LSA Refreshment functions. */
3229void
3230ospf_lsa_refresh (struct ospf_lsa *lsa)
3231{
3232 struct external_info *ei;
3233 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3234
3235 switch (lsa->data->type)
3236 {
3237 /* Router and Network LSAs are processed differently. */
3238 case OSPF_ROUTER_LSA:
3239 case OSPF_NETWORK_LSA:
3240 break;
3241 case OSPF_SUMMARY_LSA:
3242 ospf_summary_lsa_refresh (lsa);
3243 break;
3244 case OSPF_ASBR_SUMMARY_LSA:
3245 ospf_summary_asbr_lsa_refresh (lsa);
3246 break;
3247 case OSPF_AS_EXTERNAL_LSA:
3248 ei = ospf_external_info_check (lsa);
3249 if (ei)
3250 ospf_external_lsa_refresh (lsa, ei, LSA_REFRESH_FORCE);
3251 else
3252 ospf_lsa_flush_as (lsa);
3253 break;
3254#ifdef HAVE_OPAQUE_LSA
3255 case OSPF_OPAQUE_LINK_LSA:
3256 case OSPF_OPAQUE_AREA_LSA:
3257 case OSPF_OPAQUE_AS_LSA:
3258 ospf_opaque_lsa_refresh (lsa);
3259 break;
3260 default:
3261 break;
3262#endif /* HAVE_OPAQUE_LSA */
3263 }
3264}
3265
3266void
3267ospf_refresher_register_lsa (struct ospf *top, struct ospf_lsa *lsa)
3268{
3269 u_int16_t index, current_index;
3270
3271 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3272
3273 if (lsa->refresh_list < 0)
3274 {
3275 int delay;
3276
3277 if (LS_AGE (lsa) == 0 &&
3278 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3279 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3280 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3281 else
3282 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3283 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3284 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3285
3286 if (delay < 0)
3287 delay = 0;
3288
3289 current_index = top->lsa_refresh_queue.index +
3290 (time (NULL) - top->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
3291
3292 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3293 % (OSPF_LSA_REFRESHER_SLOTS);
3294
3295 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3296 zlog_info ("LSA[Refresh]: lsa with age %d added to index %d",
3297 LS_AGE (lsa), index);
3298 if (!top->lsa_refresh_queue.qs[index])
3299 top->lsa_refresh_queue.qs[index] = list_new ();
3300 listnode_add (top->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa));
3301 lsa->refresh_list = index;
f2c80652 3302 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3303 zlog_info ("LSA[Refresh]: ospf_refresher_register_lsa(): setting refresh_list on lsa %p (slod %d)", lsa, index);
718e3744 3304 }
3305}
3306
3307void
3308ospf_refresher_unregister_lsa (struct ospf *top, struct ospf_lsa *lsa)
3309{
3310 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3311 if (lsa->refresh_list >= 0)
3312 {
3313 list refresh_list = top->lsa_refresh_queue.qs[lsa->refresh_list];
3314 listnode_delete (refresh_list, lsa);
3315 if (!listcount (refresh_list))
3316 {
3317 list_free (refresh_list);
3318 top->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
3319 }
3320 ospf_lsa_unlock (lsa);
3321 lsa->refresh_list = -1;
3322 }
3323}
3324
3325int
3326ospf_lsa_refresh_walker (struct thread *t)
3327{
3328 list refresh_list;
3329 listnode node;
3330 struct ospf *top = THREAD_ARG (t);
3331 int i;
3332 list lsa_to_refresh = list_new ();
3333
3334 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3335 zlog_info ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
3336
3337
3338 i = top->lsa_refresh_queue.index;
3339
3340 top->lsa_refresh_queue.index =
3341 (top->lsa_refresh_queue.index +
3342 (time (NULL) - top->lsa_refresher_started) / OSPF_LSA_REFRESHER_GRANULARITY)
3343 % OSPF_LSA_REFRESHER_SLOTS;
3344
3345 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3346 zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
3347 top->lsa_refresh_queue.index);
3348
3349 for (;i != top->lsa_refresh_queue.index;
3350 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3351 {
3352 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3353 zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh index %d", i);
3354
3355 refresh_list = top->lsa_refresh_queue.qs [i];
3356
3357 top->lsa_refresh_queue.qs [i] = NULL;
3358
3359 if (refresh_list)
3360 {
3361 for (node = listhead (refresh_list); node;)
3362 {
3363 listnode next;
3364 struct ospf_lsa *lsa = getdata (node);
3365 next = node->next;
3366
3367 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
f2c80652 3368 zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh lsa %p (slot %d)", lsa, i);
718e3744 3369
3370 list_delete_node (refresh_list, node);
3371 ospf_lsa_unlock (lsa);
3372 lsa->refresh_list = -1;
3373 listnode_add (lsa_to_refresh, lsa);
3374 node = next;
3375 }
3376 list_free (refresh_list);
3377 }
3378 }
3379
3380 top->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3381 top, top->lsa_refresh_interval);
3382 top->lsa_refresher_started = time (NULL);
3383
3384 for (node = listhead (lsa_to_refresh); node; nextnode (node))
3385 ospf_lsa_refresh (getdata (node));
3386
3387 list_delete (lsa_to_refresh);
3388
3389 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3390 zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
3391
3392 return 0;
3393}
3394