blob: 9a9942f3ac4a7165e1a41736368ae02f7cd2d3da [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
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
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
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
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
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
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
paulf2c80652002-12-13 21:44:27 +0000256 /* 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
paul718e3742002-12-13 20:15:29 +0000265 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
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
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
paul7afa08d2002-12-13 20:59:45 +0000601/* 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
paul718e3742002-12-13 20:15:29 +0000639/* 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. */
paul2e3b2e42002-12-13 21:03:13 +0000652 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000653 {
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:
paul7afa08d2002-12-13 20:59:45 +0000669 links += lsa_link_ptomultip_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000670 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
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
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
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
paul2e3b2e42002-12-13 21:03:13 +00001403 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001404 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
paul2e3b2e42002-12-13 21:03:13 +00001424 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001425 return oi->address->u.prefix4;
1426
1427 return fwd;
1428}
1429
1430/* Get 1st IP connection for Forward Addr */
1431struct in_addr
paulf2c80652002-12-13 21:44:27 +00001432ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001433{
1434 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001435 struct in_addr best_default;
paul718e3742002-12-13 20:15:29 +00001436 listnode n1;
1437
1438 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001439 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001440
1441
1442 for (n1 = listhead (ospf_top->oiflist); n1; nextnode (n1))
1443 {
1444 struct ospf_interface *oi = getdata (n1);
1445
paul2e3b2e42002-12-13 21:03:13 +00001446 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001447 if (oi->area->external_routing == OSPF_AREA_NSSA)
paulf2c80652002-12-13 21:44:27 +00001448 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 }
paul718e3742002-12-13 20:15:29 +00001455 }
paulf2c80652002-12-13 21:44:27 +00001456 if (best_default.s_addr != 0)
1457 return best_default;
paul718e3742002-12-13 20:15:29 +00001458
1459 return fwd;
1460}
1461#endif /* HAVE_NSSA */
1462
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;
paulf2c80652002-12-13 21:44:27 +00001649 struct as_external_lsa *extlsa, *newextlsa;
1650 listnode node;
paul718e3742002-12-13 20:15:29 +00001651
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
paulf2c80652002-12-13 21:44:27 +00001667 for (node = listhead (ospf_top->areas); node; nextnode (node)) {
1668
1669 struct ospf_area *area = getdata (node);
paul718e3742002-12-13 20:15:29 +00001670
paulf2c80652002-12-13 21:44:27 +00001671 /* make lsa duplicate, lock=1 */
1672 new2 = ospf_lsa_dup(lsa);
paul718e3742002-12-13 20:15:29 +00001673
paulf2c80652002-12-13 21:44:27 +00001674 /* make type-7 */
1675 new2->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001676
paulf2c80652002-12-13 21:44:27 +00001677 /* set P-bit if not ABR */
1678 if (! OSPF_IS_ABR)
1679 {
1680 SET_FLAG(new2->data->options, OSPF_OPTION_NP);
paul718e3742002-12-13 20:15:29 +00001681
paulf2c80652002-12-13 21:44:27 +00001682 /* set non-zero FWD ADDR
paul718e3742002-12-13 20:15:29 +00001683
paulf2c80652002-12-13 21:44:27 +00001684 draft-ietf-ospf-nssa-update-09.txt
paul718e3742002-12-13 20:15:29 +00001685
paulf2c80652002-12-13 21:44:27 +00001686 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. */
paul718e3742002-12-13 20:15:29 +00001696
paulf2c80652002-12-13 21:44:27 +00001697 /* not updating lsa anymore, just new2 */
1698 extlsa = (struct as_external_lsa *)(new2->data);
paul718e3742002-12-13 20:15:29 +00001699
paulf2c80652002-12-13 21:44:27 +00001700 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);
paul718e3742002-12-13 20:15:29 +00001703
paulf2c80652002-12-13 21:44:27 +00001704 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 }
paul718e3742002-12-13 20:15:29 +00001712
paulf2c80652002-12-13 21:44:27 +00001713 /* Re-calculate checksum. */
1714 ospf_lsa_checksum (new2->data);
paul718e3742002-12-13 20:15:29 +00001715
paulf2c80652002-12-13 21:44:27 +00001716 /* install also as Type-7 */
1717 ospf_lsa_install (NULL, new2); /* Remove Old, Lock New = 2 */
1718
1719 /* will send each copy, lock=2+n */
1720 ospf_flood_through_as (NULL, new2); /* all attached NSSA's, no AS/STUBs */
1721 }
paul718e3742002-12-13 20:15:29 +00001722
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
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 {
paulf2c80652002-12-13 21:44:27 +00002286 /* 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;
paul718e3742002-12-13 20:15:29 +00002293 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:
paul09e4efd2003-01-18 00:12:02 +00002380 if (IS_LSA_SELF (lsa))
2381 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
2382 else
2383 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
2384 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002385 case OSPF_OPAQUE_AREA_LSA:
2386 case OSPF_OPAQUE_AS_LSA:
2387 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2388 break;
2389#endif /* HAVE_OPAQUE_LSA */
2390 default: /* NSSA, or type-6,8,9....nothing special */
2391#ifdef HAVE_NSSA
2392 new = ospf_external_lsa_install (lsa, rt_recalc);
2393#endif /* HAVE_NSSA */
2394 break;
2395 }
2396
2397 if (new == NULL)
2398 return new; /* Installation failed, cannot proceed further -- endo. */
2399
2400 /* Debug logs. */
2401 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2402 {
2403 char area_str[INET_ADDRSTRLEN];
2404
2405 switch (lsa->data->type)
2406 {
2407 case OSPF_AS_EXTERNAL_LSA:
2408#ifdef HAVE_OPAQUE_LSA
2409 case OSPF_OPAQUE_AS_LSA:
2410#endif /* HAVE_OPAQUE_LSA */
paulf2c80652002-12-13 21:44:27 +00002411#ifdef HAVE_NSSA
2412 case OSPF_AS_NSSA_LSA:
2413#endif
paul718e3742002-12-13 20:15:29 +00002414 zlog_info ("LSA[%s]: Install %s",
2415 dump_lsa_key (new),
2416 LOOKUP (ospf_lsa_type_msg, new->data->type));
2417 break;
2418 default:
2419 strcpy (area_str, inet_ntoa (new->area->area_id));
2420 zlog_info ("LSA[%s]: Install %s to Area %s",
2421 dump_lsa_key (new),
2422 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2423 break;
2424 }
2425 }
2426
2427 /* If received LSA' ls_age is MaxAge, set LSA on MaxAge LSA list. */
2428 if (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new))
2429 {
2430 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2431 zlog_info ("LSA[Type%d:%s]: Install LSA, MaxAge",
2432 new->data->type, inet_ntoa (new->data->id));
2433 ospf_lsa_maxage (lsa);
2434 }
2435
2436 return new;
2437}
2438
2439
2440int
2441ospf_check_nbr_status ()
2442{
2443 listnode node;
2444
2445 for (node = listhead (ospf_top->oiflist); node; node = nextnode (node))
2446 {
2447 struct ospf_interface *oi = getdata (node);
2448 struct route_node *rn;
2449 struct ospf_neighbor *nbr;
2450
2451 if (ospf_if_is_enable (oi))
2452 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2453 if ((nbr = rn->info) != NULL)
2454 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2455 {
2456 route_unlock_node (rn);
2457 return 0;
2458 }
2459 }
2460
2461 return 1;
2462}
2463
2464
2465#ifdef ORIGINAL_CODING
2466/* This function flood the maxaged LSA to DR. */
2467void
2468ospf_maxage_flood (struct ospf_lsa *lsa)
2469{
2470 switch (lsa->data->type)
2471 {
2472 case OSPF_ROUTER_LSA:
2473 case OSPF_NETWORK_LSA:
2474 case OSPF_SUMMARY_LSA:
2475 case OSPF_ASBR_SUMMARY_LSA:
2476#ifdef HAVE_NSSA
2477 case OSPF_AS_NSSA_LSA:
2478#endif /* HAVE_NSSA */
2479#ifdef HAVE_OPAQUE_LSA
2480 case OSPF_OPAQUE_LINK_LSA:
2481 case OSPF_OPAQUE_AREA_LSA:
2482#endif /* HAVE_OPAQUE_LSA */
2483 ospf_flood_through_area (lsa->area, NULL, lsa);
2484 break;
2485 case OSPF_AS_EXTERNAL_LSA:
2486#ifdef HAVE_OPAQUE_LSA
2487 case OSPF_OPAQUE_AS_LSA:
2488#endif /* HAVE_OPAQUE_LSA */
2489 ospf_flood_through_as (NULL, lsa);
2490 break;
2491 default:
2492 break;
2493 }
2494}
2495#endif /* ORIGINAL_CODING */
2496
2497int
2498ospf_maxage_lsa_remover (struct thread *thread)
2499{
2500 listnode node;
2501 listnode next;
2502 int reschedule = 0;
2503
2504 ospf_top->t_maxage = NULL;
2505
2506 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2507 zlog_info ("LSA[MaxAge]: remover Start");
2508
2509 reschedule = !ospf_check_nbr_status ();
2510
2511 if (!reschedule)
2512 for (node = listhead (ospf_top->maxage_lsa); node; node = next)
2513 {
2514 struct ospf_lsa *lsa = getdata (node);
2515 next = node->next;
2516
2517 if (lsa->retransmit_counter > 0)
2518 {
2519 reschedule = 1;
2520 continue;
2521 }
2522
2523 /* Remove LSA from the LSDB */
2524 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2525 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2526 zlog_info ("LSA[Type%d:%s]: This LSA is self-originated: ",
2527 lsa->data->type, inet_ntoa (lsa->data->id));
2528
2529 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2530 zlog_info ("LSA[Type%d:%s]: MaxAge LSA removed from list",
2531 lsa->data->type, inet_ntoa (lsa->data->id));
2532
2533 /* Flood max age LSA. */
2534#ifdef ORIGINAL_CODING
2535 ospf_maxage_flood (lsa);
2536#else /* ORIGINAL_CODING */
2537 ospf_flood_through (NULL, lsa);
2538#endif /* ORIGINAL_CODING */
2539
2540 /* Remove from lsdb. */
2541 ospf_discard_from_db (lsa->lsdb, lsa);
2542 ospf_lsdb_delete (lsa->lsdb, lsa);
2543 }
2544
2545 /* A MaxAge LSA must be removed immediately from the router's link
2546 state database as soon as both a) it is no longer contained on any
2547 neighbor Link state retransmission lists and b) none of the router's
2548 neighbors are in states Exchange or Loading. */
2549 if (reschedule)
2550 OSPF_SCHEDULE_MAXAGE (ospf_top->t_maxage, ospf_maxage_lsa_remover);
2551
2552 return 0;
2553}
2554
2555int
2556ospf_lsa_maxage_exist (struct ospf_lsa *new)
2557{
2558 listnode node;
2559
2560 for (node = listhead (ospf_top->maxage_lsa); node; nextnode (node))
2561 if (((struct ospf_lsa *) node->data) == new)
2562 return 1;
2563
2564 return 0;
2565}
2566
2567void
2568ospf_lsa_maxage_delete (struct ospf_lsa *lsa)
2569{
2570 listnode n;
2571
2572 if ((n = listnode_lookup (ospf_top->maxage_lsa, lsa)))
2573 {
2574 list_delete_node (ospf_top->maxage_lsa, n);
2575 ospf_lsa_unlock (lsa);
2576 }
2577}
2578
2579void
2580ospf_lsa_maxage (struct ospf_lsa *lsa)
2581{
2582 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2583 and schedule the MaxAge LSA remover. */
2584 if (ospf_lsa_maxage_exist (lsa))
2585 {
2586 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2587 zlog_info ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
2588 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2589 return;
2590 }
2591
2592 listnode_add (ospf_top->maxage_lsa, ospf_lsa_lock (lsa));
2593
2594 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2595 zlog_info ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
2596
2597 OSPF_SCHEDULE_MAXAGE (ospf_top->t_maxage, ospf_maxage_lsa_remover);
2598}
2599
2600int
2601ospf_lsa_maxage_walker_remover (struct ospf_lsa *lsa, void *p_arg, int int_arg)
2602{
2603#ifdef HAVE_NSSA
2604 /* Stay away from any Local Translated Type-7 LSAs */
2605 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2606 return 0;
2607#endif /* HAVE_NSSA */
2608
2609 if (IS_LSA_MAXAGE (lsa))
2610 /* Self-originated LSAs should NOT time-out instead,
2611 they're flushed and submitted to the max_age list explicitly. */
2612 if (!ospf_lsa_is_self_originated (lsa))
2613 {
2614 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2615 zlog_info("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
2616
2617 switch (lsa->data->type)
2618 {
paul718e3742002-12-13 20:15:29 +00002619#ifdef HAVE_OPAQUE_LSA
2620 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00002621 case OSPF_OPAQUE_LINK_LSA:
2622 case OSPF_OPAQUE_AREA_LSA:
2623 /*
2624 * As a general rule, whenever network topology has changed
2625 * (due to an LSA removal in this case), routing recalculation
2626 * should be triggered. However, this is not true for opaque
2627 * LSAs. Even if an opaque LSA instance is going to be removed
2628 * from the routing domain, it does not mean a change in network
2629 * topology, and thus, routing recalculation is not needed here.
2630 */
2631 break;
paul718e3742002-12-13 20:15:29 +00002632#endif /* HAVE_OPAQUE_LSA */
paulf2c80652002-12-13 21:44:27 +00002633#ifdef HAVE_NSSA
paul09e4efd2003-01-18 00:12:02 +00002634 case OSPF_AS_NSSA_LSA:
paulf2c80652002-12-13 21:44:27 +00002635#endif
paul09e4efd2003-01-18 00:12:02 +00002636 case OSPF_AS_EXTERNAL_LSA:
2637 ospf_ase_incremental_update (lsa, ospf_top);
2638 break;
paul718e3742002-12-13 20:15:29 +00002639 default:
paul09e4efd2003-01-18 00:12:02 +00002640 ospf_spf_calculate_schedule ();
2641 break;
paul718e3742002-12-13 20:15:29 +00002642 }
2643
paul09e4efd2003-01-18 00:12:02 +00002644 ospf_lsa_maxage (lsa);
paul718e3742002-12-13 20:15:29 +00002645 }
2646
2647 return 0;
2648}
2649
2650/* Periodical check of MaxAge LSA. */
2651int
2652ospf_lsa_maxage_walker (struct thread *t)
2653{
2654 listnode node;
2655
2656 ospf_top->t_maxage_walker = NULL;
2657
2658 for (node = listhead (ospf_top->areas); node; nextnode (node))
2659 {
2660 struct ospf_area *area = node->data;
2661
2662 foreach_lsa (ROUTER_LSDB (area), NULL, 0,
2663 ospf_lsa_maxage_walker_remover);
2664 foreach_lsa (NETWORK_LSDB (area), NULL, 0,
2665 ospf_lsa_maxage_walker_remover);
2666 foreach_lsa (SUMMARY_LSDB (area), NULL, 0,
2667 ospf_lsa_maxage_walker_remover);
2668 foreach_lsa (ASBR_SUMMARY_LSDB (area), NULL, 0,
2669 ospf_lsa_maxage_walker_remover);
2670#ifdef HAVE_OPAQUE_LSA
2671 foreach_lsa (OPAQUE_LINK_LSDB (area), NULL, 0,
2672 ospf_lsa_maxage_walker_remover);
2673 foreach_lsa (OPAQUE_AREA_LSDB (area), NULL, 0,
2674 ospf_lsa_maxage_walker_remover);
2675#endif /* HAVE_OPAQUE_LSA */
2676 }
2677
2678 /* for AS-eternal-LSAs. */
2679 if (ospf_top->lsdb)
2680 foreach_lsa (EXTERNAL_LSDB (ospf_top), NULL, 0,
2681 ospf_lsa_maxage_walker_remover);
2682
2683#ifdef HAVE_OPAQUE_LSA
2684 if (ospf_top->lsdb)
2685 foreach_lsa (OPAQUE_AS_LSDB (ospf_top), NULL, 0,
2686 ospf_lsa_maxage_walker_remover);
2687#endif /* HAVE_OPAQUE_LSA */
2688
2689 ospf_top->t_maxage_walker =
2690 thread_add_timer (master, ospf_lsa_maxage_walker, NULL,
2691 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
2692 return 0;
2693}
2694
2695int
2696find_summary (struct ospf_lsa *lsa, void * v, int i)
2697{
2698 struct prefix_ipv4 *p, pr;
2699
2700 if ((p = (struct prefix_ipv4 *) v) != NULL)
2701 if (lsa != NULL)
2702 /* We're looking for self-originated one */
2703 if (ospf_lsa_is_self_originated (lsa))
2704 {
2705 struct summary_lsa *sl = (struct summary_lsa *) lsa->data;
2706
2707 pr.family = AF_INET;
2708 pr.prefix = sl->header.id;
2709 pr.prefixlen = ip_masklen (sl->mask);
2710 apply_mask_ipv4 (&pr);
2711
2712 if (prefix_same ((struct prefix*) &pr, (struct prefix*) p))
2713 return 1;
2714 }
2715
2716 return 0;
2717}
2718
2719int
2720find_asbr_summary (struct ospf_lsa *lsa, void * v, int i)
2721{
2722 struct prefix_ipv4 *p;
2723
2724 if ((p = (struct prefix_ipv4 *) v) != NULL)
2725 if (lsa != NULL)
2726 /* We're looking for self-originated one */
2727 if (ospf_lsa_is_self_originated (lsa))
2728 {
2729 struct summary_lsa *sl = (struct summary_lsa *) lsa->data;
2730
2731 if (IPV4_ADDR_SAME (&p->prefix, &sl->header.id))
2732 return 1;
2733 }
2734
2735 return 0;
2736}
2737
2738struct ospf_lsa *
2739ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
2740 struct in_addr id, struct in_addr adv_router)
2741{
2742 switch (type)
2743 {
2744 case OSPF_ROUTER_LSA:
2745 case OSPF_NETWORK_LSA:
2746 case OSPF_SUMMARY_LSA:
2747 case OSPF_ASBR_SUMMARY_LSA:
2748#ifdef HAVE_NSSA
2749 case OSPF_AS_NSSA_LSA:
2750#endif /* HAVE_NSSA */
2751#ifdef HAVE_OPAQUE_LSA
2752 case OSPF_OPAQUE_LINK_LSA:
2753 case OSPF_OPAQUE_AREA_LSA:
2754#endif /* HAVE_OPAQUE_LSA */
2755 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
2756 break;
2757 case OSPF_AS_EXTERNAL_LSA:
2758#ifdef HAVE_OPAQUE_LSA
2759 case OSPF_OPAQUE_AS_LSA:
2760#endif /* HAVE_OPAQUE_LSA */
2761 return ospf_lsdb_lookup_by_id (ospf_top->lsdb, type, id, adv_router);
2762 break;
2763 default:
2764 break;
2765 }
2766
2767 return NULL;
2768}
2769
2770struct ospf_lsa *
2771ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
2772 struct in_addr id)
2773{
2774 struct ospf_lsa *lsa;
2775 struct route_node *rn;
2776
2777 switch (type)
2778 {
2779 case OSPF_ROUTER_LSA:
2780 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
2781 break;
2782 case OSPF_NETWORK_LSA:
2783 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
2784 if ((lsa = rn->info))
2785 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
2786 {
2787 route_unlock_node (rn);
2788 return lsa;
2789 }
2790 break;
2791 case OSPF_SUMMARY_LSA:
2792 case OSPF_ASBR_SUMMARY_LSA:
2793 /* Currently not used. */
2794 assert (1);
2795 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
2796 break;
2797 case OSPF_AS_EXTERNAL_LSA:
2798#ifdef HAVE_OPAQUE_LSA
2799 case OSPF_OPAQUE_LINK_LSA:
2800 case OSPF_OPAQUE_AREA_LSA:
2801 case OSPF_OPAQUE_AS_LSA:
2802 /* Currently not used. */
2803 break;
2804#endif /* HAVE_OPAQUE_LSA */
2805 default:
2806 break;
2807 }
2808
2809 return NULL;
2810}
2811
2812struct ospf_lsa *
2813ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
2814{
2815 struct ospf_lsa *match;
2816
2817#ifdef HAVE_OPAQUE_LSA
2818 /*
2819 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
2820 * is redefined to have two subfields; opaque-type and opaque-id.
2821 * However, it is harmless to treat the two sub fields together, as if
2822 * they two were forming a unique LSA-ID.
2823 */
2824#endif /* HAVE_OPAQUE_LSA */
2825
2826 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
2827
2828 if (match == NULL)
2829 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
2830 zlog_info ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
2831 lsah->type, inet_ntoa (lsah->id));
2832
2833 return match;
2834}
2835
2836/* return +n, l1 is more recent.
2837 return -n, l2 is more recent.
2838 return 0, l1 and l2 is identical. */
2839int
2840ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
2841{
2842 int r;
2843 int x, y;
2844
2845 if (l1 == NULL && l2 == NULL)
2846 return 0;
2847 if (l1 == NULL)
2848 return -1;
2849 if (l2 == NULL)
2850 return 1;
2851
2852 /* compare LS sequence number. */
2853 x = (int) ntohl (l1->data->ls_seqnum);
2854 y = (int) ntohl (l2->data->ls_seqnum);
2855 if (x > y)
2856 return 1;
2857 if (x < y)
2858 return -1;
2859
2860 /* compare LS checksum. */
2861 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
2862 if (r)
2863 return r;
2864
2865 /* compare LS age. */
2866 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
2867 return 1;
2868 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
2869 return -1;
2870
2871 /* compare LS age with MaxAgeDiff. */
2872 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
2873 return -1;
2874 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
2875 return 1;
2876
2877 /* LSAs are identical. */
2878 return 0;
2879}
2880
2881/* If two LSAs are different, return 1, otherwise return 0. */
2882int
2883ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
2884{
2885 char *p1, *p2;
2886 assert (l1);
2887 assert (l2);
2888 assert (l1->data);
2889 assert (l2->data);
2890
2891 if (l1->data->options != l2->data->options)
2892 return 1;
2893
2894 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
2895 return 1;
2896
2897 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
2898 return 1;
2899
2900 if (l1->data->length != l2->data->length)
2901 return 1;
2902
2903 if (l1->data->length == 0)
2904 return 1;
2905
2906 assert (l1->data->length > OSPF_LSA_HEADER_SIZE);
2907
2908 p1 = (char *) l1->data;
2909 p2 = (char *) l2->data;
2910
2911 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
2912 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
2913 return 1;
2914
2915 return 0;
2916}
2917
2918#ifdef ORIGINAL_CODING
2919void
2920ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
2921 struct ospf_lsa *self,
2922 struct ospf_lsa *new)
2923{
2924 u_int32_t seqnum;
2925
2926 /* Adjust LS Sequence Number. */
2927 seqnum = ntohl (new->data->ls_seqnum) + 1;
2928 self->data->ls_seqnum = htonl (seqnum);
2929
2930 /* Recalculate LSA checksum. */
2931 ospf_lsa_checksum (self->data);
2932
2933 /* Reflooding LSA. */
2934 /* RFC2328 Section 13.3
2935 On non-broadcast networks, separate Link State Update
2936 packets must be sent, as unicasts, to each adjacent neighbor
2937 (i.e., those in state Exchange or greater). The destination
2938 IP addresses for these packets are the neighbors' IP
2939 addresses. */
2940 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
2941 {
2942 struct route_node *rn;
2943 struct ospf_neighbor *onbr;
2944
2945 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
2946 if ((onbr = rn->info) != NULL)
2947 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
2948 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
2949 }
2950 else
2951 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
2952
2953 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2954 zlog_info ("LSA[Type%d:%s]: Flush self-originated LSA",
2955 self->data->type, inet_ntoa (self->data->id));
2956}
2957#else /* ORIGINAL_CODING */
2958static int
2959ospf_lsa_flush_schedule (struct ospf_lsa *lsa, void *v, int i)
2960{
2961 if (lsa == NULL || !IS_LSA_SELF (lsa))
2962 return 0;
2963
2964 if (IS_DEBUG_OSPF_EVENT)
2965 zlog_info ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
2966
2967 /* Force given lsa's age to MaxAge. */
2968 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2969
2970 switch (lsa->data->type)
2971 {
2972#ifdef HAVE_OPAQUE_LSA
2973 case OSPF_OPAQUE_LINK_LSA:
2974 case OSPF_OPAQUE_AREA_LSA:
2975 case OSPF_OPAQUE_AS_LSA:
2976 ospf_opaque_lsa_refresh (lsa);
2977 break;
2978#endif /* HAVE_OPAQUE_LSA */
2979 default:
2980 ospf_lsa_maxage (lsa);
2981 break;
2982 }
2983
2984 return 0;
2985}
2986
2987void
2988ospf_flush_self_originated_lsas_now (struct ospf *top)
2989{
2990 listnode n1, n2;
2991 struct ospf_area *area;
2992 struct ospf_interface *oi;
2993 struct ospf_lsa *lsa;
2994 int need_to_flush_ase = 0;
2995
2996 for (n1 = listhead (top->areas); n1; nextnode (n1))
2997 {
2998 if ((area = getdata (n1)) == NULL)
2999 continue;
3000
3001 if ((lsa = area->router_lsa_self) != NULL)
3002 {
3003 if (IS_DEBUG_OSPF_EVENT)
3004 zlog_info ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
3005
3006 ospf_lsa_flush_area (lsa, area);
3007 ospf_lsa_unlock (area->router_lsa_self);
3008 area->router_lsa_self = NULL;
3009 OSPF_TIMER_OFF (area->t_router_lsa_self);
3010 }
3011
3012 for (n2 = listhead (area->oiflist); n2; nextnode (n2))
3013 {
3014 if ((oi = getdata (n2)) == NULL)
3015 continue;
3016
3017 if ((lsa = oi->network_lsa_self) != NULL
3018 && oi->state == ISM_DR
3019 && oi->full_nbrs > 0)
3020 {
3021 if (IS_DEBUG_OSPF_EVENT)
3022 zlog_info ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
3023
3024 ospf_lsa_flush_area (oi->network_lsa_self, area);
3025 ospf_lsa_unlock (oi->network_lsa_self);
3026 oi->network_lsa_self = NULL;
3027 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3028 }
3029
3030 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3031 && area->external_routing == OSPF_AREA_DEFAULT)
3032 need_to_flush_ase = 1;
3033 }
3034
3035 foreach_lsa (SUMMARY_LSDB (area), NULL, 0, ospf_lsa_flush_schedule);
3036 foreach_lsa (ASBR_SUMMARY_LSDB (area), NULL, 0, ospf_lsa_flush_schedule);
3037#ifdef HAVE_OPAQUE_LSA
3038 foreach_lsa (OPAQUE_LINK_LSDB (area),
3039 NULL, 0, ospf_lsa_flush_schedule);
3040 foreach_lsa (OPAQUE_AREA_LSDB (area),
3041 NULL, 0, ospf_lsa_flush_schedule);
3042#endif /* HAVE_OPAQUE_LSA */
3043 }
3044
3045 if (need_to_flush_ase)
3046 {
3047 foreach_lsa (EXTERNAL_LSDB (top), NULL, 0, ospf_lsa_flush_schedule);
3048#ifdef HAVE_OPAQUE_LSA
3049 foreach_lsa (OPAQUE_AS_LSDB (top),
3050 NULL, 0, ospf_lsa_flush_schedule);
3051#endif /* HAVE_OPAQUE_LSA */
3052 }
3053
3054 /*
3055 * Make sure that the MaxAge LSA remover is executed immediately,
3056 * without conflicting to other threads.
3057 */
3058 if (top->t_maxage != NULL)
3059 {
3060 OSPF_TIMER_OFF (top->t_maxage);
3061 thread_execute (master, ospf_maxage_lsa_remover, top, 0);
3062 }
3063
3064 return;
3065}
3066#endif /* ORIGINAL_CODING */
3067
3068/* If there is self-originated LSA, then return 1, otherwise return 0. */
3069/* An interface-independent version of ospf_lsa_is_self_originated */
3070int
3071ospf_lsa_is_self_originated (struct ospf_lsa *lsa)
3072{
3073 listnode node;
3074
3075 /* This LSA is already checked. */
3076 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3077 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3078
3079 /* Make sure LSA is self-checked. */
3080 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3081
3082 /* AdvRouter and Router ID is the same. */
3083 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf_top->router_id))
3084 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3085
3086 /* LSA is router-LSA. */
3087 else if (lsa->data->type == OSPF_ROUTER_LSA &&
3088 IPV4_ADDR_SAME (&lsa->data->id, &ospf_top->router_id))
3089 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3090
3091 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3092 else if (lsa->data->type == OSPF_NETWORK_LSA)
3093 for (node = listhead (ospf_top->oiflist); node; nextnode (node))
3094 {
3095 struct ospf_interface *oi = getdata (node);
3096
3097 /* Ignore virtual link. */
3098 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3099 if (oi->address->family == AF_INET)
3100 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3101 {
3102 /* to make it easier later */
3103 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3104 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3105 }
3106 }
3107
3108 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3109}
3110
3111/* Get unique Link State ID. */
3112struct in_addr
3113ospf_lsa_unique_id (struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
3114{
3115 struct ospf_lsa *lsa;
3116 struct in_addr mask, id;
3117
3118 id = p->prefix;
3119
3120 /* Check existence of LSA instance. */
3121 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf_top->router_id);
3122 if (lsa)
3123 {
3124 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3125 if (ip_masklen (al->mask) == p->prefixlen)
3126 {
3127 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
3128 zlog_warn ("ospf_lsa_unique_id(): "
3129 "Can't get Link State ID for %s/%d",
3130 inet_ntoa (p->prefix), p->prefixlen);
3131 /* id.s_addr = 0; */
3132 id.s_addr = 0xffffffff;
3133 return id;
3134 }
3135 /* Masklen differs, then apply wildcard mask to Link State ID. */
3136 else
3137 {
3138 masklen2ip (p->prefixlen, &mask);
3139
3140 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3141 lsa = ospf_lsdb_lookup_by_id (ospf_top->lsdb, type,
3142 id, ospf_top->router_id);
3143 if (lsa)
3144 {
3145 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
3146 zlog_warn ("ospf_lsa_unique_id(): "
3147 "Can't get Link State ID for %s/%d",
3148 inet_ntoa (p->prefix), p->prefixlen);
3149 /* id.s_addr = 0; */
3150 id.s_addr = 0xffffffff;
3151 return id;
3152 }
3153 }
3154 }
3155
3156 return id;
3157}
3158
3159
3160#define LSA_ACTION_ORIGN_RTR 1
3161#define LSA_ACTION_ORIGN_NET 2
3162#define LSA_ACTION_FLOOD_AREA 3
3163#define LSA_ACTION_FLOOD_AS 4
3164#define LSA_ACTION_FLUSH_AREA 5
3165#define LSA_ACTION_FLUSH_AS 6
3166
3167struct lsa_action
3168{
3169 u_char action;
3170 struct ospf_area *area;
3171 struct ospf_interface *oi;
3172 struct ospf_lsa *lsa;
3173};
3174
3175int
3176ospf_lsa_action (struct thread *t)
3177{
3178 struct lsa_action *data;
3179
3180 data = THREAD_ARG (t);
3181
3182 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
3183 zlog_info ("LSA[Action]: Performing scheduled LSA action: %d",
3184 data->action);
3185
3186 switch (data->action)
3187 {
3188 case LSA_ACTION_ORIGN_RTR:
3189 ospf_router_lsa_refresh (data->area->router_lsa_self);
3190 break;
3191 case LSA_ACTION_ORIGN_NET:
3192 ospf_network_lsa_originate (data->oi);
3193 break;
3194 case LSA_ACTION_FLOOD_AREA:
3195 ospf_flood_through_area (data->area, NULL, data->lsa);
3196 break;
3197 case LSA_ACTION_FLOOD_AS:
3198 ospf_flood_through_as (NULL, data->lsa);
3199 break;
3200 case LSA_ACTION_FLUSH_AREA:
3201 ospf_lsa_flush_area (data->lsa, data->area);
3202 break;
3203 case LSA_ACTION_FLUSH_AS:
3204 ospf_lsa_flush_as (data->lsa);
3205 break;
3206 }
3207
3208 ospf_lsa_unlock (data->lsa);
3209 XFREE (MTYPE_OSPF_MESSAGE, data);
3210 return 0;
3211}
3212
3213void
3214ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3215{
3216 struct lsa_action *data;
3217
3218 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3219 memset (data, 0, sizeof (struct lsa_action));
3220
3221 data->action = LSA_ACTION_FLOOD_AREA;
3222 data->area = area;
3223 data->lsa = ospf_lsa_lock (lsa);
3224
3225 thread_add_event (master, ospf_lsa_action, data, 0);
3226}
3227
3228void
3229ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3230{
3231 struct lsa_action *data;
3232
3233 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3234 memset (data, 0, sizeof (struct lsa_action));
3235
3236 data->action = LSA_ACTION_FLUSH_AREA;
3237 data->area = area;
3238 data->lsa = ospf_lsa_lock (lsa);
3239
3240 thread_add_event (master, ospf_lsa_action, data, 0);
3241}
3242
3243
3244/* LSA Refreshment functions. */
3245void
3246ospf_lsa_refresh (struct ospf_lsa *lsa)
3247{
3248 struct external_info *ei;
3249 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3250
3251 switch (lsa->data->type)
3252 {
3253 /* Router and Network LSAs are processed differently. */
3254 case OSPF_ROUTER_LSA:
3255 case OSPF_NETWORK_LSA:
3256 break;
3257 case OSPF_SUMMARY_LSA:
3258 ospf_summary_lsa_refresh (lsa);
3259 break;
3260 case OSPF_ASBR_SUMMARY_LSA:
3261 ospf_summary_asbr_lsa_refresh (lsa);
3262 break;
3263 case OSPF_AS_EXTERNAL_LSA:
3264 ei = ospf_external_info_check (lsa);
3265 if (ei)
3266 ospf_external_lsa_refresh (lsa, ei, LSA_REFRESH_FORCE);
3267 else
3268 ospf_lsa_flush_as (lsa);
3269 break;
3270#ifdef HAVE_OPAQUE_LSA
3271 case OSPF_OPAQUE_LINK_LSA:
3272 case OSPF_OPAQUE_AREA_LSA:
3273 case OSPF_OPAQUE_AS_LSA:
3274 ospf_opaque_lsa_refresh (lsa);
3275 break;
3276 default:
3277 break;
3278#endif /* HAVE_OPAQUE_LSA */
3279 }
3280}
3281
3282void
3283ospf_refresher_register_lsa (struct ospf *top, struct ospf_lsa *lsa)
3284{
3285 u_int16_t index, current_index;
3286
3287 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3288
3289 if (lsa->refresh_list < 0)
3290 {
3291 int delay;
3292
3293 if (LS_AGE (lsa) == 0 &&
3294 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3295 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3296 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3297 else
3298 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3299 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3300 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3301
3302 if (delay < 0)
3303 delay = 0;
3304
3305 current_index = top->lsa_refresh_queue.index +
3306 (time (NULL) - top->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
3307
3308 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3309 % (OSPF_LSA_REFRESHER_SLOTS);
3310
3311 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3312 zlog_info ("LSA[Refresh]: lsa with age %d added to index %d",
3313 LS_AGE (lsa), index);
3314 if (!top->lsa_refresh_queue.qs[index])
3315 top->lsa_refresh_queue.qs[index] = list_new ();
3316 listnode_add (top->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa));
3317 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003318 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3319 zlog_info ("LSA[Refresh]: ospf_refresher_register_lsa(): setting refresh_list on lsa %p (slod %d)", lsa, index);
paul718e3742002-12-13 20:15:29 +00003320 }
3321}
3322
3323void
3324ospf_refresher_unregister_lsa (struct ospf *top, struct ospf_lsa *lsa)
3325{
3326 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3327 if (lsa->refresh_list >= 0)
3328 {
3329 list refresh_list = top->lsa_refresh_queue.qs[lsa->refresh_list];
3330 listnode_delete (refresh_list, lsa);
3331 if (!listcount (refresh_list))
3332 {
3333 list_free (refresh_list);
3334 top->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
3335 }
3336 ospf_lsa_unlock (lsa);
3337 lsa->refresh_list = -1;
3338 }
3339}
3340
3341int
3342ospf_lsa_refresh_walker (struct thread *t)
3343{
3344 list refresh_list;
3345 listnode node;
3346 struct ospf *top = THREAD_ARG (t);
3347 int i;
3348 list lsa_to_refresh = list_new ();
3349
3350 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3351 zlog_info ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
3352
3353
3354 i = top->lsa_refresh_queue.index;
3355
3356 top->lsa_refresh_queue.index =
3357 (top->lsa_refresh_queue.index +
3358 (time (NULL) - top->lsa_refresher_started) / OSPF_LSA_REFRESHER_GRANULARITY)
3359 % OSPF_LSA_REFRESHER_SLOTS;
3360
3361 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3362 zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
3363 top->lsa_refresh_queue.index);
3364
3365 for (;i != top->lsa_refresh_queue.index;
3366 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3367 {
3368 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3369 zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh index %d", i);
3370
3371 refresh_list = top->lsa_refresh_queue.qs [i];
3372
3373 top->lsa_refresh_queue.qs [i] = NULL;
3374
3375 if (refresh_list)
3376 {
3377 for (node = listhead (refresh_list); node;)
3378 {
3379 listnode next;
3380 struct ospf_lsa *lsa = getdata (node);
3381 next = node->next;
3382
3383 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
paulf2c80652002-12-13 21:44:27 +00003384 zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh lsa %p (slot %d)", lsa, i);
paul718e3742002-12-13 20:15:29 +00003385
3386 list_delete_node (refresh_list, node);
3387 ospf_lsa_unlock (lsa);
3388 lsa->refresh_list = -1;
3389 listnode_add (lsa_to_refresh, lsa);
3390 node = next;
3391 }
3392 list_free (refresh_list);
3393 }
3394 }
3395
3396 top->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3397 top, top->lsa_refresh_interval);
3398 top->lsa_refresher_started = time (NULL);
3399
3400 for (node = listhead (lsa_to_refresh); node; nextnode (node))
3401 ospf_lsa_refresh (getdata (node));
3402
3403 list_delete (lsa_to_refresh);
3404
3405 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3406 zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
3407
3408 return 0;
3409}
3410