blob: 243928f4157db5afbf71dd07122a342f6d45e9b9 [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
Paul Jakma2518efd2006-08-27 06:49:29 +0000144 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +0000145 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;
paul718e3742002-12-13 20:15:29 +0000166
Paul Jakma2518efd2006-08-27 06:49:29 +0000167 age = ntohs (lsa->data->ls_age)
168 + tv_floor (tv_sub (recent_relative_time (), lsa->tv_recv));
paul718e3742002-12-13 20:15:29 +0000169
170 return age;
171}
172
173
174/* Fletcher Checksum -- Refer to RFC1008. */
175#define MODX 4102
176#define LSA_CHECKSUM_OFFSET 15
177
178u_int16_t
179ospf_lsa_checksum (struct lsa_header *lsa)
180{
181 u_char *sp, *ep, *p, *q;
182 int c0 = 0, c1 = 0;
183 int x, y;
184 u_int16_t length;
185
186 lsa->checksum = 0;
187 length = ntohs (lsa->length) - 2;
hassoc9e52be2004-09-26 16:09:34 +0000188 sp = (u_char *) &lsa->options;
paul718e3742002-12-13 20:15:29 +0000189
190 for (ep = sp + length; sp < ep; sp = q)
191 {
192 q = sp + MODX;
193 if (q > ep)
194 q = ep;
195 for (p = sp; p < q; p++)
196 {
197 c0 += *p;
198 c1 += c0;
199 }
200 c0 %= 255;
201 c1 %= 255;
202 }
203
Paul Jakma075c2012006-03-30 14:34:31 +0000204 x = (((int)length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255;
paul718e3742002-12-13 20:15:29 +0000205 if (x <= 0)
206 x += 255;
207 y = 510 - c0 - x;
208 if (y > 255)
209 y -= 255;
210
211 /* take care endian issue. */
212 lsa->checksum = htons ((x << 8) + y);
213
214 return (lsa->checksum);
215}
216
217
218
219/* Create OSPF LSA. */
220struct ospf_lsa *
221ospf_lsa_new ()
222{
223 struct ospf_lsa *new;
224
225 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
226 memset (new, 0, sizeof (struct ospf_lsa));
227
228 new->flags = 0;
229 new->lock = 1;
230 new->retransmit_counter = 0;
Paul Jakma2518efd2006-08-27 06:49:29 +0000231 new->tv_recv = recent_relative_time ();
paul718e3742002-12-13 20:15:29 +0000232 new->tv_orig = new->tv_recv;
233 new->refresh_list = -1;
234
235 return new;
236}
237
238/* Duplicate OSPF LSA. */
239struct ospf_lsa *
240ospf_lsa_dup (struct ospf_lsa *lsa)
241{
242 struct ospf_lsa *new;
243
244 if (lsa == NULL)
245 return NULL;
246
247 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
248
249 memcpy (new, lsa, sizeof (struct ospf_lsa));
250 UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
251 new->lock = 1;
252 new->retransmit_counter = 0;
253 new->data = ospf_lsa_data_dup (lsa->data);
254
paulf2c80652002-12-13 21:44:27 +0000255 /* kevinm: Clear the refresh_list, otherwise there are going
256 to be problems when we try to remove the LSA from the
257 queue (which it's not a member of.)
258 XXX: Should we add the LSA to the refresh_list queue? */
259 new->refresh_list = -1;
260
261 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000262 zlog_debug ("LSA: duplicated %p (new: %p)", lsa, new);
paulf2c80652002-12-13 21:44:27 +0000263
paul718e3742002-12-13 20:15:29 +0000264 return new;
265}
266
267/* Free OSPF LSA. */
268void
269ospf_lsa_free (struct ospf_lsa *lsa)
270{
271 assert (lsa->lock == 0);
272
273 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000274 zlog_debug ("LSA: freed %p", lsa);
paul718e3742002-12-13 20:15:29 +0000275
276 /* Delete LSA data. */
277 if (lsa->data != NULL)
278 ospf_lsa_data_free (lsa->data);
279
280 assert (lsa->refresh_list < 0);
281
282 memset (lsa, 0, sizeof (struct ospf_lsa));
283 XFREE (MTYPE_OSPF_LSA, lsa);
284}
285
286/* Lock LSA. */
287struct ospf_lsa *
288ospf_lsa_lock (struct ospf_lsa *lsa)
289{
290 lsa->lock++;
291 return lsa;
292}
293
294/* Unlock LSA. */
295void
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000296ospf_lsa_unlock (struct ospf_lsa **lsa)
paul718e3742002-12-13 20:15:29 +0000297{
298 /* This is sanity check. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000299 if (!lsa || !*lsa)
paul718e3742002-12-13 20:15:29 +0000300 return;
301
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000302 (*lsa)->lock--;
paul718e3742002-12-13 20:15:29 +0000303
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000304 assert ((*lsa)->lock >= 0);
paul718e3742002-12-13 20:15:29 +0000305
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000306 if ((*lsa)->lock == 0)
paul718e3742002-12-13 20:15:29 +0000307 {
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000308 assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
309 ospf_lsa_free (*lsa);
310 *lsa = NULL;
paul718e3742002-12-13 20:15:29 +0000311 }
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);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000321 ospf_lsa_unlock (&lsa);
paul718e3742002-12-13 20:15:29 +0000322 }
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
paul9985f832005-02-09 15:51:56 +0000410 stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000411}
412
paul68980082003-03-25 05:07:42 +0000413
paul718e3742002-12-13 20:15:29 +0000414/* router-LSA related functions. */
415/* Get router-LSA flags. */
paul4dadc292005-05-06 21:37:42 +0000416static u_char
paul718e3742002-12-13 20:15:29 +0000417router_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. */
Greg Troxelfc787e82007-08-06 15:50:20 +0000440 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
paul88d6cf32005-10-29 12:50:09 +0000486/* Determine cost of link, taking RFC3137 stub-router support into
487 * consideration
488 */
489static u_int16_t
490ospf_link_cost (struct ospf_interface *oi)
491{
492 /* RFC3137 stub router support */
493 if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
494 return oi->output_cost;
495 else
496 return OSPF_OUTPUT_COST_INFINITE;
497}
498
paul718e3742002-12-13 20:15:29 +0000499/* Set a link information. */
paul779adb02006-01-18 15:07:38 +0000500static char
paul718e3742002-12-13 20:15:29 +0000501link_info_set (struct stream *s, struct in_addr id,
502 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
503{
paul779adb02006-01-18 15:07:38 +0000504 /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
505 * vast majority of cases. Some rare routers with lots of links need more.
506 * we try accomodate those here.
507 */
508 if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
509 {
510 size_t ret = OSPF_MAX_LSA_SIZE;
511
512 /* Can we enlarge the stream still? */
513 if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
514 {
515 /* we futz the size here for simplicity, really we need to account
516 * for just:
517 * IP Header - (sizeof (struct ip))
518 * OSPF Header - OSPF_HEADER_SIZE
519 * LSA Header - OSPF_LSA_HEADER_SIZE
520 * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
521 *
522 * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
523 */
524 ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
525 }
526
527 if (ret == OSPF_MAX_LSA_SIZE)
528 {
529 zlog_warn ("%s: Out of space in LSA stream, left %ld, size %ld",
530 __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
531 return 0;
532 }
533 }
534
paul718e3742002-12-13 20:15:29 +0000535 /* TOS based routing is not supported. */
536 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
537 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
538 stream_putc (s, type); /* Link Type. */
539 stream_putc (s, tos); /* TOS = 0. */
540 stream_putw (s, cost); /* Link Cost. */
paul779adb02006-01-18 15:07:38 +0000541
542 return 1;
paul718e3742002-12-13 20:15:29 +0000543}
544
Andrew J. Schorre4529632006-12-12 19:18:21 +0000545/* Describe Point-to-Point link (Section 12.4.1.1). */
paul4dadc292005-05-06 21:37:42 +0000546static int
paul718e3742002-12-13 20:15:29 +0000547lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
548{
549 int links = 0;
550 struct ospf_neighbor *nbr;
551 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000552 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000553
554 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000555 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
paul718e3742002-12-13 20:15:29 +0000556
paul68980082003-03-25 05:07:42 +0000557 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000558 if (nbr->state == NSM_Full)
559 {
560 /* For unnumbered point-to-point networks, the Link Data field
561 should specify the interface's MIB-II ifIndex value. */
paul779adb02006-01-18 15:07:38 +0000562 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
563 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000564 }
565
Andrew J. Schorre4529632006-12-12 19:18:21 +0000566 /* Regardless of the state of the neighboring router, we must
567 add a Type 3 link (stub network).
568 N.B. Options 1 & 2 share basically the same logic. */
569 masklen2ip (oi->address->prefixlen, &mask);
570 id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
571 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
572 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000573 return links;
574}
575
576/* Describe Broadcast Link. */
paul4dadc292005-05-06 21:37:42 +0000577static int
paul718e3742002-12-13 20:15:29 +0000578lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
579{
580 struct ospf_neighbor *dr;
581 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000582 u_int16_t cost = ospf_link_cost (oi);
583
paul718e3742002-12-13 20:15:29 +0000584 /* Describe Type 3 Link. */
585 if (oi->state == ISM_Waiting)
586 {
587 masklen2ip (oi->address->prefixlen, &mask);
588 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000589 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
590 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000591 }
592
593 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
594 /* Describe Type 2 link. */
595 if (dr && (dr->state == NSM_Full ||
596 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000597 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000598 {
paul779adb02006-01-18 15:07:38 +0000599 return link_info_set (s, DR (oi), oi->address->u.prefix4,
600 LSA_LINK_TYPE_TRANSIT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000601 }
602 /* Describe type 3 link. */
603 else
604 {
605 masklen2ip (oi->address->prefixlen, &mask);
606 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000607 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
608 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000609 }
paul718e3742002-12-13 20:15:29 +0000610}
611
paul4dadc292005-05-06 21:37:42 +0000612static int
paul718e3742002-12-13 20:15:29 +0000613lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
614{
615 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000616
paul718e3742002-12-13 20:15:29 +0000617 /* Describe Type 3 Link. */
618 if (oi->state != ISM_Loopback)
619 return 0;
620
621 mask.s_addr = 0xffffffff;
622 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000623 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000624}
625
626/* Describe Virtual Link. */
paul4dadc292005-05-06 21:37:42 +0000627static int
paul718e3742002-12-13 20:15:29 +0000628lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
629{
630 struct ospf_neighbor *nbr;
paul88d6cf32005-10-29 12:50:09 +0000631 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000632
paul718e3742002-12-13 20:15:29 +0000633 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000634 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000635 if (nbr->state == NSM_Full)
636 {
paul779adb02006-01-18 15:07:38 +0000637 return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
638 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
paul718e3742002-12-13 20:15:29 +0000639 }
640
641 return 0;
642}
643
644#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
645
paul7afa08d2002-12-13 20:59:45 +0000646/* this function add for support point-to-multipoint ,see rfc2328
64712.4.1.4.*/
648/* from "edward rrr" <edward_rrr@hotmail.com>
649 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul4dadc292005-05-06 21:37:42 +0000650static int
paul68980082003-03-25 05:07:42 +0000651lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000652{
653 int links = 0;
654 struct route_node *rn;
655 struct ospf_neighbor *nbr = NULL;
656 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000657 u_int16_t cost = ospf_link_cost (oi);
paul7afa08d2002-12-13 20:59:45 +0000658
659 mask.s_addr = 0xffffffff;
660 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000661 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
paul7afa08d2002-12-13 20:59:45 +0000662
paul1cc8f762003-04-05 19:34:32 +0000663 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000664 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000665
666 /* Search neighbor, */
667 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
668 if ((nbr = rn->info) != NULL)
669 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000670 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000671 if (nbr->state == NSM_Full)
672
673 {
paul779adb02006-01-18 15:07:38 +0000674 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
675 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul1cc8f762003-04-05 19:34:32 +0000676 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000677 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000678 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000679 }
680
681 return links;
paul7afa08d2002-12-13 20:59:45 +0000682}
683
paul718e3742002-12-13 20:15:29 +0000684/* Set router-LSA link information. */
paul4dadc292005-05-06 21:37:42 +0000685static int
paul718e3742002-12-13 20:15:29 +0000686router_lsa_link_set (struct stream *s, struct ospf_area *area)
687{
hasso52dc7ee2004-09-23 19:18:23 +0000688 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000689 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000690 int links = 0;
691
paul1eb8ef22005-04-07 07:30:20 +0000692 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +0000693 {
paul718e3742002-12-13 20:15:29 +0000694 struct interface *ifp = oi->ifp;
695
696 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000697 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000698 {
699 if (oi->state != ISM_Down)
700 {
701 /* Describe each link. */
702 switch (oi->type)
703 {
704 case OSPF_IFTYPE_POINTOPOINT:
705 links += lsa_link_ptop_set (s, oi);
706 break;
707 case OSPF_IFTYPE_BROADCAST:
708 links += lsa_link_broadcast_set (s, oi);
709 break;
710 case OSPF_IFTYPE_NBMA:
711 links += lsa_link_nbma_set (s, oi);
712 break;
713 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000714 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000715 break;
716 case OSPF_IFTYPE_VIRTUALLINK:
717 links += lsa_link_virtuallink_set (s, oi);
718 break;
719 case OSPF_IFTYPE_LOOPBACK:
720 links += lsa_link_loopback_set (s, oi);
721 }
722 }
723 }
724 }
725
726 return links;
727}
728
729/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000730static void
paul718e3742002-12-13 20:15:29 +0000731ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
732{
733 unsigned long putp;
734 u_int16_t cnt;
735
736 /* Set flags. */
737 stream_putc (s, router_lsa_flags (area));
738
739 /* Set Zero fields. */
740 stream_putc (s, 0);
741
742 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000743 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000744
745 /* Forward word */
746 stream_putw(s, 0);
747
748 /* Set all link information. */
749 cnt = router_lsa_link_set (s, area);
750
751 /* Set # of links here. */
752 stream_putw_at (s, putp, cnt);
753}
paul88d6cf32005-10-29 12:50:09 +0000754
755static int
756ospf_stub_router_timer (struct thread *t)
757{
758 struct ospf_area *area = THREAD_ARG (t);
759
760 area->t_stub_router = NULL;
761
762 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
763
764 /* clear stub route state and generate router-lsa refresh, don't
765 * clobber an administratively set stub-router state though.
766 */
767 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
768 return 0;
769
770 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
771
772 ospf_router_lsa_timer_add (area);
773
774 return 0;
775}
paul718e3742002-12-13 20:15:29 +0000776
paul88d6cf32005-10-29 12:50:09 +0000777inline static void
778ospf_stub_router_check (struct ospf_area *area)
779{
780 /* area must either be administratively configured to be stub
781 * or startup-time stub-router must be configured and we must in a pre-stub
782 * state.
783 */
784 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
785 {
786 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
787 return;
788 }
789
790 /* not admin-stubbed, check whether startup stubbing is configured and
791 * whether it's not been done yet
792 */
793 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
794 return;
795
796 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
797 {
798 /* stub-router is hence done forever for this area, even if someone
799 * tries configure it (take effect next restart).
800 */
801 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
802 return;
803 }
804
805 /* startup stub-router configured and not yet done */
806 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
807
808 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
809 area->ospf->stub_router_startup_time);
810}
811
paul718e3742002-12-13 20:15:29 +0000812/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000813static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000814ospf_router_lsa_new (struct ospf_area *area)
815{
paul68980082003-03-25 05:07:42 +0000816 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000817 struct stream *s;
818 struct lsa_header *lsah;
819 struct ospf_lsa *new;
820 int length;
821
822 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000823 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000824
paul88d6cf32005-10-29 12:50:09 +0000825 /* check whether stub-router is desired, and if this is the first
826 * router LSA.
827 */
828 ospf_stub_router_check (area);
829
paul718e3742002-12-13 20:15:29 +0000830 /* Create a stream for LSA. */
831 s = stream_new (OSPF_MAX_LSA_SIZE);
paul718e3742002-12-13 20:15:29 +0000832 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000833 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000834 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000835
836 /* Set router-LSA body fields. */
837 ospf_router_lsa_body_set (s, area);
838
839 /* Set length. */
840 length = stream_get_endp (s);
paul779adb02006-01-18 15:07:38 +0000841 lsah = (struct lsa_header *) STREAM_DATA (s);
paul718e3742002-12-13 20:15:29 +0000842 lsah->length = htons (length);
843
844 /* Now, create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000845 if ( (new = ospf_lsa_new ()) == NULL)
846 {
847 zlog_err ("%s: Unable to create new lsa", __func__);
848 return NULL;
849 }
850
paul718e3742002-12-13 20:15:29 +0000851 new->area = area;
852 SET_FLAG (new->flags, OSPF_LSA_SELF);
853
854 /* Copy LSA data to store, discard stream. */
855 new->data = ospf_lsa_data_new (length);
856 memcpy (new->data, lsah, length);
857 stream_free (s);
858
859 return new;
860}
861
862/* Originate Router-LSA. */
paul88d6cf32005-10-29 12:50:09 +0000863static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000864ospf_router_lsa_originate (struct ospf_area *area)
865{
866 struct ospf_lsa *new;
paul88d6cf32005-10-29 12:50:09 +0000867
paul718e3742002-12-13 20:15:29 +0000868 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000869 if ( (new = ospf_router_lsa_new (area)) == NULL)
870 {
871 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
872 return NULL;
873 }
paul718e3742002-12-13 20:15:29 +0000874
875 /* Sanity check. */
876 if (new->data->adv_router.s_addr == 0)
877 {
878 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000879 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000880 ospf_lsa_discard (new);
881 return NULL;
882 }
883
884 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000885 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000886
887 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000888 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000889
890 /* Flooding new LSA through area. */
891 ospf_flood_through_area (area, NULL, new);
892
893 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
894 {
ajse588f212004-12-08 18:12:06 +0000895 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
paul718e3742002-12-13 20:15:29 +0000896 new->data->type, inet_ntoa (new->data->id), new);
897 ospf_lsa_header_dump (new->data);
898 }
899
900 return new;
901}
902
903/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000904static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000905ospf_router_lsa_refresh (struct ospf_lsa *lsa)
906{
907 struct ospf_area *area = lsa->area;
908 struct ospf_lsa *new;
909
910 /* Sanity check. */
911 assert (lsa->data);
912
913 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000914 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000915
916 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000917 if ( (new = ospf_router_lsa_new (area)) == NULL)
918 {
919 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
920 return NULL;
921 }
922
paul718e3742002-12-13 20:15:29 +0000923 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
924
paul68980082003-03-25 05:07:42 +0000925 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000926
927 /* Flood LSA through area. */
928 ospf_flood_through_area (area, NULL, new);
929
930 /* Debug logging. */
931 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
932 {
ajse588f212004-12-08 18:12:06 +0000933 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000934 new->data->type, inet_ntoa (new->data->id));
935 ospf_lsa_header_dump (new->data);
936 }
937
938 return NULL;
939}
940
paul4dadc292005-05-06 21:37:42 +0000941static int
paul718e3742002-12-13 20:15:29 +0000942ospf_router_lsa_timer (struct thread *t)
943{
944 struct ospf_area *area;
945
946 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000947 zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
paul718e3742002-12-13 20:15:29 +0000948
949 area = THREAD_ARG (t);
950 area->t_router_lsa_self = NULL;
951
952 /* Now refresh router-LSA. */
953 if (area->router_lsa_self)
954 ospf_router_lsa_refresh (area->router_lsa_self);
955 /* Newly originate router-LSA. */
956 else
957 ospf_router_lsa_originate (area);
958
959 return 0;
960}
961
962void
963ospf_router_lsa_timer_add (struct ospf_area *area)
964{
965 /* Keep area's self-originated router-LSA. */
966 struct ospf_lsa *lsa = area->router_lsa_self;
967
968 /* Cancel previously scheduled router-LSA timer. */
969 if (area->t_router_lsa_self)
970 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000971 zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
paul718e3742002-12-13 20:15:29 +0000972
973 OSPF_TIMER_OFF (area->t_router_lsa_self);
974
975 /* If router-LSA is originated previously, check the interval time. */
976 if (lsa)
977 {
978 int delay;
979 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
980 {
981 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
982 ospf_router_lsa_timer, delay);
983 return;
984 }
985 }
986
987 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000988 zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
paul718e3742002-12-13 20:15:29 +0000989
990 /* Immediately refresh router-LSA. */
991 OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
992}
993
994int
paul68980082003-03-25 05:07:42 +0000995ospf_router_lsa_update_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000996{
paul68980082003-03-25 05:07:42 +0000997 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +0000998 struct listnode *node, *nnode;
999 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00001000
1001 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001002 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +00001003
paul68980082003-03-25 05:07:42 +00001004 ospf->t_router_lsa_update = NULL;
paul718e3742002-12-13 20:15:29 +00001005
paul1eb8ef22005-04-07 07:30:20 +00001006 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00001007 {
paul718e3742002-12-13 20:15:29 +00001008 struct ospf_lsa *lsa = area->router_lsa_self;
1009 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +00001010 const char *area_str;
paul718e3742002-12-13 20:15:29 +00001011
1012 /* Keep Area ID string. */
1013 area_str = AREA_NAME (area);
1014
1015 /* If LSA not exist in this Area, originate new. */
1016 if (lsa == NULL)
1017 {
1018 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001019 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +00001020
1021 ospf_router_lsa_originate (area);
1022 }
1023 /* If router-ID is changed, Link ID must change.
1024 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +00001025 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001026 {
1027 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001028 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +00001029 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
1030 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001031 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00001032 area->router_lsa_self = NULL;
1033
1034 /* Refresh router-LSA, (not install) and flood through area. */
1035 ospf_router_lsa_timer_add (area);
1036 }
1037 else
1038 {
1039 rl = (struct router_lsa *) lsa->data;
1040 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +00001041 if (rl->flags != ospf->flags)
paul718e3742002-12-13 20:15:29 +00001042 ospf_router_lsa_timer_add (area);
1043 }
1044 }
1045
1046 return 0;
1047}
1048
1049
1050/* network-LSA related functions. */
1051/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001052static void
paul718e3742002-12-13 20:15:29 +00001053ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1054{
1055 struct in_addr mask;
1056 struct route_node *rn;
1057 struct ospf_neighbor *nbr;
1058
1059 masklen2ip (oi->address->prefixlen, &mask);
1060 stream_put_ipv4 (s, mask.s_addr);
1061
1062 /* The network-LSA lists those routers that are fully adjacent to
1063 the Designated Router; each fully adjacent router is identified by
1064 its OSPF Router ID. The Designated Router includes itself in this
1065 list. RFC2328, Section 12.4.2 */
1066
1067 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1068 if ((nbr = rn->info) != NULL)
1069 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1070 stream_put_ipv4 (s, nbr->router_id.s_addr);
1071}
1072
paul4dadc292005-05-06 21:37:42 +00001073static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001074ospf_network_lsa_new (struct ospf_interface *oi)
1075{
1076 struct stream *s;
1077 struct ospf_lsa *new;
1078 struct lsa_header *lsah;
1079 int length;
1080
1081 /* If there are no neighbours on this network (the net is stub),
1082 the router does not originate network-LSA (see RFC 12.4.2) */
1083 if (oi->full_nbrs == 0)
1084 return NULL;
1085
1086 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001087 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001088
1089 /* Create new stream for LSA. */
1090 s = stream_new (OSPF_MAX_LSA_SIZE);
1091 lsah = (struct lsa_header *) STREAM_DATA (s);
1092
1093 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001094 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001095
1096 /* Set network-LSA body fields. */
1097 ospf_network_lsa_body_set (s, oi);
1098
1099 /* Set length. */
1100 length = stream_get_endp (s);
1101 lsah->length = htons (length);
1102
1103 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001104 if ( (new = ospf_lsa_new ()) == NULL)
1105 {
1106 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1107 return NULL;
1108 }
1109
paul718e3742002-12-13 20:15:29 +00001110 new->area = oi->area;
1111 SET_FLAG (new->flags, OSPF_LSA_SELF);
1112
1113 /* Copy LSA to store. */
1114 new->data = ospf_lsa_data_new (length);
1115 memcpy (new->data, lsah, length);
1116 stream_free (s);
1117
1118 return new;
1119}
1120
1121/* Originate network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001122static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001123ospf_network_lsa_originate (struct ospf_interface *oi)
1124{
1125 struct ospf_lsa *new;
1126
1127 /* Create new network-LSA instance. */
1128 new = ospf_network_lsa_new (oi);
1129 if (new == NULL)
1130 return NULL;
1131
1132 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001133 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001134
1135 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001136 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001137
1138 /* Flooding new LSA through area. */
1139 ospf_flood_through_area (oi->area, NULL, new);
1140
1141 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1142 {
ajse588f212004-12-08 18:12:06 +00001143 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001144 new->data->type, inet_ntoa (new->data->id), new);
1145 ospf_lsa_header_dump (new->data);
1146 }
1147
1148 return new;
1149}
1150
1151int
1152ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1153{
1154 struct ospf_area *area = lsa->area;
1155 struct ospf_lsa *new;
1156
1157 assert (lsa->data);
1158
1159 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001160 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001161
1162 /* Create new network-LSA instance. */
1163 new = ospf_network_lsa_new (oi);
1164 if (new == NULL)
1165 return -1;
1166 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1167
paul68980082003-03-25 05:07:42 +00001168 ospf_lsa_install (area->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001169
1170 /* Flood LSA through aera. */
1171 ospf_flood_through_area (area, NULL, new);
1172
1173 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1174 {
ajse588f212004-12-08 18:12:06 +00001175 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001176 new->data->type, inet_ntoa (new->data->id));
1177 ospf_lsa_header_dump (new->data);
1178 }
1179
1180 return 0;
1181}
1182
paul4dadc292005-05-06 21:37:42 +00001183static int
paul718e3742002-12-13 20:15:29 +00001184ospf_network_lsa_refresh_timer (struct thread *t)
1185{
1186 struct ospf_interface *oi;
1187
1188 oi = THREAD_ARG (t);
1189 oi->t_network_lsa_self = NULL;
1190
1191 if (oi->network_lsa_self)
1192 /* Now refresh network-LSA. */
1193 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1194 else
1195 /* Newly create network-LSA. */
1196 ospf_network_lsa_originate (oi);
1197
1198 return 0;
1199}
1200
1201void
1202ospf_network_lsa_timer_add (struct ospf_interface *oi)
1203{
1204 /* Keep interface's self-originated network-LSA. */
1205 struct ospf_lsa *lsa = oi->network_lsa_self;
1206
1207 /* Cancel previously schedules network-LSA timer. */
1208 if (oi->t_network_lsa_self)
1209 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001210 zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
paul718e3742002-12-13 20:15:29 +00001211 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1212
1213 /* If network-LSA is originated previously, check the interval time. */
1214 if (lsa)
1215 {
1216 int delay;
1217 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1218 {
1219 oi->t_network_lsa_self =
1220 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1221 oi, delay);
1222 return;
1223 }
1224 }
1225
1226 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001227 zlog_debug ("Scheduling network-LSA origination right away");
paul718e3742002-12-13 20:15:29 +00001228
1229 /* Immediately refresh network-LSA. */
1230 oi->t_network_lsa_self =
1231 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1232}
1233
1234
paul4dadc292005-05-06 21:37:42 +00001235static void
paul718e3742002-12-13 20:15:29 +00001236stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1237{
1238 u_int32_t metric;
1239 char *mp;
1240
1241 /* Put 0 metric. TOS metric is not supported. */
1242 metric = htonl (metric_value);
1243 mp = (char *) &metric;
1244 mp++;
1245 stream_put (s, mp, 3);
1246}
1247
1248/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001249static void
paul718e3742002-12-13 20:15:29 +00001250ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1251 u_int32_t metric)
1252{
1253 struct in_addr mask;
1254
1255 masklen2ip (p->prefixlen, &mask);
1256
1257 /* Put Network Mask. */
1258 stream_put_ipv4 (s, mask.s_addr);
1259
1260 /* Set # TOS. */
1261 stream_putc (s, (u_char) 0);
1262
1263 /* Set metric. */
1264 stream_put_ospf_metric (s, metric);
1265}
1266
paul4dadc292005-05-06 21:37:42 +00001267static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001268ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1269 u_int32_t metric, struct in_addr id)
1270{
1271 struct stream *s;
1272 struct ospf_lsa *new;
1273 struct lsa_header *lsah;
1274 int length;
1275
paulc24d6022005-11-20 14:54:12 +00001276 if (id.s_addr == 0xffffffff)
1277 {
1278 /* Maybe Link State ID not available. */
1279 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1280 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1281 OSPF_SUMMARY_LSA);
1282 return NULL;
1283 }
1284
paul718e3742002-12-13 20:15:29 +00001285 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001286 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001287
1288 /* Create new stream for LSA. */
1289 s = stream_new (OSPF_MAX_LSA_SIZE);
1290 lsah = (struct lsa_header *) STREAM_DATA (s);
1291
paul68980082003-03-25 05:07:42 +00001292 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1293 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001294
1295 /* Set summary-LSA body fields. */
1296 ospf_summary_lsa_body_set (s, p, metric);
1297
1298 /* Set length. */
1299 length = stream_get_endp (s);
1300 lsah->length = htons (length);
1301
1302 /* Create OSPF LSA instance. */
1303 new = ospf_lsa_new ();
1304 new->area = area;
1305 SET_FLAG (new->flags, OSPF_LSA_SELF);
1306
1307 /* Copy LSA to store. */
1308 new->data = ospf_lsa_data_new (length);
1309 memcpy (new->data, lsah, length);
1310 stream_free (s);
1311
1312 return new;
1313}
1314
1315/* Originate Summary-LSA. */
1316struct ospf_lsa *
1317ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1318 struct ospf_area *area)
1319{
1320 struct ospf_lsa *new;
1321 struct in_addr id;
1322
paul68980082003-03-25 05:07:42 +00001323 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001324
paulc24d6022005-11-20 14:54:12 +00001325 if (id.s_addr == 0xffffffff)
1326 {
1327 /* Maybe Link State ID not available. */
1328 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1329 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1330 OSPF_SUMMARY_LSA);
1331 return NULL;
1332 }
1333
paul718e3742002-12-13 20:15:29 +00001334 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001335 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1336 return NULL;
paul718e3742002-12-13 20:15:29 +00001337
1338 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001339 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001340
1341 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001342 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001343
1344 /* Flooding new LSA through area. */
1345 ospf_flood_through_area (area, NULL, new);
1346
1347 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1348 {
ajse588f212004-12-08 18:12:06 +00001349 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001350 new->data->type, inet_ntoa (new->data->id), new);
1351 ospf_lsa_header_dump (new->data);
1352 }
1353
1354 return new;
1355}
1356
1357struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001358ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001359{
1360 struct ospf_lsa *new;
1361 struct summary_lsa *sl;
1362 struct prefix p;
1363
1364 /* Sanity check. */
1365 assert (lsa->data);
1366
1367 sl = (struct summary_lsa *)lsa->data;
1368 p.prefixlen = ip_masklen (sl->mask);
1369 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1370 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001371
1372 if (!new)
1373 return NULL;
1374
paul718e3742002-12-13 20:15:29 +00001375 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1376
1377 /* Re-calculate checksum. */
1378 ospf_lsa_checksum (new->data);
1379
paul68980082003-03-25 05:07:42 +00001380 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001381
1382 /* Flood LSA through AS. */
1383 ospf_flood_through_area (new->area, NULL, new);
1384
1385 /* Debug logging. */
1386 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1387 {
ajse588f212004-12-08 18:12:06 +00001388 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001389 new->data->type, inet_ntoa (new->data->id));
1390 ospf_lsa_header_dump (new->data);
1391 }
1392
1393 return new;
1394}
1395
1396
1397/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001398static void
paul718e3742002-12-13 20:15:29 +00001399ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1400 u_int32_t metric)
1401{
1402 struct in_addr mask;
1403
1404 masklen2ip (p->prefixlen, &mask);
1405
1406 /* Put Network Mask. */
1407 stream_put_ipv4 (s, mask.s_addr);
1408
1409 /* Set # TOS. */
1410 stream_putc (s, (u_char) 0);
1411
1412 /* Set metric. */
1413 stream_put_ospf_metric (s, metric);
1414}
1415
paul4dadc292005-05-06 21:37:42 +00001416static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001417ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1418 u_int32_t metric, struct in_addr id)
1419{
1420 struct stream *s;
1421 struct ospf_lsa *new;
1422 struct lsa_header *lsah;
1423 int length;
1424
paulc24d6022005-11-20 14:54:12 +00001425 if (id.s_addr == 0xffffffff)
1426 {
1427 /* Maybe Link State ID not available. */
1428 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1429 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1430 OSPF_ASBR_SUMMARY_LSA);
1431 return NULL;
1432 }
1433
paul718e3742002-12-13 20:15:29 +00001434 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001435 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001436
1437 /* Create new stream for LSA. */
1438 s = stream_new (OSPF_MAX_LSA_SIZE);
1439 lsah = (struct lsa_header *) STREAM_DATA (s);
1440
paul68980082003-03-25 05:07:42 +00001441 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1442 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001443
1444 /* Set summary-LSA body fields. */
1445 ospf_summary_asbr_lsa_body_set (s, p, metric);
1446
1447 /* Set length. */
1448 length = stream_get_endp (s);
1449 lsah->length = htons (length);
1450
1451 /* Create OSPF LSA instance. */
1452 new = ospf_lsa_new ();
1453 new->area = area;
1454 SET_FLAG (new->flags, OSPF_LSA_SELF);
1455
1456 /* Copy LSA to store. */
1457 new->data = ospf_lsa_data_new (length);
1458 memcpy (new->data, lsah, length);
1459 stream_free (s);
1460
1461 return new;
1462}
1463
1464/* Originate summary-ASBR-LSA. */
1465struct ospf_lsa *
1466ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1467 struct ospf_area *area)
1468{
1469 struct ospf_lsa *new;
1470 struct in_addr id;
1471
paul68980082003-03-25 05:07:42 +00001472 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001473
paulc24d6022005-11-20 14:54:12 +00001474 if (id.s_addr == 0xffffffff)
1475 {
1476 /* Maybe Link State ID not available. */
1477 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1478 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1479 OSPF_ASBR_SUMMARY_LSA);
1480 return NULL;
1481 }
1482
paul718e3742002-12-13 20:15:29 +00001483 /* Create new summary-LSA instance. */
1484 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001485 if (!new)
1486 return NULL;
paul718e3742002-12-13 20:15:29 +00001487
1488 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001489 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001490
1491 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001492 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001493
1494 /* Flooding new LSA through area. */
1495 ospf_flood_through_area (area, NULL, new);
1496
1497 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1498 {
ajse588f212004-12-08 18:12:06 +00001499 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001500 new->data->type, inet_ntoa (new->data->id), new);
1501 ospf_lsa_header_dump (new->data);
1502 }
1503
1504 return new;
1505}
1506
1507struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001508ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001509{
1510 struct ospf_lsa *new;
1511 struct summary_lsa *sl;
1512 struct prefix p;
1513
1514 /* Sanity check. */
1515 assert (lsa->data);
1516
1517 sl = (struct summary_lsa *)lsa->data;
1518 p.prefixlen = ip_masklen (sl->mask);
1519 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1520 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001521 if (!new)
1522 return NULL;
paul718e3742002-12-13 20:15:29 +00001523
1524 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1525
1526 /* Re-calculate checksum. */
1527 ospf_lsa_checksum (new->data);
1528
paul68980082003-03-25 05:07:42 +00001529 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001530
1531 /* Flood LSA through area. */
1532 ospf_flood_through_area (new->area, NULL, new);
1533
1534 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1535 {
ajse588f212004-12-08 18:12:06 +00001536 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001537 new->data->type, inet_ntoa (new->data->id));
1538 ospf_lsa_header_dump (new->data);
1539 }
1540
1541 return new;
1542}
1543
1544/* AS-external-LSA related functions. */
1545
1546/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1547 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001548static struct in_addr
paul68980082003-03-25 05:07:42 +00001549ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001550{
1551 struct in_addr fwd;
1552 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001553 struct listnode *node;
1554 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001555
1556 fwd.s_addr = 0;
1557
1558 if (!nexthop.s_addr)
1559 return fwd;
1560
1561 /* Check whether nexthop is covered by OSPF network. */
1562 nh.family = AF_INET;
1563 nh.u.prefix4 = nexthop;
1564 nh.prefixlen = IPV4_MAX_BITLEN;
1565
paul1eb8ef22005-04-07 07:30:20 +00001566 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1567 if (if_is_operative (oi->ifp))
1568 if (oi->address->family == AF_INET)
1569 if (prefix_match (oi->address, &nh))
1570 return nexthop;
paul718e3742002-12-13 20:15:29 +00001571
1572 return fwd;
1573}
1574
paul718e3742002-12-13 20:15:29 +00001575/* NSSA-external-LSA related functions. */
1576
1577/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001578
paul718e3742002-12-13 20:15:29 +00001579struct in_addr
1580ospf_get_ip_from_ifp (struct ospf_interface *oi)
1581{
1582 struct in_addr fwd;
1583
1584 fwd.s_addr = 0;
1585
paul2e3b2e42002-12-13 21:03:13 +00001586 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001587 return oi->address->u.prefix4;
1588
1589 return fwd;
1590}
1591
1592/* Get 1st IP connection for Forward Addr */
1593struct in_addr
paulf2c80652002-12-13 21:44:27 +00001594ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001595{
1596 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001597 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001598 struct listnode *node;
1599 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001600
1601 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001602 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001603
paul1eb8ef22005-04-07 07:30:20 +00001604 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001605 {
paul2e3b2e42002-12-13 21:03:13 +00001606 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001607 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001608 if (oi->address && oi->address->family == AF_INET)
1609 {
1610 if (best_default.s_addr == 0)
1611 best_default = oi->address->u.prefix4;
1612 if (oi->area == area)
1613 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001614 }
paul718e3742002-12-13 20:15:29 +00001615 }
paulf2c80652002-12-13 21:44:27 +00001616 if (best_default.s_addr != 0)
1617 return best_default;
paul718e3742002-12-13 20:15:29 +00001618
paul68980082003-03-25 05:07:42 +00001619 if (best_default.s_addr != 0)
1620 return best_default;
1621
paul718e3742002-12-13 20:15:29 +00001622 return fwd;
1623}
hassobeebba72004-06-20 21:00:27 +00001624
paul718e3742002-12-13 20:15:29 +00001625#define DEFAULT_DEFAULT_METRIC 20
1626#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1627#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1628
1629#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1630
1631int
paul68980082003-03-25 05:07:42 +00001632metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001633{
paul68980082003-03-25 05:07:42 +00001634 return (ospf->dmetric[src].type < 0 ?
1635 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001636}
1637
1638int
paul68980082003-03-25 05:07:42 +00001639metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001640{
paul68980082003-03-25 05:07:42 +00001641 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001642 {
1643 if (src == DEFAULT_ROUTE)
1644 {
paul68980082003-03-25 05:07:42 +00001645 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001646 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1647 else
1648 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1649 }
paul68980082003-03-25 05:07:42 +00001650 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001651 return DEFAULT_DEFAULT_METRIC;
1652 else
paul68980082003-03-25 05:07:42 +00001653 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001654 }
1655
paul68980082003-03-25 05:07:42 +00001656 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001657}
1658
1659/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001660static void
paul68980082003-03-25 05:07:42 +00001661ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1662 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001663{
1664 struct prefix_ipv4 *p = &ei->p;
1665 struct in_addr mask, fwd_addr;
1666 u_int32_t mvalue;
1667 int mtype;
1668 int type;
1669
1670 /* Put Network Mask. */
1671 masklen2ip (p->prefixlen, &mask);
1672 stream_put_ipv4 (s, mask.s_addr);
1673
1674 /* If prefix is default, specify DEFAULT_ROUTE. */
1675 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1676
1677 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001678 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001679
1680 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001681 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001682
1683 /* Put type of external metric. */
1684 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1685
1686 /* Put 0 metric. TOS metric is not supported. */
1687 stream_put_ospf_metric (s, mvalue);
1688
1689 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001690 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001691
1692 /* Put forwarding address. */
1693 stream_put_ipv4 (s, fwd_addr.s_addr);
1694
1695 /* Put route tag -- This value should be introduced from configuration. */
1696 stream_putl (s, 0);
1697}
1698
1699/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001700static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001701ospf_external_lsa_new (struct ospf *ospf,
1702 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001703{
1704 struct stream *s;
1705 struct lsa_header *lsah;
1706 struct ospf_lsa *new;
1707 struct in_addr id;
1708 int length;
1709
1710 if (ei == NULL)
1711 {
1712 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001713 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
paul718e3742002-12-13 20:15:29 +00001714 return NULL;
1715 }
1716
1717 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001718 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001719
1720 /* If old Link State ID is specified, refresh LSA with same ID. */
1721 if (old_id)
1722 id = *old_id;
1723 /* Get Link State with unique ID. */
1724 else
1725 {
paul68980082003-03-25 05:07:42 +00001726 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001727 if (id.s_addr == 0xffffffff)
1728 {
1729 /* Maybe Link State ID not available. */
1730 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001731 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001732 return NULL;
1733 }
1734 }
1735
1736 /* Create new stream for LSA. */
1737 s = stream_new (OSPF_MAX_LSA_SIZE);
1738 lsah = (struct lsa_header *) STREAM_DATA (s);
1739
1740 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001741 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1742 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001743
1744 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001745 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001746
1747 /* Set length. */
1748 length = stream_get_endp (s);
1749 lsah->length = htons (length);
1750
1751 /* Now, create OSPF LSA instance. */
1752 new = ospf_lsa_new ();
1753 new->area = NULL;
1754 SET_FLAG (new->flags, OSPF_LSA_SELF|OSPF_LSA_APPROVED);
1755
1756 /* Copy LSA data to store, discard stream. */
1757 new->data = ospf_lsa_data_new (length);
1758 memcpy (new->data, lsah, length);
1759 stream_free (s);
1760
1761 return new;
1762}
1763
paul718e3742002-12-13 20:15:29 +00001764/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001765static void
paul68980082003-03-25 05:07:42 +00001766ospf_install_flood_nssa (struct ospf *ospf,
1767 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001768{
pauld4a53d52003-07-12 21:30:57 +00001769 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001770 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001771 struct ospf_area *area;
1772 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001773
pauld4a53d52003-07-12 21:30:57 +00001774 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1775 * which originated from an NSSA area. In which case it should not be
1776 * flooded back to NSSA areas.
1777 */
1778 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1779 return;
1780
paul718e3742002-12-13 20:15:29 +00001781 /* NSSA Originate or Refresh (If anyNSSA)
1782
1783 LSA is self-originated. And just installed as Type-5.
1784 Additionally, install as Type-7 LSDB for every attached NSSA.
1785
1786 P-Bit controls which ABR performs translation to outside world; If
1787 we are an ABR....do not set the P-bit, because we send the Type-5,
1788 not as the ABR Translator, but as the ASBR owner within the AS!
1789
1790 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1791 elected ABR Translator will see the P-bit, Translate, and re-flood.
1792
1793 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1794 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1795
paul1eb8ef22005-04-07 07:30:20 +00001796 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001797 {
hasso0c14ad82003-07-03 08:36:02 +00001798 /* Don't install Type-7 LSA's into nonNSSA area */
1799 if (area->external_routing != OSPF_AREA_NSSA)
1800 continue;
paul718e3742002-12-13 20:15:29 +00001801
paul68980082003-03-25 05:07:42 +00001802 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001803 new = ospf_lsa_dup (lsa);
1804 new->area = area;
1805 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001806
paul68980082003-03-25 05:07:42 +00001807 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001808 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001809 {
pauld4a53d52003-07-12 21:30:57 +00001810 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001811
1812 /* set non-zero FWD ADDR
1813
1814 draft-ietf-ospf-nssa-update-09.txt
1815
1816 if the network between the NSSA AS boundary router and the
1817 adjacent AS is advertised into OSPF as an internal OSPF route,
1818 the forwarding address should be the next op address as is cu
1819 currently done with type-5 LSAs. If the intervening network is
1820 not adversited into OSPF as an internal OSPF route and the
1821 type-7 LSA's P-bit is set a forwarding address should be
1822 selected from one of the router's active OSPF inteface addresses
1823 which belong to the NSSA. If no such addresses exist, then
1824 no type-7 LSA's with the P-bit set should originate from this
1825 router. */
1826
pauld4a53d52003-07-12 21:30:57 +00001827 /* kevinm: not updating lsa anymore, just new */
1828 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001829
1830 if (extlsa->e[0].fwd_addr.s_addr == 0)
1831 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001832
pauld7480322003-05-16 17:31:51 +00001833 if (extlsa->e[0].fwd_addr.s_addr == 0)
1834 {
1835 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001836 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001837 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001838 return;
1839 }
paulf2c80652002-12-13 21:44:27 +00001840 }
paul68980082003-03-25 05:07:42 +00001841 /* Re-calculate checksum. */
pauld4a53d52003-07-12 21:30:57 +00001842 ospf_lsa_checksum (new->data);
paul718e3742002-12-13 20:15:29 +00001843
paul68980082003-03-25 05:07:42 +00001844 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001845 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001846
1847 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001848 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001849 }
paul718e3742002-12-13 20:15:29 +00001850}
pauld4a53d52003-07-12 21:30:57 +00001851
paul4dadc292005-05-06 21:37:42 +00001852static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001853ospf_lsa_translated_nssa_new (struct ospf *ospf,
1854 struct ospf_lsa *type7)
1855{
1856
1857 struct ospf_lsa *new;
1858 struct as_external_lsa *ext, *extnew;
1859 struct external_info ei;
1860
1861 ext = (struct as_external_lsa *)(type7->data);
1862
1863 /* need external_info struct, fill in bare minimum */
1864 ei.p.family = AF_INET;
1865 ei.p.prefix = type7->data->id;
1866 ei.p.prefixlen = ip_masklen (ext->mask);
1867 ei.type = ZEBRA_ROUTE_OSPF;
1868 ei.nexthop = ext->header.adv_router;
1869 ei.route_map_set.metric = -1;
1870 ei.route_map_set.metric_type = -1;
1871 ei.tag = 0;
1872
1873 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1874 {
1875 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001876 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001877 "Translated Type-5 for %s",
1878 inet_ntoa (ei.p.prefix));
1879 return NULL;
1880 }
1881
1882 extnew = (struct as_external_lsa *)(new->data);
1883
1884 /* copy over Type-7 data to new */
1885 extnew->e[0].tos = ext->e[0].tos;
1886 extnew->e[0].route_tag = ext->e[0].route_tag;
1887 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1888 new->data->ls_seqnum = type7->data->ls_seqnum;
1889
1890 /* add translated flag, checksum and lock new lsa */
1891 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
1892 ospf_lsa_checksum (new->data);
1893 new = ospf_lsa_lock (new);
1894
1895 return new;
1896}
1897
1898/* compare type-5 to type-7
1899 * -1: err, 0: same, 1: different
1900 */
paul4dadc292005-05-06 21:37:42 +00001901static int
pauld4a53d52003-07-12 21:30:57 +00001902ospf_lsa_translated_nssa_compare (struct ospf_lsa *t7, struct ospf_lsa *t5)
1903{
1904
1905 struct as_external_lsa *e5 = (struct as_external_lsa *)t5,
1906 *e7 = (struct as_external_lsa *)t7;
1907
1908
1909 /* sanity checks */
1910 if (! ((t5->data->type == OSPF_AS_EXTERNAL_LSA)
1911 && (t7->data->type == OSPF_AS_NSSA_LSA)))
1912 return -1;
1913
1914 if (t5->data->id.s_addr != t7->data->id.s_addr)
1915 return -1;
1916
1917 if (t5->data->ls_seqnum != t7->data->ls_seqnum)
1918 return LSA_REFRESH_FORCE;
1919
1920 if (e5->mask.s_addr != e7->mask.s_addr)
1921 return LSA_REFRESH_FORCE;
1922
1923 if (e5->e[0].fwd_addr.s_addr != e7->e[0].fwd_addr.s_addr)
1924 return LSA_REFRESH_FORCE;
1925
1926 if (e5->e[0].route_tag != e7->e[0].route_tag)
1927 return LSA_REFRESH_FORCE;
1928
1929 if (GET_METRIC (e5->e[0].metric) != GET_METRIC (e7->e[0].metric))
1930 return LSA_REFRESH_FORCE;
1931
1932 return LSA_REFRESH_IF_CHANGED;
1933}
1934
1935/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1936struct ospf_lsa *
1937ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1938{
1939 struct ospf_lsa *new;
1940 struct as_external_lsa *extnew;
1941
1942 /* we cant use ospf_external_lsa_originate() as we need to set
1943 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1944 */
1945
1946 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1947 {
1948 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001949 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001950 "Type-7, Id %s, to Type-5",
1951 inet_ntoa (type7->data->id));
1952 return NULL;
1953 }
1954
1955 extnew = (struct as_external_lsa *)new;
1956
1957 if (IS_DEBUG_OSPF_NSSA)
1958 {
ajse588f212004-12-08 18:12:06 +00001959 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001960 "translated Type 7, installed:");
1961 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001962 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1963 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001964 }
1965
1966 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1967 {
1968 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001969 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001970 "Could not install LSA "
1971 "id %s", inet_ntoa (type7->data->id));
1972 return NULL;
1973 }
1974
1975 ospf->lsa_originate_count++;
1976 ospf_flood_through_as (ospf, NULL, new);
1977
1978 return new;
1979}
1980
1981/* Refresh Translated from NSSA AS-external-LSA. */
1982struct ospf_lsa *
1983ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1984 struct ospf_lsa *type5)
1985{
1986 struct ospf_lsa *new = NULL;
1987
1988 /* Sanity checks. */
1989 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00001990 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00001991 return NULL;
pauld4a53d52003-07-12 21:30:57 +00001992 if (type7)
1993 assert (type7->data);
1994 if (type5)
1995 assert (type5->data);
1996 assert (ospf->anyNSSA);
1997
1998 /* get required data according to what has been given */
1999 if (type7 && type5 == NULL)
2000 {
2001 /* find the translated Type-5 for this Type-7 */
2002 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
2003 struct prefix_ipv4 p =
2004 {
2005 .prefix = type7->data->id,
2006 .prefixlen = ip_masklen (ext->mask),
2007 .family = AF_INET,
2008 };
2009
2010 type5 = ospf_external_info_find_lsa (ospf, &p);
2011 }
2012 else if (type5 && type7 == NULL)
2013 {
2014 /* find the type-7 from which supplied type-5 was translated,
2015 * ie find first type-7 with same LSA Id.
2016 */
paul1eb8ef22005-04-07 07:30:20 +00002017 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00002018 struct route_node *rn;
2019 struct ospf_lsa *lsa;
2020 struct ospf_area *area;
2021
paul1eb8ef22005-04-07 07:30:20 +00002022 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00002023 {
2024 if (area->external_routing != OSPF_AREA_NSSA
2025 && !type7)
2026 continue;
2027
2028 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
2029 {
2030 if (lsa->data->id.s_addr == type5->data->id.s_addr)
2031 {
2032 type7 = lsa;
2033 break;
2034 }
2035 }
2036 }
2037 }
2038
2039 /* do we have type7? */
2040 if (!type7)
2041 {
2042 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002043 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00002044 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00002045 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00002046 return NULL;
2047 }
2048
2049 /* do we have valid translated type5? */
2050 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
2051 {
2052 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002053 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00002054 "found for Type-7 with Id %s",
2055 inet_ntoa (type7->data->id));
2056 return NULL;
2057 }
2058
2059 /* Delete LSA from neighbor retransmit-list. */
2060 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
2061
2062 /* create new translated LSA */
2063 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
2064 {
2065 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002066 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00002067 "Type-7 for %s to Type-5",
2068 inet_ntoa (type7->data->id));
2069 return NULL;
2070 }
2071
2072 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
2073 {
2074 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002075 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00002076 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00002077 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00002078 return NULL;
2079 }
2080
2081 /* Flood LSA through area. */
2082 ospf_flood_through_as (ospf, NULL, new);
2083
2084 return new;
2085}
paul718e3742002-12-13 20:15:29 +00002086
2087int
2088is_prefix_default (struct prefix_ipv4 *p)
2089{
2090 struct prefix_ipv4 q;
2091
2092 q.family = AF_INET;
2093 q.prefix.s_addr = 0;
2094 q.prefixlen = 0;
2095
2096 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
2097}
2098
2099/* Originate an AS-external-LSA, install and flood. */
2100struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002101ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00002102{
2103 struct ospf_lsa *new;
2104
2105 /* Added for NSSA project....
2106
2107 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2108 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2109 every area. The Type-7's are flooded to every IR and every ABR; We
2110 install the Type-5 LSDB so that the normal "refresh" code operates
2111 as usual, and flag them as not used during ASE calculations. The
2112 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2113 Address of non-zero.
2114
2115 If an ABR is the elected NSSA translator, following SPF and during
2116 the ABR task it will translate all the scanned Type-7's, with P-bit
2117 ON and not-self generated, and translate to Type-5's throughout the
2118 non-NSSA/STUB AS.
2119
2120 A difference in operation depends whether this ASBR is an ABR
2121 or not. If not an ABR, the P-bit is ON, to indicate that any
2122 elected NSSA-ABR can perform its translation.
2123
2124 If an ABR, the P-bit is OFF; No ABR will perform translation and
2125 this ASBR will flood the Type-5 LSA as usual.
2126
2127 For the case where this ASBR is not an ABR, the ASE calculations
2128 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2129 demonstrate to the user that there are LSA's that belong to any
2130 attached NSSA.
2131
2132 Finally, it just so happens that when the ABR is translating every
2133 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2134 approved Type-5 (translated from Type-7); at the end of translation
2135 if any Translated Type-5's remain unapproved, then they must be
2136 flushed from the AS.
2137
2138 */
2139
2140 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002141 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002142 return NULL;
2143
2144 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002145 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002146 {
2147 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002148 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002149 inet_ntoa (ei->p.prefix));
2150 return NULL;
2151 }
2152
2153 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002154 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002155
2156 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002157 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002158
2159 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002160 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002161
paul718e3742002-12-13 20:15:29 +00002162 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002163 if (ospf->anyNSSA &&
2164 /* stay away from translated LSAs! */
2165 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002166 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002167
2168 /* Debug logging. */
2169 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2170 {
ajse588f212004-12-08 18:12:06 +00002171 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002172 new->data->type, inet_ntoa (new->data->id), new);
2173 ospf_lsa_header_dump (new->data);
2174 }
2175
2176 return new;
2177}
2178
2179/* Originate AS-external-LSA from external info with initial flag. */
2180int
paul68980082003-03-25 05:07:42 +00002181ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002182{
paul68980082003-03-25 05:07:42 +00002183 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002184 struct route_node *rn;
2185 struct external_info *ei;
2186 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002187 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002188
paul68980082003-03-25 05:07:42 +00002189 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002190
2191 /* Originate As-external-LSA from all type of distribute source. */
2192 if ((rt = EXTERNAL_INFO (type)))
2193 for (rn = route_top (rt); rn; rn = route_next (rn))
2194 if ((ei = rn->info) != NULL)
2195 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002196 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002197 zlog_warn ("LSA: AS-external-LSA was not originated.");
2198
2199 return 0;
2200}
2201
paul4dadc292005-05-06 21:37:42 +00002202static struct external_info *
paul020709f2003-04-04 02:44:16 +00002203ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002204{
2205 int type;
2206 struct route_node *rn;
2207 struct prefix_ipv4 p;
2208
2209 p.family = AF_INET;
2210 p.prefix.s_addr = 0;
2211 p.prefixlen = 0;
2212
2213 /* First, lookup redistributed default route. */
2214 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2215 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2216 {
2217 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2218 if (rn != NULL)
2219 {
2220 route_unlock_node (rn);
2221 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002222 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002223 return rn->info;
2224 }
2225 }
2226
2227 return NULL;
2228}
2229
2230int
paul68980082003-03-25 05:07:42 +00002231ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002232{
paul718e3742002-12-13 20:15:29 +00002233 struct prefix_ipv4 p;
2234 struct in_addr nexthop;
2235 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002236 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002237
Paul Jakma4021b602006-05-12 22:55:41 +00002238 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002239
2240 p.family = AF_INET;
2241 p.prefix.s_addr = 0;
2242 p.prefixlen = 0;
2243
Paul Jakma4021b602006-05-12 22:55:41 +00002244 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002245 {
2246 /* If there is no default route via redistribute,
2247 then originate AS-external-LSA with nexthop 0 (self). */
2248 nexthop.s_addr = 0;
2249 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2250 }
2251
paul020709f2003-04-04 02:44:16 +00002252 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002253 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002254
2255 return 0;
2256}
2257
paul645878f2003-04-13 21:42:11 +00002258/* Flush any NSSA LSAs for given prefix */
2259void
2260ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2261{
paul1eb8ef22005-04-07 07:30:20 +00002262 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002263 struct ospf_lsa *lsa;
2264 struct ospf_area *area;
2265
paul1eb8ef22005-04-07 07:30:20 +00002266 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002267 {
paul1eb8ef22005-04-07 07:30:20 +00002268 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002269 {
2270 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2271 ospf->router_id)))
2272 {
2273 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002274 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002275 inet_ntoa (p->prefix), p->prefixlen);
2276 continue;
2277 }
2278 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2279 if (!IS_LSA_MAXAGE (lsa))
2280 {
2281 ospf_refresher_unregister_lsa (ospf, lsa);
2282 ospf_lsa_flush_area (lsa, area);
2283 }
2284 }
paul645878f2003-04-13 21:42:11 +00002285 }
2286}
paul645878f2003-04-13 21:42:11 +00002287
paul718e3742002-12-13 20:15:29 +00002288/* Flush an AS-external-LSA from LSDB and routing domain. */
2289void
paul68980082003-03-25 05:07:42 +00002290ospf_external_lsa_flush (struct ospf *ospf,
2291 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002292 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002293{
2294 struct ospf_lsa *lsa;
2295
2296 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002297 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002298 inet_ntoa (p->prefix), p->prefixlen);
2299
2300 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002301 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002302 {
2303 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002304 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002305 inet_ntoa (p->prefix), p->prefixlen);
2306 return;
2307 }
hassobeebba72004-06-20 21:00:27 +00002308
pauld4a53d52003-07-12 21:30:57 +00002309 /* If LSA is selforiginated, not a translated LSA, and there is
2310 * NSSA area, flush Type-7 LSA's at first.
2311 */
2312 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2313 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002314 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002315
2316 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002317 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002318
2319 /* There must be no self-originated LSA in rtrs_external. */
2320#if 0
2321 /* Remove External route from Zebra. */
2322 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2323#endif
2324
2325 if (!IS_LSA_MAXAGE (lsa))
2326 {
2327 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002328 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002329
2330 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002331 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002332 }
2333
2334 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002335 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002336}
2337
2338void
paul68980082003-03-25 05:07:42 +00002339ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002340{
2341 struct prefix_ipv4 p;
2342 struct external_info *ei;
2343 struct ospf_lsa *lsa;
2344
2345 p.family = AF_INET;
2346 p.prefixlen = 0;
2347 p.prefix.s_addr = 0;
2348
paul020709f2003-04-04 02:44:16 +00002349 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002350 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002351
2352 if (ei)
2353 {
2354 if (lsa)
2355 {
2356 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002357 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002358 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002359 }
2360 else
2361 {
2362 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002363 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002364 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002365 }
2366 }
2367 else
2368 {
2369 if (lsa)
2370 {
2371 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002372 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002373 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002374 }
2375 }
2376}
2377
2378void
paul68980082003-03-25 05:07:42 +00002379ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002380{
2381 struct route_node *rn;
2382 struct external_info *ei;
2383
2384 if (type != DEFAULT_ROUTE)
2385 if (EXTERNAL_INFO(type))
2386 /* Refresh each redistributed AS-external-LSAs. */
2387 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2388 if ((ei = rn->info))
2389 if (!is_prefix_default (&ei->p))
2390 {
2391 struct ospf_lsa *lsa;
2392
paul68980082003-03-25 05:07:42 +00002393 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2394 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002395 else
paul68980082003-03-25 05:07:42 +00002396 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002397 }
2398}
2399
2400/* Refresh AS-external-LSA. */
2401void
paul68980082003-03-25 05:07:42 +00002402ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002403 struct external_info *ei, int force)
2404{
2405 struct ospf_lsa *new;
2406 int changed;
2407
2408 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002409 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002410 {
pauld4a53d52003-07-12 21:30:57 +00002411 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002412 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002413 "redist check fail",
2414 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002415 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002416 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +00002417 return;
2418 }
2419
2420 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002421 {
2422 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002423 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002424 lsa->data->type, inet_ntoa (lsa->data->id));
2425 return;
2426 }
paul718e3742002-12-13 20:15:29 +00002427
2428 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002429 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002430
2431 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002432 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002433
paul68980082003-03-25 05:07:42 +00002434 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002435
2436 if (new == NULL)
2437 {
2438 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002439 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002440 inet_ntoa (lsa->data->id));
2441 return;
2442 }
2443
2444 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2445
paul718e3742002-12-13 20:15:29 +00002446 /* Re-calculate checksum. */
2447 ospf_lsa_checksum (new->data);
2448
paul68980082003-03-25 05:07:42 +00002449 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002450
2451 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002452 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002453
paul718e3742002-12-13 20:15:29 +00002454 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002455 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002456 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002457
pauld4a53d52003-07-12 21:30:57 +00002458 /* Register self-originated LSA to refresh queue.
2459 * Translated LSAs should not be registered, but refreshed upon
2460 * refresh of the Type-7
2461 */
2462 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2463 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002464
2465 /* Debug logging. */
2466 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2467 {
ajse588f212004-12-08 18:12:06 +00002468 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002469 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002470 ospf_lsa_header_dump (new->data);
2471 }
2472
2473 return;
2474}
2475
2476
2477/* LSA installation functions. */
2478
2479/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002480static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002481ospf_router_lsa_install (struct ospf *ospf,
2482 struct ospf_lsa *new, int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002483{
2484 struct ospf_area *area = new->area;
2485
2486 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2487 The entire routing table must be recalculated, starting with
2488 the shortest path calculations for each area (not just the
2489 area whose link-state database has changed).
2490 */
2491 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002492 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002493
2494 if (IS_LSA_SELF (new))
2495 {
2496 /* Set router-LSA refresh timer. */
2497 OSPF_TIMER_OFF (area->t_router_lsa_self);
2498 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
pauld4a53d52003-07-12 21:30:57 +00002499 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
paul718e3742002-12-13 20:15:29 +00002500
2501 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002502 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002503 area->router_lsa_self = ospf_lsa_lock (new);
2504
2505 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002506 zlog_debug("LSA[Type%d]: ID %s seq 0x%x is self-originated",
paul0c2be262004-05-31 14:16:54 +00002507 new->data->type, inet_ntoa (new->data->id),
2508 ntohl(new->data->ls_seqnum));
paul718e3742002-12-13 20:15:29 +00002509 }
2510
2511 return new;
2512}
2513
2514#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2515 if (!(T)) \
2516 (T) = thread_add_timer (master, (F), oi, (V))
2517
2518/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002519static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002520ospf_network_lsa_install (struct ospf *ospf,
2521 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002522 struct ospf_lsa *new,
2523 int rt_recalc)
2524{
2525
2526 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2527 The entire routing table must be recalculated, starting with
2528 the shortest path calculations for each area (not just the
2529 area whose link-state database has changed).
2530 */
2531 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002532 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002533
2534 /* We supposed that when LSA is originated by us, we pass the int
2535 for which it was originated. If LSA was received by flooding,
2536 the RECEIVED flag is set, so we do not link the LSA to the int. */
2537 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2538 {
2539 /* Set LSRefresh timer. */
2540 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2541
2542 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2543 ospf_network_lsa_refresh_timer,
2544 OSPF_LS_REFRESH_TIME);
2545
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002546 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002547 oi->network_lsa_self = ospf_lsa_lock (new);
2548 }
2549
2550 return new;
2551}
2552
2553/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002554static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002555ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2556 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002557{
paul718e3742002-12-13 20:15:29 +00002558 if (rt_recalc && !IS_LSA_SELF (new))
2559 {
2560 /* RFC 2328 Section 13.2 Summary-LSAs
2561 The best route to the destination described by the summary-
2562 LSA must be recalculated (see Section 16.5). If this
2563 destination is an AS boundary router, it may also be
2564 necessary to re-examine all the AS-external-LSAs.
2565 */
2566
2567#if 0
2568 /* This doesn't exist yet... */
2569 ospf_summary_incremental_update(new); */
2570#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002571 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002572#endif /* #if 0 */
2573
2574 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002575 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002576 }
2577
2578 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002579 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002580
2581 return new;
2582}
2583
2584/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002585static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002586ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2587 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002588{
2589 if (rt_recalc && !IS_LSA_SELF (new))
2590 {
2591 /* RFC 2328 Section 13.2 Summary-LSAs
2592 The best route to the destination described by the summary-
2593 LSA must be recalculated (see Section 16.5). If this
2594 destination is an AS boundary router, it may also be
2595 necessary to re-examine all the AS-external-LSAs.
2596 */
2597#if 0
2598 /* These don't exist yet... */
2599 ospf_summary_incremental_update(new);
2600 /* Isn't this done by the above call?
2601 - RFC 2328 Section 16.5 implies it should be */
2602 /* ospf_ase_calculate_schedule(); */
2603#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002604 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002605#endif /* #if 0 */
2606 }
2607
2608 /* register LSA to refresh-list. */
2609 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002610 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002611
2612 return new;
2613}
2614
2615/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002616static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002617ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2618 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002619{
paul68980082003-03-25 05:07:42 +00002620 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002621 /* If LSA is not self-originated, calculate an external route. */
2622 if (rt_recalc)
2623 {
2624 /* RFC 2328 Section 13.2 AS-external-LSAs
2625 The best route to the destination described by the AS-
2626 external-LSA must be recalculated (see Section 16.6).
2627 */
2628
2629 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002630 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002631 }
2632
pauld4a53d52003-07-12 21:30:57 +00002633 if (new->data->type == OSPF_AS_NSSA_LSA)
2634 {
2635 /* There is no point to register selforiginate Type-7 LSA for
2636 * refreshing. We rely on refreshing Type-5 LSA's
2637 */
2638 if (IS_LSA_SELF (new))
2639 return new;
2640 else
2641 {
2642 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2643 * New translations will be taken care of by the abr_task.
2644 */
2645 ospf_translated_nssa_refresh (ospf, new, NULL);
2646 }
2647 }
pauld7480322003-05-16 17:31:51 +00002648
pauld4a53d52003-07-12 21:30:57 +00002649 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002650 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002651 */
hassobeebba72004-06-20 21:00:27 +00002652 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002653 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002654
2655 return new;
2656}
2657
2658void
paul68980082003-03-25 05:07:42 +00002659ospf_discard_from_db (struct ospf *ospf,
2660 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002661{
2662 struct ospf_lsa *old;
2663
Paul Jakmaac904de2006-06-15 12:04:57 +00002664 if (!lsdb)
2665 {
2666 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2667 if (!lsa)
2668 zlog_warn ("%s: and NULL LSA!", __func__);
2669 else
2670 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2671 lsa->data->type, inet_ntoa (lsa->data->id));
2672 return;
2673 }
2674
paul718e3742002-12-13 20:15:29 +00002675 old = ospf_lsdb_lookup (lsdb, lsa);
2676
2677 if (!old)
2678 return;
2679
2680 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002681 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002682
2683 switch (old->data->type)
2684 {
2685 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002686 ospf_ase_unregister_external_lsa (old, ospf);
2687 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2688 break;
paul718e3742002-12-13 20:15:29 +00002689#ifdef HAVE_OPAQUE_LSA
2690 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002691 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002692 break;
paul69310a62005-05-11 18:09:59 +00002693#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002694 case OSPF_AS_NSSA_LSA:
2695 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2696 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002697 break;
paul718e3742002-12-13 20:15:29 +00002698 default:
paul68980082003-03-25 05:07:42 +00002699 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002700 break;
2701 }
2702
paul68980082003-03-25 05:07:42 +00002703 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002704 ospf_lsa_discard (old);
2705}
2706
paul718e3742002-12-13 20:15:29 +00002707struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002708ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2709 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002710{
2711 struct ospf_lsa *new = NULL;
2712 struct ospf_lsa *old = NULL;
2713 struct ospf_lsdb *lsdb = NULL;
2714 int rt_recalc;
2715
2716 /* Set LSDB. */
2717 switch (lsa->data->type)
2718 {
paulf2c80652002-12-13 21:44:27 +00002719 /* kevinm */
2720 case OSPF_AS_NSSA_LSA:
2721 if (lsa->area)
2722 lsdb = lsa->area->lsdb;
2723 else
paul68980082003-03-25 05:07:42 +00002724 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002725 break;
paul718e3742002-12-13 20:15:29 +00002726 case OSPF_AS_EXTERNAL_LSA:
2727#ifdef HAVE_OPAQUE_LSA
2728 case OSPF_OPAQUE_AS_LSA:
2729#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002730 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002731 break;
2732 default:
2733 lsdb = lsa->area->lsdb;
2734 break;
2735 }
2736
paul718e3742002-12-13 20:15:29 +00002737 assert (lsdb);
2738
2739 /* RFC 2328 13.2. Installing LSAs in the database
2740
2741 Installing a new LSA in the database, either as the result of
2742 flooding or a newly self-originated LSA, may cause the OSPF
2743 routing table structure to be recalculated. The contents of the
2744 new LSA should be compared to the old instance, if present. If
2745 there is no difference, there is no need to recalculate the
2746 routing table. When comparing an LSA to its previous instance,
2747 the following are all considered to be differences in contents:
2748
2749 o The LSA's Options field has changed.
2750
2751 o One of the LSA instances has LS age set to MaxAge, and
2752 the other does not.
2753
2754 o The length field in the LSA header has changed.
2755
2756 o The body of the LSA (i.e., anything outside the 20-byte
2757 LSA header) has changed. Note that this excludes changes
2758 in LS Sequence Number and LS Checksum.
2759
2760 */
2761 /* Look up old LSA and determine if any SPF calculation or incremental
2762 update is needed */
2763 old = ospf_lsdb_lookup (lsdb, lsa);
2764
2765 /* Do comparision and record if recalc needed. */
2766 rt_recalc = 0;
2767 if ( old == NULL || ospf_lsa_different(old, lsa))
2768 rt_recalc = 1;
2769
paul7ddf1d62003-10-13 09:06:46 +00002770 /*
2771 Sequence number check (Section 14.1 of rfc 2328)
2772 "Premature aging is used when it is time for a self-originated
2773 LSA's sequence number field to wrap. At this point, the current
2774 LSA instance (having LS sequence number MaxSequenceNumber) must
2775 be prematurely aged and flushed from the routing domain before a
2776 new instance with sequence number equal to InitialSequenceNumber
2777 can be originated. "
2778 */
2779
Paul Jakmac2b478d2006-03-30 14:16:11 +00002780 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002781 {
2782 if (ospf_lsa_is_self_originated(ospf, lsa))
2783 {
paul0c2be262004-05-31 14:16:54 +00002784 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2785
2786 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002787 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2788 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2789
2790 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2791 {
ajse588f212004-12-08 18:12:06 +00002792 zlog_debug ("ospf_lsa_install() Premature Aging "
paul7ddf1d62003-10-13 09:06:46 +00002793 "lsa 0x%lx", (u_long)lsa);
2794 ospf_lsa_header_dump (lsa->data);
2795 }
2796 }
2797 else
2798 {
2799 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2800 {
ajse588f212004-12-08 18:12:06 +00002801 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002802 "that was not self originated. Ignoring\n");
2803 ospf_lsa_header_dump (lsa->data);
2804 }
2805 return old;
2806 }
2807 }
2808
paul718e3742002-12-13 20:15:29 +00002809 /* discard old LSA from LSDB */
2810 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002811 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002812
paul718e3742002-12-13 20:15:29 +00002813 /* Calculate Checksum if self-originated?. */
2814 if (IS_LSA_SELF (lsa))
2815 ospf_lsa_checksum (lsa->data);
2816
hassofe71a972004-12-22 16:16:02 +00002817 /* Insert LSA to LSDB. */
2818 ospf_lsdb_add (lsdb, lsa);
2819 lsa->lsdb = lsdb;
2820
paul718e3742002-12-13 20:15:29 +00002821 /* Do LSA specific installation process. */
2822 switch (lsa->data->type)
2823 {
2824 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002825 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002826 break;
2827 case OSPF_NETWORK_LSA:
2828 assert (oi);
paul68980082003-03-25 05:07:42 +00002829 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002830 break;
2831 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002832 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002833 break;
2834 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002835 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002836 break;
2837 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002838 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002839 break;
2840#ifdef HAVE_OPAQUE_LSA
2841 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002842 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002843 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002844 else
paul68980082003-03-25 05:07:42 +00002845 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002846 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002847 case OSPF_OPAQUE_AREA_LSA:
2848 case OSPF_OPAQUE_AS_LSA:
2849 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2850 break;
2851#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002852 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002853 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002854 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002855 break;
2856 }
2857
2858 if (new == NULL)
2859 return new; /* Installation failed, cannot proceed further -- endo. */
2860
2861 /* Debug logs. */
2862 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2863 {
2864 char area_str[INET_ADDRSTRLEN];
2865
2866 switch (lsa->data->type)
2867 {
2868 case OSPF_AS_EXTERNAL_LSA:
2869#ifdef HAVE_OPAQUE_LSA
2870 case OSPF_OPAQUE_AS_LSA:
2871#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002872 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002873 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002874 dump_lsa_key (new),
2875 LOOKUP (ospf_lsa_type_msg, new->data->type));
2876 break;
2877 default:
2878 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002879 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002880 dump_lsa_key (new),
2881 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2882 break;
2883 }
2884 }
2885
paul7ddf1d62003-10-13 09:06:46 +00002886 /*
2887 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2888 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2889 */
2890 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2891 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002892 {
paul7ddf1d62003-10-13 09:06:46 +00002893 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002894 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002895 new->data->type,
2896 inet_ntoa (new->data->id),
2897 lsa);
paul68980082003-03-25 05:07:42 +00002898 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002899 }
2900
2901 return new;
2902}
2903
2904
paul4dadc292005-05-06 21:37:42 +00002905static int
paul68980082003-03-25 05:07:42 +00002906ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002907{
paul1eb8ef22005-04-07 07:30:20 +00002908 struct listnode *node, *nnode;
2909 struct ospf_interface *oi;
2910
2911 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002912 {
paul718e3742002-12-13 20:15:29 +00002913 struct route_node *rn;
2914 struct ospf_neighbor *nbr;
2915
2916 if (ospf_if_is_enable (oi))
2917 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2918 if ((nbr = rn->info) != NULL)
2919 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2920 {
2921 route_unlock_node (rn);
2922 return 0;
2923 }
2924 }
2925
2926 return 1;
2927}
2928
2929
2930#ifdef ORIGINAL_CODING
2931/* This function flood the maxaged LSA to DR. */
2932void
2933ospf_maxage_flood (struct ospf_lsa *lsa)
2934{
2935 switch (lsa->data->type)
2936 {
2937 case OSPF_ROUTER_LSA:
2938 case OSPF_NETWORK_LSA:
2939 case OSPF_SUMMARY_LSA:
2940 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00002941 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00002942#ifdef HAVE_OPAQUE_LSA
2943 case OSPF_OPAQUE_LINK_LSA:
2944 case OSPF_OPAQUE_AREA_LSA:
2945#endif /* HAVE_OPAQUE_LSA */
2946 ospf_flood_through_area (lsa->area, NULL, lsa);
2947 break;
2948 case OSPF_AS_EXTERNAL_LSA:
2949#ifdef HAVE_OPAQUE_LSA
2950 case OSPF_OPAQUE_AS_LSA:
2951#endif /* HAVE_OPAQUE_LSA */
2952 ospf_flood_through_as (NULL, lsa);
2953 break;
2954 default:
2955 break;
2956 }
2957}
2958#endif /* ORIGINAL_CODING */
2959
paul4dadc292005-05-06 21:37:42 +00002960static int
paul718e3742002-12-13 20:15:29 +00002961ospf_maxage_lsa_remover (struct thread *thread)
2962{
paul68980082003-03-25 05:07:42 +00002963 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002964 struct ospf_lsa *lsa;
2965 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002966 int reschedule = 0;
2967
paul68980082003-03-25 05:07:42 +00002968 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002969
2970 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002971 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002972
paul68980082003-03-25 05:07:42 +00002973 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002974
2975 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002976 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002977 {
paul718e3742002-12-13 20:15:29 +00002978 if (lsa->retransmit_counter > 0)
2979 {
2980 reschedule = 1;
2981 continue;
2982 }
2983
2984 /* Remove LSA from the LSDB */
2985 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2986 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002987 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
paul7ddf1d62003-10-13 09:06:46 +00002988 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002989
2990 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002991 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002992 lsa->data->type, inet_ntoa (lsa->data->id));
2993
2994 /* Flood max age LSA. */
2995#ifdef ORIGINAL_CODING
2996 ospf_maxage_flood (lsa);
2997#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00002998 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00002999#endif /* ORIGINAL_CODING */
3000
paul7ddf1d62003-10-13 09:06:46 +00003001 if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
3002 {
3003 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003004 zlog_debug ("originating new router lsa for lsa 0x%lx \n",
paul7ddf1d62003-10-13 09:06:46 +00003005 (u_long)lsa);
3006 ospf_router_lsa_originate(lsa->area);
3007 }
3008
paul718e3742002-12-13 20:15:29 +00003009 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00003010 if (lsa->lsdb)
3011 {
3012 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
3013 ospf_lsdb_delete (lsa->lsdb, lsa);
3014 }
3015 else
3016 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
3017 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00003018 }
3019
3020 /* A MaxAge LSA must be removed immediately from the router's link
3021 state database as soon as both a) it is no longer contained on any
3022 neighbor Link state retransmission lists and b) none of the router's
3023 neighbors are in states Exchange or Loading. */
3024 if (reschedule)
paul68980082003-03-25 05:07:42 +00003025 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003026
3027 return 0;
3028}
3029
paul4dadc292005-05-06 21:37:42 +00003030static int
paul68980082003-03-25 05:07:42 +00003031ospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new)
paul718e3742002-12-13 20:15:29 +00003032{
hasso52dc7ee2004-09-23 19:18:23 +00003033 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003034 struct ospf_lsa *lsa;
3035
3036 for (ALL_LIST_ELEMENTS_RO (ospf->maxage_lsa, node, lsa))
3037 if (lsa == new)
paul718e3742002-12-13 20:15:29 +00003038 return 1;
3039
3040 return 0;
3041}
3042
3043void
paul68980082003-03-25 05:07:42 +00003044ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003045{
hasso52dc7ee2004-09-23 19:18:23 +00003046 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003047
paul68980082003-03-25 05:07:42 +00003048 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00003049 {
paul68980082003-03-25 05:07:42 +00003050 list_delete_node (ospf->maxage_lsa, n);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003051 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +00003052 }
3053}
3054
3055void
paul68980082003-03-25 05:07:42 +00003056ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003057{
3058 /* When we saw a MaxAge LSA flooded to us, we put it on the list
3059 and schedule the MaxAge LSA remover. */
paul68980082003-03-25 05:07:42 +00003060 if (ospf_lsa_maxage_exist (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003061 {
3062 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003063 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00003064 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
3065 return;
3066 }
3067
paul68980082003-03-25 05:07:42 +00003068 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00003069
3070 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003071 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003072
paul68980082003-03-25 05:07:42 +00003073 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003074}
3075
paul4dadc292005-05-06 21:37:42 +00003076static int
paul68980082003-03-25 05:07:42 +00003077ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003078{
paul718e3742002-12-13 20:15:29 +00003079 /* Stay away from any Local Translated Type-7 LSAs */
3080 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3081 return 0;
paul718e3742002-12-13 20:15:29 +00003082
3083 if (IS_LSA_MAXAGE (lsa))
3084 /* Self-originated LSAs should NOT time-out instead,
3085 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00003086 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003087 {
3088 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003089 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003090
3091 switch (lsa->data->type)
3092 {
paul718e3742002-12-13 20:15:29 +00003093#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00003094 case OSPF_OPAQUE_LINK_LSA:
3095 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003096 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003097 /*
3098 * As a general rule, whenever network topology has changed
3099 * (due to an LSA removal in this case), routing recalculation
3100 * should be triggered. However, this is not true for opaque
3101 * LSAs. Even if an opaque LSA instance is going to be removed
3102 * from the routing domain, it does not mean a change in network
3103 * topology, and thus, routing recalculation is not needed here.
3104 */
3105 break;
paul718e3742002-12-13 20:15:29 +00003106#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00003107 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003108 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003109 ospf_ase_incremental_update (ospf, lsa);
3110 break;
paul718e3742002-12-13 20:15:29 +00003111 default:
paul68980082003-03-25 05:07:42 +00003112 ospf_spf_calculate_schedule (ospf);
3113 break;
paul718e3742002-12-13 20:15:29 +00003114 }
paul68980082003-03-25 05:07:42 +00003115 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003116 }
3117
3118 return 0;
3119}
3120
3121/* Periodical check of MaxAge LSA. */
3122int
paul68980082003-03-25 05:07:42 +00003123ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003124{
paul68980082003-03-25 05:07:42 +00003125 struct ospf *ospf = THREAD_ARG (thread);
3126 struct route_node *rn;
3127 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003128 struct ospf_area *area;
3129 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003130
paul68980082003-03-25 05:07:42 +00003131 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003132
paul1eb8ef22005-04-07 07:30:20 +00003133 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003134 {
paul68980082003-03-25 05:07:42 +00003135 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3136 ospf_lsa_maxage_walker_remover (ospf, lsa);
3137 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3138 ospf_lsa_maxage_walker_remover (ospf, lsa);
3139 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3140 ospf_lsa_maxage_walker_remover (ospf, lsa);
3141 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3142 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003143#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003144 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3145 ospf_lsa_maxage_walker_remover (ospf, lsa);
3146 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3147 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003148#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003149 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3150 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003151 }
3152
paul4fb949e2003-05-10 20:06:51 +00003153 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003154 if (ospf->lsdb)
3155 {
3156 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3157 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003158#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003159 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3160 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003161#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003162 }
paul718e3742002-12-13 20:15:29 +00003163
paul68980082003-03-25 05:07:42 +00003164 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3165 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003166 return 0;
3167}
3168
paul68980082003-03-25 05:07:42 +00003169struct ospf_lsa *
3170ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3171 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003172{
paul68980082003-03-25 05:07:42 +00003173 struct ospf_lsa *lsa;
3174 struct in_addr mask, id;
3175 struct lsa_header_mask
3176 {
3177 struct lsa_header header;
3178 struct in_addr mask;
3179 } *hmask;
paul718e3742002-12-13 20:15:29 +00003180
paul68980082003-03-25 05:07:42 +00003181 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3182 if (lsa == NULL)
3183 return NULL;
paul718e3742002-12-13 20:15:29 +00003184
paul68980082003-03-25 05:07:42 +00003185 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003186
paul68980082003-03-25 05:07:42 +00003187 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003188
paul68980082003-03-25 05:07:42 +00003189 if (mask.s_addr != hmask->mask.s_addr)
3190 {
3191 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3192 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3193 if (!lsa)
3194 return NULL;
3195 }
paul718e3742002-12-13 20:15:29 +00003196
paul68980082003-03-25 05:07:42 +00003197 return lsa;
paul718e3742002-12-13 20:15:29 +00003198}
3199
3200struct ospf_lsa *
3201ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3202 struct in_addr id, struct in_addr adv_router)
3203{
paule05fba42003-04-13 20:20:53 +00003204 struct ospf *ospf = ospf_lookup();
3205 assert(ospf);
3206
paul718e3742002-12-13 20:15:29 +00003207 switch (type)
3208 {
3209 case OSPF_ROUTER_LSA:
3210 case OSPF_NETWORK_LSA:
3211 case OSPF_SUMMARY_LSA:
3212 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003213 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003214#ifdef HAVE_OPAQUE_LSA
3215 case OSPF_OPAQUE_LINK_LSA:
3216 case OSPF_OPAQUE_AREA_LSA:
3217#endif /* HAVE_OPAQUE_LSA */
3218 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003219 case OSPF_AS_EXTERNAL_LSA:
3220#ifdef HAVE_OPAQUE_LSA
3221 case OSPF_OPAQUE_AS_LSA:
3222#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003223 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003224 default:
3225 break;
3226 }
3227
3228 return NULL;
3229}
3230
3231struct ospf_lsa *
3232ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3233 struct in_addr id)
3234{
3235 struct ospf_lsa *lsa;
3236 struct route_node *rn;
3237
3238 switch (type)
3239 {
3240 case OSPF_ROUTER_LSA:
3241 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003242 case OSPF_NETWORK_LSA:
3243 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3244 if ((lsa = rn->info))
3245 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3246 {
3247 route_unlock_node (rn);
3248 return lsa;
3249 }
3250 break;
3251 case OSPF_SUMMARY_LSA:
3252 case OSPF_ASBR_SUMMARY_LSA:
3253 /* Currently not used. */
3254 assert (1);
3255 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003256 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003257 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003258#ifdef HAVE_OPAQUE_LSA
3259 case OSPF_OPAQUE_LINK_LSA:
3260 case OSPF_OPAQUE_AREA_LSA:
3261 case OSPF_OPAQUE_AS_LSA:
3262 /* Currently not used. */
3263 break;
3264#endif /* HAVE_OPAQUE_LSA */
3265 default:
3266 break;
3267 }
3268
3269 return NULL;
3270}
3271
3272struct ospf_lsa *
3273ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3274{
3275 struct ospf_lsa *match;
3276
3277#ifdef HAVE_OPAQUE_LSA
3278 /*
3279 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3280 * is redefined to have two subfields; opaque-type and opaque-id.
3281 * However, it is harmless to treat the two sub fields together, as if
3282 * they two were forming a unique LSA-ID.
3283 */
3284#endif /* HAVE_OPAQUE_LSA */
3285
3286 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3287
3288 if (match == NULL)
3289 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003290 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003291 lsah->type, inet_ntoa (lsah->id));
3292
3293 return match;
3294}
3295
3296/* return +n, l1 is more recent.
3297 return -n, l2 is more recent.
3298 return 0, l1 and l2 is identical. */
3299int
3300ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3301{
3302 int r;
3303 int x, y;
3304
3305 if (l1 == NULL && l2 == NULL)
3306 return 0;
3307 if (l1 == NULL)
3308 return -1;
3309 if (l2 == NULL)
3310 return 1;
3311
3312 /* compare LS sequence number. */
3313 x = (int) ntohl (l1->data->ls_seqnum);
3314 y = (int) ntohl (l2->data->ls_seqnum);
3315 if (x > y)
3316 return 1;
3317 if (x < y)
3318 return -1;
3319
3320 /* compare LS checksum. */
3321 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3322 if (r)
3323 return r;
3324
3325 /* compare LS age. */
3326 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3327 return 1;
3328 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3329 return -1;
3330
3331 /* compare LS age with MaxAgeDiff. */
3332 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3333 return -1;
3334 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3335 return 1;
3336
3337 /* LSAs are identical. */
3338 return 0;
3339}
3340
3341/* If two LSAs are different, return 1, otherwise return 0. */
3342int
3343ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3344{
3345 char *p1, *p2;
3346 assert (l1);
3347 assert (l2);
3348 assert (l1->data);
3349 assert (l2->data);
3350
3351 if (l1->data->options != l2->data->options)
3352 return 1;
3353
3354 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3355 return 1;
3356
3357 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3358 return 1;
3359
3360 if (l1->data->length != l2->data->length)
3361 return 1;
3362
3363 if (l1->data->length == 0)
3364 return 1;
3365
pauld1825832003-04-03 01:27:01 +00003366 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003367
3368 p1 = (char *) l1->data;
3369 p2 = (char *) l2->data;
3370
3371 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3372 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3373 return 1;
3374
3375 return 0;
3376}
3377
3378#ifdef ORIGINAL_CODING
3379void
3380ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3381 struct ospf_lsa *self,
3382 struct ospf_lsa *new)
3383{
3384 u_int32_t seqnum;
3385
3386 /* Adjust LS Sequence Number. */
3387 seqnum = ntohl (new->data->ls_seqnum) + 1;
3388 self->data->ls_seqnum = htonl (seqnum);
3389
3390 /* Recalculate LSA checksum. */
3391 ospf_lsa_checksum (self->data);
3392
3393 /* Reflooding LSA. */
3394 /* RFC2328 Section 13.3
3395 On non-broadcast networks, separate Link State Update
3396 packets must be sent, as unicasts, to each adjacent neighbor
3397 (i.e., those in state Exchange or greater). The destination
3398 IP addresses for these packets are the neighbors' IP
3399 addresses. */
3400 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3401 {
3402 struct route_node *rn;
3403 struct ospf_neighbor *onbr;
3404
3405 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3406 if ((onbr = rn->info) != NULL)
3407 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3408 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3409 }
3410 else
3411 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3412
3413 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003414 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003415 self->data->type, inet_ntoa (self->data->id));
3416}
3417#else /* ORIGINAL_CODING */
3418static int
paul68980082003-03-25 05:07:42 +00003419ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003420{
3421 if (lsa == NULL || !IS_LSA_SELF (lsa))
3422 return 0;
3423
3424 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003425 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 +00003426
3427 /* Force given lsa's age to MaxAge. */
3428 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3429
3430 switch (lsa->data->type)
3431 {
3432#ifdef HAVE_OPAQUE_LSA
3433 case OSPF_OPAQUE_LINK_LSA:
3434 case OSPF_OPAQUE_AREA_LSA:
3435 case OSPF_OPAQUE_AS_LSA:
3436 ospf_opaque_lsa_refresh (lsa);
3437 break;
3438#endif /* HAVE_OPAQUE_LSA */
3439 default:
paul68980082003-03-25 05:07:42 +00003440 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003441 break;
3442 }
3443
3444 return 0;
3445}
3446
3447void
paul68980082003-03-25 05:07:42 +00003448ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003449{
paul1eb8ef22005-04-07 07:30:20 +00003450 struct listnode *node, *nnode;
3451 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003452 struct ospf_area *area;
3453 struct ospf_interface *oi;
3454 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003455 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003456 int need_to_flush_ase = 0;
3457
paul1eb8ef22005-04-07 07:30:20 +00003458 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003459 {
paul718e3742002-12-13 20:15:29 +00003460 if ((lsa = area->router_lsa_self) != NULL)
3461 {
3462 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003463 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 +00003464
3465 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003466 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003467 area->router_lsa_self = NULL;
3468 OSPF_TIMER_OFF (area->t_router_lsa_self);
3469 }
3470
paul1eb8ef22005-04-07 07:30:20 +00003471 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003472 {
paul718e3742002-12-13 20:15:29 +00003473 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003474 && oi->state == ISM_DR
3475 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003476 {
3477 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003478 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 +00003479
3480 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003481 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003482 oi->network_lsa_self = NULL;
3483 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3484 }
3485
3486 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3487 && area->external_routing == OSPF_AREA_DEFAULT)
3488 need_to_flush_ase = 1;
3489 }
3490
paul68980082003-03-25 05:07:42 +00003491 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3492 ospf_lsa_flush_schedule (ospf, lsa);
3493 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3494 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003495#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003496 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3497 ospf_lsa_flush_schedule (ospf, lsa);
3498 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3499 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003500#endif /* HAVE_OPAQUE_LSA */
3501 }
3502
3503 if (need_to_flush_ase)
3504 {
paul68980082003-03-25 05:07:42 +00003505 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3506 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003507#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003508 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3509 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003510#endif /* HAVE_OPAQUE_LSA */
3511 }
3512
3513 /*
3514 * Make sure that the MaxAge LSA remover is executed immediately,
3515 * without conflicting to other threads.
3516 */
paul68980082003-03-25 05:07:42 +00003517 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003518 {
paul68980082003-03-25 05:07:42 +00003519 OSPF_TIMER_OFF (ospf->t_maxage);
3520 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003521 }
3522
3523 return;
3524}
3525#endif /* ORIGINAL_CODING */
3526
3527/* If there is self-originated LSA, then return 1, otherwise return 0. */
3528/* An interface-independent version of ospf_lsa_is_self_originated */
3529int
paul68980082003-03-25 05:07:42 +00003530ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003531{
hasso52dc7ee2004-09-23 19:18:23 +00003532 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003533 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003534
3535 /* This LSA is already checked. */
3536 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3537 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3538
3539 /* Make sure LSA is self-checked. */
3540 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3541
3542 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003543 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003544 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3545
3546 /* LSA is router-LSA. */
3547 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003548 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003549 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3550
3551 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3552 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003553 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003554 {
paul718e3742002-12-13 20:15:29 +00003555 /* Ignore virtual link. */
3556 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3557 if (oi->address->family == AF_INET)
3558 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3559 {
3560 /* to make it easier later */
3561 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3562 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3563 }
3564 }
3565
3566 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3567}
3568
3569/* Get unique Link State ID. */
3570struct in_addr
paul68980082003-03-25 05:07:42 +00003571ospf_lsa_unique_id (struct ospf *ospf,
3572 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003573{
3574 struct ospf_lsa *lsa;
3575 struct in_addr mask, id;
3576
3577 id = p->prefix;
3578
3579 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003580 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003581 if (lsa)
3582 {
3583 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3584 if (ip_masklen (al->mask) == p->prefixlen)
3585 {
3586 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003587 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003588 "Can't get Link State ID for %s/%d",
3589 inet_ntoa (p->prefix), p->prefixlen);
3590 /* id.s_addr = 0; */
3591 id.s_addr = 0xffffffff;
3592 return id;
3593 }
3594 /* Masklen differs, then apply wildcard mask to Link State ID. */
3595 else
3596 {
3597 masklen2ip (p->prefixlen, &mask);
3598
3599 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003600 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3601 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003602 if (lsa)
3603 {
3604 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003605 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003606 "Can't get Link State ID for %s/%d",
3607 inet_ntoa (p->prefix), p->prefixlen);
3608 /* id.s_addr = 0; */
3609 id.s_addr = 0xffffffff;
3610 return id;
3611 }
3612 }
3613 }
3614
3615 return id;
3616}
3617
3618
Paul Jakma70461d72006-05-12 22:57:57 +00003619#define LSA_ACTION_FLOOD_AREA 1
3620#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003621
3622struct lsa_action
3623{
3624 u_char action;
3625 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003626 struct ospf_lsa *lsa;
3627};
3628
paul4dadc292005-05-06 21:37:42 +00003629static int
paul718e3742002-12-13 20:15:29 +00003630ospf_lsa_action (struct thread *t)
3631{
3632 struct lsa_action *data;
3633
3634 data = THREAD_ARG (t);
3635
3636 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003637 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003638 data->action);
3639
3640 switch (data->action)
3641 {
paul718e3742002-12-13 20:15:29 +00003642 case LSA_ACTION_FLOOD_AREA:
3643 ospf_flood_through_area (data->area, NULL, data->lsa);
3644 break;
paul718e3742002-12-13 20:15:29 +00003645 case LSA_ACTION_FLUSH_AREA:
3646 ospf_lsa_flush_area (data->lsa, data->area);
3647 break;
paul718e3742002-12-13 20:15:29 +00003648 }
3649
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003650 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003651 XFREE (MTYPE_OSPF_MESSAGE, data);
3652 return 0;
3653}
3654
3655void
3656ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3657{
3658 struct lsa_action *data;
3659
3660 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3661 memset (data, 0, sizeof (struct lsa_action));
3662
3663 data->action = LSA_ACTION_FLOOD_AREA;
3664 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003665 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003666
3667 thread_add_event (master, ospf_lsa_action, data, 0);
3668}
3669
3670void
3671ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3672{
3673 struct lsa_action *data;
3674
3675 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3676 memset (data, 0, sizeof (struct lsa_action));
3677
3678 data->action = LSA_ACTION_FLUSH_AREA;
3679 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003680 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003681
3682 thread_add_event (master, ospf_lsa_action, data, 0);
3683}
3684
3685
3686/* LSA Refreshment functions. */
paul4dadc292005-05-06 21:37:42 +00003687static void
paul68980082003-03-25 05:07:42 +00003688ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003689{
3690 struct external_info *ei;
3691 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3692
3693 switch (lsa->data->type)
3694 {
3695 /* Router and Network LSAs are processed differently. */
3696 case OSPF_ROUTER_LSA:
3697 case OSPF_NETWORK_LSA:
3698 break;
3699 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003700 ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003701 break;
3702 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003703 ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003704 break;
3705 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003706 /* Translated from NSSA Type-5s are refreshed when
3707 * from refresh of Type-7 - do not refresh these directly.
3708 */
3709 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3710 break;
paul718e3742002-12-13 20:15:29 +00003711 ei = ospf_external_info_check (lsa);
3712 if (ei)
pauld4a53d52003-07-12 21:30:57 +00003713 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003714 else
pauld4a53d52003-07-12 21:30:57 +00003715 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003716 break;
3717#ifdef HAVE_OPAQUE_LSA
3718 case OSPF_OPAQUE_LINK_LSA:
3719 case OSPF_OPAQUE_AREA_LSA:
3720 case OSPF_OPAQUE_AS_LSA:
3721 ospf_opaque_lsa_refresh (lsa);
3722 break;
pauld7480322003-05-16 17:31:51 +00003723#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003724 default:
3725 break;
paul718e3742002-12-13 20:15:29 +00003726 }
3727}
3728
3729void
paul68980082003-03-25 05:07:42 +00003730ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003731{
3732 u_int16_t index, current_index;
3733
3734 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3735
3736 if (lsa->refresh_list < 0)
3737 {
3738 int delay;
3739
3740 if (LS_AGE (lsa) == 0 &&
3741 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3742 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3743 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3744 else
3745 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3746 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3747 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3748
3749 if (delay < 0)
3750 delay = 0;
3751
paul68980082003-03-25 05:07:42 +00003752 current_index = ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003753 (quagga_time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003754
3755 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3756 % (OSPF_LSA_REFRESHER_SLOTS);
3757
3758 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003759 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003760 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003761 if (!ospf->lsa_refresh_queue.qs[index])
3762 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003763 listnode_add (ospf->lsa_refresh_queue.qs[index],
3764 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003765 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003766 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003767 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003768 "setting refresh_list on lsa %p (slod %d)",
3769 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003770 }
3771}
3772
3773void
paul68980082003-03-25 05:07:42 +00003774ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003775{
3776 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3777 if (lsa->refresh_list >= 0)
3778 {
hasso52dc7ee2004-09-23 19:18:23 +00003779 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003780 listnode_delete (refresh_list, lsa);
3781 if (!listcount (refresh_list))
3782 {
3783 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003784 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003785 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003786 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003787 lsa->refresh_list = -1;
3788 }
3789}
3790
3791int
3792ospf_lsa_refresh_walker (struct thread *t)
3793{
hasso52dc7ee2004-09-23 19:18:23 +00003794 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003795 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003796 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003797 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003798 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003799 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003800
3801 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003802 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003803
3804
paul68980082003-03-25 05:07:42 +00003805 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003806
ajs9dbc7972005-03-13 19:27:22 +00003807 /* Note: if clock has jumped backwards, then time change could be negative,
3808 so we are careful to cast the expression to unsigned before taking
3809 modulus. */
paul68980082003-03-25 05:07:42 +00003810 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003811 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003812 (quagga_time (NULL) - ospf->lsa_refresher_started) /
ajs9dbc7972005-03-13 19:27:22 +00003813 OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003814
3815 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003816 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003817 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003818
paul68980082003-03-25 05:07:42 +00003819 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003820 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3821 {
3822 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003823 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003824 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003825
paul68980082003-03-25 05:07:42 +00003826 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003827
paul68980082003-03-25 05:07:42 +00003828 ospf->lsa_refresh_queue.qs [i] = NULL;
3829
paul718e3742002-12-13 20:15:29 +00003830 if (refresh_list)
3831 {
paul1eb8ef22005-04-07 07:30:20 +00003832 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003833 {
paul718e3742002-12-13 20:15:29 +00003834 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003835 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003836 "refresh lsa %p (slot %d)",
3837 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003838
3839 list_delete_node (refresh_list, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003840 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003841 lsa->refresh_list = -1;
3842 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003843 }
3844 list_free (refresh_list);
3845 }
3846 }
3847
paul68980082003-03-25 05:07:42 +00003848 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3849 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003850 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003851
paul1eb8ef22005-04-07 07:30:20 +00003852 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
3853 ospf_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003854
3855 list_delete (lsa_to_refresh);
3856
3857 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003858 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003859
3860 return 0;
3861}
3862