blob: b237adbc6e16c9d2bae1c0de855e1c174078f275 [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))
ajse588f212004-12-08 18:12:06 +0000152 zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
paul718e3742002-12-13 20:15:29 +0000153 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;
hassoc9e52be2004-09-26 16:09:34 +0000189 sp = (u_char *) &lsa->options;
paul718e3742002-12-13 20:15:29 +0000190
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))
ajse588f212004-12-08 18:12:06 +0000263 zlog_debug ("LSA: duplicated %p (new: %p)", lsa, new);
paulf2c80652002-12-13 21:44:27 +0000264
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))
ajse588f212004-12-08 18:12:06 +0000275 zlog_debug ("LSA: freed %p", lsa);
paul718e3742002-12-13 20:15:29 +0000276
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))
ajse588f212004-12-08 18:12:06 +0000354 zlog_debug ("LSA[Type%d:%s]: data freed %p",
paul718e3742002-12-13 20:15:29 +0000355 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[] = {
hasso52dc7ee2004-09-23 19:18:23 +0000367 "Type255,id(255.255.255.255),ar(255.255.255.255)"
paul718e3742002-12-13 20:15:29 +0000368 };
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)
paul942b6c12003-06-22 08:22:18 +0000441 UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
442 /* If ASBR set External flag */
443 else if (IS_OSPF_ASBR (area->ospf))
444 SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
445
446 /* Set ABR dependent flags */
447 if (IS_OSPF_ABR (area->ospf))
448 {
449 SET_FLAG (flags, ROUTER_LSA_BORDER);
paul942b6c12003-06-22 08:22:18 +0000450 /* If Area is NSSA and we are both ABR and unconditional translator,
pauld4a53d52003-07-12 21:30:57 +0000451 * set Nt bit to inform other routers.
paul942b6c12003-06-22 08:22:18 +0000452 */
pauld4a53d52003-07-12 21:30:57 +0000453 if ( (area->external_routing == OSPF_AREA_NSSA)
454 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
455 SET_FLAG (flags, ROUTER_LSA_NT);
paul942b6c12003-06-22 08:22:18 +0000456 }
paul718e3742002-12-13 20:15:29 +0000457 return flags;
458}
459
460/* Lookup neighbor other than myself.
461 And check neighbor count,
462 Point-to-Point link must have only 1 neighbor. */
463struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +0000464ospf_nbr_lookup_ptop (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +0000465{
paul718e3742002-12-13 20:15:29 +0000466 struct ospf_neighbor *nbr = NULL;
paul68980082003-03-25 05:07:42 +0000467 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000468
469 /* Search neighbor, there must be one of two nbrs. */
paul68980082003-03-25 05:07:42 +0000470 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
471 if ((nbr = rn->info))
472 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000473 if (nbr->state == NSM_Full)
paul68980082003-03-25 05:07:42 +0000474 {
475 route_unlock_node (rn);
476 break;
477 }
paul718e3742002-12-13 20:15:29 +0000478
479 /* PtoP link must have only 1 neighbor. */
paul68980082003-03-25 05:07:42 +0000480 if (ospf_nbr_count (oi, 0) > 1)
paul718e3742002-12-13 20:15:29 +0000481 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
482
483 return nbr;
484}
485
486/* Set a link information. */
487void
488link_info_set (struct stream *s, struct in_addr id,
489 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
490{
491 /* TOS based routing is not supported. */
492 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
493 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
494 stream_putc (s, type); /* Link Type. */
495 stream_putc (s, tos); /* TOS = 0. */
496 stream_putw (s, cost); /* Link Cost. */
497}
498
499/* Describe Point-to-Point link. */
500int
501lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
502{
503 int links = 0;
504 struct ospf_neighbor *nbr;
505 struct in_addr id, mask;
506
507 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000508 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
paul718e3742002-12-13 20:15:29 +0000509
paul68980082003-03-25 05:07:42 +0000510 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000511 if (nbr->state == NSM_Full)
512 {
513 /* For unnumbered point-to-point networks, the Link Data field
514 should specify the interface's MIB-II ifIndex value. */
515 link_info_set (s, nbr->router_id, oi->address->u.prefix4,
516 LSA_LINK_TYPE_POINTOPOINT, 0, oi->output_cost);
517 links++;
518 }
519
hasso3fb9cd62004-10-19 19:44:43 +0000520 if (CONNECTED_DEST_HOST(oi->connected))
paul718e3742002-12-13 20:15:29 +0000521 {
522 /* Option 1:
523 link_type = LSA_LINK_TYPE_STUB;
524 link_id = nbr->address.u.prefix4;
525 link_data.s_addr = 0xffffffff;
526 link_cost = o->output_cost; */
527
528 id.s_addr = oi->connected->destination->u.prefix4.s_addr;
529 mask.s_addr = 0xffffffff;
530 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
531 }
532 else
533 {
534 /* Option 2: We need to include link to a stub
535 network regardless of the state of the neighbor */
536 masklen2ip (oi->address->prefixlen, &mask);
537 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
538 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
539 }
540 links++;
541
542 return links;
543}
544
545/* Describe Broadcast Link. */
546int
547lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
548{
549 struct ospf_neighbor *dr;
550 struct in_addr id, mask;
551
552 /* Describe Type 3 Link. */
553 if (oi->state == ISM_Waiting)
554 {
555 masklen2ip (oi->address->prefixlen, &mask);
556 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
557 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
558 return 1;
559 }
560
561 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
562 /* Describe Type 2 link. */
563 if (dr && (dr->state == NSM_Full ||
564 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000565 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000566 {
567 link_info_set (s, DR (oi), oi->address->u.prefix4,
568 LSA_LINK_TYPE_TRANSIT, 0, oi->output_cost);
569 }
570 /* Describe type 3 link. */
571 else
572 {
573 masklen2ip (oi->address->prefixlen, &mask);
574 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
575 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
576 }
577 return 1;
578}
579
580int
581lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
582{
583 struct in_addr id, mask;
584
585 /* Describe Type 3 Link. */
586 if (oi->state != ISM_Loopback)
587 return 0;
588
589 mask.s_addr = 0xffffffff;
590 id.s_addr = oi->address->u.prefix4.s_addr;
591 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
592 return 1;
593}
594
595/* Describe Virtual Link. */
596int
597lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
598{
599 struct ospf_neighbor *nbr;
600
paul718e3742002-12-13 20:15:29 +0000601 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000602 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000603 if (nbr->state == NSM_Full)
604 {
605 link_info_set (s, nbr->router_id, oi->address->u.prefix4,
606 LSA_LINK_TYPE_VIRTUALLINK, 0, oi->output_cost);
607 return 1;
608 }
609
610 return 0;
611}
612
613#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
614
paul7afa08d2002-12-13 20:59:45 +0000615/* this function add for support point-to-multipoint ,see rfc2328
61612.4.1.4.*/
617/* from "edward rrr" <edward_rrr@hotmail.com>
618 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul68980082003-03-25 05:07:42 +0000619int
620lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000621{
622 int links = 0;
623 struct route_node *rn;
624 struct ospf_neighbor *nbr = NULL;
625 struct in_addr id, mask;
626
627 mask.s_addr = 0xffffffff;
628 id.s_addr = oi->address->u.prefix4.s_addr;
629 link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
630 links++;
631
paul1cc8f762003-04-05 19:34:32 +0000632 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000633 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000634
635 /* Search neighbor, */
636 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
637 if ((nbr = rn->info) != NULL)
638 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000639 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000640 if (nbr->state == NSM_Full)
641
642 {
paul7afa08d2002-12-13 20:59:45 +0000643 link_info_set (s, nbr->router_id, oi->address->u.prefix4,
644 LSA_LINK_TYPE_POINTOPOINT, 0, oi->output_cost);
645 links++;
paul1cc8f762003-04-05 19:34:32 +0000646 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000647 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000648 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000649 }
650
651 return links;
paul7afa08d2002-12-13 20:59:45 +0000652}
653
paul718e3742002-12-13 20:15:29 +0000654/* Set router-LSA link information. */
655int
656router_lsa_link_set (struct stream *s, struct ospf_area *area)
657{
hasso52dc7ee2004-09-23 19:18:23 +0000658 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000659 int links = 0;
660
661 for (node = listhead (area->oiflist); node; node = nextnode (node))
662 {
663 struct ospf_interface *oi = node->data;
664 struct interface *ifp = oi->ifp;
665
666 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000667 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000668 {
669 if (oi->state != ISM_Down)
670 {
671 /* Describe each link. */
672 switch (oi->type)
673 {
674 case OSPF_IFTYPE_POINTOPOINT:
675 links += lsa_link_ptop_set (s, oi);
676 break;
677 case OSPF_IFTYPE_BROADCAST:
678 links += lsa_link_broadcast_set (s, oi);
679 break;
680 case OSPF_IFTYPE_NBMA:
681 links += lsa_link_nbma_set (s, oi);
682 break;
683 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000684 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000685 break;
686 case OSPF_IFTYPE_VIRTUALLINK:
687 links += lsa_link_virtuallink_set (s, oi);
688 break;
689 case OSPF_IFTYPE_LOOPBACK:
690 links += lsa_link_loopback_set (s, oi);
691 }
692 }
693 }
694 }
695
696 return links;
697}
698
699/* Set router-LSA body. */
700void
701ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
702{
703 unsigned long putp;
704 u_int16_t cnt;
705
706 /* Set flags. */
707 stream_putc (s, router_lsa_flags (area));
708
709 /* Set Zero fields. */
710 stream_putc (s, 0);
711
712 /* Keep pointer to # links. */
713 putp = s->putp;
714
715 /* Forward word */
716 stream_putw(s, 0);
717
718 /* Set all link information. */
719 cnt = router_lsa_link_set (s, area);
720
721 /* Set # of links here. */
722 stream_putw_at (s, putp, cnt);
723}
724
725/* Create new router-LSA. */
726struct ospf_lsa *
727ospf_router_lsa_new (struct ospf_area *area)
728{
paul68980082003-03-25 05:07:42 +0000729 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000730 struct stream *s;
731 struct lsa_header *lsah;
732 struct ospf_lsa *new;
733 int length;
734
735 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000736 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000737
738 /* Create a stream for LSA. */
739 s = stream_new (OSPF_MAX_LSA_SIZE);
740 lsah = (struct lsa_header *) STREAM_DATA (s);
741
paul718e3742002-12-13 20:15:29 +0000742 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000743 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000744 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000745
746 /* Set router-LSA body fields. */
747 ospf_router_lsa_body_set (s, area);
748
749 /* Set length. */
750 length = stream_get_endp (s);
751 lsah->length = htons (length);
752
753 /* Now, create OSPF LSA instance. */
754 new = ospf_lsa_new ();
755 new->area = area;
756 SET_FLAG (new->flags, OSPF_LSA_SELF);
757
758 /* Copy LSA data to store, discard stream. */
759 new->data = ospf_lsa_data_new (length);
760 memcpy (new->data, lsah, length);
761 stream_free (s);
762
763 return new;
764}
765
766/* Originate Router-LSA. */
767struct ospf_lsa *
768ospf_router_lsa_originate (struct ospf_area *area)
769{
770 struct ospf_lsa *new;
771
772 /* Create new router-LSA instance. */
773 new = ospf_router_lsa_new (area);
774
775 /* Sanity check. */
776 if (new->data->adv_router.s_addr == 0)
777 {
778 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000779 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000780 ospf_lsa_discard (new);
781 return NULL;
782 }
783
784 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000785 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000786
787 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000788 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000789
790 /* Flooding new LSA through area. */
791 ospf_flood_through_area (area, NULL, new);
792
793 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
794 {
ajse588f212004-12-08 18:12:06 +0000795 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
paul718e3742002-12-13 20:15:29 +0000796 new->data->type, inet_ntoa (new->data->id), new);
797 ospf_lsa_header_dump (new->data);
798 }
799
800 return new;
801}
802
803/* Refresh router-LSA. */
804struct ospf_lsa *
805ospf_router_lsa_refresh (struct ospf_lsa *lsa)
806{
807 struct ospf_area *area = lsa->area;
808 struct ospf_lsa *new;
809
810 /* Sanity check. */
811 assert (lsa->data);
812
813 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000814 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000815
816 /* Create new router-LSA instance. */
817 new = ospf_router_lsa_new (area);
818 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
819
paul68980082003-03-25 05:07:42 +0000820 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000821
822 /* Flood LSA through area. */
823 ospf_flood_through_area (area, NULL, new);
824
825 /* Debug logging. */
826 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
827 {
ajse588f212004-12-08 18:12:06 +0000828 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000829 new->data->type, inet_ntoa (new->data->id));
830 ospf_lsa_header_dump (new->data);
831 }
832
833 return NULL;
834}
835
836int
837ospf_router_lsa_timer (struct thread *t)
838{
839 struct ospf_area *area;
840
841 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000842 zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
paul718e3742002-12-13 20:15:29 +0000843
844 area = THREAD_ARG (t);
845 area->t_router_lsa_self = NULL;
846
847 /* Now refresh router-LSA. */
848 if (area->router_lsa_self)
849 ospf_router_lsa_refresh (area->router_lsa_self);
850 /* Newly originate router-LSA. */
851 else
852 ospf_router_lsa_originate (area);
853
854 return 0;
855}
856
857void
858ospf_router_lsa_timer_add (struct ospf_area *area)
859{
860 /* Keep area's self-originated router-LSA. */
861 struct ospf_lsa *lsa = area->router_lsa_self;
862
863 /* Cancel previously scheduled router-LSA timer. */
864 if (area->t_router_lsa_self)
865 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000866 zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
paul718e3742002-12-13 20:15:29 +0000867
868 OSPF_TIMER_OFF (area->t_router_lsa_self);
869
870 /* If router-LSA is originated previously, check the interval time. */
871 if (lsa)
872 {
873 int delay;
874 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
875 {
876 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
877 ospf_router_lsa_timer, delay);
878 return;
879 }
880 }
881
882 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000883 zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
paul718e3742002-12-13 20:15:29 +0000884
885 /* Immediately refresh router-LSA. */
886 OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
887}
888
889int
paul68980082003-03-25 05:07:42 +0000890ospf_router_lsa_update_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000891{
paul68980082003-03-25 05:07:42 +0000892 struct ospf *ospf = THREAD_ARG (thread);
hasso52dc7ee2004-09-23 19:18:23 +0000893 struct listnode *node;
paul718e3742002-12-13 20:15:29 +0000894
895 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000896 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +0000897
paul68980082003-03-25 05:07:42 +0000898 ospf->t_router_lsa_update = NULL;
paul718e3742002-12-13 20:15:29 +0000899
paul68980082003-03-25 05:07:42 +0000900 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +0000901 {
902 struct ospf_area *area = getdata (node);
903 struct ospf_lsa *lsa = area->router_lsa_self;
904 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +0000905 const char *area_str;
paul718e3742002-12-13 20:15:29 +0000906
907 /* Keep Area ID string. */
908 area_str = AREA_NAME (area);
909
910 /* If LSA not exist in this Area, originate new. */
911 if (lsa == NULL)
912 {
913 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000914 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +0000915
916 ospf_router_lsa_originate (area);
917 }
918 /* If router-ID is changed, Link ID must change.
919 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +0000920 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000921 {
922 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000923 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +0000924 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
925 ospf_lsa_flush_area (lsa, area);
926 ospf_lsa_unlock (area->router_lsa_self);
927 area->router_lsa_self = NULL;
928
929 /* Refresh router-LSA, (not install) and flood through area. */
930 ospf_router_lsa_timer_add (area);
931 }
932 else
933 {
934 rl = (struct router_lsa *) lsa->data;
935 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +0000936 if (rl->flags != ospf->flags)
paul718e3742002-12-13 20:15:29 +0000937 ospf_router_lsa_timer_add (area);
938 }
939 }
940
941 return 0;
942}
943
944
945/* network-LSA related functions. */
946/* Originate Network-LSA. */
947void
948ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
949{
950 struct in_addr mask;
951 struct route_node *rn;
952 struct ospf_neighbor *nbr;
953
954 masklen2ip (oi->address->prefixlen, &mask);
955 stream_put_ipv4 (s, mask.s_addr);
956
957 /* The network-LSA lists those routers that are fully adjacent to
958 the Designated Router; each fully adjacent router is identified by
959 its OSPF Router ID. The Designated Router includes itself in this
960 list. RFC2328, Section 12.4.2 */
961
962 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
963 if ((nbr = rn->info) != NULL)
964 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
965 stream_put_ipv4 (s, nbr->router_id.s_addr);
966}
967
968struct ospf_lsa *
969ospf_network_lsa_new (struct ospf_interface *oi)
970{
971 struct stream *s;
972 struct ospf_lsa *new;
973 struct lsa_header *lsah;
974 int length;
975
976 /* If there are no neighbours on this network (the net is stub),
977 the router does not originate network-LSA (see RFC 12.4.2) */
978 if (oi->full_nbrs == 0)
979 return NULL;
980
981 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000982 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +0000983
984 /* Create new stream for LSA. */
985 s = stream_new (OSPF_MAX_LSA_SIZE);
986 lsah = (struct lsa_header *) STREAM_DATA (s);
987
988 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +0000989 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000990
991 /* Set network-LSA body fields. */
992 ospf_network_lsa_body_set (s, oi);
993
994 /* Set length. */
995 length = stream_get_endp (s);
996 lsah->length = htons (length);
997
998 /* Create OSPF LSA instance. */
999 new = ospf_lsa_new ();
1000 new->area = oi->area;
1001 SET_FLAG (new->flags, OSPF_LSA_SELF);
1002
1003 /* Copy LSA to store. */
1004 new->data = ospf_lsa_data_new (length);
1005 memcpy (new->data, lsah, length);
1006 stream_free (s);
1007
1008 return new;
1009}
1010
1011/* Originate network-LSA. */
1012struct ospf_lsa *
1013ospf_network_lsa_originate (struct ospf_interface *oi)
1014{
1015 struct ospf_lsa *new;
1016
1017 /* Create new network-LSA instance. */
1018 new = ospf_network_lsa_new (oi);
1019 if (new == NULL)
1020 return NULL;
1021
1022 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001023 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001024
1025 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001026 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001027
1028 /* Flooding new LSA through area. */
1029 ospf_flood_through_area (oi->area, NULL, new);
1030
1031 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1032 {
ajse588f212004-12-08 18:12:06 +00001033 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001034 new->data->type, inet_ntoa (new->data->id), new);
1035 ospf_lsa_header_dump (new->data);
1036 }
1037
1038 return new;
1039}
1040
1041int
1042ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1043{
1044 struct ospf_area *area = lsa->area;
1045 struct ospf_lsa *new;
1046
1047 assert (lsa->data);
1048
1049 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001050 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001051
1052 /* Create new network-LSA instance. */
1053 new = ospf_network_lsa_new (oi);
1054 if (new == NULL)
1055 return -1;
1056 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1057
paul68980082003-03-25 05:07:42 +00001058 ospf_lsa_install (area->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001059
1060 /* Flood LSA through aera. */
1061 ospf_flood_through_area (area, NULL, new);
1062
1063 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1064 {
ajse588f212004-12-08 18:12:06 +00001065 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001066 new->data->type, inet_ntoa (new->data->id));
1067 ospf_lsa_header_dump (new->data);
1068 }
1069
1070 return 0;
1071}
1072
1073int
1074ospf_network_lsa_refresh_timer (struct thread *t)
1075{
1076 struct ospf_interface *oi;
1077
1078 oi = THREAD_ARG (t);
1079 oi->t_network_lsa_self = NULL;
1080
1081 if (oi->network_lsa_self)
1082 /* Now refresh network-LSA. */
1083 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1084 else
1085 /* Newly create network-LSA. */
1086 ospf_network_lsa_originate (oi);
1087
1088 return 0;
1089}
1090
1091void
1092ospf_network_lsa_timer_add (struct ospf_interface *oi)
1093{
1094 /* Keep interface's self-originated network-LSA. */
1095 struct ospf_lsa *lsa = oi->network_lsa_self;
1096
1097 /* Cancel previously schedules network-LSA timer. */
1098 if (oi->t_network_lsa_self)
1099 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001100 zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
paul718e3742002-12-13 20:15:29 +00001101 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1102
1103 /* If network-LSA is originated previously, check the interval time. */
1104 if (lsa)
1105 {
1106 int delay;
1107 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1108 {
1109 oi->t_network_lsa_self =
1110 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1111 oi, delay);
1112 return;
1113 }
1114 }
1115
1116 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001117 zlog_debug ("Scheduling network-LSA origination right away");
paul718e3742002-12-13 20:15:29 +00001118
1119 /* Immediately refresh network-LSA. */
1120 oi->t_network_lsa_self =
1121 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1122}
1123
1124
1125void
1126stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1127{
1128 u_int32_t metric;
1129 char *mp;
1130
1131 /* Put 0 metric. TOS metric is not supported. */
1132 metric = htonl (metric_value);
1133 mp = (char *) &metric;
1134 mp++;
1135 stream_put (s, mp, 3);
1136}
1137
1138/* summary-LSA related functions. */
1139void
1140ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1141 u_int32_t metric)
1142{
1143 struct in_addr mask;
1144
1145 masklen2ip (p->prefixlen, &mask);
1146
1147 /* Put Network Mask. */
1148 stream_put_ipv4 (s, mask.s_addr);
1149
1150 /* Set # TOS. */
1151 stream_putc (s, (u_char) 0);
1152
1153 /* Set metric. */
1154 stream_put_ospf_metric (s, metric);
1155}
1156
1157struct ospf_lsa *
1158ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1159 u_int32_t metric, struct in_addr id)
1160{
1161 struct stream *s;
1162 struct ospf_lsa *new;
1163 struct lsa_header *lsah;
1164 int length;
1165
1166 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001167 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001168
1169 /* Create new stream for LSA. */
1170 s = stream_new (OSPF_MAX_LSA_SIZE);
1171 lsah = (struct lsa_header *) STREAM_DATA (s);
1172
paul68980082003-03-25 05:07:42 +00001173 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1174 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001175
1176 /* Set summary-LSA body fields. */
1177 ospf_summary_lsa_body_set (s, p, metric);
1178
1179 /* Set length. */
1180 length = stream_get_endp (s);
1181 lsah->length = htons (length);
1182
1183 /* Create OSPF LSA instance. */
1184 new = ospf_lsa_new ();
1185 new->area = area;
1186 SET_FLAG (new->flags, OSPF_LSA_SELF);
1187
1188 /* Copy LSA to store. */
1189 new->data = ospf_lsa_data_new (length);
1190 memcpy (new->data, lsah, length);
1191 stream_free (s);
1192
1193 return new;
1194}
1195
1196/* Originate Summary-LSA. */
1197struct ospf_lsa *
1198ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1199 struct ospf_area *area)
1200{
1201 struct ospf_lsa *new;
1202 struct in_addr id;
1203
paul68980082003-03-25 05:07:42 +00001204 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001205
1206 /* Create new summary-LSA instance. */
1207 new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id);
1208
1209 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001210 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001211
1212 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001213 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001214
1215 /* Flooding new LSA through area. */
1216 ospf_flood_through_area (area, NULL, new);
1217
1218 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1219 {
ajse588f212004-12-08 18:12:06 +00001220 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001221 new->data->type, inet_ntoa (new->data->id), new);
1222 ospf_lsa_header_dump (new->data);
1223 }
1224
1225 return new;
1226}
1227
1228struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001229ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001230{
1231 struct ospf_lsa *new;
1232 struct summary_lsa *sl;
1233 struct prefix p;
1234
1235 /* Sanity check. */
1236 assert (lsa->data);
1237
1238 sl = (struct summary_lsa *)lsa->data;
1239 p.prefixlen = ip_masklen (sl->mask);
1240 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1241 sl->header.id);
1242
1243 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1244
1245 /* Re-calculate checksum. */
1246 ospf_lsa_checksum (new->data);
1247
paul68980082003-03-25 05:07:42 +00001248 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001249
1250 /* Flood LSA through AS. */
1251 ospf_flood_through_area (new->area, NULL, new);
1252
1253 /* Debug logging. */
1254 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1255 {
ajse588f212004-12-08 18:12:06 +00001256 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001257 new->data->type, inet_ntoa (new->data->id));
1258 ospf_lsa_header_dump (new->data);
1259 }
1260
1261 return new;
1262}
1263
1264
1265/* summary-ASBR-LSA related functions. */
1266void
1267ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1268 u_int32_t metric)
1269{
1270 struct in_addr mask;
1271
1272 masklen2ip (p->prefixlen, &mask);
1273
1274 /* Put Network Mask. */
1275 stream_put_ipv4 (s, mask.s_addr);
1276
1277 /* Set # TOS. */
1278 stream_putc (s, (u_char) 0);
1279
1280 /* Set metric. */
1281 stream_put_ospf_metric (s, metric);
1282}
1283
1284struct ospf_lsa *
1285ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1286 u_int32_t metric, struct in_addr id)
1287{
1288 struct stream *s;
1289 struct ospf_lsa *new;
1290 struct lsa_header *lsah;
1291 int length;
1292
1293 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001294 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001295
1296 /* Create new stream for LSA. */
1297 s = stream_new (OSPF_MAX_LSA_SIZE);
1298 lsah = (struct lsa_header *) STREAM_DATA (s);
1299
paul68980082003-03-25 05:07:42 +00001300 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1301 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001302
1303 /* Set summary-LSA body fields. */
1304 ospf_summary_asbr_lsa_body_set (s, p, metric);
1305
1306 /* Set length. */
1307 length = stream_get_endp (s);
1308 lsah->length = htons (length);
1309
1310 /* Create OSPF LSA instance. */
1311 new = ospf_lsa_new ();
1312 new->area = area;
1313 SET_FLAG (new->flags, OSPF_LSA_SELF);
1314
1315 /* Copy LSA to store. */
1316 new->data = ospf_lsa_data_new (length);
1317 memcpy (new->data, lsah, length);
1318 stream_free (s);
1319
1320 return new;
1321}
1322
1323/* Originate summary-ASBR-LSA. */
1324struct ospf_lsa *
1325ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1326 struct ospf_area *area)
1327{
1328 struct ospf_lsa *new;
1329 struct in_addr id;
1330
paul68980082003-03-25 05:07:42 +00001331 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001332
1333 /* Create new summary-LSA instance. */
1334 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
1335
1336 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001337 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001338
1339 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001340 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001341
1342 /* Flooding new LSA through area. */
1343 ospf_flood_through_area (area, NULL, new);
1344
1345 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1346 {
ajse588f212004-12-08 18:12:06 +00001347 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001348 new->data->type, inet_ntoa (new->data->id), new);
1349 ospf_lsa_header_dump (new->data);
1350 }
1351
1352 return new;
1353}
1354
1355struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001356ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001357{
1358 struct ospf_lsa *new;
1359 struct summary_lsa *sl;
1360 struct prefix p;
1361
1362 /* Sanity check. */
1363 assert (lsa->data);
1364
1365 sl = (struct summary_lsa *)lsa->data;
1366 p.prefixlen = ip_masklen (sl->mask);
1367 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1368 sl->header.id);
1369
1370 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1371
1372 /* Re-calculate checksum. */
1373 ospf_lsa_checksum (new->data);
1374
paul68980082003-03-25 05:07:42 +00001375 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001376
1377 /* Flood LSA through area. */
1378 ospf_flood_through_area (new->area, NULL, new);
1379
1380 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1381 {
ajse588f212004-12-08 18:12:06 +00001382 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001383 new->data->type, inet_ntoa (new->data->id));
1384 ospf_lsa_header_dump (new->data);
1385 }
1386
1387 return new;
1388}
1389
1390/* AS-external-LSA related functions. */
1391
1392/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1393 is connected, else 0*/
1394struct in_addr
paul68980082003-03-25 05:07:42 +00001395ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001396{
1397 struct in_addr fwd;
1398 struct prefix nh;
hasso52dc7ee2004-09-23 19:18:23 +00001399 struct listnode *n1;
paul718e3742002-12-13 20:15:29 +00001400
1401 fwd.s_addr = 0;
1402
1403 if (!nexthop.s_addr)
1404 return fwd;
1405
1406 /* Check whether nexthop is covered by OSPF network. */
1407 nh.family = AF_INET;
1408 nh.u.prefix4 = nexthop;
1409 nh.prefixlen = IPV4_MAX_BITLEN;
1410
paul68980082003-03-25 05:07:42 +00001411 for (n1 = listhead (ospf->oiflist); n1; nextnode (n1))
paul718e3742002-12-13 20:15:29 +00001412 {
1413 struct ospf_interface *oi = getdata (n1);
1414
paul2e3b2e42002-12-13 21:03:13 +00001415 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001416 if (oi->address->family == AF_INET)
1417 if (prefix_match (oi->address, &nh))
1418 return nexthop;
1419 }
1420
1421 return fwd;
1422}
1423
paul718e3742002-12-13 20:15:29 +00001424/* NSSA-external-LSA related functions. */
1425
1426/* Get 1st IP connection for Forward Addr */
1427
1428struct in_addr
1429ospf_get_ip_from_ifp (struct ospf_interface *oi)
1430{
1431 struct in_addr fwd;
1432
1433 fwd.s_addr = 0;
1434
paul2e3b2e42002-12-13 21:03:13 +00001435 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001436 return oi->address->u.prefix4;
1437
1438 return fwd;
1439}
1440
1441/* Get 1st IP connection for Forward Addr */
1442struct in_addr
paulf2c80652002-12-13 21:44:27 +00001443ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001444{
1445 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001446 struct in_addr best_default;
hasso52dc7ee2004-09-23 19:18:23 +00001447 struct listnode *n1;
paul718e3742002-12-13 20:15:29 +00001448
1449 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001450 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001451
paul68980082003-03-25 05:07:42 +00001452 for (n1 = listhead (area->ospf->oiflist); n1; nextnode (n1))
paul718e3742002-12-13 20:15:29 +00001453 {
1454 struct ospf_interface *oi = getdata (n1);
1455
paul2e3b2e42002-12-13 21:03:13 +00001456 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001457 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001458 if (oi->address && oi->address->family == AF_INET)
1459 {
1460 if (best_default.s_addr == 0)
1461 best_default = oi->address->u.prefix4;
1462 if (oi->area == area)
1463 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001464 }
paul718e3742002-12-13 20:15:29 +00001465 }
paulf2c80652002-12-13 21:44:27 +00001466 if (best_default.s_addr != 0)
1467 return best_default;
paul718e3742002-12-13 20:15:29 +00001468
paul68980082003-03-25 05:07:42 +00001469 if (best_default.s_addr != 0)
1470 return best_default;
1471
paul718e3742002-12-13 20:15:29 +00001472 return fwd;
1473}
hassobeebba72004-06-20 21:00:27 +00001474
paul718e3742002-12-13 20:15:29 +00001475#define DEFAULT_DEFAULT_METRIC 20
1476#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1477#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1478
1479#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1480
1481int
paul68980082003-03-25 05:07:42 +00001482metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001483{
paul68980082003-03-25 05:07:42 +00001484 return (ospf->dmetric[src].type < 0 ?
1485 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001486}
1487
1488int
paul68980082003-03-25 05:07:42 +00001489metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001490{
paul68980082003-03-25 05:07:42 +00001491 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001492 {
1493 if (src == DEFAULT_ROUTE)
1494 {
paul68980082003-03-25 05:07:42 +00001495 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001496 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1497 else
1498 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1499 }
paul68980082003-03-25 05:07:42 +00001500 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001501 return DEFAULT_DEFAULT_METRIC;
1502 else
paul68980082003-03-25 05:07:42 +00001503 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001504 }
1505
paul68980082003-03-25 05:07:42 +00001506 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001507}
1508
1509/* Set AS-external-LSA body. */
1510void
paul68980082003-03-25 05:07:42 +00001511ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1512 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001513{
1514 struct prefix_ipv4 *p = &ei->p;
1515 struct in_addr mask, fwd_addr;
1516 u_int32_t mvalue;
1517 int mtype;
1518 int type;
1519
1520 /* Put Network Mask. */
1521 masklen2ip (p->prefixlen, &mask);
1522 stream_put_ipv4 (s, mask.s_addr);
1523
1524 /* If prefix is default, specify DEFAULT_ROUTE. */
1525 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1526
1527 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001528 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001529
1530 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001531 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001532
1533 /* Put type of external metric. */
1534 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1535
1536 /* Put 0 metric. TOS metric is not supported. */
1537 stream_put_ospf_metric (s, mvalue);
1538
1539 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001540 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001541
1542 /* Put forwarding address. */
1543 stream_put_ipv4 (s, fwd_addr.s_addr);
1544
1545 /* Put route tag -- This value should be introduced from configuration. */
1546 stream_putl (s, 0);
1547}
1548
1549/* Create new external-LSA. */
1550struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001551ospf_external_lsa_new (struct ospf *ospf,
1552 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001553{
1554 struct stream *s;
1555 struct lsa_header *lsah;
1556 struct ospf_lsa *new;
1557 struct in_addr id;
1558 int length;
1559
1560 if (ei == NULL)
1561 {
1562 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001563 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
paul718e3742002-12-13 20:15:29 +00001564 return NULL;
1565 }
1566
1567 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001568 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001569
1570 /* If old Link State ID is specified, refresh LSA with same ID. */
1571 if (old_id)
1572 id = *old_id;
1573 /* Get Link State with unique ID. */
1574 else
1575 {
paul68980082003-03-25 05:07:42 +00001576 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001577 if (id.s_addr == 0xffffffff)
1578 {
1579 /* Maybe Link State ID not available. */
1580 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001581 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001582 return NULL;
1583 }
1584 }
1585
1586 /* Create new stream for LSA. */
1587 s = stream_new (OSPF_MAX_LSA_SIZE);
1588 lsah = (struct lsa_header *) STREAM_DATA (s);
1589
1590 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001591 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1592 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001593
1594 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001595 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001596
1597 /* Set length. */
1598 length = stream_get_endp (s);
1599 lsah->length = htons (length);
1600
1601 /* Now, create OSPF LSA instance. */
1602 new = ospf_lsa_new ();
1603 new->area = NULL;
1604 SET_FLAG (new->flags, OSPF_LSA_SELF|OSPF_LSA_APPROVED);
1605
1606 /* Copy LSA data to store, discard stream. */
1607 new->data = ospf_lsa_data_new (length);
1608 memcpy (new->data, lsah, length);
1609 stream_free (s);
1610
1611 return new;
1612}
1613
paul718e3742002-12-13 20:15:29 +00001614/* As Type-7 */
1615void
paul68980082003-03-25 05:07:42 +00001616ospf_install_flood_nssa (struct ospf *ospf,
1617 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001618{
pauld4a53d52003-07-12 21:30:57 +00001619 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001620 struct as_external_lsa *extlsa;
hasso52dc7ee2004-09-23 19:18:23 +00001621 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00001622
pauld4a53d52003-07-12 21:30:57 +00001623 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1624 * which originated from an NSSA area. In which case it should not be
1625 * flooded back to NSSA areas.
1626 */
1627 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1628 return;
1629
paul718e3742002-12-13 20:15:29 +00001630 /* NSSA Originate or Refresh (If anyNSSA)
1631
1632 LSA is self-originated. And just installed as Type-5.
1633 Additionally, install as Type-7 LSDB for every attached NSSA.
1634
1635 P-Bit controls which ABR performs translation to outside world; If
1636 we are an ABR....do not set the P-bit, because we send the Type-5,
1637 not as the ABR Translator, but as the ASBR owner within the AS!
1638
1639 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1640 elected ABR Translator will see the P-bit, Translate, and re-flood.
1641
1642 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1643 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1644
paul68980082003-03-25 05:07:42 +00001645 for (node = listhead (ospf->areas); node; nextnode (node))
1646 {
1647 struct ospf_area *area = getdata (node);
hasso0c14ad82003-07-03 08:36:02 +00001648
1649 /* Don't install Type-7 LSA's into nonNSSA area */
1650 if (area->external_routing != OSPF_AREA_NSSA)
1651 continue;
paul718e3742002-12-13 20:15:29 +00001652
paul68980082003-03-25 05:07:42 +00001653 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001654 new = ospf_lsa_dup (lsa);
1655 new->area = area;
1656 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001657
paul68980082003-03-25 05:07:42 +00001658 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001659 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001660 {
pauld4a53d52003-07-12 21:30:57 +00001661 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001662
1663 /* set non-zero FWD ADDR
1664
1665 draft-ietf-ospf-nssa-update-09.txt
1666
1667 if the network between the NSSA AS boundary router and the
1668 adjacent AS is advertised into OSPF as an internal OSPF route,
1669 the forwarding address should be the next op address as is cu
1670 currently done with type-5 LSAs. If the intervening network is
1671 not adversited into OSPF as an internal OSPF route and the
1672 type-7 LSA's P-bit is set a forwarding address should be
1673 selected from one of the router's active OSPF inteface addresses
1674 which belong to the NSSA. If no such addresses exist, then
1675 no type-7 LSA's with the P-bit set should originate from this
1676 router. */
1677
pauld4a53d52003-07-12 21:30:57 +00001678 /* kevinm: not updating lsa anymore, just new */
1679 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001680
1681 if (extlsa->e[0].fwd_addr.s_addr == 0)
1682 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001683
pauld7480322003-05-16 17:31:51 +00001684 if (extlsa->e[0].fwd_addr.s_addr == 0)
1685 {
1686 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001687 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
pauld4a53d52003-07-12 21:30:57 +00001688 ospf_lsa_discard(new);
pauld7480322003-05-16 17:31:51 +00001689 return;
1690 }
paulf2c80652002-12-13 21:44:27 +00001691 }
paul68980082003-03-25 05:07:42 +00001692 /* Re-calculate checksum. */
pauld4a53d52003-07-12 21:30:57 +00001693 ospf_lsa_checksum (new->data);
paul718e3742002-12-13 20:15:29 +00001694
paul68980082003-03-25 05:07:42 +00001695 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001696 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001697
1698 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001699 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001700 }
paul718e3742002-12-13 20:15:29 +00001701}
pauld4a53d52003-07-12 21:30:57 +00001702
1703struct ospf_lsa *
1704ospf_lsa_translated_nssa_new (struct ospf *ospf,
1705 struct ospf_lsa *type7)
1706{
1707
1708 struct ospf_lsa *new;
1709 struct as_external_lsa *ext, *extnew;
1710 struct external_info ei;
1711
1712 ext = (struct as_external_lsa *)(type7->data);
1713
1714 /* need external_info struct, fill in bare minimum */
1715 ei.p.family = AF_INET;
1716 ei.p.prefix = type7->data->id;
1717 ei.p.prefixlen = ip_masklen (ext->mask);
1718 ei.type = ZEBRA_ROUTE_OSPF;
1719 ei.nexthop = ext->header.adv_router;
1720 ei.route_map_set.metric = -1;
1721 ei.route_map_set.metric_type = -1;
1722 ei.tag = 0;
1723
1724 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1725 {
1726 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001727 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001728 "Translated Type-5 for %s",
1729 inet_ntoa (ei.p.prefix));
1730 return NULL;
1731 }
1732
1733 extnew = (struct as_external_lsa *)(new->data);
1734
1735 /* copy over Type-7 data to new */
1736 extnew->e[0].tos = ext->e[0].tos;
1737 extnew->e[0].route_tag = ext->e[0].route_tag;
1738 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1739 new->data->ls_seqnum = type7->data->ls_seqnum;
1740
1741 /* add translated flag, checksum and lock new lsa */
1742 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
1743 ospf_lsa_checksum (new->data);
1744 new = ospf_lsa_lock (new);
1745
1746 return new;
1747}
1748
1749/* compare type-5 to type-7
1750 * -1: err, 0: same, 1: different
1751 */
1752int
1753ospf_lsa_translated_nssa_compare (struct ospf_lsa *t7, struct ospf_lsa *t5)
1754{
1755
1756 struct as_external_lsa *e5 = (struct as_external_lsa *)t5,
1757 *e7 = (struct as_external_lsa *)t7;
1758
1759
1760 /* sanity checks */
1761 if (! ((t5->data->type == OSPF_AS_EXTERNAL_LSA)
1762 && (t7->data->type == OSPF_AS_NSSA_LSA)))
1763 return -1;
1764
1765 if (t5->data->id.s_addr != t7->data->id.s_addr)
1766 return -1;
1767
1768 if (t5->data->ls_seqnum != t7->data->ls_seqnum)
1769 return LSA_REFRESH_FORCE;
1770
1771 if (e5->mask.s_addr != e7->mask.s_addr)
1772 return LSA_REFRESH_FORCE;
1773
1774 if (e5->e[0].fwd_addr.s_addr != e7->e[0].fwd_addr.s_addr)
1775 return LSA_REFRESH_FORCE;
1776
1777 if (e5->e[0].route_tag != e7->e[0].route_tag)
1778 return LSA_REFRESH_FORCE;
1779
1780 if (GET_METRIC (e5->e[0].metric) != GET_METRIC (e7->e[0].metric))
1781 return LSA_REFRESH_FORCE;
1782
1783 return LSA_REFRESH_IF_CHANGED;
1784}
1785
1786/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1787struct ospf_lsa *
1788ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1789{
1790 struct ospf_lsa *new;
1791 struct as_external_lsa *extnew;
1792
1793 /* we cant use ospf_external_lsa_originate() as we need to set
1794 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1795 */
1796
1797 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1798 {
1799 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001800 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001801 "Type-7, Id %s, to Type-5",
1802 inet_ntoa (type7->data->id));
1803 return NULL;
1804 }
1805
1806 extnew = (struct as_external_lsa *)new;
1807
1808 if (IS_DEBUG_OSPF_NSSA)
1809 {
ajse588f212004-12-08 18:12:06 +00001810 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001811 "translated Type 7, installed:");
1812 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001813 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1814 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001815 }
1816
1817 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1818 {
1819 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001820 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001821 "Could not install LSA "
1822 "id %s", inet_ntoa (type7->data->id));
1823 return NULL;
1824 }
1825
1826 ospf->lsa_originate_count++;
1827 ospf_flood_through_as (ospf, NULL, new);
1828
1829 return new;
1830}
1831
1832/* Refresh Translated from NSSA AS-external-LSA. */
1833struct ospf_lsa *
1834ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1835 struct ospf_lsa *type5)
1836{
1837 struct ospf_lsa *new = NULL;
1838
1839 /* Sanity checks. */
1840 assert (type7 || type5);
1841 if (type7)
1842 assert (type7->data);
1843 if (type5)
1844 assert (type5->data);
1845 assert (ospf->anyNSSA);
1846
1847 /* get required data according to what has been given */
1848 if (type7 && type5 == NULL)
1849 {
1850 /* find the translated Type-5 for this Type-7 */
1851 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1852 struct prefix_ipv4 p =
1853 {
1854 .prefix = type7->data->id,
1855 .prefixlen = ip_masklen (ext->mask),
1856 .family = AF_INET,
1857 };
1858
1859 type5 = ospf_external_info_find_lsa (ospf, &p);
1860 }
1861 else if (type5 && type7 == NULL)
1862 {
1863 /* find the type-7 from which supplied type-5 was translated,
1864 * ie find first type-7 with same LSA Id.
1865 */
hasso52dc7ee2004-09-23 19:18:23 +00001866 struct listnode *ln;
pauld4a53d52003-07-12 21:30:57 +00001867 struct route_node *rn;
1868 struct ospf_lsa *lsa;
1869 struct ospf_area *area;
1870
1871 LIST_LOOP (ospf->areas, area, ln)
1872 {
1873 if (area->external_routing != OSPF_AREA_NSSA
1874 && !type7)
1875 continue;
1876
1877 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
1878 {
1879 if (lsa->data->id.s_addr == type5->data->id.s_addr)
1880 {
1881 type7 = lsa;
1882 break;
1883 }
1884 }
1885 }
1886 }
1887
1888 /* do we have type7? */
1889 if (!type7)
1890 {
1891 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001892 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00001893 "Type-5 LSA Id %s",
1894 inet_ntoa (type7->data->id));
1895 return NULL;
1896 }
1897
1898 /* do we have valid translated type5? */
1899 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
1900 {
1901 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001902 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00001903 "found for Type-7 with Id %s",
1904 inet_ntoa (type7->data->id));
1905 return NULL;
1906 }
1907
1908 /* Delete LSA from neighbor retransmit-list. */
1909 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
1910
1911 /* create new translated LSA */
1912 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1913 {
1914 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001915 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001916 "Type-7 for %s to Type-5",
1917 inet_ntoa (type7->data->id));
1918 return NULL;
1919 }
1920
1921 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
1922 {
1923 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001924 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00001925 "translated LSA, Id %s",
1926 inet_ntoa (new->data->id));
1927 return NULL;
1928 }
1929
1930 /* Flood LSA through area. */
1931 ospf_flood_through_as (ospf, NULL, new);
1932
1933 return new;
1934}
paul718e3742002-12-13 20:15:29 +00001935
1936int
1937is_prefix_default (struct prefix_ipv4 *p)
1938{
1939 struct prefix_ipv4 q;
1940
1941 q.family = AF_INET;
1942 q.prefix.s_addr = 0;
1943 q.prefixlen = 0;
1944
1945 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
1946}
1947
1948/* Originate an AS-external-LSA, install and flood. */
1949struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001950ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001951{
1952 struct ospf_lsa *new;
1953
1954 /* Added for NSSA project....
1955
1956 External LSAs are originated in ASBRs as usual, but for NSSA systems.
1957 there is the global Type-5 LSDB and a Type-7 LSDB installed for
1958 every area. The Type-7's are flooded to every IR and every ABR; We
1959 install the Type-5 LSDB so that the normal "refresh" code operates
1960 as usual, and flag them as not used during ASE calculations. The
1961 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
1962 Address of non-zero.
1963
1964 If an ABR is the elected NSSA translator, following SPF and during
1965 the ABR task it will translate all the scanned Type-7's, with P-bit
1966 ON and not-self generated, and translate to Type-5's throughout the
1967 non-NSSA/STUB AS.
1968
1969 A difference in operation depends whether this ASBR is an ABR
1970 or not. If not an ABR, the P-bit is ON, to indicate that any
1971 elected NSSA-ABR can perform its translation.
1972
1973 If an ABR, the P-bit is OFF; No ABR will perform translation and
1974 this ASBR will flood the Type-5 LSA as usual.
1975
1976 For the case where this ASBR is not an ABR, the ASE calculations
1977 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
1978 demonstrate to the user that there are LSA's that belong to any
1979 attached NSSA.
1980
1981 Finally, it just so happens that when the ABR is translating every
1982 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
1983 approved Type-5 (translated from Type-7); at the end of translation
1984 if any Translated Type-5's remain unapproved, then they must be
1985 flushed from the AS.
1986
1987 */
1988
1989 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00001990 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00001991 return NULL;
1992
1993 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00001994 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00001995 {
1996 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00001997 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00001998 inet_ntoa (ei->p.prefix));
1999 return NULL;
2000 }
2001
2002 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002003 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002004
2005 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002006 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002007
2008 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002009 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002010
paul718e3742002-12-13 20:15:29 +00002011 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002012 if (ospf->anyNSSA &&
2013 /* stay away from translated LSAs! */
2014 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002015 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002016
2017 /* Debug logging. */
2018 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2019 {
ajse588f212004-12-08 18:12:06 +00002020 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002021 new->data->type, inet_ntoa (new->data->id), new);
2022 ospf_lsa_header_dump (new->data);
2023 }
2024
2025 return new;
2026}
2027
2028/* Originate AS-external-LSA from external info with initial flag. */
2029int
paul68980082003-03-25 05:07:42 +00002030ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002031{
paul68980082003-03-25 05:07:42 +00002032 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002033 struct route_node *rn;
2034 struct external_info *ei;
2035 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002036 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002037
paul68980082003-03-25 05:07:42 +00002038 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002039
2040 /* Originate As-external-LSA from all type of distribute source. */
2041 if ((rt = EXTERNAL_INFO (type)))
2042 for (rn = route_top (rt); rn; rn = route_next (rn))
2043 if ((ei = rn->info) != NULL)
2044 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002045 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002046 zlog_warn ("LSA: AS-external-LSA was not originated.");
2047
2048 return 0;
2049}
2050
2051struct external_info *
paul020709f2003-04-04 02:44:16 +00002052ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002053{
2054 int type;
2055 struct route_node *rn;
2056 struct prefix_ipv4 p;
2057
2058 p.family = AF_INET;
2059 p.prefix.s_addr = 0;
2060 p.prefixlen = 0;
2061
2062 /* First, lookup redistributed default route. */
2063 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2064 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2065 {
2066 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2067 if (rn != NULL)
2068 {
2069 route_unlock_node (rn);
2070 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002071 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002072 return rn->info;
2073 }
2074 }
2075
2076 return NULL;
2077}
2078
2079int
paul68980082003-03-25 05:07:42 +00002080ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002081{
2082 int *origin;
2083 struct prefix_ipv4 p;
2084 struct in_addr nexthop;
2085 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002086 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002087
paul020709f2003-04-04 02:44:16 +00002088 ospf = ospf_lookup ();
2089
paul718e3742002-12-13 20:15:29 +00002090 /* Get originate flags. */
paul68980082003-03-25 05:07:42 +00002091 origin = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002092
2093 p.family = AF_INET;
2094 p.prefix.s_addr = 0;
2095 p.prefixlen = 0;
2096
2097 if (*origin == DEFAULT_ORIGINATE_ALWAYS)
2098 {
2099 /* If there is no default route via redistribute,
2100 then originate AS-external-LSA with nexthop 0 (self). */
2101 nexthop.s_addr = 0;
2102 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2103 }
2104
paul020709f2003-04-04 02:44:16 +00002105 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002106 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002107
2108 return 0;
2109}
2110
paul645878f2003-04-13 21:42:11 +00002111/* Flush any NSSA LSAs for given prefix */
2112void
2113ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2114{
2115 struct listnode *node;
2116 struct ospf_lsa *lsa;
2117 struct ospf_area *area;
2118
pauld7480322003-05-16 17:31:51 +00002119 for (node = listhead (ospf->areas); node; nextnode (node))
paul645878f2003-04-13 21:42:11 +00002120 {
pauld7480322003-05-16 17:31:51 +00002121 if (((area = getdata (node)) != NULL)
2122 && (area->external_routing == OSPF_AREA_NSSA))
2123 {
2124 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2125 ospf->router_id)))
2126 {
2127 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002128 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002129 inet_ntoa (p->prefix), p->prefixlen);
2130 continue;
2131 }
2132 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2133 if (!IS_LSA_MAXAGE (lsa))
2134 {
2135 ospf_refresher_unregister_lsa (ospf, lsa);
2136 ospf_lsa_flush_area (lsa, area);
2137 }
2138 }
paul645878f2003-04-13 21:42:11 +00002139 }
2140}
paul645878f2003-04-13 21:42:11 +00002141
paul718e3742002-12-13 20:15:29 +00002142/* Flush an AS-external-LSA from LSDB and routing domain. */
2143void
paul68980082003-03-25 05:07:42 +00002144ospf_external_lsa_flush (struct ospf *ospf,
2145 u_char type, struct prefix_ipv4 *p,
paul718e3742002-12-13 20:15:29 +00002146 unsigned int ifindex, struct in_addr nexthop)
2147{
2148 struct ospf_lsa *lsa;
2149
2150 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002151 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002152 inet_ntoa (p->prefix), p->prefixlen);
2153
2154 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002155 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002156 {
2157 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002158 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002159 inet_ntoa (p->prefix), p->prefixlen);
2160 return;
2161 }
hassobeebba72004-06-20 21:00:27 +00002162
pauld4a53d52003-07-12 21:30:57 +00002163 /* If LSA is selforiginated, not a translated LSA, and there is
2164 * NSSA area, flush Type-7 LSA's at first.
2165 */
2166 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2167 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002168 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002169
2170 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002171 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002172
2173 /* There must be no self-originated LSA in rtrs_external. */
2174#if 0
2175 /* Remove External route from Zebra. */
2176 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2177#endif
2178
2179 if (!IS_LSA_MAXAGE (lsa))
2180 {
2181 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002182 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002183
2184 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002185 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002186 }
2187
2188 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002189 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002190}
2191
2192void
paul68980082003-03-25 05:07:42 +00002193ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002194{
2195 struct prefix_ipv4 p;
2196 struct external_info *ei;
2197 struct ospf_lsa *lsa;
2198
2199 p.family = AF_INET;
2200 p.prefixlen = 0;
2201 p.prefix.s_addr = 0;
2202
paul020709f2003-04-04 02:44:16 +00002203 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002204 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002205
2206 if (ei)
2207 {
2208 if (lsa)
2209 {
2210 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002211 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002212 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002213 }
2214 else
2215 {
2216 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002217 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002218 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002219 }
2220 }
2221 else
2222 {
2223 if (lsa)
2224 {
2225 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002226 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002227 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002228 }
2229 }
2230}
2231
2232void
paul68980082003-03-25 05:07:42 +00002233ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002234{
2235 struct route_node *rn;
2236 struct external_info *ei;
2237
2238 if (type != DEFAULT_ROUTE)
2239 if (EXTERNAL_INFO(type))
2240 /* Refresh each redistributed AS-external-LSAs. */
2241 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2242 if ((ei = rn->info))
2243 if (!is_prefix_default (&ei->p))
2244 {
2245 struct ospf_lsa *lsa;
2246
paul68980082003-03-25 05:07:42 +00002247 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2248 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002249 else
paul68980082003-03-25 05:07:42 +00002250 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002251 }
2252}
2253
2254/* Refresh AS-external-LSA. */
2255void
paul68980082003-03-25 05:07:42 +00002256ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002257 struct external_info *ei, int force)
2258{
2259 struct ospf_lsa *new;
2260 int changed;
2261
2262 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002263 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002264 {
pauld4a53d52003-07-12 21:30:57 +00002265 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002266 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002267 "redist check fail",
2268 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002269 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
2270 ei->ifindex, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00002271 return;
2272 }
2273
2274 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002275 {
2276 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002277 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002278 lsa->data->type, inet_ntoa (lsa->data->id));
2279 return;
2280 }
paul718e3742002-12-13 20:15:29 +00002281
2282 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002283 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002284
2285 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002286 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002287
paul68980082003-03-25 05:07:42 +00002288 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002289
2290 if (new == NULL)
2291 {
2292 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002293 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002294 inet_ntoa (lsa->data->id));
2295 return;
2296 }
2297
2298 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2299
2300 /* Record timestamp. */
2301 gettimeofday (&new->tv_orig, NULL);
2302
2303 /* Re-calculate checksum. */
2304 ospf_lsa_checksum (new->data);
2305
paul68980082003-03-25 05:07:42 +00002306 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002307
2308 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002309 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002310
paul718e3742002-12-13 20:15:29 +00002311 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002312 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002313 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002314
pauld4a53d52003-07-12 21:30:57 +00002315 /* Register self-originated LSA to refresh queue.
2316 * Translated LSAs should not be registered, but refreshed upon
2317 * refresh of the Type-7
2318 */
2319 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2320 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002321
2322 /* Debug logging. */
2323 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2324 {
ajse588f212004-12-08 18:12:06 +00002325 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002326 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002327 ospf_lsa_header_dump (new->data);
2328 }
2329
2330 return;
2331}
2332
2333
2334/* LSA installation functions. */
2335
2336/* Install router-LSA to an area. */
2337struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002338ospf_router_lsa_install (struct ospf *ospf,
2339 struct ospf_lsa *new, int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002340{
2341 struct ospf_area *area = new->area;
2342
2343 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2344 The entire routing table must be recalculated, starting with
2345 the shortest path calculations for each area (not just the
2346 area whose link-state database has changed).
2347 */
2348 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002349 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002350
2351 if (IS_LSA_SELF (new))
2352 {
2353 /* Set router-LSA refresh timer. */
2354 OSPF_TIMER_OFF (area->t_router_lsa_self);
2355 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
pauld4a53d52003-07-12 21:30:57 +00002356 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
paul718e3742002-12-13 20:15:29 +00002357
2358 /* Set self-originated router-LSA. */
2359 ospf_lsa_unlock (area->router_lsa_self);
2360 area->router_lsa_self = ospf_lsa_lock (new);
2361
2362 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002363 zlog_debug("LSA[Type%d]: ID %s seq 0x%x is self-originated",
paul0c2be262004-05-31 14:16:54 +00002364 new->data->type, inet_ntoa (new->data->id),
2365 ntohl(new->data->ls_seqnum));
paul718e3742002-12-13 20:15:29 +00002366 }
2367
2368 return new;
2369}
2370
2371#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2372 if (!(T)) \
2373 (T) = thread_add_timer (master, (F), oi, (V))
2374
2375/* Install network-LSA to an area. */
2376struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002377ospf_network_lsa_install (struct ospf *ospf,
2378 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002379 struct ospf_lsa *new,
2380 int rt_recalc)
2381{
2382
2383 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2384 The entire routing table must be recalculated, starting with
2385 the shortest path calculations for each area (not just the
2386 area whose link-state database has changed).
2387 */
2388 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002389 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002390
2391 /* We supposed that when LSA is originated by us, we pass the int
2392 for which it was originated. If LSA was received by flooding,
2393 the RECEIVED flag is set, so we do not link the LSA to the int. */
2394 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2395 {
2396 /* Set LSRefresh timer. */
2397 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2398
2399 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2400 ospf_network_lsa_refresh_timer,
2401 OSPF_LS_REFRESH_TIME);
2402
2403 ospf_lsa_unlock (oi->network_lsa_self);
2404 oi->network_lsa_self = ospf_lsa_lock (new);
2405 }
2406
2407 return new;
2408}
2409
2410/* Install summary-LSA to an area. */
2411struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002412ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2413 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002414{
paul718e3742002-12-13 20:15:29 +00002415 if (rt_recalc && !IS_LSA_SELF (new))
2416 {
2417 /* RFC 2328 Section 13.2 Summary-LSAs
2418 The best route to the destination described by the summary-
2419 LSA must be recalculated (see Section 16.5). If this
2420 destination is an AS boundary router, it may also be
2421 necessary to re-examine all the AS-external-LSAs.
2422 */
2423
2424#if 0
2425 /* This doesn't exist yet... */
2426 ospf_summary_incremental_update(new); */
2427#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002428 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002429#endif /* #if 0 */
2430
2431 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002432 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002433 }
2434
2435 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002436 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002437
2438 return new;
2439}
2440
2441/* Install ASBR-summary-LSA to an area. */
2442struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002443ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2444 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002445{
2446 if (rt_recalc && !IS_LSA_SELF (new))
2447 {
2448 /* RFC 2328 Section 13.2 Summary-LSAs
2449 The best route to the destination described by the summary-
2450 LSA must be recalculated (see Section 16.5). If this
2451 destination is an AS boundary router, it may also be
2452 necessary to re-examine all the AS-external-LSAs.
2453 */
2454#if 0
2455 /* These don't exist yet... */
2456 ospf_summary_incremental_update(new);
2457 /* Isn't this done by the above call?
2458 - RFC 2328 Section 16.5 implies it should be */
2459 /* ospf_ase_calculate_schedule(); */
2460#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002461 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002462#endif /* #if 0 */
2463 }
2464
2465 /* register LSA to refresh-list. */
2466 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002467 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002468
2469 return new;
2470}
2471
2472/* Install AS-external-LSA. */
2473struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002474ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2475 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002476{
paul68980082003-03-25 05:07:42 +00002477 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002478 /* If LSA is not self-originated, calculate an external route. */
2479 if (rt_recalc)
2480 {
2481 /* RFC 2328 Section 13.2 AS-external-LSAs
2482 The best route to the destination described by the AS-
2483 external-LSA must be recalculated (see Section 16.6).
2484 */
2485
2486 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002487 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002488 }
2489
pauld4a53d52003-07-12 21:30:57 +00002490 if (new->data->type == OSPF_AS_NSSA_LSA)
2491 {
2492 /* There is no point to register selforiginate Type-7 LSA for
2493 * refreshing. We rely on refreshing Type-5 LSA's
2494 */
2495 if (IS_LSA_SELF (new))
2496 return new;
2497 else
2498 {
2499 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2500 * New translations will be taken care of by the abr_task.
2501 */
2502 ospf_translated_nssa_refresh (ospf, new, NULL);
2503 }
2504 }
pauld7480322003-05-16 17:31:51 +00002505
pauld4a53d52003-07-12 21:30:57 +00002506 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002507 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002508 */
hassobeebba72004-06-20 21:00:27 +00002509 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002510 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002511
2512 return new;
2513}
2514
2515void
paul68980082003-03-25 05:07:42 +00002516ospf_discard_from_db (struct ospf *ospf,
2517 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002518{
2519 struct ospf_lsa *old;
2520
2521 old = ospf_lsdb_lookup (lsdb, lsa);
2522
2523 if (!old)
2524 return;
2525
2526 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002527 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002528
2529 switch (old->data->type)
2530 {
2531 case OSPF_AS_EXTERNAL_LSA:
2532#ifdef HAVE_OPAQUE_LSA
2533 case OSPF_OPAQUE_AS_LSA:
2534#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002535 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2536 ospf_ase_unregister_external_lsa (old, ospf);
paul718e3742002-12-13 20:15:29 +00002537 break;
pauld7480322003-05-16 17:31:51 +00002538 case OSPF_AS_NSSA_LSA:
2539 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2540 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002541 break;
paul718e3742002-12-13 20:15:29 +00002542 default:
paul68980082003-03-25 05:07:42 +00002543 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002544 break;
2545 }
2546
paul68980082003-03-25 05:07:42 +00002547 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002548 ospf_lsa_discard (old);
2549}
2550
paul718e3742002-12-13 20:15:29 +00002551struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002552ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2553 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002554{
2555 struct ospf_lsa *new = NULL;
2556 struct ospf_lsa *old = NULL;
2557 struct ospf_lsdb *lsdb = NULL;
2558 int rt_recalc;
2559
2560 /* Set LSDB. */
2561 switch (lsa->data->type)
2562 {
paulf2c80652002-12-13 21:44:27 +00002563 /* kevinm */
2564 case OSPF_AS_NSSA_LSA:
2565 if (lsa->area)
2566 lsdb = lsa->area->lsdb;
2567 else
paul68980082003-03-25 05:07:42 +00002568 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002569 break;
paul718e3742002-12-13 20:15:29 +00002570 case OSPF_AS_EXTERNAL_LSA:
2571#ifdef HAVE_OPAQUE_LSA
2572 case OSPF_OPAQUE_AS_LSA:
2573#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002574 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002575 break;
2576 default:
2577 lsdb = lsa->area->lsdb;
2578 break;
2579 }
2580
paul718e3742002-12-13 20:15:29 +00002581 assert (lsdb);
2582
2583 /* RFC 2328 13.2. Installing LSAs in the database
2584
2585 Installing a new LSA in the database, either as the result of
2586 flooding or a newly self-originated LSA, may cause the OSPF
2587 routing table structure to be recalculated. The contents of the
2588 new LSA should be compared to the old instance, if present. If
2589 there is no difference, there is no need to recalculate the
2590 routing table. When comparing an LSA to its previous instance,
2591 the following are all considered to be differences in contents:
2592
2593 o The LSA's Options field has changed.
2594
2595 o One of the LSA instances has LS age set to MaxAge, and
2596 the other does not.
2597
2598 o The length field in the LSA header has changed.
2599
2600 o The body of the LSA (i.e., anything outside the 20-byte
2601 LSA header) has changed. Note that this excludes changes
2602 in LS Sequence Number and LS Checksum.
2603
2604 */
2605 /* Look up old LSA and determine if any SPF calculation or incremental
2606 update is needed */
2607 old = ospf_lsdb_lookup (lsdb, lsa);
2608
2609 /* Do comparision and record if recalc needed. */
2610 rt_recalc = 0;
2611 if ( old == NULL || ospf_lsa_different(old, lsa))
2612 rt_recalc = 1;
2613
paul7ddf1d62003-10-13 09:06:46 +00002614 /*
2615 Sequence number check (Section 14.1 of rfc 2328)
2616 "Premature aging is used when it is time for a self-originated
2617 LSA's sequence number field to wrap. At this point, the current
2618 LSA instance (having LS sequence number MaxSequenceNumber) must
2619 be prematurely aged and flushed from the routing domain before a
2620 new instance with sequence number equal to InitialSequenceNumber
2621 can be originated. "
2622 */
2623
paul553ff112004-06-06 09:41:00 +00002624 if (ntohl(lsa->data->ls_seqnum) - 1 == htonl(OSPF_MAX_SEQUENCE_NUMBER))
paul7ddf1d62003-10-13 09:06:46 +00002625 {
2626 if (ospf_lsa_is_self_originated(ospf, lsa))
2627 {
paul0c2be262004-05-31 14:16:54 +00002628 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2629
2630 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002631 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2632 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2633
2634 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2635 {
ajse588f212004-12-08 18:12:06 +00002636 zlog_debug ("ospf_lsa_install() Premature Aging "
paul7ddf1d62003-10-13 09:06:46 +00002637 "lsa 0x%lx", (u_long)lsa);
2638 ospf_lsa_header_dump (lsa->data);
2639 }
2640 }
2641 else
2642 {
2643 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2644 {
ajse588f212004-12-08 18:12:06 +00002645 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002646 "that was not self originated. Ignoring\n");
2647 ospf_lsa_header_dump (lsa->data);
2648 }
2649 return old;
2650 }
2651 }
2652
paul718e3742002-12-13 20:15:29 +00002653 /* discard old LSA from LSDB */
2654 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002655 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002656
2657 /* Insert LSA to LSDB. */
2658 ospf_lsdb_add (lsdb, lsa);
2659 lsa->lsdb = lsdb;
2660
2661 /* Calculate Checksum if self-originated?. */
2662 if (IS_LSA_SELF (lsa))
2663 ospf_lsa_checksum (lsa->data);
2664
2665 /* Do LSA specific installation process. */
2666 switch (lsa->data->type)
2667 {
2668 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002669 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002670 break;
2671 case OSPF_NETWORK_LSA:
2672 assert (oi);
paul68980082003-03-25 05:07:42 +00002673 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002674 break;
2675 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002676 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002677 break;
2678 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002679 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002680 break;
2681 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002682 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002683 break;
2684#ifdef HAVE_OPAQUE_LSA
2685 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002686 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002687 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002688 else
paul68980082003-03-25 05:07:42 +00002689 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002690 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002691 case OSPF_OPAQUE_AREA_LSA:
2692 case OSPF_OPAQUE_AS_LSA:
2693 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2694 break;
2695#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002696 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002697 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002698 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002699 break;
2700 }
2701
2702 if (new == NULL)
2703 return new; /* Installation failed, cannot proceed further -- endo. */
2704
2705 /* Debug logs. */
2706 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2707 {
2708 char area_str[INET_ADDRSTRLEN];
2709
2710 switch (lsa->data->type)
2711 {
2712 case OSPF_AS_EXTERNAL_LSA:
2713#ifdef HAVE_OPAQUE_LSA
2714 case OSPF_OPAQUE_AS_LSA:
2715#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002716 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002717 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002718 dump_lsa_key (new),
2719 LOOKUP (ospf_lsa_type_msg, new->data->type));
2720 break;
2721 default:
2722 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002723 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002724 dump_lsa_key (new),
2725 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2726 break;
2727 }
2728 }
2729
paul7ddf1d62003-10-13 09:06:46 +00002730 /*
2731 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2732 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2733 */
2734 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2735 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002736 {
paul7ddf1d62003-10-13 09:06:46 +00002737 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002738 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002739 new->data->type,
2740 inet_ntoa (new->data->id),
2741 lsa);
paul68980082003-03-25 05:07:42 +00002742 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002743 }
2744
2745 return new;
2746}
2747
2748
2749int
paul68980082003-03-25 05:07:42 +00002750ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002751{
hasso52dc7ee2004-09-23 19:18:23 +00002752 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002753
paul68980082003-03-25 05:07:42 +00002754 for (node = listhead (ospf->oiflist); node; node = nextnode (node))
paul718e3742002-12-13 20:15:29 +00002755 {
2756 struct ospf_interface *oi = getdata (node);
2757 struct route_node *rn;
2758 struct ospf_neighbor *nbr;
2759
2760 if (ospf_if_is_enable (oi))
2761 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2762 if ((nbr = rn->info) != NULL)
2763 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2764 {
2765 route_unlock_node (rn);
2766 return 0;
2767 }
2768 }
2769
2770 return 1;
2771}
2772
2773
2774#ifdef ORIGINAL_CODING
2775/* This function flood the maxaged LSA to DR. */
2776void
2777ospf_maxage_flood (struct ospf_lsa *lsa)
2778{
2779 switch (lsa->data->type)
2780 {
2781 case OSPF_ROUTER_LSA:
2782 case OSPF_NETWORK_LSA:
2783 case OSPF_SUMMARY_LSA:
2784 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00002785 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00002786#ifdef HAVE_OPAQUE_LSA
2787 case OSPF_OPAQUE_LINK_LSA:
2788 case OSPF_OPAQUE_AREA_LSA:
2789#endif /* HAVE_OPAQUE_LSA */
2790 ospf_flood_through_area (lsa->area, NULL, lsa);
2791 break;
2792 case OSPF_AS_EXTERNAL_LSA:
2793#ifdef HAVE_OPAQUE_LSA
2794 case OSPF_OPAQUE_AS_LSA:
2795#endif /* HAVE_OPAQUE_LSA */
2796 ospf_flood_through_as (NULL, lsa);
2797 break;
2798 default:
2799 break;
2800 }
2801}
2802#endif /* ORIGINAL_CODING */
2803
2804int
2805ospf_maxage_lsa_remover (struct thread *thread)
2806{
paul68980082003-03-25 05:07:42 +00002807 struct ospf *ospf = THREAD_ARG (thread);
hasso52dc7ee2004-09-23 19:18:23 +00002808 struct listnode *node;
2809 struct listnode *next;
paul718e3742002-12-13 20:15:29 +00002810 int reschedule = 0;
2811
paul68980082003-03-25 05:07:42 +00002812 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002813
2814 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002815 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002816
paul68980082003-03-25 05:07:42 +00002817 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002818
2819 if (!reschedule)
paul68980082003-03-25 05:07:42 +00002820 for (node = listhead (ospf->maxage_lsa); node; node = next)
paul718e3742002-12-13 20:15:29 +00002821 {
2822 struct ospf_lsa *lsa = getdata (node);
2823 next = node->next;
2824
2825 if (lsa->retransmit_counter > 0)
2826 {
2827 reschedule = 1;
2828 continue;
2829 }
2830
2831 /* Remove LSA from the LSDB */
2832 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2833 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002834 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
paul7ddf1d62003-10-13 09:06:46 +00002835 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002836
2837 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002838 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002839 lsa->data->type, inet_ntoa (lsa->data->id));
2840
2841 /* Flood max age LSA. */
2842#ifdef ORIGINAL_CODING
2843 ospf_maxage_flood (lsa);
2844#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00002845 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00002846#endif /* ORIGINAL_CODING */
2847
paul7ddf1d62003-10-13 09:06:46 +00002848 if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
2849 {
2850 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002851 zlog_debug ("originating new router lsa for lsa 0x%lx \n",
paul7ddf1d62003-10-13 09:06:46 +00002852 (u_long)lsa);
2853 ospf_router_lsa_originate(lsa->area);
2854 }
2855
paul718e3742002-12-13 20:15:29 +00002856 /* Remove from lsdb. */
paul68980082003-03-25 05:07:42 +00002857 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002858 ospf_lsdb_delete (lsa->lsdb, lsa);
2859 }
2860
2861 /* A MaxAge LSA must be removed immediately from the router's link
2862 state database as soon as both a) it is no longer contained on any
2863 neighbor Link state retransmission lists and b) none of the router's
2864 neighbors are in states Exchange or Loading. */
2865 if (reschedule)
paul68980082003-03-25 05:07:42 +00002866 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00002867
2868 return 0;
2869}
2870
2871int
paul68980082003-03-25 05:07:42 +00002872ospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new)
paul718e3742002-12-13 20:15:29 +00002873{
hasso52dc7ee2004-09-23 19:18:23 +00002874 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002875
paul68980082003-03-25 05:07:42 +00002876 for (node = listhead (ospf->maxage_lsa); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002877 if (((struct ospf_lsa *) node->data) == new)
2878 return 1;
2879
2880 return 0;
2881}
2882
2883void
paul68980082003-03-25 05:07:42 +00002884ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002885{
hasso52dc7ee2004-09-23 19:18:23 +00002886 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00002887
paul68980082003-03-25 05:07:42 +00002888 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00002889 {
paul68980082003-03-25 05:07:42 +00002890 list_delete_node (ospf->maxage_lsa, n);
paul718e3742002-12-13 20:15:29 +00002891 ospf_lsa_unlock (lsa);
2892 }
2893}
2894
2895void
paul68980082003-03-25 05:07:42 +00002896ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002897{
2898 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2899 and schedule the MaxAge LSA remover. */
paul68980082003-03-25 05:07:42 +00002900 if (ospf_lsa_maxage_exist (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002901 {
2902 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002903 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00002904 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2905 return;
2906 }
2907
paul68980082003-03-25 05:07:42 +00002908 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00002909
2910 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002911 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002912
paul68980082003-03-25 05:07:42 +00002913 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00002914}
2915
2916int
paul68980082003-03-25 05:07:42 +00002917ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002918{
paul718e3742002-12-13 20:15:29 +00002919 /* Stay away from any Local Translated Type-7 LSAs */
2920 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2921 return 0;
paul718e3742002-12-13 20:15:29 +00002922
2923 if (IS_LSA_MAXAGE (lsa))
2924 /* Self-originated LSAs should NOT time-out instead,
2925 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00002926 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002927 {
2928 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002929 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002930
2931 switch (lsa->data->type)
2932 {
paul718e3742002-12-13 20:15:29 +00002933#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00002934 case OSPF_OPAQUE_LINK_LSA:
2935 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00002936 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00002937 /*
2938 * As a general rule, whenever network topology has changed
2939 * (due to an LSA removal in this case), routing recalculation
2940 * should be triggered. However, this is not true for opaque
2941 * LSAs. Even if an opaque LSA instance is going to be removed
2942 * from the routing domain, it does not mean a change in network
2943 * topology, and thus, routing recalculation is not needed here.
2944 */
2945 break;
paul718e3742002-12-13 20:15:29 +00002946#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00002947 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00002948 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002949 ospf_ase_incremental_update (ospf, lsa);
2950 break;
paul718e3742002-12-13 20:15:29 +00002951 default:
paul68980082003-03-25 05:07:42 +00002952 ospf_spf_calculate_schedule (ospf);
2953 break;
paul718e3742002-12-13 20:15:29 +00002954 }
paul68980082003-03-25 05:07:42 +00002955 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002956 }
2957
2958 return 0;
2959}
2960
2961/* Periodical check of MaxAge LSA. */
2962int
paul68980082003-03-25 05:07:42 +00002963ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002964{
paul68980082003-03-25 05:07:42 +00002965 struct ospf *ospf = THREAD_ARG (thread);
2966 struct route_node *rn;
2967 struct ospf_lsa *lsa;
hasso52dc7ee2004-09-23 19:18:23 +00002968 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00002969
paul68980082003-03-25 05:07:42 +00002970 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00002971
paul68980082003-03-25 05:07:42 +00002972 for (node = listhead (ospf->areas); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00002973 {
2974 struct ospf_area *area = node->data;
2975
paul68980082003-03-25 05:07:42 +00002976 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
2977 ospf_lsa_maxage_walker_remover (ospf, lsa);
2978 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
2979 ospf_lsa_maxage_walker_remover (ospf, lsa);
2980 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
2981 ospf_lsa_maxage_walker_remover (ospf, lsa);
2982 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
2983 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002984#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002985 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
2986 ospf_lsa_maxage_walker_remover (ospf, lsa);
2987 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
2988 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002989#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00002990 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
2991 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002992 }
2993
paul4fb949e2003-05-10 20:06:51 +00002994 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00002995 if (ospf->lsdb)
2996 {
2997 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
2998 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002999#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003000 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3001 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003002#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003003 }
paul718e3742002-12-13 20:15:29 +00003004
paul68980082003-03-25 05:07:42 +00003005 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3006 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003007 return 0;
3008}
3009
paul68980082003-03-25 05:07:42 +00003010struct ospf_lsa *
3011ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3012 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003013{
paul68980082003-03-25 05:07:42 +00003014 struct ospf_lsa *lsa;
3015 struct in_addr mask, id;
3016 struct lsa_header_mask
3017 {
3018 struct lsa_header header;
3019 struct in_addr mask;
3020 } *hmask;
paul718e3742002-12-13 20:15:29 +00003021
paul68980082003-03-25 05:07:42 +00003022 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3023 if (lsa == NULL)
3024 return NULL;
paul718e3742002-12-13 20:15:29 +00003025
paul68980082003-03-25 05:07:42 +00003026 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003027
paul68980082003-03-25 05:07:42 +00003028 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003029
paul68980082003-03-25 05:07:42 +00003030 if (mask.s_addr != hmask->mask.s_addr)
3031 {
3032 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3033 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3034 if (!lsa)
3035 return NULL;
3036 }
paul718e3742002-12-13 20:15:29 +00003037
paul68980082003-03-25 05:07:42 +00003038 return lsa;
paul718e3742002-12-13 20:15:29 +00003039}
3040
3041struct ospf_lsa *
3042ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3043 struct in_addr id, struct in_addr adv_router)
3044{
paule05fba42003-04-13 20:20:53 +00003045 struct ospf *ospf = ospf_lookup();
3046 assert(ospf);
3047
paul718e3742002-12-13 20:15:29 +00003048 switch (type)
3049 {
3050 case OSPF_ROUTER_LSA:
3051 case OSPF_NETWORK_LSA:
3052 case OSPF_SUMMARY_LSA:
3053 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003054 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003055#ifdef HAVE_OPAQUE_LSA
3056 case OSPF_OPAQUE_LINK_LSA:
3057 case OSPF_OPAQUE_AREA_LSA:
3058#endif /* HAVE_OPAQUE_LSA */
3059 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
3060 break;
3061 case OSPF_AS_EXTERNAL_LSA:
3062#ifdef HAVE_OPAQUE_LSA
3063 case OSPF_OPAQUE_AS_LSA:
3064#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003065 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003066 break;
3067 default:
3068 break;
3069 }
3070
3071 return NULL;
3072}
3073
3074struct ospf_lsa *
3075ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3076 struct in_addr id)
3077{
3078 struct ospf_lsa *lsa;
3079 struct route_node *rn;
3080
3081 switch (type)
3082 {
3083 case OSPF_ROUTER_LSA:
3084 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
3085 break;
3086 case OSPF_NETWORK_LSA:
3087 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3088 if ((lsa = rn->info))
3089 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3090 {
3091 route_unlock_node (rn);
3092 return lsa;
3093 }
3094 break;
3095 case OSPF_SUMMARY_LSA:
3096 case OSPF_ASBR_SUMMARY_LSA:
3097 /* Currently not used. */
3098 assert (1);
3099 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
3100 break;
3101 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003102 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003103#ifdef HAVE_OPAQUE_LSA
3104 case OSPF_OPAQUE_LINK_LSA:
3105 case OSPF_OPAQUE_AREA_LSA:
3106 case OSPF_OPAQUE_AS_LSA:
3107 /* Currently not used. */
3108 break;
3109#endif /* HAVE_OPAQUE_LSA */
3110 default:
3111 break;
3112 }
3113
3114 return NULL;
3115}
3116
3117struct ospf_lsa *
3118ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3119{
3120 struct ospf_lsa *match;
3121
3122#ifdef HAVE_OPAQUE_LSA
3123 /*
3124 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3125 * is redefined to have two subfields; opaque-type and opaque-id.
3126 * However, it is harmless to treat the two sub fields together, as if
3127 * they two were forming a unique LSA-ID.
3128 */
3129#endif /* HAVE_OPAQUE_LSA */
3130
3131 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3132
3133 if (match == NULL)
3134 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003135 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003136 lsah->type, inet_ntoa (lsah->id));
3137
3138 return match;
3139}
3140
3141/* return +n, l1 is more recent.
3142 return -n, l2 is more recent.
3143 return 0, l1 and l2 is identical. */
3144int
3145ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3146{
3147 int r;
3148 int x, y;
3149
3150 if (l1 == NULL && l2 == NULL)
3151 return 0;
3152 if (l1 == NULL)
3153 return -1;
3154 if (l2 == NULL)
3155 return 1;
3156
3157 /* compare LS sequence number. */
3158 x = (int) ntohl (l1->data->ls_seqnum);
3159 y = (int) ntohl (l2->data->ls_seqnum);
3160 if (x > y)
3161 return 1;
3162 if (x < y)
3163 return -1;
3164
3165 /* compare LS checksum. */
3166 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3167 if (r)
3168 return r;
3169
3170 /* compare LS age. */
3171 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3172 return 1;
3173 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3174 return -1;
3175
3176 /* compare LS age with MaxAgeDiff. */
3177 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3178 return -1;
3179 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3180 return 1;
3181
3182 /* LSAs are identical. */
3183 return 0;
3184}
3185
3186/* If two LSAs are different, return 1, otherwise return 0. */
3187int
3188ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3189{
3190 char *p1, *p2;
3191 assert (l1);
3192 assert (l2);
3193 assert (l1->data);
3194 assert (l2->data);
3195
3196 if (l1->data->options != l2->data->options)
3197 return 1;
3198
3199 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3200 return 1;
3201
3202 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3203 return 1;
3204
3205 if (l1->data->length != l2->data->length)
3206 return 1;
3207
3208 if (l1->data->length == 0)
3209 return 1;
3210
pauld1825832003-04-03 01:27:01 +00003211 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003212
3213 p1 = (char *) l1->data;
3214 p2 = (char *) l2->data;
3215
3216 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3217 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3218 return 1;
3219
3220 return 0;
3221}
3222
3223#ifdef ORIGINAL_CODING
3224void
3225ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3226 struct ospf_lsa *self,
3227 struct ospf_lsa *new)
3228{
3229 u_int32_t seqnum;
3230
3231 /* Adjust LS Sequence Number. */
3232 seqnum = ntohl (new->data->ls_seqnum) + 1;
3233 self->data->ls_seqnum = htonl (seqnum);
3234
3235 /* Recalculate LSA checksum. */
3236 ospf_lsa_checksum (self->data);
3237
3238 /* Reflooding LSA. */
3239 /* RFC2328 Section 13.3
3240 On non-broadcast networks, separate Link State Update
3241 packets must be sent, as unicasts, to each adjacent neighbor
3242 (i.e., those in state Exchange or greater). The destination
3243 IP addresses for these packets are the neighbors' IP
3244 addresses. */
3245 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3246 {
3247 struct route_node *rn;
3248 struct ospf_neighbor *onbr;
3249
3250 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3251 if ((onbr = rn->info) != NULL)
3252 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3253 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3254 }
3255 else
3256 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3257
3258 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003259 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003260 self->data->type, inet_ntoa (self->data->id));
3261}
3262#else /* ORIGINAL_CODING */
3263static int
paul68980082003-03-25 05:07:42 +00003264ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003265{
3266 if (lsa == NULL || !IS_LSA_SELF (lsa))
3267 return 0;
3268
3269 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003270 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00003271
3272 /* Force given lsa's age to MaxAge. */
3273 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3274
3275 switch (lsa->data->type)
3276 {
3277#ifdef HAVE_OPAQUE_LSA
3278 case OSPF_OPAQUE_LINK_LSA:
3279 case OSPF_OPAQUE_AREA_LSA:
3280 case OSPF_OPAQUE_AS_LSA:
3281 ospf_opaque_lsa_refresh (lsa);
3282 break;
3283#endif /* HAVE_OPAQUE_LSA */
3284 default:
paul68980082003-03-25 05:07:42 +00003285 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003286 break;
3287 }
3288
3289 return 0;
3290}
3291
3292void
paul68980082003-03-25 05:07:42 +00003293ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003294{
hasso52dc7ee2004-09-23 19:18:23 +00003295 struct listnode *n1, *n2;
paul718e3742002-12-13 20:15:29 +00003296 struct ospf_area *area;
3297 struct ospf_interface *oi;
3298 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003299 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003300 int need_to_flush_ase = 0;
3301
paul68980082003-03-25 05:07:42 +00003302 for (n1 = listhead (ospf->areas); n1; nextnode (n1))
paul718e3742002-12-13 20:15:29 +00003303 {
3304 if ((area = getdata (n1)) == NULL)
3305 continue;
3306
3307 if ((lsa = area->router_lsa_self) != NULL)
3308 {
3309 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003310 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00003311
3312 ospf_lsa_flush_area (lsa, area);
3313 ospf_lsa_unlock (area->router_lsa_self);
3314 area->router_lsa_self = NULL;
3315 OSPF_TIMER_OFF (area->t_router_lsa_self);
3316 }
3317
3318 for (n2 = listhead (area->oiflist); n2; nextnode (n2))
3319 {
3320 if ((oi = getdata (n2)) == NULL)
3321 continue;
3322
3323 if ((lsa = oi->network_lsa_self) != NULL
3324 && oi->state == ISM_DR
3325 && oi->full_nbrs > 0)
3326 {
3327 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003328 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00003329
3330 ospf_lsa_flush_area (oi->network_lsa_self, area);
3331 ospf_lsa_unlock (oi->network_lsa_self);
3332 oi->network_lsa_self = NULL;
3333 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3334 }
3335
3336 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3337 && area->external_routing == OSPF_AREA_DEFAULT)
3338 need_to_flush_ase = 1;
3339 }
3340
paul68980082003-03-25 05:07:42 +00003341 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3342 ospf_lsa_flush_schedule (ospf, lsa);
3343 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3344 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003345#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003346 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3347 ospf_lsa_flush_schedule (ospf, lsa);
3348 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3349 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003350#endif /* HAVE_OPAQUE_LSA */
3351 }
3352
3353 if (need_to_flush_ase)
3354 {
paul68980082003-03-25 05:07:42 +00003355 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3356 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003357#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003358 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3359 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003360#endif /* HAVE_OPAQUE_LSA */
3361 }
3362
3363 /*
3364 * Make sure that the MaxAge LSA remover is executed immediately,
3365 * without conflicting to other threads.
3366 */
paul68980082003-03-25 05:07:42 +00003367 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003368 {
paul68980082003-03-25 05:07:42 +00003369 OSPF_TIMER_OFF (ospf->t_maxage);
3370 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003371 }
3372
3373 return;
3374}
3375#endif /* ORIGINAL_CODING */
3376
3377/* If there is self-originated LSA, then return 1, otherwise return 0. */
3378/* An interface-independent version of ospf_lsa_is_self_originated */
3379int
paul68980082003-03-25 05:07:42 +00003380ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003381{
hasso52dc7ee2004-09-23 19:18:23 +00003382 struct listnode *node;
paul718e3742002-12-13 20:15:29 +00003383
3384 /* This LSA is already checked. */
3385 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3386 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3387
3388 /* Make sure LSA is self-checked. */
3389 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3390
3391 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003392 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003393 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3394
3395 /* LSA is router-LSA. */
3396 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003397 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003398 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3399
3400 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3401 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul68980082003-03-25 05:07:42 +00003402 for (node = listhead (ospf->oiflist); node; nextnode (node))
paul718e3742002-12-13 20:15:29 +00003403 {
3404 struct ospf_interface *oi = getdata (node);
3405
3406 /* Ignore virtual link. */
3407 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3408 if (oi->address->family == AF_INET)
3409 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3410 {
3411 /* to make it easier later */
3412 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3413 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3414 }
3415 }
3416
3417 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3418}
3419
3420/* Get unique Link State ID. */
3421struct in_addr
paul68980082003-03-25 05:07:42 +00003422ospf_lsa_unique_id (struct ospf *ospf,
3423 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003424{
3425 struct ospf_lsa *lsa;
3426 struct in_addr mask, id;
3427
3428 id = p->prefix;
3429
3430 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003431 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003432 if (lsa)
3433 {
3434 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3435 if (ip_masklen (al->mask) == p->prefixlen)
3436 {
3437 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003438 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003439 "Can't get Link State ID for %s/%d",
3440 inet_ntoa (p->prefix), p->prefixlen);
3441 /* id.s_addr = 0; */
3442 id.s_addr = 0xffffffff;
3443 return id;
3444 }
3445 /* Masklen differs, then apply wildcard mask to Link State ID. */
3446 else
3447 {
3448 masklen2ip (p->prefixlen, &mask);
3449
3450 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003451 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3452 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003453 if (lsa)
3454 {
3455 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003456 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003457 "Can't get Link State ID for %s/%d",
3458 inet_ntoa (p->prefix), p->prefixlen);
3459 /* id.s_addr = 0; */
3460 id.s_addr = 0xffffffff;
3461 return id;
3462 }
3463 }
3464 }
3465
3466 return id;
3467}
3468
3469
3470#define LSA_ACTION_ORIGN_RTR 1
3471#define LSA_ACTION_ORIGN_NET 2
3472#define LSA_ACTION_FLOOD_AREA 3
3473#define LSA_ACTION_FLOOD_AS 4
3474#define LSA_ACTION_FLUSH_AREA 5
3475#define LSA_ACTION_FLUSH_AS 6
3476
3477struct lsa_action
3478{
3479 u_char action;
3480 struct ospf_area *area;
3481 struct ospf_interface *oi;
3482 struct ospf_lsa *lsa;
3483};
3484
3485int
3486ospf_lsa_action (struct thread *t)
3487{
3488 struct lsa_action *data;
paul020709f2003-04-04 02:44:16 +00003489 struct ospf *ospf;
3490
3491 ospf = ospf_lookup ();
paul718e3742002-12-13 20:15:29 +00003492
3493 data = THREAD_ARG (t);
3494
3495 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003496 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003497 data->action);
3498
3499 switch (data->action)
3500 {
3501 case LSA_ACTION_ORIGN_RTR:
3502 ospf_router_lsa_refresh (data->area->router_lsa_self);
3503 break;
3504 case LSA_ACTION_ORIGN_NET:
3505 ospf_network_lsa_originate (data->oi);
3506 break;
3507 case LSA_ACTION_FLOOD_AREA:
3508 ospf_flood_through_area (data->area, NULL, data->lsa);
3509 break;
3510 case LSA_ACTION_FLOOD_AS:
paul68980082003-03-25 05:07:42 +00003511 ospf_flood_through_as (ospf, NULL, data->lsa);
paul718e3742002-12-13 20:15:29 +00003512 break;
3513 case LSA_ACTION_FLUSH_AREA:
3514 ospf_lsa_flush_area (data->lsa, data->area);
3515 break;
3516 case LSA_ACTION_FLUSH_AS:
paul68980082003-03-25 05:07:42 +00003517 ospf_lsa_flush_as (ospf, data->lsa);
paul718e3742002-12-13 20:15:29 +00003518 break;
3519 }
3520
3521 ospf_lsa_unlock (data->lsa);
3522 XFREE (MTYPE_OSPF_MESSAGE, data);
3523 return 0;
3524}
3525
3526void
3527ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3528{
3529 struct lsa_action *data;
3530
3531 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3532 memset (data, 0, sizeof (struct lsa_action));
3533
3534 data->action = LSA_ACTION_FLOOD_AREA;
3535 data->area = area;
3536 data->lsa = ospf_lsa_lock (lsa);
3537
3538 thread_add_event (master, ospf_lsa_action, data, 0);
3539}
3540
3541void
3542ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3543{
3544 struct lsa_action *data;
3545
3546 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3547 memset (data, 0, sizeof (struct lsa_action));
3548
3549 data->action = LSA_ACTION_FLUSH_AREA;
3550 data->area = area;
3551 data->lsa = ospf_lsa_lock (lsa);
3552
3553 thread_add_event (master, ospf_lsa_action, data, 0);
3554}
3555
3556
3557/* LSA Refreshment functions. */
3558void
paul68980082003-03-25 05:07:42 +00003559ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003560{
3561 struct external_info *ei;
3562 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3563
3564 switch (lsa->data->type)
3565 {
3566 /* Router and Network LSAs are processed differently. */
3567 case OSPF_ROUTER_LSA:
3568 case OSPF_NETWORK_LSA:
3569 break;
3570 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003571 ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003572 break;
3573 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003574 ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003575 break;
3576 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003577 /* Translated from NSSA Type-5s are refreshed when
3578 * from refresh of Type-7 - do not refresh these directly.
3579 */
3580 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3581 break;
paul718e3742002-12-13 20:15:29 +00003582 ei = ospf_external_info_check (lsa);
3583 if (ei)
pauld4a53d52003-07-12 21:30:57 +00003584 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003585 else
pauld4a53d52003-07-12 21:30:57 +00003586 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003587 break;
3588#ifdef HAVE_OPAQUE_LSA
3589 case OSPF_OPAQUE_LINK_LSA:
3590 case OSPF_OPAQUE_AREA_LSA:
3591 case OSPF_OPAQUE_AS_LSA:
3592 ospf_opaque_lsa_refresh (lsa);
3593 break;
pauld7480322003-05-16 17:31:51 +00003594#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003595 default:
3596 break;
paul718e3742002-12-13 20:15:29 +00003597 }
3598}
3599
3600void
paul68980082003-03-25 05:07:42 +00003601ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003602{
3603 u_int16_t index, current_index;
3604
3605 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3606
3607 if (lsa->refresh_list < 0)
3608 {
3609 int delay;
3610
3611 if (LS_AGE (lsa) == 0 &&
3612 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3613 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3614 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3615 else
3616 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3617 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3618 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3619
3620 if (delay < 0)
3621 delay = 0;
3622
paul68980082003-03-25 05:07:42 +00003623 current_index = ospf->lsa_refresh_queue.index +
3624 (time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003625
3626 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3627 % (OSPF_LSA_REFRESHER_SLOTS);
3628
3629 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003630 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003631 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003632 if (!ospf->lsa_refresh_queue.qs[index])
3633 ospf->lsa_refresh_queue.qs[index] = list_new ();
3634 listnode_add (ospf->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00003635 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003636 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003637 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003638 "setting refresh_list on lsa %p (slod %d)",
3639 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003640 }
3641}
3642
3643void
paul68980082003-03-25 05:07:42 +00003644ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003645{
3646 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3647 if (lsa->refresh_list >= 0)
3648 {
hasso52dc7ee2004-09-23 19:18:23 +00003649 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003650 listnode_delete (refresh_list, lsa);
3651 if (!listcount (refresh_list))
3652 {
3653 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003654 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003655 }
3656 ospf_lsa_unlock (lsa);
3657 lsa->refresh_list = -1;
3658 }
3659}
3660
3661int
3662ospf_lsa_refresh_walker (struct thread *t)
3663{
hasso52dc7ee2004-09-23 19:18:23 +00003664 struct list *refresh_list;
3665 struct listnode *node;
paul68980082003-03-25 05:07:42 +00003666 struct ospf *ospf = THREAD_ARG (t);
paul718e3742002-12-13 20:15:29 +00003667 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003668 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003669
3670 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003671 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003672
3673
paul68980082003-03-25 05:07:42 +00003674 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003675
paul68980082003-03-25 05:07:42 +00003676 ospf->lsa_refresh_queue.index =
3677 (ospf->lsa_refresh_queue.index +
3678 (time (NULL) - ospf->lsa_refresher_started) / OSPF_LSA_REFRESHER_GRANULARITY)
paul718e3742002-12-13 20:15:29 +00003679 % OSPF_LSA_REFRESHER_SLOTS;
3680
3681 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003682 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003683 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003684
paul68980082003-03-25 05:07:42 +00003685 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003686 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3687 {
3688 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003689 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003690 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003691
paul68980082003-03-25 05:07:42 +00003692 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003693
paul68980082003-03-25 05:07:42 +00003694 ospf->lsa_refresh_queue.qs [i] = NULL;
3695
paul718e3742002-12-13 20:15:29 +00003696 if (refresh_list)
3697 {
3698 for (node = listhead (refresh_list); node;)
3699 {
hasso52dc7ee2004-09-23 19:18:23 +00003700 struct listnode *next;
paul718e3742002-12-13 20:15:29 +00003701 struct ospf_lsa *lsa = getdata (node);
3702 next = node->next;
3703
3704 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003705 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003706 "refresh lsa %p (slot %d)",
3707 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003708
3709 list_delete_node (refresh_list, node);
3710 ospf_lsa_unlock (lsa);
3711 lsa->refresh_list = -1;
3712 listnode_add (lsa_to_refresh, lsa);
3713 node = next;
3714 }
3715 list_free (refresh_list);
3716 }
3717 }
3718
paul68980082003-03-25 05:07:42 +00003719 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3720 ospf, ospf->lsa_refresh_interval);
3721 ospf->lsa_refresher_started = time (NULL);
paul718e3742002-12-13 20:15:29 +00003722
3723 for (node = listhead (lsa_to_refresh); node; nextnode (node))
paul68980082003-03-25 05:07:42 +00003724 ospf_lsa_refresh (ospf, getdata (node));
paul718e3742002-12-13 20:15:29 +00003725
3726 list_delete (lsa_to_refresh);
3727
3728 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003729 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003730
3731 return 0;
3732}
3733