blob: e01dbd0d0283d634cd4e086d7f733ef873d53b05 [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 */
1641 if (! OSPF_IS_ABR)
1642 {
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 *
1802ospf_default_external_info ()
1803{
1804 int type;
1805 struct route_node *rn;
1806 struct prefix_ipv4 p;
paul68980082003-03-25 05:07:42 +00001807 struct ospf *ospf = ospf_top;
paul718e3742002-12-13 20:15:29 +00001808
1809 p.family = AF_INET;
1810 p.prefix.s_addr = 0;
1811 p.prefixlen = 0;
1812
1813 /* First, lookup redistributed default route. */
1814 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
1815 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
1816 {
1817 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
1818 if (rn != NULL)
1819 {
1820 route_unlock_node (rn);
1821 assert (rn->info);
paul68980082003-03-25 05:07:42 +00001822 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00001823 return rn->info;
1824 }
1825 }
1826
1827 return NULL;
1828}
1829
1830int
paul68980082003-03-25 05:07:42 +00001831ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00001832{
1833 int *origin;
1834 struct prefix_ipv4 p;
1835 struct in_addr nexthop;
1836 struct external_info *ei;
paul68980082003-03-25 05:07:42 +00001837 struct ospf *ospf = ospf_top;
paul718e3742002-12-13 20:15:29 +00001838
1839 /* Get originate flags. */
paul68980082003-03-25 05:07:42 +00001840 origin = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00001841
1842 p.family = AF_INET;
1843 p.prefix.s_addr = 0;
1844 p.prefixlen = 0;
1845
1846 if (*origin == DEFAULT_ORIGINATE_ALWAYS)
1847 {
1848 /* If there is no default route via redistribute,
1849 then originate AS-external-LSA with nexthop 0 (self). */
1850 nexthop.s_addr = 0;
1851 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
1852 }
1853
1854 if ((ei = ospf_default_external_info ()))
paul68980082003-03-25 05:07:42 +00001855 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00001856
1857 return 0;
1858}
1859
1860/* Flush an AS-external-LSA from LSDB and routing domain. */
1861void
paul68980082003-03-25 05:07:42 +00001862ospf_external_lsa_flush (struct ospf *ospf,
1863 u_char type, struct prefix_ipv4 *p,
paul718e3742002-12-13 20:15:29 +00001864 unsigned int ifindex, struct in_addr nexthop)
1865{
1866 struct ospf_lsa *lsa;
1867
1868 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
1869 zlog_info ("LSA: Flushing AS-external-LSA %s/%d",
1870 inet_ntoa (p->prefix), p->prefixlen);
1871
1872 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00001873 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00001874 {
1875 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
1876 zlog_warn ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
1877 inet_ntoa (p->prefix), p->prefixlen);
1878 return;
1879 }
1880
1881 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00001882 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00001883
1884 /* There must be no self-originated LSA in rtrs_external. */
1885#if 0
1886 /* Remove External route from Zebra. */
1887 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
1888#endif
1889
1890 if (!IS_LSA_MAXAGE (lsa))
1891 {
1892 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00001893 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00001894
1895 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00001896 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00001897 }
1898
1899 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
1900 zlog_info ("ospf_external_lsa_flush(): stop");
1901}
1902
1903void
paul68980082003-03-25 05:07:42 +00001904ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001905{
1906 struct prefix_ipv4 p;
1907 struct external_info *ei;
1908 struct ospf_lsa *lsa;
1909
1910 p.family = AF_INET;
1911 p.prefixlen = 0;
1912 p.prefix.s_addr = 0;
1913
1914 ei = ospf_default_external_info ();
paul68980082003-03-25 05:07:42 +00001915 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00001916
1917 if (ei)
1918 {
1919 if (lsa)
1920 {
1921 if (IS_DEBUG_OSPF_EVENT)
1922 zlog_info ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00001923 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00001924 }
1925 else
1926 {
1927 if (IS_DEBUG_OSPF_EVENT)
1928 zlog_info ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00001929 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00001930 }
1931 }
1932 else
1933 {
1934 if (lsa)
1935 {
1936 if (IS_DEBUG_OSPF_EVENT)
1937 zlog_info ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00001938 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00001939 }
1940 }
1941}
1942
1943void
paul68980082003-03-25 05:07:42 +00001944ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00001945{
1946 struct route_node *rn;
1947 struct external_info *ei;
1948
1949 if (type != DEFAULT_ROUTE)
1950 if (EXTERNAL_INFO(type))
1951 /* Refresh each redistributed AS-external-LSAs. */
1952 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
1953 if ((ei = rn->info))
1954 if (!is_prefix_default (&ei->p))
1955 {
1956 struct ospf_lsa *lsa;
1957
paul68980082003-03-25 05:07:42 +00001958 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
1959 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00001960 else
paul68980082003-03-25 05:07:42 +00001961 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00001962 }
1963}
1964
1965/* Refresh AS-external-LSA. */
1966void
paul68980082003-03-25 05:07:42 +00001967ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00001968 struct external_info *ei, int force)
1969{
1970 struct ospf_lsa *new;
1971 int changed;
1972
1973 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00001974 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00001975 {
paul68980082003-03-25 05:07:42 +00001976 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
1977 ei->ifindex, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001978 return;
1979 }
1980
1981 if (!changed && !force)
1982 return;
1983
1984 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001985 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00001986
1987 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00001988 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00001989
paul68980082003-03-25 05:07:42 +00001990 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00001991
1992 if (new == NULL)
1993 {
1994 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1995 zlog_warn ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
1996 inet_ntoa (lsa->data->id));
1997 return;
1998 }
1999
2000 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2001
2002 /* Record timestamp. */
2003 gettimeofday (&new->tv_orig, NULL);
2004
2005 /* Re-calculate checksum. */
2006 ospf_lsa_checksum (new->data);
2007
paul68980082003-03-25 05:07:42 +00002008 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002009
2010 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002011 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002012
2013#ifdef HAVE_NSSA
2014 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
paul68980082003-03-25 05:07:42 +00002015 if (ospf->anyNSSA)
2016 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002017#endif /* HAVE_NSSA */
2018
2019 /* Register slef-originated LSA to refresh queue. */
paul68980082003-03-25 05:07:42 +00002020 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002021
2022 /* Debug logging. */
2023 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2024 {
2025 zlog_info ("LSA[Type%d:%s]: AS-external-LSA refresh",
2026 new->data->type, inet_ntoa (new->data->id));
2027 ospf_lsa_header_dump (new->data);
2028 }
2029
2030 return;
2031}
2032
2033
2034/* LSA installation functions. */
2035
2036/* Install router-LSA to an area. */
2037struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002038ospf_router_lsa_install (struct ospf *ospf,
2039 struct ospf_lsa *new, int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002040{
2041 struct ospf_area *area = new->area;
2042
2043 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2044 The entire routing table must be recalculated, starting with
2045 the shortest path calculations for each area (not just the
2046 area whose link-state database has changed).
2047 */
2048 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002049 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002050
2051 if (IS_LSA_SELF (new))
2052 {
2053 /* Set router-LSA refresh timer. */
2054 OSPF_TIMER_OFF (area->t_router_lsa_self);
2055 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
2056 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
2057
2058 /* Set self-originated router-LSA. */
2059 ospf_lsa_unlock (area->router_lsa_self);
2060 area->router_lsa_self = ospf_lsa_lock (new);
2061
2062 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2063 zlog_info("LSA[Type%d]: ID %s is self-originated",
2064 new->data->type, inet_ntoa (new->data->id));
2065 }
2066
2067 return new;
2068}
2069
2070#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2071 if (!(T)) \
2072 (T) = thread_add_timer (master, (F), oi, (V))
2073
2074/* Install network-LSA to an area. */
2075struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002076ospf_network_lsa_install (struct ospf *ospf,
2077 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002078 struct ospf_lsa *new,
2079 int rt_recalc)
2080{
2081
2082 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2083 The entire routing table must be recalculated, starting with
2084 the shortest path calculations for each area (not just the
2085 area whose link-state database has changed).
2086 */
2087 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002088 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002089
2090 /* We supposed that when LSA is originated by us, we pass the int
2091 for which it was originated. If LSA was received by flooding,
2092 the RECEIVED flag is set, so we do not link the LSA to the int. */
2093 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2094 {
2095 /* Set LSRefresh timer. */
2096 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2097
2098 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2099 ospf_network_lsa_refresh_timer,
2100 OSPF_LS_REFRESH_TIME);
2101
2102 ospf_lsa_unlock (oi->network_lsa_self);
2103 oi->network_lsa_self = ospf_lsa_lock (new);
2104 }
2105
2106 return new;
2107}
2108
2109/* Install summary-LSA to an area. */
2110struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002111ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2112 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002113{
paul718e3742002-12-13 20:15:29 +00002114 if (rt_recalc && !IS_LSA_SELF (new))
2115 {
2116 /* RFC 2328 Section 13.2 Summary-LSAs
2117 The best route to the destination described by the summary-
2118 LSA must be recalculated (see Section 16.5). If this
2119 destination is an AS boundary router, it may also be
2120 necessary to re-examine all the AS-external-LSAs.
2121 */
2122
2123#if 0
2124 /* This doesn't exist yet... */
2125 ospf_summary_incremental_update(new); */
2126#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002127 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002128#endif /* #if 0 */
2129
2130 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2131 zlog_info ("ospf_summary_lsa_install(): SPF scheduled");
2132 }
2133
2134 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002135 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002136
2137 return new;
2138}
2139
2140/* Install ASBR-summary-LSA to an area. */
2141struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002142ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2143 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002144{
2145 if (rt_recalc && !IS_LSA_SELF (new))
2146 {
2147 /* RFC 2328 Section 13.2 Summary-LSAs
2148 The best route to the destination described by the summary-
2149 LSA must be recalculated (see Section 16.5). If this
2150 destination is an AS boundary router, it may also be
2151 necessary to re-examine all the AS-external-LSAs.
2152 */
2153#if 0
2154 /* These don't exist yet... */
2155 ospf_summary_incremental_update(new);
2156 /* Isn't this done by the above call?
2157 - RFC 2328 Section 16.5 implies it should be */
2158 /* ospf_ase_calculate_schedule(); */
2159#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002160 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002161#endif /* #if 0 */
2162 }
2163
2164 /* register LSA to refresh-list. */
2165 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002166 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002167
2168 return new;
2169}
2170
2171/* Install AS-external-LSA. */
2172struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002173ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2174 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002175{
paul68980082003-03-25 05:07:42 +00002176 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002177 /* If LSA is not self-originated, calculate an external route. */
2178 if (rt_recalc)
2179 {
2180 /* RFC 2328 Section 13.2 AS-external-LSAs
2181 The best route to the destination described by the AS-
2182 external-LSA must be recalculated (see Section 16.6).
2183 */
2184
2185 if (!IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002186 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002187 }
2188
2189 /* Register self-originated LSA to refresh queue. */
2190 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002191 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002192
2193 return new;
2194}
2195
2196void
paul68980082003-03-25 05:07:42 +00002197ospf_discard_from_db (struct ospf *ospf,
2198 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002199{
2200 struct ospf_lsa *old;
2201
2202 old = ospf_lsdb_lookup (lsdb, lsa);
2203
2204 if (!old)
2205 return;
2206
2207 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002208 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002209
2210 switch (old->data->type)
2211 {
2212 case OSPF_AS_EXTERNAL_LSA:
2213#ifdef HAVE_OPAQUE_LSA
2214 case OSPF_OPAQUE_AS_LSA:
2215#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002216 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2217 ospf_ase_unregister_external_lsa (old, ospf);
paul718e3742002-12-13 20:15:29 +00002218 break;
2219 default:
paul68980082003-03-25 05:07:42 +00002220 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002221 break;
2222 }
2223
paul68980082003-03-25 05:07:42 +00002224 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002225 ospf_lsa_discard (old);
2226}
2227
paul718e3742002-12-13 20:15:29 +00002228struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002229ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2230 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002231{
2232 struct ospf_lsa *new = NULL;
2233 struct ospf_lsa *old = NULL;
2234 struct ospf_lsdb *lsdb = NULL;
2235 int rt_recalc;
2236
2237 /* Set LSDB. */
2238 switch (lsa->data->type)
2239 {
paul68980082003-03-25 05:07:42 +00002240#ifdef HAVE_NSSA
paulf2c80652002-12-13 21:44:27 +00002241 /* kevinm */
2242 case OSPF_AS_NSSA_LSA:
2243 if (lsa->area)
2244 lsdb = lsa->area->lsdb;
2245 else
paul68980082003-03-25 05:07:42 +00002246 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002247 break;
paul68980082003-03-25 05:07:42 +00002248#endif /* HAVE_NSSA */
paul718e3742002-12-13 20:15:29 +00002249 case OSPF_AS_EXTERNAL_LSA:
2250#ifdef HAVE_OPAQUE_LSA
2251 case OSPF_OPAQUE_AS_LSA:
2252#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002253 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002254 break;
2255 default:
2256 lsdb = lsa->area->lsdb;
2257 break;
2258 }
2259
paul718e3742002-12-13 20:15:29 +00002260 assert (lsdb);
2261
2262 /* RFC 2328 13.2. Installing LSAs in the database
2263
2264 Installing a new LSA in the database, either as the result of
2265 flooding or a newly self-originated LSA, may cause the OSPF
2266 routing table structure to be recalculated. The contents of the
2267 new LSA should be compared to the old instance, if present. If
2268 there is no difference, there is no need to recalculate the
2269 routing table. When comparing an LSA to its previous instance,
2270 the following are all considered to be differences in contents:
2271
2272 o The LSA's Options field has changed.
2273
2274 o One of the LSA instances has LS age set to MaxAge, and
2275 the other does not.
2276
2277 o The length field in the LSA header has changed.
2278
2279 o The body of the LSA (i.e., anything outside the 20-byte
2280 LSA header) has changed. Note that this excludes changes
2281 in LS Sequence Number and LS Checksum.
2282
2283 */
2284 /* Look up old LSA and determine if any SPF calculation or incremental
2285 update is needed */
2286 old = ospf_lsdb_lookup (lsdb, lsa);
2287
2288 /* Do comparision and record if recalc needed. */
2289 rt_recalc = 0;
2290 if ( old == NULL || ospf_lsa_different(old, lsa))
2291 rt_recalc = 1;
2292
2293 /* discard old LSA from LSDB */
2294 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002295 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002296
2297 /* Insert LSA to LSDB. */
2298 ospf_lsdb_add (lsdb, lsa);
2299 lsa->lsdb = lsdb;
2300
2301 /* Calculate Checksum if self-originated?. */
2302 if (IS_LSA_SELF (lsa))
2303 ospf_lsa_checksum (lsa->data);
2304
2305 /* Do LSA specific installation process. */
2306 switch (lsa->data->type)
2307 {
2308 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002309 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002310 break;
2311 case OSPF_NETWORK_LSA:
2312 assert (oi);
paul68980082003-03-25 05:07:42 +00002313 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002314 break;
2315 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002316 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002317 break;
2318 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002319 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002320 break;
2321 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002322 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002323 break;
2324#ifdef HAVE_OPAQUE_LSA
2325 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002326 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002327 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002328 else
paul68980082003-03-25 05:07:42 +00002329 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002330 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002331 case OSPF_OPAQUE_AREA_LSA:
2332 case OSPF_OPAQUE_AS_LSA:
2333 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2334 break;
2335#endif /* HAVE_OPAQUE_LSA */
2336 default: /* NSSA, or type-6,8,9....nothing special */
2337#ifdef HAVE_NSSA
paul68980082003-03-25 05:07:42 +00002338 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002339#endif /* HAVE_NSSA */
2340 break;
2341 }
2342
2343 if (new == NULL)
2344 return new; /* Installation failed, cannot proceed further -- endo. */
2345
2346 /* Debug logs. */
2347 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2348 {
2349 char area_str[INET_ADDRSTRLEN];
2350
2351 switch (lsa->data->type)
2352 {
2353 case OSPF_AS_EXTERNAL_LSA:
2354#ifdef HAVE_OPAQUE_LSA
2355 case OSPF_OPAQUE_AS_LSA:
2356#endif /* HAVE_OPAQUE_LSA */
paulf2c80652002-12-13 21:44:27 +00002357#ifdef HAVE_NSSA
2358 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002359#endif /* HAVE_NSSA */
paul718e3742002-12-13 20:15:29 +00002360 zlog_info ("LSA[%s]: Install %s",
2361 dump_lsa_key (new),
2362 LOOKUP (ospf_lsa_type_msg, new->data->type));
2363 break;
2364 default:
2365 strcpy (area_str, inet_ntoa (new->area->area_id));
2366 zlog_info ("LSA[%s]: Install %s to Area %s",
2367 dump_lsa_key (new),
2368 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2369 break;
2370 }
2371 }
2372
2373 /* If received LSA' ls_age is MaxAge, set LSA on MaxAge LSA list. */
2374 if (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new))
2375 {
2376 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2377 zlog_info ("LSA[Type%d:%s]: Install LSA, MaxAge",
2378 new->data->type, inet_ntoa (new->data->id));
paul68980082003-03-25 05:07:42 +00002379 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002380 }
2381
2382 return new;
2383}
2384
2385
2386int
paul68980082003-03-25 05:07:42 +00002387ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002388{
2389 listnode node;
2390
paul68980082003-03-25 05:07:42 +00002391 for (node = listhead (ospf->oiflist); node; node = nextnode (node))
paul718e3742002-12-13 20:15:29 +00002392 {
2393 struct ospf_interface *oi = getdata (node);
2394 struct route_node *rn;
2395 struct ospf_neighbor *nbr;
2396
2397 if (ospf_if_is_enable (oi))
2398 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2399 if ((nbr = rn->info) != NULL)
2400 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2401 {
2402 route_unlock_node (rn);
2403 return 0;
2404 }
2405 }
2406
2407 return 1;
2408}
2409
2410
2411#ifdef ORIGINAL_CODING
2412/* This function flood the maxaged LSA to DR. */
2413void
2414ospf_maxage_flood (struct ospf_lsa *lsa)
2415{
2416 switch (lsa->data->type)
2417 {
2418 case OSPF_ROUTER_LSA:
2419 case OSPF_NETWORK_LSA:
2420 case OSPF_SUMMARY_LSA:
2421 case OSPF_ASBR_SUMMARY_LSA:
2422#ifdef HAVE_NSSA
2423 case OSPF_AS_NSSA_LSA:
2424#endif /* HAVE_NSSA */
2425#ifdef HAVE_OPAQUE_LSA
2426 case OSPF_OPAQUE_LINK_LSA:
2427 case OSPF_OPAQUE_AREA_LSA:
2428#endif /* HAVE_OPAQUE_LSA */
2429 ospf_flood_through_area (lsa->area, NULL, lsa);
2430 break;
2431 case OSPF_AS_EXTERNAL_LSA:
2432#ifdef HAVE_OPAQUE_LSA
2433 case OSPF_OPAQUE_AS_LSA:
2434#endif /* HAVE_OPAQUE_LSA */
2435 ospf_flood_through_as (NULL, lsa);
2436 break;
2437 default:
2438 break;
2439 }
2440}
2441#endif /* ORIGINAL_CODING */
2442
2443int
2444ospf_maxage_lsa_remover (struct thread *thread)
2445{
paul68980082003-03-25 05:07:42 +00002446 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002447 listnode node;
2448 listnode next;
2449 int reschedule = 0;
2450
paul68980082003-03-25 05:07:42 +00002451 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002452
2453 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2454 zlog_info ("LSA[MaxAge]: remover Start");
2455
paul68980082003-03-25 05:07:42 +00002456 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002457
2458 if (!reschedule)
paul68980082003-03-25 05:07:42 +00002459 for (node = listhead (ospf->maxage_lsa); node; node = next)
paul718e3742002-12-13 20:15:29 +00002460 {
2461 struct ospf_lsa *lsa = getdata (node);
2462 next = node->next;
2463
2464 if (lsa->retransmit_counter > 0)
2465 {
2466 reschedule = 1;
2467 continue;
2468 }
2469
2470 /* Remove LSA from the LSDB */
2471 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2472 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2473 zlog_info ("LSA[Type%d:%s]: This LSA is self-originated: ",
2474 lsa->data->type, inet_ntoa (lsa->data->id));
2475
2476 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2477 zlog_info ("LSA[Type%d:%s]: MaxAge LSA removed from list",
2478 lsa->data->type, inet_ntoa (lsa->data->id));
2479
2480 /* Flood max age LSA. */
2481#ifdef ORIGINAL_CODING
2482 ospf_maxage_flood (lsa);
2483#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00002484 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00002485#endif /* ORIGINAL_CODING */
2486
2487 /* Remove from lsdb. */
paul68980082003-03-25 05:07:42 +00002488 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002489 ospf_lsdb_delete (lsa->lsdb, lsa);
2490 }
2491
2492 /* A MaxAge LSA must be removed immediately from the router's link
2493 state database as soon as both a) it is no longer contained on any
2494 neighbor Link state retransmission lists and b) none of the router's
2495 neighbors are in states Exchange or Loading. */
2496 if (reschedule)
paul68980082003-03-25 05:07:42 +00002497 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00002498
2499 return 0;
2500}
2501
2502int
paul68980082003-03-25 05:07:42 +00002503ospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new)
paul718e3742002-12-13 20:15:29 +00002504{
2505 listnode node;
2506
paul68980082003-03-25 05:07:42 +00002507 for (node = listhead (ospf->maxage_lsa); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002508 if (((struct ospf_lsa *) node->data) == new)
2509 return 1;
2510
2511 return 0;
2512}
2513
2514void
paul68980082003-03-25 05:07:42 +00002515ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002516{
2517 listnode n;
2518
paul68980082003-03-25 05:07:42 +00002519 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00002520 {
paul68980082003-03-25 05:07:42 +00002521 list_delete_node (ospf->maxage_lsa, n);
paul718e3742002-12-13 20:15:29 +00002522 ospf_lsa_unlock (lsa);
2523 }
2524}
2525
2526void
paul68980082003-03-25 05:07:42 +00002527ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002528{
2529 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2530 and schedule the MaxAge LSA remover. */
paul68980082003-03-25 05:07:42 +00002531 if (ospf_lsa_maxage_exist (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002532 {
2533 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2534 zlog_info ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
2535 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2536 return;
2537 }
2538
paul68980082003-03-25 05:07:42 +00002539 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00002540
2541 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2542 zlog_info ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
2543
paul68980082003-03-25 05:07:42 +00002544 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00002545}
2546
2547int
paul68980082003-03-25 05:07:42 +00002548ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002549{
2550#ifdef HAVE_NSSA
2551 /* Stay away from any Local Translated Type-7 LSAs */
2552 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2553 return 0;
2554#endif /* HAVE_NSSA */
2555
2556 if (IS_LSA_MAXAGE (lsa))
2557 /* Self-originated LSAs should NOT time-out instead,
2558 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00002559 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002560 {
2561 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2562 zlog_info("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
2563
2564 switch (lsa->data->type)
2565 {
paul718e3742002-12-13 20:15:29 +00002566#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00002567 case OSPF_OPAQUE_LINK_LSA:
2568 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00002569 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00002570 /*
2571 * As a general rule, whenever network topology has changed
2572 * (due to an LSA removal in this case), routing recalculation
2573 * should be triggered. However, this is not true for opaque
2574 * LSAs. Even if an opaque LSA instance is going to be removed
2575 * from the routing domain, it does not mean a change in network
2576 * topology, and thus, routing recalculation is not needed here.
2577 */
2578 break;
paul718e3742002-12-13 20:15:29 +00002579#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00002580 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002581#ifdef HAVE_NSSA
2582 case OSPF_AS_NSSA_LSA:
2583#endif /* HAVE_NSSA */
2584 ospf_ase_incremental_update (ospf, lsa);
2585 break;
paul718e3742002-12-13 20:15:29 +00002586 default:
paul68980082003-03-25 05:07:42 +00002587 ospf_spf_calculate_schedule (ospf);
2588 break;
paul718e3742002-12-13 20:15:29 +00002589 }
paul68980082003-03-25 05:07:42 +00002590 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002591 }
2592
2593 return 0;
2594}
2595
2596/* Periodical check of MaxAge LSA. */
2597int
paul68980082003-03-25 05:07:42 +00002598ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002599{
paul68980082003-03-25 05:07:42 +00002600 struct ospf *ospf = THREAD_ARG (thread);
2601 struct route_node *rn;
2602 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00002603 listnode node;
2604
paul68980082003-03-25 05:07:42 +00002605 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00002606
paul68980082003-03-25 05:07:42 +00002607 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002608 {
2609 struct ospf_area *area = node->data;
2610
paul68980082003-03-25 05:07:42 +00002611 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
2612 ospf_lsa_maxage_walker_remover (ospf, lsa);
2613 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
2614 ospf_lsa_maxage_walker_remover (ospf, lsa);
2615 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
2616 ospf_lsa_maxage_walker_remover (ospf, lsa);
2617 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
2618 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002619#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002620 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
2621 ospf_lsa_maxage_walker_remover (ospf, lsa);
2622 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
2623 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002624#endif /* HAVE_OPAQUE_LSA */
2625 }
2626
2627 /* for AS-eternal-LSAs. */
paul68980082003-03-25 05:07:42 +00002628 if (ospf->lsdb)
2629 {
2630 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
2631 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002632#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002633 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
2634 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002635#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002636 }
paul718e3742002-12-13 20:15:29 +00002637
paul68980082003-03-25 05:07:42 +00002638 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
2639 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00002640 return 0;
2641}
2642
paul68980082003-03-25 05:07:42 +00002643struct ospf_lsa *
2644ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
2645 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00002646{
paul68980082003-03-25 05:07:42 +00002647 struct ospf_lsa *lsa;
2648 struct in_addr mask, id;
2649 struct lsa_header_mask
2650 {
2651 struct lsa_header header;
2652 struct in_addr mask;
2653 } *hmask;
paul718e3742002-12-13 20:15:29 +00002654
paul68980082003-03-25 05:07:42 +00002655 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
2656 if (lsa == NULL)
2657 return NULL;
paul718e3742002-12-13 20:15:29 +00002658
paul68980082003-03-25 05:07:42 +00002659 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00002660
paul68980082003-03-25 05:07:42 +00002661 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00002662
paul68980082003-03-25 05:07:42 +00002663 if (mask.s_addr != hmask->mask.s_addr)
2664 {
2665 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
2666 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
2667 if (!lsa)
2668 return NULL;
2669 }
paul718e3742002-12-13 20:15:29 +00002670
paul68980082003-03-25 05:07:42 +00002671 return lsa;
paul718e3742002-12-13 20:15:29 +00002672}
2673
2674struct ospf_lsa *
2675ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
2676 struct in_addr id, struct in_addr adv_router)
2677{
2678 switch (type)
2679 {
2680 case OSPF_ROUTER_LSA:
2681 case OSPF_NETWORK_LSA:
2682 case OSPF_SUMMARY_LSA:
2683 case OSPF_ASBR_SUMMARY_LSA:
2684#ifdef HAVE_NSSA
2685 case OSPF_AS_NSSA_LSA:
2686#endif /* HAVE_NSSA */
2687#ifdef HAVE_OPAQUE_LSA
2688 case OSPF_OPAQUE_LINK_LSA:
2689 case OSPF_OPAQUE_AREA_LSA:
2690#endif /* HAVE_OPAQUE_LSA */
2691 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
2692 break;
2693 case OSPF_AS_EXTERNAL_LSA:
2694#ifdef HAVE_OPAQUE_LSA
2695 case OSPF_OPAQUE_AS_LSA:
2696#endif /* HAVE_OPAQUE_LSA */
2697 return ospf_lsdb_lookup_by_id (ospf_top->lsdb, type, id, adv_router);
2698 break;
2699 default:
2700 break;
2701 }
2702
2703 return NULL;
2704}
2705
2706struct ospf_lsa *
2707ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
2708 struct in_addr id)
2709{
2710 struct ospf_lsa *lsa;
2711 struct route_node *rn;
2712
2713 switch (type)
2714 {
2715 case OSPF_ROUTER_LSA:
2716 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
2717 break;
2718 case OSPF_NETWORK_LSA:
2719 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
2720 if ((lsa = rn->info))
2721 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
2722 {
2723 route_unlock_node (rn);
2724 return lsa;
2725 }
2726 break;
2727 case OSPF_SUMMARY_LSA:
2728 case OSPF_ASBR_SUMMARY_LSA:
2729 /* Currently not used. */
2730 assert (1);
2731 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
2732 break;
2733 case OSPF_AS_EXTERNAL_LSA:
2734#ifdef HAVE_OPAQUE_LSA
2735 case OSPF_OPAQUE_LINK_LSA:
2736 case OSPF_OPAQUE_AREA_LSA:
2737 case OSPF_OPAQUE_AS_LSA:
2738 /* Currently not used. */
2739 break;
2740#endif /* HAVE_OPAQUE_LSA */
2741 default:
2742 break;
2743 }
2744
2745 return NULL;
2746}
2747
2748struct ospf_lsa *
2749ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
2750{
2751 struct ospf_lsa *match;
2752
2753#ifdef HAVE_OPAQUE_LSA
2754 /*
2755 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
2756 * is redefined to have two subfields; opaque-type and opaque-id.
2757 * However, it is harmless to treat the two sub fields together, as if
2758 * they two were forming a unique LSA-ID.
2759 */
2760#endif /* HAVE_OPAQUE_LSA */
2761
2762 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
2763
2764 if (match == NULL)
2765 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
2766 zlog_info ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
2767 lsah->type, inet_ntoa (lsah->id));
2768
2769 return match;
2770}
2771
2772/* return +n, l1 is more recent.
2773 return -n, l2 is more recent.
2774 return 0, l1 and l2 is identical. */
2775int
2776ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
2777{
2778 int r;
2779 int x, y;
2780
2781 if (l1 == NULL && l2 == NULL)
2782 return 0;
2783 if (l1 == NULL)
2784 return -1;
2785 if (l2 == NULL)
2786 return 1;
2787
2788 /* compare LS sequence number. */
2789 x = (int) ntohl (l1->data->ls_seqnum);
2790 y = (int) ntohl (l2->data->ls_seqnum);
2791 if (x > y)
2792 return 1;
2793 if (x < y)
2794 return -1;
2795
2796 /* compare LS checksum. */
2797 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
2798 if (r)
2799 return r;
2800
2801 /* compare LS age. */
2802 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
2803 return 1;
2804 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
2805 return -1;
2806
2807 /* compare LS age with MaxAgeDiff. */
2808 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
2809 return -1;
2810 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
2811 return 1;
2812
2813 /* LSAs are identical. */
2814 return 0;
2815}
2816
2817/* If two LSAs are different, return 1, otherwise return 0. */
2818int
2819ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
2820{
2821 char *p1, *p2;
2822 assert (l1);
2823 assert (l2);
2824 assert (l1->data);
2825 assert (l2->data);
2826
2827 if (l1->data->options != l2->data->options)
2828 return 1;
2829
2830 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
2831 return 1;
2832
2833 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
2834 return 1;
2835
2836 if (l1->data->length != l2->data->length)
2837 return 1;
2838
2839 if (l1->data->length == 0)
2840 return 1;
2841
2842 assert (l1->data->length > OSPF_LSA_HEADER_SIZE);
2843
2844 p1 = (char *) l1->data;
2845 p2 = (char *) l2->data;
2846
2847 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
2848 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
2849 return 1;
2850
2851 return 0;
2852}
2853
2854#ifdef ORIGINAL_CODING
2855void
2856ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
2857 struct ospf_lsa *self,
2858 struct ospf_lsa *new)
2859{
2860 u_int32_t seqnum;
2861
2862 /* Adjust LS Sequence Number. */
2863 seqnum = ntohl (new->data->ls_seqnum) + 1;
2864 self->data->ls_seqnum = htonl (seqnum);
2865
2866 /* Recalculate LSA checksum. */
2867 ospf_lsa_checksum (self->data);
2868
2869 /* Reflooding LSA. */
2870 /* RFC2328 Section 13.3
2871 On non-broadcast networks, separate Link State Update
2872 packets must be sent, as unicasts, to each adjacent neighbor
2873 (i.e., those in state Exchange or greater). The destination
2874 IP addresses for these packets are the neighbors' IP
2875 addresses. */
2876 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
2877 {
2878 struct route_node *rn;
2879 struct ospf_neighbor *onbr;
2880
2881 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
2882 if ((onbr = rn->info) != NULL)
2883 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
2884 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
2885 }
2886 else
2887 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
2888
2889 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2890 zlog_info ("LSA[Type%d:%s]: Flush self-originated LSA",
2891 self->data->type, inet_ntoa (self->data->id));
2892}
2893#else /* ORIGINAL_CODING */
2894static int
paul68980082003-03-25 05:07:42 +00002895ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002896{
2897 if (lsa == NULL || !IS_LSA_SELF (lsa))
2898 return 0;
2899
2900 if (IS_DEBUG_OSPF_EVENT)
2901 zlog_info ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
2902
2903 /* Force given lsa's age to MaxAge. */
2904 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2905
2906 switch (lsa->data->type)
2907 {
2908#ifdef HAVE_OPAQUE_LSA
2909 case OSPF_OPAQUE_LINK_LSA:
2910 case OSPF_OPAQUE_AREA_LSA:
2911 case OSPF_OPAQUE_AS_LSA:
2912 ospf_opaque_lsa_refresh (lsa);
2913 break;
2914#endif /* HAVE_OPAQUE_LSA */
2915 default:
paul68980082003-03-25 05:07:42 +00002916 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002917 break;
2918 }
2919
2920 return 0;
2921}
2922
2923void
paul68980082003-03-25 05:07:42 +00002924ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002925{
2926 listnode n1, n2;
2927 struct ospf_area *area;
2928 struct ospf_interface *oi;
2929 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00002930 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00002931 int need_to_flush_ase = 0;
2932
paul68980082003-03-25 05:07:42 +00002933 for (n1 = listhead (ospf->areas); n1; nextnode (n1))
paul718e3742002-12-13 20:15:29 +00002934 {
2935 if ((area = getdata (n1)) == NULL)
2936 continue;
2937
2938 if ((lsa = area->router_lsa_self) != NULL)
2939 {
2940 if (IS_DEBUG_OSPF_EVENT)
2941 zlog_info ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
2942
2943 ospf_lsa_flush_area (lsa, area);
2944 ospf_lsa_unlock (area->router_lsa_self);
2945 area->router_lsa_self = NULL;
2946 OSPF_TIMER_OFF (area->t_router_lsa_self);
2947 }
2948
2949 for (n2 = listhead (area->oiflist); n2; nextnode (n2))
2950 {
2951 if ((oi = getdata (n2)) == NULL)
2952 continue;
2953
2954 if ((lsa = oi->network_lsa_self) != NULL
2955 && oi->state == ISM_DR
2956 && oi->full_nbrs > 0)
2957 {
2958 if (IS_DEBUG_OSPF_EVENT)
2959 zlog_info ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
2960
2961 ospf_lsa_flush_area (oi->network_lsa_self, area);
2962 ospf_lsa_unlock (oi->network_lsa_self);
2963 oi->network_lsa_self = NULL;
2964 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2965 }
2966
2967 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
2968 && area->external_routing == OSPF_AREA_DEFAULT)
2969 need_to_flush_ase = 1;
2970 }
2971
paul68980082003-03-25 05:07:42 +00002972 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
2973 ospf_lsa_flush_schedule (ospf, lsa);
2974 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
2975 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002976#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002977 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
2978 ospf_lsa_flush_schedule (ospf, lsa);
2979 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
2980 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002981#endif /* HAVE_OPAQUE_LSA */
2982 }
2983
2984 if (need_to_flush_ase)
2985 {
paul68980082003-03-25 05:07:42 +00002986 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
2987 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002988#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002989 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
2990 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002991#endif /* HAVE_OPAQUE_LSA */
2992 }
2993
2994 /*
2995 * Make sure that the MaxAge LSA remover is executed immediately,
2996 * without conflicting to other threads.
2997 */
paul68980082003-03-25 05:07:42 +00002998 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00002999 {
paul68980082003-03-25 05:07:42 +00003000 OSPF_TIMER_OFF (ospf->t_maxage);
3001 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003002 }
3003
3004 return;
3005}
3006#endif /* ORIGINAL_CODING */
3007
3008/* If there is self-originated LSA, then return 1, otherwise return 0. */
3009/* An interface-independent version of ospf_lsa_is_self_originated */
3010int
paul68980082003-03-25 05:07:42 +00003011ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003012{
3013 listnode node;
3014
3015 /* This LSA is already checked. */
3016 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3017 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3018
3019 /* Make sure LSA is self-checked. */
3020 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3021
3022 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003023 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003024 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3025
3026 /* LSA is router-LSA. */
3027 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003028 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003029 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3030
3031 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3032 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul68980082003-03-25 05:07:42 +00003033 for (node = listhead (ospf->oiflist); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00003034 {
3035 struct ospf_interface *oi = getdata (node);
3036
3037 /* Ignore virtual link. */
3038 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3039 if (oi->address->family == AF_INET)
3040 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3041 {
3042 /* to make it easier later */
3043 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3044 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3045 }
3046 }
3047
3048 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3049}
3050
3051/* Get unique Link State ID. */
3052struct in_addr
paul68980082003-03-25 05:07:42 +00003053ospf_lsa_unique_id (struct ospf *ospf,
3054 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003055{
3056 struct ospf_lsa *lsa;
3057 struct in_addr mask, id;
3058
3059 id = p->prefix;
3060
3061 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003062 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003063 if (lsa)
3064 {
3065 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3066 if (ip_masklen (al->mask) == p->prefixlen)
3067 {
3068 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
3069 zlog_warn ("ospf_lsa_unique_id(): "
3070 "Can't get Link State ID for %s/%d",
3071 inet_ntoa (p->prefix), p->prefixlen);
3072 /* id.s_addr = 0; */
3073 id.s_addr = 0xffffffff;
3074 return id;
3075 }
3076 /* Masklen differs, then apply wildcard mask to Link State ID. */
3077 else
3078 {
3079 masklen2ip (p->prefixlen, &mask);
3080
3081 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003082 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3083 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003084 if (lsa)
3085 {
3086 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
3087 zlog_warn ("ospf_lsa_unique_id(): "
3088 "Can't get Link State ID for %s/%d",
3089 inet_ntoa (p->prefix), p->prefixlen);
3090 /* id.s_addr = 0; */
3091 id.s_addr = 0xffffffff;
3092 return id;
3093 }
3094 }
3095 }
3096
3097 return id;
3098}
3099
3100
3101#define LSA_ACTION_ORIGN_RTR 1
3102#define LSA_ACTION_ORIGN_NET 2
3103#define LSA_ACTION_FLOOD_AREA 3
3104#define LSA_ACTION_FLOOD_AS 4
3105#define LSA_ACTION_FLUSH_AREA 5
3106#define LSA_ACTION_FLUSH_AS 6
3107
3108struct lsa_action
3109{
3110 u_char action;
3111 struct ospf_area *area;
3112 struct ospf_interface *oi;
3113 struct ospf_lsa *lsa;
3114};
3115
3116int
3117ospf_lsa_action (struct thread *t)
3118{
3119 struct lsa_action *data;
paul68980082003-03-25 05:07:42 +00003120 struct ospf *ospf = ospf_top;
paul718e3742002-12-13 20:15:29 +00003121
3122 data = THREAD_ARG (t);
3123
3124 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
3125 zlog_info ("LSA[Action]: Performing scheduled LSA action: %d",
3126 data->action);
3127
3128 switch (data->action)
3129 {
3130 case LSA_ACTION_ORIGN_RTR:
3131 ospf_router_lsa_refresh (data->area->router_lsa_self);
3132 break;
3133 case LSA_ACTION_ORIGN_NET:
3134 ospf_network_lsa_originate (data->oi);
3135 break;
3136 case LSA_ACTION_FLOOD_AREA:
3137 ospf_flood_through_area (data->area, NULL, data->lsa);
3138 break;
3139 case LSA_ACTION_FLOOD_AS:
paul68980082003-03-25 05:07:42 +00003140 ospf_flood_through_as (ospf, NULL, data->lsa);
paul718e3742002-12-13 20:15:29 +00003141 break;
3142 case LSA_ACTION_FLUSH_AREA:
3143 ospf_lsa_flush_area (data->lsa, data->area);
3144 break;
3145 case LSA_ACTION_FLUSH_AS:
paul68980082003-03-25 05:07:42 +00003146 ospf_lsa_flush_as (ospf, data->lsa);
paul718e3742002-12-13 20:15:29 +00003147 break;
3148 }
3149
3150 ospf_lsa_unlock (data->lsa);
3151 XFREE (MTYPE_OSPF_MESSAGE, data);
3152 return 0;
3153}
3154
3155void
3156ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3157{
3158 struct lsa_action *data;
3159
3160 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3161 memset (data, 0, sizeof (struct lsa_action));
3162
3163 data->action = LSA_ACTION_FLOOD_AREA;
3164 data->area = area;
3165 data->lsa = ospf_lsa_lock (lsa);
3166
3167 thread_add_event (master, ospf_lsa_action, data, 0);
3168}
3169
3170void
3171ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3172{
3173 struct lsa_action *data;
3174
3175 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3176 memset (data, 0, sizeof (struct lsa_action));
3177
3178 data->action = LSA_ACTION_FLUSH_AREA;
3179 data->area = area;
3180 data->lsa = ospf_lsa_lock (lsa);
3181
3182 thread_add_event (master, ospf_lsa_action, data, 0);
3183}
3184
3185
3186/* LSA Refreshment functions. */
3187void
paul68980082003-03-25 05:07:42 +00003188ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003189{
3190 struct external_info *ei;
3191 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3192
3193 switch (lsa->data->type)
3194 {
3195 /* Router and Network LSAs are processed differently. */
3196 case OSPF_ROUTER_LSA:
3197 case OSPF_NETWORK_LSA:
3198 break;
3199 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003200 ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003201 break;
3202 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003203 ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003204 break;
3205 case OSPF_AS_EXTERNAL_LSA:
3206 ei = ospf_external_info_check (lsa);
3207 if (ei)
paul68980082003-03-25 05:07:42 +00003208 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003209 else
paul68980082003-03-25 05:07:42 +00003210 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003211 break;
3212#ifdef HAVE_OPAQUE_LSA
3213 case OSPF_OPAQUE_LINK_LSA:
3214 case OSPF_OPAQUE_AREA_LSA:
3215 case OSPF_OPAQUE_AS_LSA:
3216 ospf_opaque_lsa_refresh (lsa);
3217 break;
3218 default:
3219 break;
3220#endif /* HAVE_OPAQUE_LSA */
3221 }
3222}
3223
3224void
paul68980082003-03-25 05:07:42 +00003225ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003226{
3227 u_int16_t index, current_index;
3228
3229 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3230
3231 if (lsa->refresh_list < 0)
3232 {
3233 int delay;
3234
3235 if (LS_AGE (lsa) == 0 &&
3236 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3237 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3238 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3239 else
3240 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3241 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3242 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3243
3244 if (delay < 0)
3245 delay = 0;
3246
paul68980082003-03-25 05:07:42 +00003247 current_index = ospf->lsa_refresh_queue.index +
3248 (time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003249
3250 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3251 % (OSPF_LSA_REFRESHER_SLOTS);
3252
3253 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3254 zlog_info ("LSA[Refresh]: lsa with age %d added to index %d",
3255 LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003256 if (!ospf->lsa_refresh_queue.qs[index])
3257 ospf->lsa_refresh_queue.qs[index] = list_new ();
3258 listnode_add (ospf->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00003259 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003260 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3261 zlog_info ("LSA[Refresh]: ospf_refresher_register_lsa(): setting refresh_list on lsa %p (slod %d)", lsa, index);
paul718e3742002-12-13 20:15:29 +00003262 }
3263}
3264
3265void
paul68980082003-03-25 05:07:42 +00003266ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003267{
3268 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3269 if (lsa->refresh_list >= 0)
3270 {
paul68980082003-03-25 05:07:42 +00003271 list refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003272 listnode_delete (refresh_list, lsa);
3273 if (!listcount (refresh_list))
3274 {
3275 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003276 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003277 }
3278 ospf_lsa_unlock (lsa);
3279 lsa->refresh_list = -1;
3280 }
3281}
3282
3283int
3284ospf_lsa_refresh_walker (struct thread *t)
3285{
3286 list refresh_list;
3287 listnode node;
paul68980082003-03-25 05:07:42 +00003288 struct ospf *ospf = THREAD_ARG (t);
paul718e3742002-12-13 20:15:29 +00003289 int i;
3290 list lsa_to_refresh = list_new ();
3291
3292 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3293 zlog_info ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
3294
3295
paul68980082003-03-25 05:07:42 +00003296 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003297
paul68980082003-03-25 05:07:42 +00003298 ospf->lsa_refresh_queue.index =
3299 (ospf->lsa_refresh_queue.index +
3300 (time (NULL) - ospf->lsa_refresher_started) / OSPF_LSA_REFRESHER_GRANULARITY)
paul718e3742002-12-13 20:15:29 +00003301 % OSPF_LSA_REFRESHER_SLOTS;
3302
3303 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3304 zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003305 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003306
paul68980082003-03-25 05:07:42 +00003307 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003308 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3309 {
3310 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3311 zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh index %d", i);
3312
paul68980082003-03-25 05:07:42 +00003313 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003314
paul68980082003-03-25 05:07:42 +00003315 ospf->lsa_refresh_queue.qs [i] = NULL;
3316
paul718e3742002-12-13 20:15:29 +00003317 if (refresh_list)
3318 {
3319 for (node = listhead (refresh_list); node;)
3320 {
3321 listnode next;
3322 struct ospf_lsa *lsa = getdata (node);
3323 next = node->next;
3324
3325 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
paulf2c80652002-12-13 21:44:27 +00003326 zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh lsa %p (slot %d)", lsa, i);
paul718e3742002-12-13 20:15:29 +00003327
3328 list_delete_node (refresh_list, node);
3329 ospf_lsa_unlock (lsa);
3330 lsa->refresh_list = -1;
3331 listnode_add (lsa_to_refresh, lsa);
3332 node = next;
3333 }
3334 list_free (refresh_list);
3335 }
3336 }
3337
paul68980082003-03-25 05:07:42 +00003338 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3339 ospf, ospf->lsa_refresh_interval);
3340 ospf->lsa_refresher_started = time (NULL);
paul718e3742002-12-13 20:15:29 +00003341
3342 for (node = listhead (lsa_to_refresh); node; nextnode (node))
paul68980082003-03-25 05:07:42 +00003343 ospf_lsa_refresh (ospf, getdata (node));
paul718e3742002-12-13 20:15:29 +00003344
3345 list_delete (lsa_to_refresh);
3346
3347 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
3348 zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
3349
3350 return 0;
3351}
3352