blob: 9c81327e10710e8ff33a0557be7d19713c340099 [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,
paul68980082003-03-25 05:07:42 +0000397 u_char type, struct in_addr id, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +0000398{
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;
paul68980082003-03-25 05:07:42 +0000407 lsah->adv_router = router_id;
paul718e3742002-12-13 20:15:29 +0000408 lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
409
410 ospf_output_forward (s, OSPF_LSA_HEADER_SIZE);
411}
412
paul68980082003-03-25 05:07:42 +0000413
paul718e3742002-12-13 20:15:29 +0000414/* router-LSA related functions. */
415/* Get router-LSA flags. */
416u_char
417router_lsa_flags (struct ospf_area *area)
418{
419 u_char flags;
420
paul68980082003-03-25 05:07:42 +0000421 flags = area->ospf->flags;
paul718e3742002-12-13 20:15:29 +0000422
423 /* Set virtual link flag. */
424 if (ospf_full_virtual_nbrs (area))
425 SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
426 else
427 /* Just sanity check */
428 UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);
429
430 /* Set Shortcut ABR behabiour flag. */
431 UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
paul68980082003-03-25 05:07:42 +0000432 if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
paul718e3742002-12-13 20:15:29 +0000433 if (!OSPF_IS_AREA_BACKBONE (area))
434 if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
paul68980082003-03-25 05:07:42 +0000435 area->ospf->backbone == NULL) ||
paul718e3742002-12-13 20:15:29 +0000436 area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
437 SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
438
439 /* ASBR can't exit in stub area. */
440 if (area->external_routing == OSPF_AREA_STUB)
441 UNSET_FLAG (flags, OSPF_FLAG_ASBR);
442
443 return flags;
444}
445
446/* Lookup neighbor other than myself.
447 And check neighbor count,
448 Point-to-Point link must have only 1 neighbor. */
449struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +0000450ospf_nbr_lookup_ptop (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +0000451{
paul718e3742002-12-13 20:15:29 +0000452 struct ospf_neighbor *nbr = NULL;
paul68980082003-03-25 05:07:42 +0000453 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000454
455 /* Search neighbor, there must be one of two nbrs. */
paul68980082003-03-25 05:07:42 +0000456 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
457 if ((nbr = rn->info))
458 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000459 if (nbr->state == NSM_Full)
paul68980082003-03-25 05:07:42 +0000460 {
461 route_unlock_node (rn);
462 break;
463 }
paul718e3742002-12-13 20:15:29 +0000464
465 /* PtoP link must have only 1 neighbor. */
paul68980082003-03-25 05:07:42 +0000466 if (ospf_nbr_count (oi, 0) > 1)
paul718e3742002-12-13 20:15:29 +0000467 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
468
469 return nbr;
470}
471
472/* Set a link information. */
473void
474link_info_set (struct stream *s, struct in_addr id,
475 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
476{
477 /* TOS based routing is not supported. */
478 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
479 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
480 stream_putc (s, type); /* Link Type. */
481 stream_putc (s, tos); /* TOS = 0. */
482 stream_putw (s, cost); /* Link Cost. */
483}
484
485/* Describe Point-to-Point link. */
486int
487lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
488{
489 int links = 0;
490 struct ospf_neighbor *nbr;
491 struct in_addr id, mask;
492
493 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
494 zlog_info ("LSA[Type1]: Set link Point-to-Point");
495
paul68980082003-03-25 05:07:42 +0000496 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000497 if (nbr->state == NSM_Full)
498 {
499 /* For unnumbered point-to-point networks, the Link Data field
500 should specify the interface's MIB-II ifIndex value. */
501 link_info_set (s, nbr->router_id, oi->address->u.prefix4,
502 LSA_LINK_TYPE_POINTOPOINT, 0, oi->output_cost);
503 links++;
504 }
505
506 if (oi->connected->destination != NULL)
507 {
508 /* Option 1:
509 link_type = LSA_LINK_TYPE_STUB;
510 link_id = nbr->address.u.prefix4;
511 link_data.s_addr = 0xffffffff;
512 link_cost = o->output_cost; */
513
514 id.s_addr = oi->connected->destination->u.prefix4.s_addr;
515 mask.s_addr = 0xffffffff;
516 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
517 }
518 else
519 {
520 /* Option 2: We need to include link to a stub
521 network regardless of the state of the neighbor */
522 masklen2ip (oi->address->prefixlen, &mask);
523 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
524 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
525 }
526 links++;
527
528 return links;
529}
530
531/* Describe Broadcast Link. */
532int
533lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
534{
535 struct ospf_neighbor *dr;
536 struct in_addr id, mask;
537
538 /* Describe Type 3 Link. */
539 if (oi->state == ISM_Waiting)
540 {
541 masklen2ip (oi->address->prefixlen, &mask);
542 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
543 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
544 return 1;
545 }
546
547 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
548 /* Describe Type 2 link. */
549 if (dr && (dr->state == NSM_Full ||
550 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000551 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000552 {
553 link_info_set (s, DR (oi), oi->address->u.prefix4,
554 LSA_LINK_TYPE_TRANSIT, 0, oi->output_cost);
555 }
556 /* Describe type 3 link. */
557 else
558 {
559 masklen2ip (oi->address->prefixlen, &mask);
560 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
561 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
562 }
563 return 1;
564}
565
566int
567lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
568{
569 struct in_addr id, mask;
570
571 /* Describe Type 3 Link. */
572 if (oi->state != ISM_Loopback)
573 return 0;
574
575 mask.s_addr = 0xffffffff;
576 id.s_addr = oi->address->u.prefix4.s_addr;
577 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
578 return 1;
579}
580
581/* Describe Virtual Link. */
582int
583lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
584{
585 struct ospf_neighbor *nbr;
586
paul718e3742002-12-13 20:15:29 +0000587 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000588 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000589 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 */
paul68980082003-03-25 05:07:42 +0000605int
606lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000607{
608 int links = 0;
609 struct route_node *rn;
610 struct ospf_neighbor *nbr = NULL;
611 struct in_addr id, mask;
612
613 mask.s_addr = 0xffffffff;
614 id.s_addr = oi->address->u.prefix4.s_addr;
615 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
616 links++;
617
618 zlog_info ("PointToMultipoint: running ptomultip_set");
619
620 /* Search neighbor, */
621 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
622 if ((nbr = rn->info) != NULL)
623 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000624 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000625 if (nbr->state == NSM_Full)
626
627 {
paul7afa08d2002-12-13 20:59:45 +0000628 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;
paul7afa08d2002-12-13 20:59:45 +0000636}
637
paul718e3742002-12-13 20:15:29 +0000638/* Set router-LSA link information. */
639int
640router_lsa_link_set (struct stream *s, struct ospf_area *area)
641{
642 listnode node;
643 int links = 0;
644
645 for (node = listhead (area->oiflist); node; node = nextnode (node))
646 {
647 struct ospf_interface *oi = node->data;
648 struct interface *ifp = oi->ifp;
649
650 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000651 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000652 {
653 if (oi->state != ISM_Down)
654 {
655 /* Describe each link. */
656 switch (oi->type)
657 {
658 case OSPF_IFTYPE_POINTOPOINT:
659 links += lsa_link_ptop_set (s, oi);
660 break;
661 case OSPF_IFTYPE_BROADCAST:
662 links += lsa_link_broadcast_set (s, oi);
663 break;
664 case OSPF_IFTYPE_NBMA:
665 links += lsa_link_nbma_set (s, oi);
666 break;
667 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000668 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000669 break;
670 case OSPF_IFTYPE_VIRTUALLINK:
671 links += lsa_link_virtuallink_set (s, oi);
672 break;
673 case OSPF_IFTYPE_LOOPBACK:
674 links += lsa_link_loopback_set (s, oi);
675 }
676 }
677 }
678 }
679
680 return links;
681}
682
683/* Set router-LSA body. */
684void
685ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
686{
687 unsigned long putp;
688 u_int16_t cnt;
689
690 /* Set flags. */
691 stream_putc (s, router_lsa_flags (area));
692
693 /* Set Zero fields. */
694 stream_putc (s, 0);
695
696 /* Keep pointer to # links. */
697 putp = s->putp;
698
699 /* Forward word */
700 stream_putw(s, 0);
701
702 /* Set all link information. */
703 cnt = router_lsa_link_set (s, area);
704
705 /* Set # of links here. */
706 stream_putw_at (s, putp, cnt);
707}
708
709/* Create new router-LSA. */
710struct ospf_lsa *
711ospf_router_lsa_new (struct ospf_area *area)
712{
paul68980082003-03-25 05:07:42 +0000713 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000714 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),
paul68980082003-03-25 05:07:42 +0000729 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000730#else /* ! HAVE_NSSA */
731 /* Set LSA common header fields. */
732 lsa_header_set (s, LSA_OPTIONS_GET (area),
paul68980082003-03-25 05:07:42 +0000733 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000734#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. */
paul68980082003-03-25 05:07:42 +0000775 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000776
777 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000778 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000779
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. */
paul68980082003-03-25 05:07:42 +0000804 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000805
806 /* Create new router-LSA instance. */
807 new = ospf_router_lsa_new (area);
808 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
809
paul68980082003-03-25 05:07:42 +0000810 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000811
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
paul68980082003-03-25 05:07:42 +0000880ospf_router_lsa_update_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000881{
paul68980082003-03-25 05:07:42 +0000882 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +0000883 listnode node;
884
885 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
886 zlog_info ("Timer[router-LSA Update]: (timer expire)");
887
paul68980082003-03-25 05:07:42 +0000888 ospf->t_router_lsa_update = NULL;
paul718e3742002-12-13 20:15:29 +0000889
paul68980082003-03-25 05:07:42 +0000890 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +0000891 {
892 struct ospf_area *area = getdata (node);
893 struct ospf_lsa *lsa = area->router_lsa_self;
894 struct router_lsa *rl;
895 char *area_str;
896
897 /* Keep Area ID string. */
898 area_str = AREA_NAME (area);
899
900 /* If LSA not exist in this Area, originate new. */
901 if (lsa == NULL)
902 {
903 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
904 zlog_info("LSA[Type1]: Create router-LSA for Area %s", area_str);
905
906 ospf_router_lsa_originate (area);
907 }
908 /* If router-ID is changed, Link ID must change.
909 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +0000910 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000911 {
912 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
913 zlog_info("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
914 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
915 ospf_lsa_flush_area (lsa, area);
916 ospf_lsa_unlock (area->router_lsa_self);
917 area->router_lsa_self = NULL;
918
919 /* Refresh router-LSA, (not install) and flood through area. */
920 ospf_router_lsa_timer_add (area);
921 }
922 else
923 {
924 rl = (struct router_lsa *) lsa->data;
925 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +0000926 if (rl->flags != ospf->flags)
paul718e3742002-12-13 20:15:29 +0000927 ospf_router_lsa_timer_add (area);
928 }
929 }
930
931 return 0;
932}
933
934
935/* network-LSA related functions. */
936/* Originate Network-LSA. */
937void
938ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
939{
940 struct in_addr mask;
941 struct route_node *rn;
942 struct ospf_neighbor *nbr;
943
944 masklen2ip (oi->address->prefixlen, &mask);
945 stream_put_ipv4 (s, mask.s_addr);
946
947 /* The network-LSA lists those routers that are fully adjacent to
948 the Designated Router; each fully adjacent router is identified by
949 its OSPF Router ID. The Designated Router includes itself in this
950 list. RFC2328, Section 12.4.2 */
951
952 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
953 if ((nbr = rn->info) != NULL)
954 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
955 stream_put_ipv4 (s, nbr->router_id.s_addr);
956}
957
958struct ospf_lsa *
959ospf_network_lsa_new (struct ospf_interface *oi)
960{
961 struct stream *s;
962 struct ospf_lsa *new;
963 struct lsa_header *lsah;
964 int length;
965
966 /* If there are no neighbours on this network (the net is stub),
967 the router does not originate network-LSA (see RFC 12.4.2) */
968 if (oi->full_nbrs == 0)
969 return NULL;
970
971 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
972 zlog_info ("LSA[Type2]: Create network-LSA instance");
973
974 /* Create new stream for LSA. */
975 s = stream_new (OSPF_MAX_LSA_SIZE);
976 lsah = (struct lsa_header *) STREAM_DATA (s);
977
978 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +0000979 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000980
981 /* Set network-LSA body fields. */
982 ospf_network_lsa_body_set (s, oi);
983
984 /* Set length. */
985 length = stream_get_endp (s);
986 lsah->length = htons (length);
987
988 /* Create OSPF LSA instance. */
989 new = ospf_lsa_new ();
990 new->area = oi->area;
991 SET_FLAG (new->flags, OSPF_LSA_SELF);
992
993 /* Copy LSA to store. */
994 new->data = ospf_lsa_data_new (length);
995 memcpy (new->data, lsah, length);
996 stream_free (s);
997
998 return new;
999}
1000
1001/* Originate network-LSA. */
1002struct ospf_lsa *
1003ospf_network_lsa_originate (struct ospf_interface *oi)
1004{
1005 struct ospf_lsa *new;
1006
1007 /* Create new network-LSA instance. */
1008 new = ospf_network_lsa_new (oi);
1009 if (new == NULL)
1010 return NULL;
1011
1012 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001013 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001014
1015 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001016 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001017
1018 /* Flooding new LSA through area. */
1019 ospf_flood_through_area (oi->area, NULL, new);
1020
1021 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1022 {
1023 zlog_info ("LSA[Type%d:%s]: Originate network-LSA %p",
1024 new->data->type, inet_ntoa (new->data->id), new);
1025 ospf_lsa_header_dump (new->data);
1026 }
1027
1028 return new;
1029}
1030
1031int
1032ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1033{
1034 struct ospf_area *area = lsa->area;
1035 struct ospf_lsa *new;
1036
1037 assert (lsa->data);
1038
1039 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001040 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001041
1042 /* Create new network-LSA instance. */
1043 new = ospf_network_lsa_new (oi);
1044 if (new == NULL)
1045 return -1;
1046 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1047
paul68980082003-03-25 05:07:42 +00001048 ospf_lsa_install (area->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001049
1050 /* Flood LSA through aera. */
1051 ospf_flood_through_area (area, NULL, new);
1052
1053 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1054 {
1055 zlog_info ("LSA[Type%d:%s]: network-LSA refresh",
1056 new->data->type, inet_ntoa (new->data->id));
1057 ospf_lsa_header_dump (new->data);
1058 }
1059
1060 return 0;
1061}
1062
1063int
1064ospf_network_lsa_refresh_timer (struct thread *t)
1065{
1066 struct ospf_interface *oi;
1067
1068 oi = THREAD_ARG (t);
1069 oi->t_network_lsa_self = NULL;
1070
1071 if (oi->network_lsa_self)
1072 /* Now refresh network-LSA. */
1073 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1074 else
1075 /* Newly create network-LSA. */
1076 ospf_network_lsa_originate (oi);
1077
1078 return 0;
1079}
1080
1081void
1082ospf_network_lsa_timer_add (struct ospf_interface *oi)
1083{
1084 /* Keep interface's self-originated network-LSA. */
1085 struct ospf_lsa *lsa = oi->network_lsa_self;
1086
1087 /* Cancel previously schedules network-LSA timer. */
1088 if (oi->t_network_lsa_self)
1089 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1090 zlog_info ("LSA[Type2]: Cancel previous network-LSA timer");
1091 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1092
1093 /* If network-LSA is originated previously, check the interval time. */
1094 if (lsa)
1095 {
1096 int delay;
1097 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1098 {
1099 oi->t_network_lsa_self =
1100 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1101 oi, delay);
1102 return;
1103 }
1104 }
1105
1106 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1107 zlog_info ("Scheduling network-LSA origination right away");
1108
1109 /* Immediately refresh network-LSA. */
1110 oi->t_network_lsa_self =
1111 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1112}
1113
1114
1115void
1116stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1117{
1118 u_int32_t metric;
1119 char *mp;
1120
1121 /* Put 0 metric. TOS metric is not supported. */
1122 metric = htonl (metric_value);
1123 mp = (char *) &metric;
1124 mp++;
1125 stream_put (s, mp, 3);
1126}
1127
1128/* summary-LSA related functions. */
1129void
1130ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1131 u_int32_t metric)
1132{
1133 struct in_addr mask;
1134
1135 masklen2ip (p->prefixlen, &mask);
1136
1137 /* Put Network Mask. */
1138 stream_put_ipv4 (s, mask.s_addr);
1139
1140 /* Set # TOS. */
1141 stream_putc (s, (u_char) 0);
1142
1143 /* Set metric. */
1144 stream_put_ospf_metric (s, metric);
1145}
1146
1147struct ospf_lsa *
1148ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1149 u_int32_t metric, struct in_addr id)
1150{
1151 struct stream *s;
1152 struct ospf_lsa *new;
1153 struct lsa_header *lsah;
1154 int length;
1155
1156 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1157 zlog_info ("LSA[Type3]: Create summary-LSA instance");
1158
1159 /* Create new stream for LSA. */
1160 s = stream_new (OSPF_MAX_LSA_SIZE);
1161 lsah = (struct lsa_header *) STREAM_DATA (s);
1162
paul68980082003-03-25 05:07:42 +00001163 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1164 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001165
1166 /* Set summary-LSA body fields. */
1167 ospf_summary_lsa_body_set (s, p, metric);
1168
1169 /* Set length. */
1170 length = stream_get_endp (s);
1171 lsah->length = htons (length);
1172
1173 /* Create OSPF LSA instance. */
1174 new = ospf_lsa_new ();
1175 new->area = area;
1176 SET_FLAG (new->flags, OSPF_LSA_SELF);
1177
1178 /* Copy LSA to store. */
1179 new->data = ospf_lsa_data_new (length);
1180 memcpy (new->data, lsah, length);
1181 stream_free (s);
1182
1183 return new;
1184}
1185
1186/* Originate Summary-LSA. */
1187struct ospf_lsa *
1188ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1189 struct ospf_area *area)
1190{
1191 struct ospf_lsa *new;
1192 struct in_addr id;
1193
paul68980082003-03-25 05:07:42 +00001194 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001195
1196 /* Create new summary-LSA instance. */
1197 new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id);
1198
1199 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001200 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001201
1202 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001203 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001204
1205 /* Flooding new LSA through area. */
1206 ospf_flood_through_area (area, NULL, new);
1207
1208 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1209 {
1210 zlog_info ("LSA[Type%d:%s]: Originate summary-LSA %p",
1211 new->data->type, inet_ntoa (new->data->id), new);
1212 ospf_lsa_header_dump (new->data);
1213 }
1214
1215 return new;
1216}
1217
1218struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001219ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001220{
1221 struct ospf_lsa *new;
1222 struct summary_lsa *sl;
1223 struct prefix p;
1224
1225 /* Sanity check. */
1226 assert (lsa->data);
1227
1228 sl = (struct summary_lsa *)lsa->data;
1229 p.prefixlen = ip_masklen (sl->mask);
1230 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1231 sl->header.id);
1232
1233 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1234
1235 /* Re-calculate checksum. */
1236 ospf_lsa_checksum (new->data);
1237
paul68980082003-03-25 05:07:42 +00001238 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001239
1240 /* Flood LSA through AS. */
1241 ospf_flood_through_area (new->area, NULL, new);
1242
1243 /* Debug logging. */
1244 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1245 {
1246 zlog_info ("LSA[Type%d:%s]: summary-LSA refresh",
1247 new->data->type, inet_ntoa (new->data->id));
1248 ospf_lsa_header_dump (new->data);
1249 }
1250
1251 return new;
1252}
1253
1254
1255/* summary-ASBR-LSA related functions. */
1256void
1257ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1258 u_int32_t metric)
1259{
1260 struct in_addr mask;
1261
1262 masklen2ip (p->prefixlen, &mask);
1263
1264 /* Put Network Mask. */
1265 stream_put_ipv4 (s, mask.s_addr);
1266
1267 /* Set # TOS. */
1268 stream_putc (s, (u_char) 0);
1269
1270 /* Set metric. */
1271 stream_put_ospf_metric (s, metric);
1272}
1273
1274struct ospf_lsa *
1275ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1276 u_int32_t metric, struct in_addr id)
1277{
1278 struct stream *s;
1279 struct ospf_lsa *new;
1280 struct lsa_header *lsah;
1281 int length;
1282
1283 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1284 zlog_info ("LSA[Type3]: Create summary-LSA instance");
1285
1286 /* Create new stream for LSA. */
1287 s = stream_new (OSPF_MAX_LSA_SIZE);
1288 lsah = (struct lsa_header *) STREAM_DATA (s);
1289
paul68980082003-03-25 05:07:42 +00001290 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1291 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001292
1293 /* Set summary-LSA body fields. */
1294 ospf_summary_asbr_lsa_body_set (s, p, metric);
1295
1296 /* Set length. */
1297 length = stream_get_endp (s);
1298 lsah->length = htons (length);
1299
1300 /* Create OSPF LSA instance. */
1301 new = ospf_lsa_new ();
1302 new->area = area;
1303 SET_FLAG (new->flags, OSPF_LSA_SELF);
1304
1305 /* Copy LSA to store. */
1306 new->data = ospf_lsa_data_new (length);
1307 memcpy (new->data, lsah, length);
1308 stream_free (s);
1309
1310 return new;
1311}
1312
1313/* Originate summary-ASBR-LSA. */
1314struct ospf_lsa *
1315ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1316 struct ospf_area *area)
1317{
1318 struct ospf_lsa *new;
1319 struct in_addr id;
1320
paul68980082003-03-25 05:07:42 +00001321 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001322
1323 /* Create new summary-LSA instance. */
1324 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
1325
1326 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001327 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001328
1329 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001330 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001331
1332 /* Flooding new LSA through area. */
1333 ospf_flood_through_area (area, NULL, new);
1334
1335 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1336 {
1337 zlog_info ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
1338 new->data->type, inet_ntoa (new->data->id), new);
1339 ospf_lsa_header_dump (new->data);
1340 }
1341
1342 return new;
1343}
1344
1345struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001346ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001347{
1348 struct ospf_lsa *new;
1349 struct summary_lsa *sl;
1350 struct prefix p;
1351
1352 /* Sanity check. */
1353 assert (lsa->data);
1354
1355 sl = (struct summary_lsa *)lsa->data;
1356 p.prefixlen = ip_masklen (sl->mask);
1357 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1358 sl->header.id);
1359
1360 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1361
1362 /* Re-calculate checksum. */
1363 ospf_lsa_checksum (new->data);
1364
paul68980082003-03-25 05:07:42 +00001365 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001366
1367 /* Flood LSA through area. */
1368 ospf_flood_through_area (new->area, NULL, new);
1369
1370 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1371 {
1372 zlog_info ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
1373 new->data->type, inet_ntoa (new->data->id));
1374 ospf_lsa_header_dump (new->data);
1375 }
1376
1377 return new;
1378}
1379
1380/* AS-external-LSA related functions. */
1381
1382/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1383 is connected, else 0*/
1384struct in_addr
paul68980082003-03-25 05:07:42 +00001385ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001386{
1387 struct in_addr fwd;
1388 struct prefix nh;
paul718e3742002-12-13 20:15:29 +00001389 listnode n1;
1390
1391 fwd.s_addr = 0;
1392
1393 if (!nexthop.s_addr)
1394 return fwd;
1395
1396 /* Check whether nexthop is covered by OSPF network. */
1397 nh.family = AF_INET;
1398 nh.u.prefix4 = nexthop;
1399 nh.prefixlen = IPV4_MAX_BITLEN;
1400
paul68980082003-03-25 05:07:42 +00001401 for (n1 = listhead (ospf->oiflist); n1; nextnode (n1))
paul718e3742002-12-13 20:15:29 +00001402 {
1403 struct ospf_interface *oi = getdata (n1);
1404
paul2e3b2e42002-12-13 21:03:13 +00001405 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001406 if (oi->address->family == AF_INET)
1407 if (prefix_match (oi->address, &nh))
1408 return nexthop;
1409 }
1410
1411 return fwd;
1412}
1413
1414#ifdef HAVE_NSSA
1415/* NSSA-external-LSA related functions. */
1416
1417/* Get 1st IP connection for Forward Addr */
1418
1419struct in_addr
1420ospf_get_ip_from_ifp (struct ospf_interface *oi)
1421{
1422 struct in_addr fwd;
1423
1424 fwd.s_addr = 0;
1425
paul2e3b2e42002-12-13 21:03:13 +00001426 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001427 return oi->address->u.prefix4;
1428
1429 return fwd;
1430}
1431
1432/* Get 1st IP connection for Forward Addr */
1433struct in_addr
paulf2c80652002-12-13 21:44:27 +00001434ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001435{
1436 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001437 struct in_addr best_default;
paul718e3742002-12-13 20:15:29 +00001438 listnode n1;
1439
1440 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001441 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001442
paul68980082003-03-25 05:07:42 +00001443 for (n1 = listhead (area->ospf->oiflist); n1; nextnode (n1))
paul718e3742002-12-13 20:15:29 +00001444 {
1445 struct ospf_interface *oi = getdata (n1);
1446
paul2e3b2e42002-12-13 21:03:13 +00001447 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001448 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001449 if (oi->address && oi->address->family == AF_INET)
1450 {
1451 if (best_default.s_addr == 0)
1452 best_default = oi->address->u.prefix4;
1453 if (oi->area == area)
1454 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001455 }
paul718e3742002-12-13 20:15:29 +00001456 }
paulf2c80652002-12-13 21:44:27 +00001457 if (best_default.s_addr != 0)
1458 return best_default;
paul718e3742002-12-13 20:15:29 +00001459
paul68980082003-03-25 05:07:42 +00001460 if (best_default.s_addr != 0)
1461 return best_default;
1462
paul718e3742002-12-13 20:15:29 +00001463 return fwd;
1464}
1465#endif /* HAVE_NSSA */
1466
1467#define DEFAULT_DEFAULT_METRIC 20
1468#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1469#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1470
1471#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1472
1473int
paul68980082003-03-25 05:07:42 +00001474metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001475{
paul68980082003-03-25 05:07:42 +00001476 return (ospf->dmetric[src].type < 0 ?
1477 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001478}
1479
1480int
paul68980082003-03-25 05:07:42 +00001481metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001482{
paul68980082003-03-25 05:07:42 +00001483 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001484 {
1485 if (src == DEFAULT_ROUTE)
1486 {
paul68980082003-03-25 05:07:42 +00001487 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001488 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1489 else
1490 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1491 }
paul68980082003-03-25 05:07:42 +00001492 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001493 return DEFAULT_DEFAULT_METRIC;
1494 else
paul68980082003-03-25 05:07:42 +00001495 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001496 }
1497
paul68980082003-03-25 05:07:42 +00001498 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001499}
1500
1501/* Set AS-external-LSA body. */
1502void
paul68980082003-03-25 05:07:42 +00001503ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1504 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001505{
1506 struct prefix_ipv4 *p = &ei->p;
1507 struct in_addr mask, fwd_addr;
1508 u_int32_t mvalue;
1509 int mtype;
1510 int type;
1511
1512 /* Put Network Mask. */
1513 masklen2ip (p->prefixlen, &mask);
1514 stream_put_ipv4 (s, mask.s_addr);
1515
1516 /* If prefix is default, specify DEFAULT_ROUTE. */
1517 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1518
1519 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001520 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001521
1522 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001523 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001524
1525 /* Put type of external metric. */
1526 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1527
1528 /* Put 0 metric. TOS metric is not supported. */
1529 stream_put_ospf_metric (s, mvalue);
1530
1531 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001532 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001533
1534 /* Put forwarding address. */
1535 stream_put_ipv4 (s, fwd_addr.s_addr);
1536
1537 /* Put route tag -- This value should be introduced from configuration. */
1538 stream_putl (s, 0);
1539}
1540
1541/* Create new external-LSA. */
1542struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001543ospf_external_lsa_new (struct ospf *ospf,
1544 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001545{
1546 struct stream *s;
1547 struct lsa_header *lsah;
1548 struct ospf_lsa *new;
1549 struct in_addr id;
1550 int length;
1551
1552 if (ei == NULL)
1553 {
1554 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1555 zlog_warn ("LSA[Type5]: External info is NULL, could not originated");
1556 return NULL;
1557 }
1558
1559 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1560 zlog_info ("LSA[Type5]: Originate AS-external-LSA instance");
1561
1562 /* If old Link State ID is specified, refresh LSA with same ID. */
1563 if (old_id)
1564 id = *old_id;
1565 /* Get Link State with unique ID. */
1566 else
1567 {
paul68980082003-03-25 05:07:42 +00001568 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001569 if (id.s_addr == 0xffffffff)
1570 {
1571 /* Maybe Link State ID not available. */
1572 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1573 zlog_info ("LSA[Type5]: Link ID not available, can't originate");
1574 return NULL;
1575 }
1576 }
1577
1578 /* Create new stream for LSA. */
1579 s = stream_new (OSPF_MAX_LSA_SIZE);
1580 lsah = (struct lsa_header *) STREAM_DATA (s);
1581
1582 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001583 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1584 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001585
1586 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001587 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001588
1589 /* Set length. */
1590 length = stream_get_endp (s);
1591 lsah->length = htons (length);
1592
1593 /* Now, create OSPF LSA instance. */
1594 new = ospf_lsa_new ();
1595 new->area = NULL;
1596 SET_FLAG (new->flags, OSPF_LSA_SELF|OSPF_LSA_APPROVED);
1597
1598 /* Copy LSA data to store, discard stream. */
1599 new->data = ospf_lsa_data_new (length);
1600 memcpy (new->data, lsah, length);
1601 stream_free (s);
1602
1603 return new;
1604}
1605
1606#ifdef HAVE_NSSA
paul718e3742002-12-13 20:15:29 +00001607/* As Type-7 */
1608void
paul68980082003-03-25 05:07:42 +00001609ospf_install_flood_nssa (struct ospf *ospf,
1610 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001611{
1612 struct ospf_lsa *new2;
paul68980082003-03-25 05:07:42 +00001613 struct as_external_lsa *extlsa;
paulf2c80652002-12-13 21:44:27 +00001614 listnode node;
paul718e3742002-12-13 20:15:29 +00001615
1616 /* NSSA Originate or Refresh (If anyNSSA)
1617
1618 LSA is self-originated. And just installed as Type-5.
1619 Additionally, install as Type-7 LSDB for every attached NSSA.
1620
1621 P-Bit controls which ABR performs translation to outside world; If
1622 we are an ABR....do not set the P-bit, because we send the Type-5,
1623 not as the ABR Translator, but as the ASBR owner within the AS!
1624
1625 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1626 elected ABR Translator will see the P-bit, Translate, and re-flood.
1627
1628 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1629 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1630
paul68980082003-03-25 05:07:42 +00001631 for (node = listhead (ospf->areas); node; nextnode (node))
1632 {
1633 struct ospf_area *area = getdata (node);
paul718e3742002-12-13 20:15:29 +00001634
paul68980082003-03-25 05:07:42 +00001635 /* make lsa duplicate, lock=1 */
1636 new2 = ospf_lsa_dup (lsa);
1637 new2->area = area;
1638 new2->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001639
paul68980082003-03-25 05:07:42 +00001640 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001641 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001642 {
1643 SET_FLAG(new2->data->options, OSPF_OPTION_NP);
1644
1645 /* set non-zero FWD ADDR
1646
1647 draft-ietf-ospf-nssa-update-09.txt
1648
1649 if the network between the NSSA AS boundary router and the
1650 adjacent AS is advertised into OSPF as an internal OSPF route,
1651 the forwarding address should be the next op address as is cu
1652 currently done with type-5 LSAs. If the intervening network is
1653 not adversited into OSPF as an internal OSPF route and the
1654 type-7 LSA's P-bit is set a forwarding address should be
1655 selected from one of the router's active OSPF inteface addresses
1656 which belong to the NSSA. If no such addresses exist, then
1657 no type-7 LSA's with the P-bit set should originate from this
1658 router. */
1659
1660 /* kevinm: not updating lsa anymore, just new2 */
1661 extlsa = (struct as_external_lsa *)(new2->data);
1662
1663 if (extlsa->e[0].fwd_addr.s_addr == 0)
1664 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001665
paul68980082003-03-25 05:07:42 +00001666 if (IS_DEBUG_OSPF_NSSA)
1667 if (extlsa->e[0].fwd_addr.s_addr == 0)
1668 {
1669 zlog_info ("LSA[Type-7]: Could not build FWD-ADDR");
1670 ospf_lsa_discard(new2);
1671 return;
1672 }
paulf2c80652002-12-13 21:44:27 +00001673 }
paul68980082003-03-25 05:07:42 +00001674 /* Re-calculate checksum. */
1675 ospf_lsa_checksum (new2->data);
paul718e3742002-12-13 20:15:29 +00001676
paul68980082003-03-25 05:07:42 +00001677 /* install also as Type-7 */
1678 ospf_lsa_install (ospf, NULL, new2); /* Remove Old, Lock New = 2 */
1679
1680 /* will send each copy, lock=2+n */
1681 ospf_flood_through_as (ospf, NULL, new2); /* all attached NSSA's, no AS/STUBs */
1682 }
paul718e3742002-12-13 20:15:29 +00001683}
1684#endif /* HAVE_NSSA */
1685
1686int
1687is_prefix_default (struct prefix_ipv4 *p)
1688{
1689 struct prefix_ipv4 q;
1690
1691 q.family = AF_INET;
1692 q.prefix.s_addr = 0;
1693 q.prefixlen = 0;
1694
1695 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
1696}
1697
1698/* Originate an AS-external-LSA, install and flood. */
1699struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001700ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001701{
1702 struct ospf_lsa *new;
1703
1704 /* Added for NSSA project....
1705
1706 External LSAs are originated in ASBRs as usual, but for NSSA systems.
1707 there is the global Type-5 LSDB and a Type-7 LSDB installed for
1708 every area. The Type-7's are flooded to every IR and every ABR; We
1709 install the Type-5 LSDB so that the normal "refresh" code operates
1710 as usual, and flag them as not used during ASE calculations. The
1711 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
1712 Address of non-zero.
1713
1714 If an ABR is the elected NSSA translator, following SPF and during
1715 the ABR task it will translate all the scanned Type-7's, with P-bit
1716 ON and not-self generated, and translate to Type-5's throughout the
1717 non-NSSA/STUB AS.
1718
1719 A difference in operation depends whether this ASBR is an ABR
1720 or not. If not an ABR, the P-bit is ON, to indicate that any
1721 elected NSSA-ABR can perform its translation.
1722
1723 If an ABR, the P-bit is OFF; No ABR will perform translation and
1724 this ASBR will flood the Type-5 LSA as usual.
1725
1726 For the case where this ASBR is not an ABR, the ASE calculations
1727 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
1728 demonstrate to the user that there are LSA's that belong to any
1729 attached NSSA.
1730
1731 Finally, it just so happens that when the ABR is translating every
1732 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
1733 approved Type-5 (translated from Type-7); at the end of translation
1734 if any Translated Type-5's remain unapproved, then they must be
1735 flushed from the AS.
1736
1737 */
1738
1739 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00001740 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00001741 return NULL;
1742
1743 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00001744 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00001745 {
1746 if (IS_DEBUG_OSPF_EVENT)
1747 zlog_info ("LSA[Type5:%s]: Could not originate AS-external-LSA",
1748 inet_ntoa (ei->p.prefix));
1749 return NULL;
1750 }
1751
1752 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00001753 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001754
1755 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001756 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001757
1758 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00001759 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001760
1761#ifdef HAVE_NSSA
1762 /* If there is any attached NSSA, do special handling */
paul68980082003-03-25 05:07:42 +00001763 if (ospf->anyNSSA)
1764 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00001765#endif /* HAVE_NSSA */
1766
1767 /* Debug logging. */
1768 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1769 {
1770 zlog_info ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
1771 new->data->type, inet_ntoa (new->data->id), new);
1772 ospf_lsa_header_dump (new->data);
1773 }
1774
1775 return new;
1776}
1777
1778/* Originate AS-external-LSA from external info with initial flag. */
1779int
paul68980082003-03-25 05:07:42 +00001780ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00001781{
paul68980082003-03-25 05:07:42 +00001782 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00001783 struct route_node *rn;
1784 struct external_info *ei;
1785 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00001786 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00001787
paul68980082003-03-25 05:07:42 +00001788 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00001789
1790 /* Originate As-external-LSA from all type of distribute source. */
1791 if ((rt = EXTERNAL_INFO (type)))
1792 for (rn = route_top (rt); rn; rn = route_next (rn))
1793 if ((ei = rn->info) != NULL)
1794 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00001795 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00001796 zlog_warn ("LSA: AS-external-LSA was not originated.");
1797
1798 return 0;
1799}
1800
1801struct external_info *
paul020709f2003-04-04 02:44:16 +00001802ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001803{
1804 int type;
1805 struct route_node *rn;
1806 struct prefix_ipv4 p;
1807
1808 p.family = AF_INET;
1809 p.prefix.s_addr = 0;
1810 p.prefixlen = 0;
1811
1812 /* First, lookup redistributed default route. */
1813 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
1814 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
1815 {
1816 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
1817 if (rn != NULL)
1818 {
1819 route_unlock_node (rn);
1820 assert (rn->info);
paul68980082003-03-25 05:07:42 +00001821 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00001822 return rn->info;
1823 }
1824 }
1825
1826 return NULL;
1827}
1828
1829int
paul68980082003-03-25 05:07:42 +00001830ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00001831{
1832 int *origin;
1833 struct prefix_ipv4 p;
1834 struct in_addr nexthop;
1835 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00001836 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00001837
paul020709f2003-04-04 02:44:16 +00001838 ospf = ospf_lookup ();
1839
paul718e3742002-12-13 20:15:29 +00001840 /* Get originate flags. */
paul68980082003-03-25 05:07:42 +00001841 origin = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00001842
1843 p.family = AF_INET;
1844 p.prefix.s_addr = 0;
1845 p.prefixlen = 0;
1846
1847 if (*origin == DEFAULT_ORIGINATE_ALWAYS)
1848 {
1849 /* If there is no default route via redistribute,
1850 then originate AS-external-LSA with nexthop 0 (self). */
1851 nexthop.s_addr = 0;
1852 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
1853 }
1854
paul020709f2003-04-04 02:44:16 +00001855 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00001856 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00001857
1858 return 0;
1859}
1860
1861/* Flush an AS-external-LSA from LSDB and routing domain. */
1862void
paul68980082003-03-25 05:07:42 +00001863ospf_external_lsa_flush (struct ospf *ospf,
1864 u_char type, struct prefix_ipv4 *p,
paul718e3742002-12-13 20:15:29 +00001865 unsigned int ifindex, struct in_addr nexthop)
1866{
1867 struct ospf_lsa *lsa;
1868
1869 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
1870 zlog_info ("LSA: Flushing AS-external-LSA %s/%d",
1871 inet_ntoa (p->prefix), p->prefixlen);
1872
1873 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00001874 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00001875 {
1876 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
1877 zlog_warn ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
1878 inet_ntoa (p->prefix), p->prefixlen);
1879 return;
1880 }
1881
1882 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00001883 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00001884
1885 /* There must be no self-originated LSA in rtrs_external. */
1886#if 0
1887 /* Remove External route from Zebra. */
1888 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
1889#endif
1890
1891 if (!IS_LSA_MAXAGE (lsa))
1892 {
1893 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00001894 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00001895
1896 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00001897 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00001898 }
1899
1900 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
1901 zlog_info ("ospf_external_lsa_flush(): stop");
1902}
1903
1904void
paul68980082003-03-25 05:07:42 +00001905ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001906{
1907 struct prefix_ipv4 p;
1908 struct external_info *ei;
1909 struct ospf_lsa *lsa;
1910
1911 p.family = AF_INET;
1912 p.prefixlen = 0;
1913 p.prefix.s_addr = 0;
1914
paul020709f2003-04-04 02:44:16 +00001915 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00001916 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00001917
1918 if (ei)
1919 {
1920 if (lsa)
1921 {
1922 if (IS_DEBUG_OSPF_EVENT)
1923 zlog_info ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00001924 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00001925 }
1926 else
1927 {
1928 if (IS_DEBUG_OSPF_EVENT)
1929 zlog_info ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00001930 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00001931 }
1932 }
1933 else
1934 {
1935 if (lsa)
1936 {
1937 if (IS_DEBUG_OSPF_EVENT)
1938 zlog_info ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00001939 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00001940 }
1941 }
1942}
1943
1944void
paul68980082003-03-25 05:07:42 +00001945ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00001946{
1947 struct route_node *rn;
1948 struct external_info *ei;
1949
1950 if (type != DEFAULT_ROUTE)
1951 if (EXTERNAL_INFO(type))
1952 /* Refresh each redistributed AS-external-LSAs. */
1953 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
1954 if ((ei = rn->info))
1955 if (!is_prefix_default (&ei->p))
1956 {
1957 struct ospf_lsa *lsa;
1958
paul68980082003-03-25 05:07:42 +00001959 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
1960 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00001961 else
paul68980082003-03-25 05:07:42 +00001962 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00001963 }
1964}
1965
1966/* Refresh AS-external-LSA. */
1967void
paul68980082003-03-25 05:07:42 +00001968ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00001969 struct external_info *ei, int force)
1970{
1971 struct ospf_lsa *new;
1972 int changed;
1973
1974 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00001975 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00001976 {
paul68980082003-03-25 05:07:42 +00001977 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
1978 ei->ifindex, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001979 return;
1980 }
1981
1982 if (!changed && !force)
1983 return;
1984
1985 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001986 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00001987
1988 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00001989 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00001990
paul68980082003-03-25 05:07:42 +00001991 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00001992
1993 if (new == NULL)
1994 {
1995 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1996 zlog_warn ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
1997 inet_ntoa (lsa->data->id));
1998 return;
1999 }
2000
2001 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2002
2003 /* Record timestamp. */
2004 gettimeofday (&new->tv_orig, NULL);
2005
2006 /* Re-calculate checksum. */
2007 ospf_lsa_checksum (new->data);
2008
paul68980082003-03-25 05:07:42 +00002009 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002010
2011 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002012 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002013
2014#ifdef HAVE_NSSA
2015 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
paul68980082003-03-25 05:07:42 +00002016 if (ospf->anyNSSA)
2017 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002018#endif /* HAVE_NSSA */
2019
2020 /* Register slef-originated LSA to refresh queue. */
paul68980082003-03-25 05:07:42 +00002021 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002022
2023 /* Debug logging. */
2024 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2025 {
2026 zlog_info ("LSA[Type%d:%s]: AS-external-LSA refresh",
2027 new->data->type, inet_ntoa (new->data->id));
2028 ospf_lsa_header_dump (new->data);
2029 }
2030
2031 return;
2032}
2033
2034
2035/* LSA installation functions. */
2036
2037/* Install router-LSA to an area. */
2038struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002039ospf_router_lsa_install (struct ospf *ospf,
2040 struct ospf_lsa *new, int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002041{
2042 struct ospf_area *area = new->area;
2043
2044 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2045 The entire routing table must be recalculated, starting with
2046 the shortest path calculations for each area (not just the
2047 area whose link-state database has changed).
2048 */
2049 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002050 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002051
2052 if (IS_LSA_SELF (new))
2053 {
2054 /* Set router-LSA refresh timer. */
2055 OSPF_TIMER_OFF (area->t_router_lsa_self);
2056 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
2057 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
2058
2059 /* Set self-originated router-LSA. */
2060 ospf_lsa_unlock (area->router_lsa_self);
2061 area->router_lsa_self = ospf_lsa_lock (new);
2062
2063 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2064 zlog_info("LSA[Type%d]: ID %s is self-originated",
2065 new->data->type, inet_ntoa (new->data->id));
2066 }
2067
2068 return new;
2069}
2070
2071#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2072 if (!(T)) \
2073 (T) = thread_add_timer (master, (F), oi, (V))
2074
2075/* Install network-LSA to an area. */
2076struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002077ospf_network_lsa_install (struct ospf *ospf,
2078 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002079 struct ospf_lsa *new,
2080 int rt_recalc)
2081{
2082
2083 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2084 The entire routing table must be recalculated, starting with
2085 the shortest path calculations for each area (not just the
2086 area whose link-state database has changed).
2087 */
2088 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002089 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002090
2091 /* We supposed that when LSA is originated by us, we pass the int
2092 for which it was originated. If LSA was received by flooding,
2093 the RECEIVED flag is set, so we do not link the LSA to the int. */
2094 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2095 {
2096 /* Set LSRefresh timer. */
2097 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2098
2099 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2100 ospf_network_lsa_refresh_timer,
2101 OSPF_LS_REFRESH_TIME);
2102
2103 ospf_lsa_unlock (oi->network_lsa_self);
2104 oi->network_lsa_self = ospf_lsa_lock (new);
2105 }
2106
2107 return new;
2108}
2109
2110/* Install summary-LSA to an area. */
2111struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002112ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2113 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002114{
paul718e3742002-12-13 20:15:29 +00002115 if (rt_recalc && !IS_LSA_SELF (new))
2116 {
2117 /* RFC 2328 Section 13.2 Summary-LSAs
2118 The best route to the destination described by the summary-
2119 LSA must be recalculated (see Section 16.5). If this
2120 destination is an AS boundary router, it may also be
2121 necessary to re-examine all the AS-external-LSAs.
2122 */
2123
2124#if 0
2125 /* This doesn't exist yet... */
2126 ospf_summary_incremental_update(new); */
2127#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002128 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002129#endif /* #if 0 */
2130
2131 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2132 zlog_info ("ospf_summary_lsa_install(): SPF scheduled");
2133 }
2134
2135 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002136 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002137
2138 return new;
2139}
2140
2141/* Install ASBR-summary-LSA to an area. */
2142struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002143ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2144 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002145{
2146 if (rt_recalc && !IS_LSA_SELF (new))
2147 {
2148 /* RFC 2328 Section 13.2 Summary-LSAs
2149 The best route to the destination described by the summary-
2150 LSA must be recalculated (see Section 16.5). If this
2151 destination is an AS boundary router, it may also be
2152 necessary to re-examine all the AS-external-LSAs.
2153 */
2154#if 0
2155 /* These don't exist yet... */
2156 ospf_summary_incremental_update(new);
2157 /* Isn't this done by the above call?
2158 - RFC 2328 Section 16.5 implies it should be */
2159 /* ospf_ase_calculate_schedule(); */
2160#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002161 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002162#endif /* #if 0 */
2163 }
2164
2165 /* register LSA to refresh-list. */
2166 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002167 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002168
2169 return new;
2170}
2171
2172/* Install AS-external-LSA. */
2173struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002174ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2175 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002176{
paul68980082003-03-25 05:07:42 +00002177 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002178 /* If LSA is not self-originated, calculate an external route. */
2179 if (rt_recalc)
2180 {
2181 /* RFC 2328 Section 13.2 AS-external-LSAs
2182 The best route to the destination described by the AS-
2183 external-LSA must be recalculated (see Section 16.6).
2184 */
2185
2186 if (!IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002187 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002188 }
2189
2190 /* Register self-originated LSA to refresh queue. */
2191 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002192 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002193
2194 return new;
2195}
2196
2197void
paul68980082003-03-25 05:07:42 +00002198ospf_discard_from_db (struct ospf *ospf,
2199 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002200{
2201 struct ospf_lsa *old;
2202
2203 old = ospf_lsdb_lookup (lsdb, lsa);
2204
2205 if (!old)
2206 return;
2207
2208 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002209 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002210
2211 switch (old->data->type)
2212 {
2213 case OSPF_AS_EXTERNAL_LSA:
2214#ifdef HAVE_OPAQUE_LSA
2215 case OSPF_OPAQUE_AS_LSA:
2216#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002217 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2218 ospf_ase_unregister_external_lsa (old, ospf);
paul718e3742002-12-13 20:15:29 +00002219 break;
2220 default:
paul68980082003-03-25 05:07:42 +00002221 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002222 break;
2223 }
2224
paul68980082003-03-25 05:07:42 +00002225 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002226 ospf_lsa_discard (old);
2227}
2228
paul718e3742002-12-13 20:15:29 +00002229struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002230ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2231 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002232{
2233 struct ospf_lsa *new = NULL;
2234 struct ospf_lsa *old = NULL;
2235 struct ospf_lsdb *lsdb = NULL;
2236 int rt_recalc;
2237
2238 /* Set LSDB. */
2239 switch (lsa->data->type)
2240 {
paul68980082003-03-25 05:07:42 +00002241#ifdef HAVE_NSSA
paulf2c80652002-12-13 21:44:27 +00002242 /* kevinm */
2243 case OSPF_AS_NSSA_LSA:
2244 if (lsa->area)
2245 lsdb = lsa->area->lsdb;
2246 else
paul68980082003-03-25 05:07:42 +00002247 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002248 break;
paul68980082003-03-25 05:07:42 +00002249#endif /* HAVE_NSSA */
paul718e3742002-12-13 20:15:29 +00002250 case OSPF_AS_EXTERNAL_LSA:
2251#ifdef HAVE_OPAQUE_LSA
2252 case OSPF_OPAQUE_AS_LSA:
2253#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002254 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002255 break;
2256 default:
2257 lsdb = lsa->area->lsdb;
2258 break;
2259 }
2260
paul718e3742002-12-13 20:15:29 +00002261 assert (lsdb);
2262
2263 /* RFC 2328 13.2. Installing LSAs in the database
2264
2265 Installing a new LSA in the database, either as the result of
2266 flooding or a newly self-originated LSA, may cause the OSPF
2267 routing table structure to be recalculated. The contents of the
2268 new LSA should be compared to the old instance, if present. If
2269 there is no difference, there is no need to recalculate the
2270 routing table. When comparing an LSA to its previous instance,
2271 the following are all considered to be differences in contents:
2272
2273 o The LSA's Options field has changed.
2274
2275 o One of the LSA instances has LS age set to MaxAge, and
2276 the other does not.
2277
2278 o The length field in the LSA header has changed.
2279
2280 o The body of the LSA (i.e., anything outside the 20-byte
2281 LSA header) has changed. Note that this excludes changes
2282 in LS Sequence Number and LS Checksum.
2283
2284 */
2285 /* Look up old LSA and determine if any SPF calculation or incremental
2286 update is needed */
2287 old = ospf_lsdb_lookup (lsdb, lsa);
2288
2289 /* Do comparision and record if recalc needed. */
2290 rt_recalc = 0;
2291 if ( old == NULL || ospf_lsa_different(old, lsa))
2292 rt_recalc = 1;
2293
2294 /* discard old LSA from LSDB */
2295 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002296 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002297
2298 /* Insert LSA to LSDB. */
2299 ospf_lsdb_add (lsdb, lsa);
2300 lsa->lsdb = lsdb;
2301
2302 /* Calculate Checksum if self-originated?. */
2303 if (IS_LSA_SELF (lsa))
2304 ospf_lsa_checksum (lsa->data);
2305
2306 /* Do LSA specific installation process. */
2307 switch (lsa->data->type)
2308 {
2309 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002310 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002311 break;
2312 case OSPF_NETWORK_LSA:
2313 assert (oi);
paul68980082003-03-25 05:07:42 +00002314 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002315 break;
2316 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002317 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002318 break;
2319 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002320 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002321 break;
2322 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002323 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002324 break;
2325#ifdef HAVE_OPAQUE_LSA
2326 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002327 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002328 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002329 else
paul68980082003-03-25 05:07:42 +00002330 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002331 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002332 case OSPF_OPAQUE_AREA_LSA:
2333 case OSPF_OPAQUE_AS_LSA:
2334 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2335 break;
2336#endif /* HAVE_OPAQUE_LSA */
2337 default: /* NSSA, or type-6,8,9....nothing special */
2338#ifdef HAVE_NSSA
paul68980082003-03-25 05:07:42 +00002339 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002340#endif /* HAVE_NSSA */
2341 break;
2342 }
2343
2344 if (new == NULL)
2345 return new; /* Installation failed, cannot proceed further -- endo. */
2346
2347 /* Debug logs. */
2348 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2349 {
2350 char area_str[INET_ADDRSTRLEN];
2351
2352 switch (lsa->data->type)
2353 {
2354 case OSPF_AS_EXTERNAL_LSA:
2355#ifdef HAVE_OPAQUE_LSA
2356 case OSPF_OPAQUE_AS_LSA:
2357#endif /* HAVE_OPAQUE_LSA */
paulf2c80652002-12-13 21:44:27 +00002358#ifdef HAVE_NSSA
2359 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002360#endif /* HAVE_NSSA */
paul718e3742002-12-13 20:15:29 +00002361 zlog_info ("LSA[%s]: Install %s",
2362 dump_lsa_key (new),
2363 LOOKUP (ospf_lsa_type_msg, new->data->type));
2364 break;
2365 default:
2366 strcpy (area_str, inet_ntoa (new->area->area_id));
2367 zlog_info ("LSA[%s]: Install %s to Area %s",
2368 dump_lsa_key (new),
2369 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2370 break;
2371 }
2372 }
2373
2374 /* If received LSA' ls_age is MaxAge, set LSA on MaxAge LSA list. */
2375 if (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new))
2376 {
2377 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2378 zlog_info ("LSA[Type%d:%s]: Install LSA, MaxAge",
2379 new->data->type, inet_ntoa (new->data->id));
paul68980082003-03-25 05:07:42 +00002380 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002381 }
2382
2383 return new;
2384}
2385
2386
2387int
paul68980082003-03-25 05:07:42 +00002388ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002389{
2390 listnode node;
2391
paul68980082003-03-25 05:07:42 +00002392 for (node = listhead (ospf->oiflist); node; node = nextnode (node))
paul718e3742002-12-13 20:15:29 +00002393 {
2394 struct ospf_interface *oi = getdata (node);
2395 struct route_node *rn;
2396 struct ospf_neighbor *nbr;
2397
2398 if (ospf_if_is_enable (oi))
2399 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2400 if ((nbr = rn->info) != NULL)
2401 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2402 {
2403 route_unlock_node (rn);
2404 return 0;
2405 }
2406 }
2407
2408 return 1;
2409}
2410
2411
2412#ifdef ORIGINAL_CODING
2413/* This function flood the maxaged LSA to DR. */
2414void
2415ospf_maxage_flood (struct ospf_lsa *lsa)
2416{
2417 switch (lsa->data->type)
2418 {
2419 case OSPF_ROUTER_LSA:
2420 case OSPF_NETWORK_LSA:
2421 case OSPF_SUMMARY_LSA:
2422 case OSPF_ASBR_SUMMARY_LSA:
2423#ifdef HAVE_NSSA
2424 case OSPF_AS_NSSA_LSA:
2425#endif /* HAVE_NSSA */
2426#ifdef HAVE_OPAQUE_LSA
2427 case OSPF_OPAQUE_LINK_LSA:
2428 case OSPF_OPAQUE_AREA_LSA:
2429#endif /* HAVE_OPAQUE_LSA */
2430 ospf_flood_through_area (lsa->area, NULL, lsa);
2431 break;
2432 case OSPF_AS_EXTERNAL_LSA:
2433#ifdef HAVE_OPAQUE_LSA
2434 case OSPF_OPAQUE_AS_LSA:
2435#endif /* HAVE_OPAQUE_LSA */
2436 ospf_flood_through_as (NULL, lsa);
2437 break;
2438 default:
2439 break;
2440 }
2441}
2442#endif /* ORIGINAL_CODING */
2443
2444int
2445ospf_maxage_lsa_remover (struct thread *thread)
2446{
paul68980082003-03-25 05:07:42 +00002447 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002448 listnode node;
2449 listnode next;
2450 int reschedule = 0;
2451
paul68980082003-03-25 05:07:42 +00002452 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002453
2454 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2455 zlog_info ("LSA[MaxAge]: remover Start");
2456
paul68980082003-03-25 05:07:42 +00002457 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002458
2459 if (!reschedule)
paul68980082003-03-25 05:07:42 +00002460 for (node = listhead (ospf->maxage_lsa); node; node = next)
paul718e3742002-12-13 20:15:29 +00002461 {
2462 struct ospf_lsa *lsa = getdata (node);
2463 next = node->next;
2464
2465 if (lsa->retransmit_counter > 0)
2466 {
2467 reschedule = 1;
2468 continue;
2469 }
2470
2471 /* Remove LSA from the LSDB */
2472 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2473 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2474 zlog_info ("LSA[Type%d:%s]: This LSA is self-originated: ",
2475 lsa->data->type, inet_ntoa (lsa->data->id));
2476
2477 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2478 zlog_info ("LSA[Type%d:%s]: MaxAge LSA removed from list",
2479 lsa->data->type, inet_ntoa (lsa->data->id));
2480
2481 /* Flood max age LSA. */
2482#ifdef ORIGINAL_CODING
2483 ospf_maxage_flood (lsa);
2484#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00002485 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00002486#endif /* ORIGINAL_CODING */
2487
2488 /* Remove from lsdb. */
paul68980082003-03-25 05:07:42 +00002489 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002490 ospf_lsdb_delete (lsa->lsdb, lsa);
2491 }
2492
2493 /* A MaxAge LSA must be removed immediately from the router's link
2494 state database as soon as both a) it is no longer contained on any
2495 neighbor Link state retransmission lists and b) none of the router's
2496 neighbors are in states Exchange or Loading. */
2497 if (reschedule)
paul68980082003-03-25 05:07:42 +00002498 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00002499
2500 return 0;
2501}
2502
2503int
paul68980082003-03-25 05:07:42 +00002504ospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new)
paul718e3742002-12-13 20:15:29 +00002505{
2506 listnode node;
2507
paul68980082003-03-25 05:07:42 +00002508 for (node = listhead (ospf->maxage_lsa); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002509 if (((struct ospf_lsa *) node->data) == new)
2510 return 1;
2511
2512 return 0;
2513}
2514
2515void
paul68980082003-03-25 05:07:42 +00002516ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002517{
2518 listnode n;
2519
paul68980082003-03-25 05:07:42 +00002520 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00002521 {
paul68980082003-03-25 05:07:42 +00002522 list_delete_node (ospf->maxage_lsa, n);
paul718e3742002-12-13 20:15:29 +00002523 ospf_lsa_unlock (lsa);
2524 }
2525}
2526
2527void
paul68980082003-03-25 05:07:42 +00002528ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002529{
2530 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2531 and schedule the MaxAge LSA remover. */
paul68980082003-03-25 05:07:42 +00002532 if (ospf_lsa_maxage_exist (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002533 {
2534 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2535 zlog_info ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
2536 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2537 return;
2538 }
2539
paul68980082003-03-25 05:07:42 +00002540 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00002541
2542 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2543 zlog_info ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
2544
paul68980082003-03-25 05:07:42 +00002545 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00002546}
2547
2548int
paul68980082003-03-25 05:07:42 +00002549ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002550{
2551#ifdef HAVE_NSSA
2552 /* Stay away from any Local Translated Type-7 LSAs */
2553 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2554 return 0;
2555#endif /* HAVE_NSSA */
2556
2557 if (IS_LSA_MAXAGE (lsa))
2558 /* Self-originated LSAs should NOT time-out instead,
2559 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00002560 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002561 {
2562 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2563 zlog_info("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
2564
2565 switch (lsa->data->type)
2566 {
paul718e3742002-12-13 20:15:29 +00002567#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00002568 case OSPF_OPAQUE_LINK_LSA:
2569 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00002570 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00002571 /*
2572 * As a general rule, whenever network topology has changed
2573 * (due to an LSA removal in this case), routing recalculation
2574 * should be triggered. However, this is not true for opaque
2575 * LSAs. Even if an opaque LSA instance is going to be removed
2576 * from the routing domain, it does not mean a change in network
2577 * topology, and thus, routing recalculation is not needed here.
2578 */
2579 break;
paul718e3742002-12-13 20:15:29 +00002580#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00002581 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002582#ifdef HAVE_NSSA
2583 case OSPF_AS_NSSA_LSA:
2584#endif /* HAVE_NSSA */
2585 ospf_ase_incremental_update (ospf, lsa);
2586 break;
paul718e3742002-12-13 20:15:29 +00002587 default:
paul68980082003-03-25 05:07:42 +00002588 ospf_spf_calculate_schedule (ospf);
2589 break;
paul718e3742002-12-13 20:15:29 +00002590 }
paul68980082003-03-25 05:07:42 +00002591 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002592 }
2593
2594 return 0;
2595}
2596
2597/* Periodical check of MaxAge LSA. */
2598int
paul68980082003-03-25 05:07:42 +00002599ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002600{
paul68980082003-03-25 05:07:42 +00002601 struct ospf *ospf = THREAD_ARG (thread);
2602 struct route_node *rn;
2603 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00002604 listnode node;
2605
paul68980082003-03-25 05:07:42 +00002606 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00002607
paul68980082003-03-25 05:07:42 +00002608 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002609 {
2610 struct ospf_area *area = node->data;
2611
paul68980082003-03-25 05:07:42 +00002612 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
2613 ospf_lsa_maxage_walker_remover (ospf, lsa);
2614 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
2615 ospf_lsa_maxage_walker_remover (ospf, lsa);
2616 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
2617 ospf_lsa_maxage_walker_remover (ospf, lsa);
2618 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
2619 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002620#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002621 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
2622 ospf_lsa_maxage_walker_remover (ospf, lsa);
2623 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
2624 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002625#endif /* HAVE_OPAQUE_LSA */
2626 }
2627
2628 /* for AS-eternal-LSAs. */
paul68980082003-03-25 05:07:42 +00002629 if (ospf->lsdb)
2630 {
2631 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
2632 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002633#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002634 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
2635 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002636#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002637 }
paul718e3742002-12-13 20:15:29 +00002638
paul68980082003-03-25 05:07:42 +00002639 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
2640 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00002641 return 0;
2642}
2643
paul68980082003-03-25 05:07:42 +00002644struct ospf_lsa *
2645ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
2646 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00002647{
paul68980082003-03-25 05:07:42 +00002648 struct ospf_lsa *lsa;
2649 struct in_addr mask, id;
2650 struct lsa_header_mask
2651 {
2652 struct lsa_header header;
2653 struct in_addr mask;
2654 } *hmask;
paul718e3742002-12-13 20:15:29 +00002655
paul68980082003-03-25 05:07:42 +00002656 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
2657 if (lsa == NULL)
2658 return NULL;
paul718e3742002-12-13 20:15:29 +00002659
paul68980082003-03-25 05:07:42 +00002660 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00002661
paul68980082003-03-25 05:07:42 +00002662 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00002663
paul68980082003-03-25 05:07:42 +00002664 if (mask.s_addr != hmask->mask.s_addr)
2665 {
2666 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
2667 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
2668 if (!lsa)
2669 return NULL;
2670 }
paul718e3742002-12-13 20:15:29 +00002671
paul68980082003-03-25 05:07:42 +00002672 return lsa;
paul718e3742002-12-13 20:15:29 +00002673}
2674
2675struct ospf_lsa *
2676ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
2677 struct in_addr id, struct in_addr adv_router)
2678{
2679 switch (type)
2680 {
2681 case OSPF_ROUTER_LSA:
2682 case OSPF_NETWORK_LSA:
2683 case OSPF_SUMMARY_LSA:
2684 case OSPF_ASBR_SUMMARY_LSA:
2685#ifdef HAVE_NSSA
2686 case OSPF_AS_NSSA_LSA:
2687#endif /* HAVE_NSSA */
2688#ifdef HAVE_OPAQUE_LSA
2689 case OSPF_OPAQUE_LINK_LSA:
2690 case OSPF_OPAQUE_AREA_LSA:
2691#endif /* HAVE_OPAQUE_LSA */
2692 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
2693 break;
2694 case OSPF_AS_EXTERNAL_LSA:
2695#ifdef HAVE_OPAQUE_LSA
2696 case OSPF_OPAQUE_AS_LSA:
2697#endif /* HAVE_OPAQUE_LSA */
paul020709f2003-04-04 02:44:16 +00002698 return ospf_lsdb_lookup_by_id (area->ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00002699 break;
2700 default:
2701 break;
2702 }
2703
2704 return NULL;
2705}
2706
2707struct ospf_lsa *
2708ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
2709 struct in_addr id)
2710{
2711 struct ospf_lsa *lsa;
2712 struct route_node *rn;
2713
2714 switch (type)
2715 {
2716 case OSPF_ROUTER_LSA:
2717 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
2718 break;
2719 case OSPF_NETWORK_LSA:
2720 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
2721 if ((lsa = rn->info))
2722 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
2723 {
2724 route_unlock_node (rn);
2725 return lsa;
2726 }
2727 break;
2728 case OSPF_SUMMARY_LSA:
2729 case OSPF_ASBR_SUMMARY_LSA:
2730 /* Currently not used. */
2731 assert (1);
2732 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
2733 break;
2734 case OSPF_AS_EXTERNAL_LSA:
2735#ifdef HAVE_OPAQUE_LSA
2736 case OSPF_OPAQUE_LINK_LSA:
2737 case OSPF_OPAQUE_AREA_LSA:
2738 case OSPF_OPAQUE_AS_LSA:
2739 /* Currently not used. */
2740 break;
2741#endif /* HAVE_OPAQUE_LSA */
2742 default:
2743 break;
2744 }
2745
2746 return NULL;
2747}
2748
2749struct ospf_lsa *
2750ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
2751{
2752 struct ospf_lsa *match;
2753
2754#ifdef HAVE_OPAQUE_LSA
2755 /*
2756 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
2757 * is redefined to have two subfields; opaque-type and opaque-id.
2758 * However, it is harmless to treat the two sub fields together, as if
2759 * they two were forming a unique LSA-ID.
2760 */
2761#endif /* HAVE_OPAQUE_LSA */
2762
2763 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
2764
2765 if (match == NULL)
2766 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
2767 zlog_info ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
2768 lsah->type, inet_ntoa (lsah->id));
2769
2770 return match;
2771}
2772
2773/* return +n, l1 is more recent.
2774 return -n, l2 is more recent.
2775 return 0, l1 and l2 is identical. */
2776int
2777ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
2778{
2779 int r;
2780 int x, y;
2781
2782 if (l1 == NULL && l2 == NULL)
2783 return 0;
2784 if (l1 == NULL)
2785 return -1;
2786 if (l2 == NULL)
2787 return 1;
2788
2789 /* compare LS sequence number. */
2790 x = (int) ntohl (l1->data->ls_seqnum);
2791 y = (int) ntohl (l2->data->ls_seqnum);
2792 if (x > y)
2793 return 1;
2794 if (x < y)
2795 return -1;
2796
2797 /* compare LS checksum. */
2798 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
2799 if (r)
2800 return r;
2801
2802 /* compare LS age. */
2803 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
2804 return 1;
2805 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
2806 return -1;
2807
2808 /* compare LS age with MaxAgeDiff. */
2809 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
2810 return -1;
2811 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
2812 return 1;
2813
2814 /* LSAs are identical. */
2815 return 0;
2816}
2817
2818/* If two LSAs are different, return 1, otherwise return 0. */
2819int
2820ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
2821{
2822 char *p1, *p2;
2823 assert (l1);
2824 assert (l2);
2825 assert (l1->data);
2826 assert (l2->data);
2827
2828 if (l1->data->options != l2->data->options)
2829 return 1;
2830
2831 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
2832 return 1;
2833
2834 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
2835 return 1;
2836
2837 if (l1->data->length != l2->data->length)
2838 return 1;
2839
2840 if (l1->data->length == 0)
2841 return 1;
2842
pauld1825832003-04-03 01:27:01 +00002843 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00002844
2845 p1 = (char *) l1->data;
2846 p2 = (char *) l2->data;
2847
2848 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
2849 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
2850 return 1;
2851
2852 return 0;
2853}
2854
2855#ifdef ORIGINAL_CODING
2856void
2857ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
2858 struct ospf_lsa *self,
2859 struct ospf_lsa *new)
2860{
2861 u_int32_t seqnum;
2862
2863 /* Adjust LS Sequence Number. */
2864 seqnum = ntohl (new->data->ls_seqnum) + 1;
2865 self->data->ls_seqnum = htonl (seqnum);
2866
2867 /* Recalculate LSA checksum. */
2868 ospf_lsa_checksum (self->data);
2869
2870 /* Reflooding LSA. */
2871 /* RFC2328 Section 13.3
2872 On non-broadcast networks, separate Link State Update
2873 packets must be sent, as unicasts, to each adjacent neighbor
2874 (i.e., those in state Exchange or greater). The destination
2875 IP addresses for these packets are the neighbors' IP
2876 addresses. */
2877 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
2878 {
2879 struct route_node *rn;
2880 struct ospf_neighbor *onbr;
2881
2882 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
2883 if ((onbr = rn->info) != NULL)
2884 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
2885 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
2886 }
2887 else
2888 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
2889
2890 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2891 zlog_info ("LSA[Type%d:%s]: Flush self-originated LSA",
2892 self->data->type, inet_ntoa (self->data->id));
2893}
2894#else /* ORIGINAL_CODING */
2895static int
paul68980082003-03-25 05:07:42 +00002896ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002897{
2898 if (lsa == NULL || !IS_LSA_SELF (lsa))
2899 return 0;
2900
2901 if (IS_DEBUG_OSPF_EVENT)
2902 zlog_info ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
2903
2904 /* Force given lsa's age to MaxAge. */
2905 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2906
2907 switch (lsa->data->type)
2908 {
2909#ifdef HAVE_OPAQUE_LSA
2910 case OSPF_OPAQUE_LINK_LSA:
2911 case OSPF_OPAQUE_AREA_LSA:
2912 case OSPF_OPAQUE_AS_LSA:
2913 ospf_opaque_lsa_refresh (lsa);
2914 break;
2915#endif /* HAVE_OPAQUE_LSA */
2916 default:
paul68980082003-03-25 05:07:42 +00002917 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002918 break;
2919 }
2920
2921 return 0;
2922}
2923
2924void
paul68980082003-03-25 05:07:42 +00002925ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002926{
2927 listnode n1, n2;
2928 struct ospf_area *area;
2929 struct ospf_interface *oi;
2930 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00002931 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00002932 int need_to_flush_ase = 0;
2933
paul68980082003-03-25 05:07:42 +00002934 for (n1 = listhead (ospf->areas); n1; nextnode (n1))
paul718e3742002-12-13 20:15:29 +00002935 {
2936 if ((area = getdata (n1)) == NULL)
2937 continue;
2938
2939 if ((lsa = area->router_lsa_self) != NULL)
2940 {
2941 if (IS_DEBUG_OSPF_EVENT)
2942 zlog_info ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
2943
2944 ospf_lsa_flush_area (lsa, area);
2945 ospf_lsa_unlock (area->router_lsa_self);
2946 area->router_lsa_self = NULL;
2947 OSPF_TIMER_OFF (area->t_router_lsa_self);
2948 }
2949
2950 for (n2 = listhead (area->oiflist); n2; nextnode (n2))
2951 {
2952 if ((oi = getdata (n2)) == NULL)
2953 continue;
2954
2955 if ((lsa = oi->network_lsa_self) != NULL
2956 && oi->state == ISM_DR
2957 && oi->full_nbrs > 0)
2958 {
2959 if (IS_DEBUG_OSPF_EVENT)
2960 zlog_info ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
2961
2962 ospf_lsa_flush_area (oi->network_lsa_self, area);
2963 ospf_lsa_unlock (oi->network_lsa_self);
2964 oi->network_lsa_self = NULL;
2965 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2966 }
2967
2968 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
2969 && area->external_routing == OSPF_AREA_DEFAULT)
2970 need_to_flush_ase = 1;
2971 }
2972
paul68980082003-03-25 05:07:42 +00002973 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
2974 ospf_lsa_flush_schedule (ospf, lsa);
2975 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
2976 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002977#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002978 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
2979 ospf_lsa_flush_schedule (ospf, lsa);
2980 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
2981 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002982#endif /* HAVE_OPAQUE_LSA */
2983 }
2984
2985 if (need_to_flush_ase)
2986 {
paul68980082003-03-25 05:07:42 +00002987 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
2988 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002989#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002990 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
2991 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002992#endif /* HAVE_OPAQUE_LSA */
2993 }
2994
2995 /*
2996 * Make sure that the MaxAge LSA remover is executed immediately,
2997 * without conflicting to other threads.
2998 */
paul68980082003-03-25 05:07:42 +00002999 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003000 {
paul68980082003-03-25 05:07:42 +00003001 OSPF_TIMER_OFF (ospf->t_maxage);
3002 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003003 }
3004
3005 return;
3006}
3007#endif /* ORIGINAL_CODING */
3008
3009/* If there is self-originated LSA, then return 1, otherwise return 0. */
3010/* An interface-independent version of ospf_lsa_is_self_originated */
3011int
paul68980082003-03-25 05:07:42 +00003012ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003013{
3014 listnode node;
3015
3016 /* This LSA is already checked. */
3017 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3018 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3019
3020 /* Make sure LSA is self-checked. */
3021 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3022
3023 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003024 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003025 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3026
3027 /* LSA is router-LSA. */
3028 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003029 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003030 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3031
3032 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3033 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul68980082003-03-25 05:07:42 +00003034 for (node = listhead (ospf->oiflist); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00003035 {
3036 struct ospf_interface *oi = getdata (node);
3037
3038 /* Ignore virtual link. */
3039 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3040 if (oi->address->family == AF_INET)
3041 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3042 {
3043 /* to make it easier later */
3044 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3045 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3046 }
3047 }
3048
3049 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3050}
3051
3052/* Get unique Link State ID. */
3053struct in_addr
paul68980082003-03-25 05:07:42 +00003054ospf_lsa_unique_id (struct ospf *ospf,
3055 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003056{
3057 struct ospf_lsa *lsa;
3058 struct in_addr mask, id;
3059
3060 id = p->prefix;
3061
3062 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003063 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003064 if (lsa)
3065 {
3066 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3067 if (ip_masklen (al->mask) == p->prefixlen)
3068 {
3069 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
3070 zlog_warn ("ospf_lsa_unique_id(): "
3071 "Can't get Link State ID for %s/%d",
3072 inet_ntoa (p->prefix), p->prefixlen);
3073 /* id.s_addr = 0; */
3074 id.s_addr = 0xffffffff;
3075 return id;
3076 }
3077 /* Masklen differs, then apply wildcard mask to Link State ID. */
3078 else
3079 {
3080 masklen2ip (p->prefixlen, &mask);
3081
3082 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003083 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3084 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003085 if (lsa)
3086 {
3087 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
3088 zlog_warn ("ospf_lsa_unique_id(): "
3089 "Can't get Link State ID for %s/%d",
3090 inet_ntoa (p->prefix), p->prefixlen);
3091 /* id.s_addr = 0; */
3092 id.s_addr = 0xffffffff;
3093 return id;
3094 }
3095 }
3096 }
3097
3098 return id;
3099}
3100
3101
3102#define LSA_ACTION_ORIGN_RTR 1
3103#define LSA_ACTION_ORIGN_NET 2
3104#define LSA_ACTION_FLOOD_AREA 3
3105#define LSA_ACTION_FLOOD_AS 4
3106#define LSA_ACTION_FLUSH_AREA 5
3107#define LSA_ACTION_FLUSH_AS 6
3108
3109struct lsa_action
3110{
3111 u_char action;
3112 struct ospf_area *area;
3113 struct ospf_interface *oi;
3114 struct ospf_lsa *lsa;
3115};
3116
3117int
3118ospf_lsa_action (struct thread *t)
3119{
3120 struct lsa_action *data;
paul020709f2003-04-04 02:44:16 +00003121 struct ospf *ospf;
3122
3123 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00003124
3125 data = THREAD_ARG (t);
3126
3127 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
3128 zlog_info ("LSA[Action]: Performing scheduled LSA action: %d",
3129 data->action);
3130
3131 switch (data->action)
3132 {
3133 case LSA_ACTION_ORIGN_RTR:
3134 ospf_router_lsa_refresh (data->area->router_lsa_self);
3135 break;
3136 case LSA_ACTION_ORIGN_NET:
3137 ospf_network_lsa_originate (data->oi);
3138 break;
3139 case LSA_ACTION_FLOOD_AREA:
3140 ospf_flood_through_area (data->area, NULL, data->lsa);
3141 break;
3142 case LSA_ACTION_FLOOD_AS:
paul68980082003-03-25 05:07:42 +00003143 ospf_flood_through_as (ospf, NULL, data->lsa);
paul718e3742002-12-13 20:15:29 +00003144 break;
3145 case LSA_ACTION_FLUSH_AREA:
3146 ospf_lsa_flush_area (data->lsa, data->area);
3147 break;
3148 case LSA_ACTION_FLUSH_AS:
paul68980082003-03-25 05:07:42 +00003149 ospf_lsa_flush_as (ospf, data->lsa);
paul718e3742002-12-13 20:15:29 +00003150 break;
3151 }
3152
3153 ospf_lsa_unlock (data->lsa);
3154 XFREE (MTYPE_OSPF_MESSAGE, data);
3155 return 0;
3156}
3157
3158void
3159ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3160{
3161 struct lsa_action *data;
3162
3163 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3164 memset (data, 0, sizeof (struct lsa_action));
3165
3166 data->action = LSA_ACTION_FLOOD_AREA;
3167 data->area = area;
3168 data->lsa = ospf_lsa_lock (lsa);
3169
3170 thread_add_event (master, ospf_lsa_action, data, 0);
3171}
3172
3173void
3174ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3175{
3176 struct lsa_action *data;
3177
3178 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3179 memset (data, 0, sizeof (struct lsa_action));
3180
3181 data->action = LSA_ACTION_FLUSH_AREA;
3182 data->area = area;
3183 data->lsa = ospf_lsa_lock (lsa);
3184
3185 thread_add_event (master, ospf_lsa_action, data, 0);
3186}
3187
3188
3189/* LSA Refreshment functions. */
3190void
paul68980082003-03-25 05:07:42 +00003191ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003192{
3193 struct external_info *ei;
3194 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3195
3196 switch (lsa->data->type)
3197 {
3198 /* Router and Network LSAs are processed differently. */
3199 case OSPF_ROUTER_LSA:
3200 case OSPF_NETWORK_LSA:
3201 break;
3202 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003203 ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003204 break;
3205 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003206 ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003207 break;
3208 case OSPF_AS_EXTERNAL_LSA:
3209 ei = ospf_external_info_check (lsa);
3210 if (ei)
paul68980082003-03-25 05:07:42 +00003211 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003212 else
paul68980082003-03-25 05:07:42 +00003213 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003214 break;
3215#ifdef HAVE_OPAQUE_LSA
3216 case OSPF_OPAQUE_LINK_LSA:
3217 case OSPF_OPAQUE_AREA_LSA:
3218 case OSPF_OPAQUE_AS_LSA:
3219 ospf_opaque_lsa_refresh (lsa);
3220 break;
3221 default:
3222 break;
3223#endif /* HAVE_OPAQUE_LSA */
3224 }
3225}
3226
3227void
paul68980082003-03-25 05:07:42 +00003228ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003229{
3230 u_int16_t index, current_index;
3231
3232 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3233
3234 if (lsa->refresh_list < 0)
3235 {
3236 int delay;
3237
3238 if (LS_AGE (lsa) == 0 &&
3239 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3240 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3241 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3242 else
3243 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3244 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3245 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3246
3247 if (delay < 0)
3248 delay = 0;
3249
paul68980082003-03-25 05:07:42 +00003250 current_index = ospf->lsa_refresh_queue.index +
3251 (time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003252
3253 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3254 % (OSPF_LSA_REFRESHER_SLOTS);
3255
3256 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3257 zlog_info ("LSA[Refresh]: lsa with age %d added to index %d",
3258 LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003259 if (!ospf->lsa_refresh_queue.qs[index])
3260 ospf->lsa_refresh_queue.qs[index] = list_new ();
3261 listnode_add (ospf->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00003262 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003263 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3264 zlog_info ("LSA[Refresh]: ospf_refresher_register_lsa(): setting refresh_list on lsa %p (slod %d)", lsa, index);
paul718e3742002-12-13 20:15:29 +00003265 }
3266}
3267
3268void
paul68980082003-03-25 05:07:42 +00003269ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003270{
3271 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3272 if (lsa->refresh_list >= 0)
3273 {
paul68980082003-03-25 05:07:42 +00003274 list refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003275 listnode_delete (refresh_list, lsa);
3276 if (!listcount (refresh_list))
3277 {
3278 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003279 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003280 }
3281 ospf_lsa_unlock (lsa);
3282 lsa->refresh_list = -1;
3283 }
3284}
3285
3286int
3287ospf_lsa_refresh_walker (struct thread *t)
3288{
3289 list refresh_list;
3290 listnode node;
paul68980082003-03-25 05:07:42 +00003291 struct ospf *ospf = THREAD_ARG (t);
paul718e3742002-12-13 20:15:29 +00003292 int i;
3293 list lsa_to_refresh = list_new ();
3294
3295 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3296 zlog_info ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
3297
3298
paul68980082003-03-25 05:07:42 +00003299 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003300
paul68980082003-03-25 05:07:42 +00003301 ospf->lsa_refresh_queue.index =
3302 (ospf->lsa_refresh_queue.index +
3303 (time (NULL) - ospf->lsa_refresher_started) / OSPF_LSA_REFRESHER_GRANULARITY)
paul718e3742002-12-13 20:15:29 +00003304 % OSPF_LSA_REFRESHER_SLOTS;
3305
3306 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3307 zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003308 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003309
paul68980082003-03-25 05:07:42 +00003310 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003311 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3312 {
3313 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3314 zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh index %d", i);
3315
paul68980082003-03-25 05:07:42 +00003316 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003317
paul68980082003-03-25 05:07:42 +00003318 ospf->lsa_refresh_queue.qs [i] = NULL;
3319
paul718e3742002-12-13 20:15:29 +00003320 if (refresh_list)
3321 {
3322 for (node = listhead (refresh_list); node;)
3323 {
3324 listnode next;
3325 struct ospf_lsa *lsa = getdata (node);
3326 next = node->next;
3327
3328 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
paulf2c80652002-12-13 21:44:27 +00003329 zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh lsa %p (slot %d)", lsa, i);
paul718e3742002-12-13 20:15:29 +00003330
3331 list_delete_node (refresh_list, node);
3332 ospf_lsa_unlock (lsa);
3333 lsa->refresh_list = -1;
3334 listnode_add (lsa_to_refresh, lsa);
3335 node = next;
3336 }
3337 list_free (refresh_list);
3338 }
3339 }
3340
paul68980082003-03-25 05:07:42 +00003341 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3342 ospf, ospf->lsa_refresh_interval);
3343 ospf->lsa_refresher_started = time (NULL);
paul718e3742002-12-13 20:15:29 +00003344
3345 for (node = listhead (lsa_to_refresh); node; nextnode (node))
paul68980082003-03-25 05:07:42 +00003346 ospf_lsa_refresh (ospf, getdata (node));
paul718e3742002-12-13 20:15:29 +00003347
3348 list_delete (lsa_to_refresh);
3349
3350 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3351 zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
3352
3353 return 0;
3354}
3355