blob: 22612f6f5181ff7b86c3fefc4010d010bf8f9c57 [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() */
Jingjing Duan6a270cd2008-08-13 19:09:10 +010035#include "checksum.h"
paul718e3742002-12-13 20:15:29 +000036
37#include "ospfd/ospfd.h"
38#include "ospfd/ospf_interface.h"
39#include "ospfd/ospf_ism.h"
40#include "ospfd/ospf_asbr.h"
41#include "ospfd/ospf_lsa.h"
42#include "ospfd/ospf_lsdb.h"
43#include "ospfd/ospf_neighbor.h"
44#include "ospfd/ospf_nsm.h"
45#include "ospfd/ospf_flood.h"
46#include "ospfd/ospf_packet.h"
47#include "ospfd/ospf_spf.h"
48#include "ospfd/ospf_dump.h"
49#include "ospfd/ospf_route.h"
50#include "ospfd/ospf_ase.h"
51#include "ospfd/ospf_zebra.h"
52
53
54u_int32_t
55get_metric (u_char *metric)
56{
57 u_int32_t m;
58 m = metric[0];
59 m = (m << 8) + metric[1];
60 m = (m << 8) + metric[2];
61 return m;
62}
63
64
65struct timeval
66tv_adjust (struct timeval a)
67{
68 while (a.tv_usec >= 1000000)
69 {
70 a.tv_usec -= 1000000;
71 a.tv_sec++;
72 }
73
74 while (a.tv_usec < 0)
75 {
76 a.tv_usec += 1000000;
77 a.tv_sec--;
78 }
79
80 return a;
81}
82
83int
84tv_ceil (struct timeval a)
85{
86 a = tv_adjust (a);
87
88 return (a.tv_usec ? a.tv_sec + 1 : a.tv_sec);
89}
90
91int
92tv_floor (struct timeval a)
93{
94 a = tv_adjust (a);
95
96 return a.tv_sec;
97}
98
99struct timeval
100int2tv (int a)
101{
102 struct timeval ret;
103
104 ret.tv_sec = a;
105 ret.tv_usec = 0;
106
107 return ret;
108}
109
110struct timeval
111tv_add (struct timeval a, struct timeval b)
112{
113 struct timeval ret;
114
115 ret.tv_sec = a.tv_sec + b.tv_sec;
116 ret.tv_usec = a.tv_usec + b.tv_usec;
117
118 return tv_adjust (ret);
119}
120
121struct timeval
122tv_sub (struct timeval a, struct timeval b)
123{
124 struct timeval ret;
125
126 ret.tv_sec = a.tv_sec - b.tv_sec;
127 ret.tv_usec = a.tv_usec - b.tv_usec;
128
129 return tv_adjust (ret);
130}
131
132int
133tv_cmp (struct timeval a, struct timeval b)
134{
135 return (a.tv_sec == b.tv_sec ?
136 a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
137}
138
139int
140ospf_lsa_refresh_delay (struct ospf_lsa *lsa)
141{
142 struct timeval delta, now;
143 int delay = 0;
144
Paul Jakma2518efd2006-08-27 06:49:29 +0000145 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +0000146 delta = tv_sub (now, lsa->tv_orig);
147
148 if (tv_cmp (delta, int2tv (OSPF_MIN_LS_INTERVAL)) < 0)
149 {
150 delay = tv_ceil (tv_sub (int2tv (OSPF_MIN_LS_INTERVAL), delta));
151
152 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000153 zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
paul718e3742002-12-13 20:15:29 +0000154 lsa->data->type, inet_ntoa (lsa->data->id), delay);
155
156 assert (delay > 0);
157 }
158
159 return delay;
160}
161
162
163int
164get_age (struct ospf_lsa *lsa)
165{
166 int age;
paul718e3742002-12-13 20:15:29 +0000167
Paul Jakma2518efd2006-08-27 06:49:29 +0000168 age = ntohs (lsa->data->ls_age)
169 + tv_floor (tv_sub (recent_relative_time (), lsa->tv_recv));
paul718e3742002-12-13 20:15:29 +0000170
171 return age;
172}
173
174
175/* Fletcher Checksum -- Refer to RFC1008. */
paul718e3742002-12-13 20:15:29 +0000176
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100177/* All the offsets are zero-based. The offsets in the RFC1008 are
178 one-based. */
paul718e3742002-12-13 20:15:29 +0000179u_int16_t
180ospf_lsa_checksum (struct lsa_header *lsa)
181{
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100182 u_char *buffer = (u_char *) &lsa->options;
183 int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */
paul718e3742002-12-13 20:15:29 +0000184
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100185 /* Skip the AGE field */
186 u_int16_t len = ntohs(lsa->length) - options_offset;
paul718e3742002-12-13 20:15:29 +0000187
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100188 /* Checksum offset starts from "options" field, not the beginning of the
189 lsa_header struct. The offset is 14, rather than 16. */
190 int checksum_offset = (u_char *) &lsa->checksum - buffer;
paul718e3742002-12-13 20:15:29 +0000191
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100192 return fletcher_checksum(buffer, len, checksum_offset);
paul718e3742002-12-13 20:15:29 +0000193}
194
195
196
197/* Create OSPF LSA. */
198struct ospf_lsa *
199ospf_lsa_new ()
200{
201 struct ospf_lsa *new;
202
203 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
paul718e3742002-12-13 20:15:29 +0000204
205 new->flags = 0;
206 new->lock = 1;
207 new->retransmit_counter = 0;
Paul Jakma2518efd2006-08-27 06:49:29 +0000208 new->tv_recv = recent_relative_time ();
paul718e3742002-12-13 20:15:29 +0000209 new->tv_orig = new->tv_recv;
210 new->refresh_list = -1;
211
212 return new;
213}
214
215/* Duplicate OSPF LSA. */
216struct ospf_lsa *
217ospf_lsa_dup (struct ospf_lsa *lsa)
218{
219 struct ospf_lsa *new;
220
221 if (lsa == NULL)
222 return NULL;
223
224 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
225
226 memcpy (new, lsa, sizeof (struct ospf_lsa));
227 UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
228 new->lock = 1;
229 new->retransmit_counter = 0;
230 new->data = ospf_lsa_data_dup (lsa->data);
231
paulf2c80652002-12-13 21:44:27 +0000232 /* kevinm: Clear the refresh_list, otherwise there are going
233 to be problems when we try to remove the LSA from the
234 queue (which it's not a member of.)
235 XXX: Should we add the LSA to the refresh_list queue? */
236 new->refresh_list = -1;
237
238 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000239 zlog_debug ("LSA: duplicated %p (new: %p)", lsa, new);
paulf2c80652002-12-13 21:44:27 +0000240
paul718e3742002-12-13 20:15:29 +0000241 return new;
242}
243
244/* Free OSPF LSA. */
245void
246ospf_lsa_free (struct ospf_lsa *lsa)
247{
248 assert (lsa->lock == 0);
249
250 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000251 zlog_debug ("LSA: freed %p", lsa);
paul718e3742002-12-13 20:15:29 +0000252
253 /* Delete LSA data. */
254 if (lsa->data != NULL)
255 ospf_lsa_data_free (lsa->data);
256
257 assert (lsa->refresh_list < 0);
258
259 memset (lsa, 0, sizeof (struct ospf_lsa));
260 XFREE (MTYPE_OSPF_LSA, lsa);
261}
262
263/* Lock LSA. */
264struct ospf_lsa *
265ospf_lsa_lock (struct ospf_lsa *lsa)
266{
267 lsa->lock++;
268 return lsa;
269}
270
271/* Unlock LSA. */
272void
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000273ospf_lsa_unlock (struct ospf_lsa **lsa)
paul718e3742002-12-13 20:15:29 +0000274{
275 /* This is sanity check. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000276 if (!lsa || !*lsa)
paul718e3742002-12-13 20:15:29 +0000277 return;
278
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000279 (*lsa)->lock--;
paul718e3742002-12-13 20:15:29 +0000280
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000281 assert ((*lsa)->lock >= 0);
paul718e3742002-12-13 20:15:29 +0000282
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000283 if ((*lsa)->lock == 0)
paul718e3742002-12-13 20:15:29 +0000284 {
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000285 assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
286 ospf_lsa_free (*lsa);
287 *lsa = NULL;
paul718e3742002-12-13 20:15:29 +0000288 }
289}
290
291/* Check discard flag. */
292void
293ospf_lsa_discard (struct ospf_lsa *lsa)
294{
295 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
296 {
297 SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000298 ospf_lsa_unlock (&lsa);
paul718e3742002-12-13 20:15:29 +0000299 }
300}
301
302/* Create LSA data. */
303struct lsa_header *
304ospf_lsa_data_new (size_t size)
305{
Stephen Hemminger393deb92008-08-18 14:13:29 -0700306 return XCALLOC (MTYPE_OSPF_LSA_DATA, size);
paul718e3742002-12-13 20:15:29 +0000307}
308
309/* Duplicate LSA data. */
310struct lsa_header *
311ospf_lsa_data_dup (struct lsa_header *lsah)
312{
313 struct lsa_header *new;
314
315 new = ospf_lsa_data_new (ntohs (lsah->length));
316 memcpy (new, lsah, ntohs (lsah->length));
317
318 return new;
319}
320
321/* Free LSA data. */
322void
323ospf_lsa_data_free (struct lsa_header *lsah)
324{
325 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000326 zlog_debug ("LSA[Type%d:%s]: data freed %p",
paul718e3742002-12-13 20:15:29 +0000327 lsah->type, inet_ntoa (lsah->id), lsah);
328
329 XFREE (MTYPE_OSPF_LSA_DATA, lsah);
330}
331
332
333/* LSA general functions. */
334
335const char *
336dump_lsa_key (struct ospf_lsa *lsa)
337{
338 static char buf[] = {
hasso52dc7ee2004-09-23 19:18:23 +0000339 "Type255,id(255.255.255.255),ar(255.255.255.255)"
paul718e3742002-12-13 20:15:29 +0000340 };
341 struct lsa_header *lsah;
342
343 if (lsa != NULL && (lsah = lsa->data) != NULL)
344 {
345 char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
346 strcpy (id, inet_ntoa (lsah->id));
347 strcpy (ar, inet_ntoa (lsah->adv_router));
348
349 sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
350 }
351 else
352 strcpy (buf, "NULL");
353
354 return buf;
355}
356
357u_int32_t
358lsa_seqnum_increment (struct ospf_lsa *lsa)
359{
360 u_int32_t seqnum;
361
362 seqnum = ntohl (lsa->data->ls_seqnum) + 1;
363
364 return htonl (seqnum);
365}
366
367void
368lsa_header_set (struct stream *s, u_char options,
paul68980082003-03-25 05:07:42 +0000369 u_char type, struct in_addr id, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +0000370{
371 struct lsa_header *lsah;
372
373 lsah = (struct lsa_header *) STREAM_DATA (s);
374
375 lsah->ls_age = htons (0);
376 lsah->options = options;
377 lsah->type = type;
378 lsah->id = id;
paul68980082003-03-25 05:07:42 +0000379 lsah->adv_router = router_id;
paul718e3742002-12-13 20:15:29 +0000380 lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
381
paul9985f832005-02-09 15:51:56 +0000382 stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000383}
384
paul68980082003-03-25 05:07:42 +0000385
paul718e3742002-12-13 20:15:29 +0000386/* router-LSA related functions. */
387/* Get router-LSA flags. */
paul4dadc292005-05-06 21:37:42 +0000388static u_char
paul718e3742002-12-13 20:15:29 +0000389router_lsa_flags (struct ospf_area *area)
390{
391 u_char flags;
392
paul68980082003-03-25 05:07:42 +0000393 flags = area->ospf->flags;
paul718e3742002-12-13 20:15:29 +0000394
395 /* Set virtual link flag. */
396 if (ospf_full_virtual_nbrs (area))
397 SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
398 else
399 /* Just sanity check */
400 UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);
401
402 /* Set Shortcut ABR behabiour flag. */
403 UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
paul68980082003-03-25 05:07:42 +0000404 if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
paul718e3742002-12-13 20:15:29 +0000405 if (!OSPF_IS_AREA_BACKBONE (area))
406 if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
paul68980082003-03-25 05:07:42 +0000407 area->ospf->backbone == NULL) ||
paul718e3742002-12-13 20:15:29 +0000408 area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
409 SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
410
411 /* ASBR can't exit in stub area. */
Greg Troxelfc787e82007-08-06 15:50:20 +0000412 if (area->external_routing == OSPF_AREA_STUB)
paul942b6c12003-06-22 08:22:18 +0000413 UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
414 /* If ASBR set External flag */
415 else if (IS_OSPF_ASBR (area->ospf))
416 SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
417
418 /* Set ABR dependent flags */
419 if (IS_OSPF_ABR (area->ospf))
420 {
421 SET_FLAG (flags, ROUTER_LSA_BORDER);
paul942b6c12003-06-22 08:22:18 +0000422 /* If Area is NSSA and we are both ABR and unconditional translator,
pauld4a53d52003-07-12 21:30:57 +0000423 * set Nt bit to inform other routers.
paul942b6c12003-06-22 08:22:18 +0000424 */
pauld4a53d52003-07-12 21:30:57 +0000425 if ( (area->external_routing == OSPF_AREA_NSSA)
426 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
427 SET_FLAG (flags, ROUTER_LSA_NT);
paul942b6c12003-06-22 08:22:18 +0000428 }
paul718e3742002-12-13 20:15:29 +0000429 return flags;
430}
431
432/* Lookup neighbor other than myself.
433 And check neighbor count,
434 Point-to-Point link must have only 1 neighbor. */
435struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +0000436ospf_nbr_lookup_ptop (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +0000437{
paul718e3742002-12-13 20:15:29 +0000438 struct ospf_neighbor *nbr = NULL;
paul68980082003-03-25 05:07:42 +0000439 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000440
441 /* Search neighbor, there must be one of two nbrs. */
paul68980082003-03-25 05:07:42 +0000442 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
443 if ((nbr = rn->info))
444 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000445 if (nbr->state == NSM_Full)
paul68980082003-03-25 05:07:42 +0000446 {
447 route_unlock_node (rn);
448 break;
449 }
paul718e3742002-12-13 20:15:29 +0000450
451 /* PtoP link must have only 1 neighbor. */
paul68980082003-03-25 05:07:42 +0000452 if (ospf_nbr_count (oi, 0) > 1)
paul718e3742002-12-13 20:15:29 +0000453 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
454
455 return nbr;
456}
457
paul88d6cf32005-10-29 12:50:09 +0000458/* Determine cost of link, taking RFC3137 stub-router support into
459 * consideration
460 */
461static u_int16_t
462ospf_link_cost (struct ospf_interface *oi)
463{
464 /* RFC3137 stub router support */
465 if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
466 return oi->output_cost;
467 else
468 return OSPF_OUTPUT_COST_INFINITE;
469}
470
paul718e3742002-12-13 20:15:29 +0000471/* Set a link information. */
paul779adb02006-01-18 15:07:38 +0000472static char
paul718e3742002-12-13 20:15:29 +0000473link_info_set (struct stream *s, struct in_addr id,
474 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
475{
paul779adb02006-01-18 15:07:38 +0000476 /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
477 * vast majority of cases. Some rare routers with lots of links need more.
478 * we try accomodate those here.
479 */
480 if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
481 {
482 size_t ret = OSPF_MAX_LSA_SIZE;
483
484 /* Can we enlarge the stream still? */
485 if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
486 {
487 /* we futz the size here for simplicity, really we need to account
488 * for just:
489 * IP Header - (sizeof (struct ip))
490 * OSPF Header - OSPF_HEADER_SIZE
491 * LSA Header - OSPF_LSA_HEADER_SIZE
492 * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
493 *
494 * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
495 */
496 ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
497 }
498
499 if (ret == OSPF_MAX_LSA_SIZE)
500 {
Paul Jakma53725102009-08-03 16:34:16 +0100501 zlog_warn ("%s: Out of space in LSA stream, left %zd, size %zd",
paul779adb02006-01-18 15:07:38 +0000502 __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
503 return 0;
504 }
505 }
506
paul718e3742002-12-13 20:15:29 +0000507 /* TOS based routing is not supported. */
508 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
509 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
510 stream_putc (s, type); /* Link Type. */
511 stream_putc (s, tos); /* TOS = 0. */
512 stream_putw (s, cost); /* Link Cost. */
paul779adb02006-01-18 15:07:38 +0000513
514 return 1;
paul718e3742002-12-13 20:15:29 +0000515}
516
Andrew J. Schorre4529632006-12-12 19:18:21 +0000517/* Describe Point-to-Point link (Section 12.4.1.1). */
paul4dadc292005-05-06 21:37:42 +0000518static int
paul718e3742002-12-13 20:15:29 +0000519lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
520{
521 int links = 0;
522 struct ospf_neighbor *nbr;
523 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000524 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000525
526 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000527 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
paul718e3742002-12-13 20:15:29 +0000528
paul68980082003-03-25 05:07:42 +0000529 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000530 if (nbr->state == NSM_Full)
531 {
532 /* For unnumbered point-to-point networks, the Link Data field
533 should specify the interface's MIB-II ifIndex value. */
paul779adb02006-01-18 15:07:38 +0000534 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
535 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000536 }
537
Andrew J. Schorre4529632006-12-12 19:18:21 +0000538 /* Regardless of the state of the neighboring router, we must
539 add a Type 3 link (stub network).
540 N.B. Options 1 & 2 share basically the same logic. */
541 masklen2ip (oi->address->prefixlen, &mask);
542 id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
543 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
544 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000545 return links;
546}
547
548/* Describe Broadcast Link. */
paul4dadc292005-05-06 21:37:42 +0000549static int
paul718e3742002-12-13 20:15:29 +0000550lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
551{
552 struct ospf_neighbor *dr;
553 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000554 u_int16_t cost = ospf_link_cost (oi);
555
paul718e3742002-12-13 20:15:29 +0000556 /* Describe Type 3 Link. */
557 if (oi->state == ISM_Waiting)
558 {
559 masklen2ip (oi->address->prefixlen, &mask);
560 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000561 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
562 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000563 }
564
565 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
566 /* Describe Type 2 link. */
567 if (dr && (dr->state == NSM_Full ||
568 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000569 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000570 {
paul779adb02006-01-18 15:07:38 +0000571 return link_info_set (s, DR (oi), oi->address->u.prefix4,
572 LSA_LINK_TYPE_TRANSIT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000573 }
574 /* Describe type 3 link. */
575 else
576 {
577 masklen2ip (oi->address->prefixlen, &mask);
578 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000579 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
580 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000581 }
paul718e3742002-12-13 20:15:29 +0000582}
583
paul4dadc292005-05-06 21:37:42 +0000584static int
paul718e3742002-12-13 20:15:29 +0000585lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
586{
587 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000588
paul718e3742002-12-13 20:15:29 +0000589 /* Describe Type 3 Link. */
590 if (oi->state != ISM_Loopback)
591 return 0;
592
593 mask.s_addr = 0xffffffff;
594 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000595 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000596}
597
598/* Describe Virtual Link. */
paul4dadc292005-05-06 21:37:42 +0000599static int
paul718e3742002-12-13 20:15:29 +0000600lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
601{
602 struct ospf_neighbor *nbr;
paul88d6cf32005-10-29 12:50:09 +0000603 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000604
paul718e3742002-12-13 20:15:29 +0000605 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000606 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000607 if (nbr->state == NSM_Full)
608 {
paul779adb02006-01-18 15:07:38 +0000609 return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
610 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
paul718e3742002-12-13 20:15:29 +0000611 }
612
613 return 0;
614}
615
616#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
617
paul7afa08d2002-12-13 20:59:45 +0000618/* this function add for support point-to-multipoint ,see rfc2328
61912.4.1.4.*/
620/* from "edward rrr" <edward_rrr@hotmail.com>
621 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul4dadc292005-05-06 21:37:42 +0000622static int
paul68980082003-03-25 05:07:42 +0000623lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000624{
625 int links = 0;
626 struct route_node *rn;
627 struct ospf_neighbor *nbr = NULL;
628 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000629 u_int16_t cost = ospf_link_cost (oi);
paul7afa08d2002-12-13 20:59:45 +0000630
631 mask.s_addr = 0xffffffff;
632 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000633 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
paul7afa08d2002-12-13 20:59:45 +0000634
paul1cc8f762003-04-05 19:34:32 +0000635 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000636 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000637
638 /* Search neighbor, */
639 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
640 if ((nbr = rn->info) != NULL)
641 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000642 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000643 if (nbr->state == NSM_Full)
644
645 {
paul779adb02006-01-18 15:07:38 +0000646 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
647 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul1cc8f762003-04-05 19:34:32 +0000648 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000649 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000650 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000651 }
652
653 return links;
paul7afa08d2002-12-13 20:59:45 +0000654}
655
paul718e3742002-12-13 20:15:29 +0000656/* Set router-LSA link information. */
paul4dadc292005-05-06 21:37:42 +0000657static int
paul718e3742002-12-13 20:15:29 +0000658router_lsa_link_set (struct stream *s, struct ospf_area *area)
659{
hasso52dc7ee2004-09-23 19:18:23 +0000660 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000661 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000662 int links = 0;
663
paul1eb8ef22005-04-07 07:30:20 +0000664 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +0000665 {
paul718e3742002-12-13 20:15:29 +0000666 struct interface *ifp = oi->ifp;
667
668 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000669 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000670 {
671 if (oi->state != ISM_Down)
672 {
673 /* Describe each link. */
674 switch (oi->type)
675 {
676 case OSPF_IFTYPE_POINTOPOINT:
677 links += lsa_link_ptop_set (s, oi);
678 break;
679 case OSPF_IFTYPE_BROADCAST:
680 links += lsa_link_broadcast_set (s, oi);
681 break;
682 case OSPF_IFTYPE_NBMA:
683 links += lsa_link_nbma_set (s, oi);
684 break;
685 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000686 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000687 break;
688 case OSPF_IFTYPE_VIRTUALLINK:
689 links += lsa_link_virtuallink_set (s, oi);
690 break;
691 case OSPF_IFTYPE_LOOPBACK:
692 links += lsa_link_loopback_set (s, oi);
693 }
694 }
695 }
696 }
697
698 return links;
699}
700
701/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000702static void
paul718e3742002-12-13 20:15:29 +0000703ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
704{
705 unsigned long putp;
706 u_int16_t cnt;
707
708 /* Set flags. */
709 stream_putc (s, router_lsa_flags (area));
710
711 /* Set Zero fields. */
712 stream_putc (s, 0);
713
714 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000715 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000716
717 /* Forward word */
718 stream_putw(s, 0);
719
720 /* Set all link information. */
721 cnt = router_lsa_link_set (s, area);
722
723 /* Set # of links here. */
724 stream_putw_at (s, putp, cnt);
725}
paul88d6cf32005-10-29 12:50:09 +0000726
727static int
728ospf_stub_router_timer (struct thread *t)
729{
730 struct ospf_area *area = THREAD_ARG (t);
731
732 area->t_stub_router = NULL;
733
734 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
735
736 /* clear stub route state and generate router-lsa refresh, don't
737 * clobber an administratively set stub-router state though.
738 */
739 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
740 return 0;
741
742 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
743
744 ospf_router_lsa_timer_add (area);
745
746 return 0;
747}
paul718e3742002-12-13 20:15:29 +0000748
paul88d6cf32005-10-29 12:50:09 +0000749inline static void
750ospf_stub_router_check (struct ospf_area *area)
751{
752 /* area must either be administratively configured to be stub
753 * or startup-time stub-router must be configured and we must in a pre-stub
754 * state.
755 */
756 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
757 {
758 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
759 return;
760 }
761
762 /* not admin-stubbed, check whether startup stubbing is configured and
763 * whether it's not been done yet
764 */
765 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
766 return;
767
768 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
769 {
770 /* stub-router is hence done forever for this area, even if someone
771 * tries configure it (take effect next restart).
772 */
773 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
774 return;
775 }
776
777 /* startup stub-router configured and not yet done */
778 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
779
780 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
781 area->ospf->stub_router_startup_time);
782}
783
paul718e3742002-12-13 20:15:29 +0000784/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000785static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000786ospf_router_lsa_new (struct ospf_area *area)
787{
paul68980082003-03-25 05:07:42 +0000788 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000789 struct stream *s;
790 struct lsa_header *lsah;
791 struct ospf_lsa *new;
792 int length;
793
794 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000795 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000796
paul88d6cf32005-10-29 12:50:09 +0000797 /* check whether stub-router is desired, and if this is the first
798 * router LSA.
799 */
800 ospf_stub_router_check (area);
801
paul718e3742002-12-13 20:15:29 +0000802 /* Create a stream for LSA. */
803 s = stream_new (OSPF_MAX_LSA_SIZE);
paul718e3742002-12-13 20:15:29 +0000804 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000805 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000806 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000807
808 /* Set router-LSA body fields. */
809 ospf_router_lsa_body_set (s, area);
810
811 /* Set length. */
812 length = stream_get_endp (s);
paul779adb02006-01-18 15:07:38 +0000813 lsah = (struct lsa_header *) STREAM_DATA (s);
paul718e3742002-12-13 20:15:29 +0000814 lsah->length = htons (length);
815
816 /* Now, create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000817 if ( (new = ospf_lsa_new ()) == NULL)
818 {
819 zlog_err ("%s: Unable to create new lsa", __func__);
820 return NULL;
821 }
822
paul718e3742002-12-13 20:15:29 +0000823 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +0000824 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +0000825
826 /* Copy LSA data to store, discard stream. */
827 new->data = ospf_lsa_data_new (length);
828 memcpy (new->data, lsah, length);
829 stream_free (s);
830
831 return new;
832}
833
834/* Originate Router-LSA. */
paul88d6cf32005-10-29 12:50:09 +0000835static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000836ospf_router_lsa_originate (struct ospf_area *area)
837{
838 struct ospf_lsa *new;
paul88d6cf32005-10-29 12:50:09 +0000839
paul718e3742002-12-13 20:15:29 +0000840 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000841 if ( (new = ospf_router_lsa_new (area)) == NULL)
842 {
843 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
844 return NULL;
845 }
paul718e3742002-12-13 20:15:29 +0000846
847 /* Sanity check. */
848 if (new->data->adv_router.s_addr == 0)
849 {
850 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000851 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000852 ospf_lsa_discard (new);
853 return NULL;
854 }
855
856 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000857 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000858
859 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000860 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000861
862 /* Flooding new LSA through area. */
863 ospf_flood_through_area (area, NULL, new);
864
865 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
866 {
ajse588f212004-12-08 18:12:06 +0000867 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
paul718e3742002-12-13 20:15:29 +0000868 new->data->type, inet_ntoa (new->data->id), new);
869 ospf_lsa_header_dump (new->data);
870 }
871
872 return new;
873}
874
875/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000876static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000877ospf_router_lsa_refresh (struct ospf_lsa *lsa)
878{
879 struct ospf_area *area = lsa->area;
880 struct ospf_lsa *new;
881
882 /* Sanity check. */
883 assert (lsa->data);
884
885 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000886 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000887
888 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000889 if ( (new = ospf_router_lsa_new (area)) == NULL)
890 {
891 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
892 return NULL;
893 }
894
paul718e3742002-12-13 20:15:29 +0000895 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
896
paul68980082003-03-25 05:07:42 +0000897 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000898
899 /* Flood LSA through area. */
900 ospf_flood_through_area (area, NULL, new);
901
902 /* Debug logging. */
903 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
904 {
ajse588f212004-12-08 18:12:06 +0000905 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000906 new->data->type, inet_ntoa (new->data->id));
907 ospf_lsa_header_dump (new->data);
908 }
909
910 return NULL;
911}
912
paul4dadc292005-05-06 21:37:42 +0000913static int
paul718e3742002-12-13 20:15:29 +0000914ospf_router_lsa_timer (struct thread *t)
915{
916 struct ospf_area *area;
917
918 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000919 zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
paul718e3742002-12-13 20:15:29 +0000920
921 area = THREAD_ARG (t);
922 area->t_router_lsa_self = NULL;
923
924 /* Now refresh router-LSA. */
925 if (area->router_lsa_self)
926 ospf_router_lsa_refresh (area->router_lsa_self);
927 /* Newly originate router-LSA. */
928 else
929 ospf_router_lsa_originate (area);
930
931 return 0;
932}
933
934void
935ospf_router_lsa_timer_add (struct ospf_area *area)
936{
937 /* Keep area's self-originated router-LSA. */
938 struct ospf_lsa *lsa = area->router_lsa_self;
939
940 /* Cancel previously scheduled router-LSA timer. */
941 if (area->t_router_lsa_self)
942 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000943 zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
paul718e3742002-12-13 20:15:29 +0000944
945 OSPF_TIMER_OFF (area->t_router_lsa_self);
946
947 /* If router-LSA is originated previously, check the interval time. */
948 if (lsa)
949 {
950 int delay;
951 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
952 {
953 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
954 ospf_router_lsa_timer, delay);
955 return;
956 }
957 }
958
959 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000960 zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
paul718e3742002-12-13 20:15:29 +0000961
962 /* Immediately refresh router-LSA. */
963 OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
964}
965
966int
paul68980082003-03-25 05:07:42 +0000967ospf_router_lsa_update_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000968{
paul68980082003-03-25 05:07:42 +0000969 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +0000970 struct listnode *node, *nnode;
971 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +0000972
973 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000974 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +0000975
paul68980082003-03-25 05:07:42 +0000976 ospf->t_router_lsa_update = NULL;
paul718e3742002-12-13 20:15:29 +0000977
paul1eb8ef22005-04-07 07:30:20 +0000978 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000979 {
paul718e3742002-12-13 20:15:29 +0000980 struct ospf_lsa *lsa = area->router_lsa_self;
981 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +0000982 const char *area_str;
paul718e3742002-12-13 20:15:29 +0000983
984 /* Keep Area ID string. */
985 area_str = AREA_NAME (area);
986
987 /* If LSA not exist in this Area, originate new. */
988 if (lsa == NULL)
989 {
990 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000991 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +0000992
993 ospf_router_lsa_originate (area);
994 }
995 /* If router-ID is changed, Link ID must change.
996 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +0000997 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000998 {
999 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001000 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +00001001 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
1002 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001003 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00001004 area->router_lsa_self = NULL;
1005
1006 /* Refresh router-LSA, (not install) and flood through area. */
1007 ospf_router_lsa_timer_add (area);
1008 }
1009 else
1010 {
1011 rl = (struct router_lsa *) lsa->data;
1012 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +00001013 if (rl->flags != ospf->flags)
paul718e3742002-12-13 20:15:29 +00001014 ospf_router_lsa_timer_add (area);
1015 }
1016 }
1017
1018 return 0;
1019}
1020
1021
1022/* network-LSA related functions. */
1023/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001024static void
paul718e3742002-12-13 20:15:29 +00001025ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1026{
1027 struct in_addr mask;
1028 struct route_node *rn;
1029 struct ospf_neighbor *nbr;
1030
1031 masklen2ip (oi->address->prefixlen, &mask);
1032 stream_put_ipv4 (s, mask.s_addr);
1033
1034 /* The network-LSA lists those routers that are fully adjacent to
1035 the Designated Router; each fully adjacent router is identified by
1036 its OSPF Router ID. The Designated Router includes itself in this
1037 list. RFC2328, Section 12.4.2 */
1038
1039 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1040 if ((nbr = rn->info) != NULL)
1041 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1042 stream_put_ipv4 (s, nbr->router_id.s_addr);
1043}
1044
paul4dadc292005-05-06 21:37:42 +00001045static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001046ospf_network_lsa_new (struct ospf_interface *oi)
1047{
1048 struct stream *s;
1049 struct ospf_lsa *new;
1050 struct lsa_header *lsah;
1051 int length;
1052
1053 /* If there are no neighbours on this network (the net is stub),
1054 the router does not originate network-LSA (see RFC 12.4.2) */
1055 if (oi->full_nbrs == 0)
1056 return NULL;
1057
1058 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001059 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001060
1061 /* Create new stream for LSA. */
1062 s = stream_new (OSPF_MAX_LSA_SIZE);
1063 lsah = (struct lsa_header *) STREAM_DATA (s);
1064
1065 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001066 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001067
1068 /* Set network-LSA body fields. */
1069 ospf_network_lsa_body_set (s, oi);
1070
1071 /* Set length. */
1072 length = stream_get_endp (s);
1073 lsah->length = htons (length);
1074
1075 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001076 if ( (new = ospf_lsa_new ()) == NULL)
1077 {
1078 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1079 return NULL;
1080 }
1081
paul718e3742002-12-13 20:15:29 +00001082 new->area = oi->area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001083 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001084
1085 /* Copy LSA to store. */
1086 new->data = ospf_lsa_data_new (length);
1087 memcpy (new->data, lsah, length);
1088 stream_free (s);
1089
1090 return new;
1091}
1092
1093/* Originate network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001094static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001095ospf_network_lsa_originate (struct ospf_interface *oi)
1096{
1097 struct ospf_lsa *new;
1098
1099 /* Create new network-LSA instance. */
1100 new = ospf_network_lsa_new (oi);
1101 if (new == NULL)
1102 return NULL;
1103
1104 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001105 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001106
1107 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001108 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001109
1110 /* Flooding new LSA through area. */
1111 ospf_flood_through_area (oi->area, NULL, new);
1112
1113 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1114 {
ajse588f212004-12-08 18:12:06 +00001115 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001116 new->data->type, inet_ntoa (new->data->id), new);
1117 ospf_lsa_header_dump (new->data);
1118 }
1119
1120 return new;
1121}
1122
1123int
1124ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1125{
1126 struct ospf_area *area = lsa->area;
1127 struct ospf_lsa *new;
1128
1129 assert (lsa->data);
1130
1131 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001132 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001133
1134 /* Create new network-LSA instance. */
1135 new = ospf_network_lsa_new (oi);
1136 if (new == NULL)
1137 return -1;
1138 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1139
paul68980082003-03-25 05:07:42 +00001140 ospf_lsa_install (area->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001141
1142 /* Flood LSA through aera. */
1143 ospf_flood_through_area (area, NULL, new);
1144
1145 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1146 {
ajse588f212004-12-08 18:12:06 +00001147 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001148 new->data->type, inet_ntoa (new->data->id));
1149 ospf_lsa_header_dump (new->data);
1150 }
1151
1152 return 0;
1153}
1154
paul4dadc292005-05-06 21:37:42 +00001155static int
paul718e3742002-12-13 20:15:29 +00001156ospf_network_lsa_refresh_timer (struct thread *t)
1157{
1158 struct ospf_interface *oi;
1159
1160 oi = THREAD_ARG (t);
1161 oi->t_network_lsa_self = NULL;
1162
1163 if (oi->network_lsa_self)
1164 /* Now refresh network-LSA. */
1165 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1166 else
1167 /* Newly create network-LSA. */
1168 ospf_network_lsa_originate (oi);
1169
1170 return 0;
1171}
1172
1173void
1174ospf_network_lsa_timer_add (struct ospf_interface *oi)
1175{
1176 /* Keep interface's self-originated network-LSA. */
1177 struct ospf_lsa *lsa = oi->network_lsa_self;
1178
1179 /* Cancel previously schedules network-LSA timer. */
1180 if (oi->t_network_lsa_self)
1181 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001182 zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
paul718e3742002-12-13 20:15:29 +00001183 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1184
1185 /* If network-LSA is originated previously, check the interval time. */
1186 if (lsa)
1187 {
1188 int delay;
1189 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1190 {
1191 oi->t_network_lsa_self =
1192 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1193 oi, delay);
1194 return;
1195 }
1196 }
1197
1198 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001199 zlog_debug ("Scheduling network-LSA origination right away");
paul718e3742002-12-13 20:15:29 +00001200
1201 /* Immediately refresh network-LSA. */
1202 oi->t_network_lsa_self =
1203 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1204}
1205
1206
paul4dadc292005-05-06 21:37:42 +00001207static void
paul718e3742002-12-13 20:15:29 +00001208stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1209{
1210 u_int32_t metric;
1211 char *mp;
1212
1213 /* Put 0 metric. TOS metric is not supported. */
1214 metric = htonl (metric_value);
1215 mp = (char *) &metric;
1216 mp++;
1217 stream_put (s, mp, 3);
1218}
1219
1220/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001221static void
paul718e3742002-12-13 20:15:29 +00001222ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1223 u_int32_t metric)
1224{
1225 struct in_addr mask;
1226
1227 masklen2ip (p->prefixlen, &mask);
1228
1229 /* Put Network Mask. */
1230 stream_put_ipv4 (s, mask.s_addr);
1231
1232 /* Set # TOS. */
1233 stream_putc (s, (u_char) 0);
1234
1235 /* Set metric. */
1236 stream_put_ospf_metric (s, metric);
1237}
1238
paul4dadc292005-05-06 21:37:42 +00001239static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001240ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1241 u_int32_t metric, struct in_addr id)
1242{
1243 struct stream *s;
1244 struct ospf_lsa *new;
1245 struct lsa_header *lsah;
1246 int length;
1247
paulc24d6022005-11-20 14:54:12 +00001248 if (id.s_addr == 0xffffffff)
1249 {
1250 /* Maybe Link State ID not available. */
1251 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1252 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1253 OSPF_SUMMARY_LSA);
1254 return NULL;
1255 }
1256
paul718e3742002-12-13 20:15:29 +00001257 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001258 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001259
1260 /* Create new stream for LSA. */
1261 s = stream_new (OSPF_MAX_LSA_SIZE);
1262 lsah = (struct lsa_header *) STREAM_DATA (s);
1263
paul68980082003-03-25 05:07:42 +00001264 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1265 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001266
1267 /* Set summary-LSA body fields. */
1268 ospf_summary_lsa_body_set (s, p, metric);
1269
1270 /* Set length. */
1271 length = stream_get_endp (s);
1272 lsah->length = htons (length);
1273
1274 /* Create OSPF LSA instance. */
1275 new = ospf_lsa_new ();
1276 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001277 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001278
1279 /* Copy LSA to store. */
1280 new->data = ospf_lsa_data_new (length);
1281 memcpy (new->data, lsah, length);
1282 stream_free (s);
1283
1284 return new;
1285}
1286
1287/* Originate Summary-LSA. */
1288struct ospf_lsa *
1289ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1290 struct ospf_area *area)
1291{
1292 struct ospf_lsa *new;
1293 struct in_addr id;
1294
paul68980082003-03-25 05:07:42 +00001295 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001296
paulc24d6022005-11-20 14:54:12 +00001297 if (id.s_addr == 0xffffffff)
1298 {
1299 /* Maybe Link State ID not available. */
1300 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1301 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1302 OSPF_SUMMARY_LSA);
1303 return NULL;
1304 }
1305
paul718e3742002-12-13 20:15:29 +00001306 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001307 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1308 return NULL;
paul718e3742002-12-13 20:15:29 +00001309
1310 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001311 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001312
1313 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001314 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001315
1316 /* Flooding new LSA through area. */
1317 ospf_flood_through_area (area, NULL, new);
1318
1319 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1320 {
ajse588f212004-12-08 18:12:06 +00001321 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001322 new->data->type, inet_ntoa (new->data->id), new);
1323 ospf_lsa_header_dump (new->data);
1324 }
1325
1326 return new;
1327}
1328
1329struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001330ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001331{
1332 struct ospf_lsa *new;
1333 struct summary_lsa *sl;
1334 struct prefix p;
1335
1336 /* Sanity check. */
1337 assert (lsa->data);
1338
1339 sl = (struct summary_lsa *)lsa->data;
1340 p.prefixlen = ip_masklen (sl->mask);
1341 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1342 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001343
1344 if (!new)
1345 return NULL;
1346
paul718e3742002-12-13 20:15:29 +00001347 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001348
paul68980082003-03-25 05:07:42 +00001349 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001350
1351 /* Flood LSA through AS. */
1352 ospf_flood_through_area (new->area, NULL, new);
1353
1354 /* Debug logging. */
1355 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1356 {
ajse588f212004-12-08 18:12:06 +00001357 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001358 new->data->type, inet_ntoa (new->data->id));
1359 ospf_lsa_header_dump (new->data);
1360 }
1361
1362 return new;
1363}
1364
1365
1366/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001367static void
paul718e3742002-12-13 20:15:29 +00001368ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1369 u_int32_t metric)
1370{
1371 struct in_addr mask;
1372
1373 masklen2ip (p->prefixlen, &mask);
1374
1375 /* Put Network Mask. */
1376 stream_put_ipv4 (s, mask.s_addr);
1377
1378 /* Set # TOS. */
1379 stream_putc (s, (u_char) 0);
1380
1381 /* Set metric. */
1382 stream_put_ospf_metric (s, metric);
1383}
1384
paul4dadc292005-05-06 21:37:42 +00001385static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001386ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1387 u_int32_t metric, struct in_addr id)
1388{
1389 struct stream *s;
1390 struct ospf_lsa *new;
1391 struct lsa_header *lsah;
1392 int length;
1393
paulc24d6022005-11-20 14:54:12 +00001394 if (id.s_addr == 0xffffffff)
1395 {
1396 /* Maybe Link State ID not available. */
1397 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1398 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1399 OSPF_ASBR_SUMMARY_LSA);
1400 return NULL;
1401 }
1402
paul718e3742002-12-13 20:15:29 +00001403 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001404 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001405
1406 /* Create new stream for LSA. */
1407 s = stream_new (OSPF_MAX_LSA_SIZE);
1408 lsah = (struct lsa_header *) STREAM_DATA (s);
1409
paul68980082003-03-25 05:07:42 +00001410 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1411 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001412
1413 /* Set summary-LSA body fields. */
1414 ospf_summary_asbr_lsa_body_set (s, p, metric);
1415
1416 /* Set length. */
1417 length = stream_get_endp (s);
1418 lsah->length = htons (length);
1419
1420 /* Create OSPF LSA instance. */
1421 new = ospf_lsa_new ();
1422 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001423 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001424
1425 /* Copy LSA to store. */
1426 new->data = ospf_lsa_data_new (length);
1427 memcpy (new->data, lsah, length);
1428 stream_free (s);
1429
1430 return new;
1431}
1432
1433/* Originate summary-ASBR-LSA. */
1434struct ospf_lsa *
1435ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1436 struct ospf_area *area)
1437{
1438 struct ospf_lsa *new;
1439 struct in_addr id;
1440
paul68980082003-03-25 05:07:42 +00001441 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001442
paulc24d6022005-11-20 14:54:12 +00001443 if (id.s_addr == 0xffffffff)
1444 {
1445 /* Maybe Link State ID not available. */
1446 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1447 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1448 OSPF_ASBR_SUMMARY_LSA);
1449 return NULL;
1450 }
1451
paul718e3742002-12-13 20:15:29 +00001452 /* Create new summary-LSA instance. */
1453 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001454 if (!new)
1455 return NULL;
paul718e3742002-12-13 20:15:29 +00001456
1457 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001458 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001459
1460 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001461 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001462
1463 /* Flooding new LSA through area. */
1464 ospf_flood_through_area (area, NULL, new);
1465
1466 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1467 {
ajse588f212004-12-08 18:12:06 +00001468 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001469 new->data->type, inet_ntoa (new->data->id), new);
1470 ospf_lsa_header_dump (new->data);
1471 }
1472
1473 return new;
1474}
1475
1476struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001477ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001478{
1479 struct ospf_lsa *new;
1480 struct summary_lsa *sl;
1481 struct prefix p;
1482
1483 /* Sanity check. */
1484 assert (lsa->data);
1485
1486 sl = (struct summary_lsa *)lsa->data;
1487 p.prefixlen = ip_masklen (sl->mask);
1488 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1489 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001490 if (!new)
1491 return NULL;
paul718e3742002-12-13 20:15:29 +00001492
1493 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001494
paul68980082003-03-25 05:07:42 +00001495 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001496
1497 /* Flood LSA through area. */
1498 ospf_flood_through_area (new->area, NULL, new);
1499
1500 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1501 {
ajse588f212004-12-08 18:12:06 +00001502 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001503 new->data->type, inet_ntoa (new->data->id));
1504 ospf_lsa_header_dump (new->data);
1505 }
1506
1507 return new;
1508}
1509
1510/* AS-external-LSA related functions. */
1511
1512/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1513 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001514static struct in_addr
paul68980082003-03-25 05:07:42 +00001515ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001516{
1517 struct in_addr fwd;
1518 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001519 struct listnode *node;
1520 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001521
1522 fwd.s_addr = 0;
1523
1524 if (!nexthop.s_addr)
1525 return fwd;
1526
1527 /* Check whether nexthop is covered by OSPF network. */
1528 nh.family = AF_INET;
1529 nh.u.prefix4 = nexthop;
1530 nh.prefixlen = IPV4_MAX_BITLEN;
Paul Jakma4ca15d42009-08-03 15:16:41 +01001531
1532 /* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be
1533 * better to make use of the per-ifp table of ois.
1534 */
paul1eb8ef22005-04-07 07:30:20 +00001535 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1536 if (if_is_operative (oi->ifp))
1537 if (oi->address->family == AF_INET)
1538 if (prefix_match (oi->address, &nh))
1539 return nexthop;
paul718e3742002-12-13 20:15:29 +00001540
1541 return fwd;
1542}
1543
paul718e3742002-12-13 20:15:29 +00001544/* NSSA-external-LSA related functions. */
1545
1546/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001547
paul718e3742002-12-13 20:15:29 +00001548struct in_addr
1549ospf_get_ip_from_ifp (struct ospf_interface *oi)
1550{
1551 struct in_addr fwd;
1552
1553 fwd.s_addr = 0;
1554
paul2e3b2e42002-12-13 21:03:13 +00001555 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001556 return oi->address->u.prefix4;
1557
1558 return fwd;
1559}
1560
1561/* Get 1st IP connection for Forward Addr */
1562struct in_addr
paulf2c80652002-12-13 21:44:27 +00001563ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001564{
1565 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001566 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001567 struct listnode *node;
1568 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001569
1570 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001571 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001572
paul1eb8ef22005-04-07 07:30:20 +00001573 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001574 {
paul2e3b2e42002-12-13 21:03:13 +00001575 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001576 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001577 if (oi->address && oi->address->family == AF_INET)
1578 {
1579 if (best_default.s_addr == 0)
1580 best_default = oi->address->u.prefix4;
1581 if (oi->area == area)
1582 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001583 }
paul718e3742002-12-13 20:15:29 +00001584 }
paulf2c80652002-12-13 21:44:27 +00001585 if (best_default.s_addr != 0)
1586 return best_default;
paul718e3742002-12-13 20:15:29 +00001587
paul68980082003-03-25 05:07:42 +00001588 if (best_default.s_addr != 0)
1589 return best_default;
1590
paul718e3742002-12-13 20:15:29 +00001591 return fwd;
1592}
hassobeebba72004-06-20 21:00:27 +00001593
paul718e3742002-12-13 20:15:29 +00001594#define DEFAULT_DEFAULT_METRIC 20
1595#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1596#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1597
1598#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1599
1600int
paul68980082003-03-25 05:07:42 +00001601metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001602{
paul68980082003-03-25 05:07:42 +00001603 return (ospf->dmetric[src].type < 0 ?
1604 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001605}
1606
1607int
paul68980082003-03-25 05:07:42 +00001608metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001609{
paul68980082003-03-25 05:07:42 +00001610 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001611 {
1612 if (src == DEFAULT_ROUTE)
1613 {
paul68980082003-03-25 05:07:42 +00001614 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001615 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1616 else
1617 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1618 }
paul68980082003-03-25 05:07:42 +00001619 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001620 return DEFAULT_DEFAULT_METRIC;
1621 else
paul68980082003-03-25 05:07:42 +00001622 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001623 }
1624
paul68980082003-03-25 05:07:42 +00001625 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001626}
1627
1628/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001629static void
paul68980082003-03-25 05:07:42 +00001630ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1631 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001632{
1633 struct prefix_ipv4 *p = &ei->p;
1634 struct in_addr mask, fwd_addr;
1635 u_int32_t mvalue;
1636 int mtype;
1637 int type;
1638
1639 /* Put Network Mask. */
1640 masklen2ip (p->prefixlen, &mask);
1641 stream_put_ipv4 (s, mask.s_addr);
1642
1643 /* If prefix is default, specify DEFAULT_ROUTE. */
1644 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1645
1646 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001647 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001648
1649 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001650 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001651
1652 /* Put type of external metric. */
1653 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1654
1655 /* Put 0 metric. TOS metric is not supported. */
1656 stream_put_ospf_metric (s, mvalue);
1657
1658 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001659 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001660
1661 /* Put forwarding address. */
1662 stream_put_ipv4 (s, fwd_addr.s_addr);
1663
1664 /* Put route tag -- This value should be introduced from configuration. */
1665 stream_putl (s, 0);
1666}
1667
1668/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001669static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001670ospf_external_lsa_new (struct ospf *ospf,
1671 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001672{
1673 struct stream *s;
1674 struct lsa_header *lsah;
1675 struct ospf_lsa *new;
1676 struct in_addr id;
1677 int length;
1678
1679 if (ei == NULL)
1680 {
1681 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001682 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
paul718e3742002-12-13 20:15:29 +00001683 return NULL;
1684 }
1685
1686 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001687 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001688
1689 /* If old Link State ID is specified, refresh LSA with same ID. */
1690 if (old_id)
1691 id = *old_id;
1692 /* Get Link State with unique ID. */
1693 else
1694 {
paul68980082003-03-25 05:07:42 +00001695 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001696 if (id.s_addr == 0xffffffff)
1697 {
1698 /* Maybe Link State ID not available. */
1699 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001700 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001701 return NULL;
1702 }
1703 }
1704
1705 /* Create new stream for LSA. */
1706 s = stream_new (OSPF_MAX_LSA_SIZE);
1707 lsah = (struct lsa_header *) STREAM_DATA (s);
1708
1709 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001710 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1711 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001712
1713 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001714 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001715
1716 /* Set length. */
1717 length = stream_get_endp (s);
1718 lsah->length = htons (length);
1719
1720 /* Now, create OSPF LSA instance. */
1721 new = ospf_lsa_new ();
1722 new->area = NULL;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001723 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001724
1725 /* Copy LSA data to store, discard stream. */
1726 new->data = ospf_lsa_data_new (length);
1727 memcpy (new->data, lsah, length);
1728 stream_free (s);
1729
1730 return new;
1731}
1732
paul718e3742002-12-13 20:15:29 +00001733/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001734static void
paul68980082003-03-25 05:07:42 +00001735ospf_install_flood_nssa (struct ospf *ospf,
1736 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001737{
pauld4a53d52003-07-12 21:30:57 +00001738 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001739 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001740 struct ospf_area *area;
1741 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001742
pauld4a53d52003-07-12 21:30:57 +00001743 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1744 * which originated from an NSSA area. In which case it should not be
1745 * flooded back to NSSA areas.
1746 */
1747 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1748 return;
1749
paul718e3742002-12-13 20:15:29 +00001750 /* NSSA Originate or Refresh (If anyNSSA)
1751
1752 LSA is self-originated. And just installed as Type-5.
1753 Additionally, install as Type-7 LSDB for every attached NSSA.
1754
1755 P-Bit controls which ABR performs translation to outside world; If
1756 we are an ABR....do not set the P-bit, because we send the Type-5,
1757 not as the ABR Translator, but as the ASBR owner within the AS!
1758
1759 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1760 elected ABR Translator will see the P-bit, Translate, and re-flood.
1761
1762 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1763 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1764
paul1eb8ef22005-04-07 07:30:20 +00001765 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001766 {
hasso0c14ad82003-07-03 08:36:02 +00001767 /* Don't install Type-7 LSA's into nonNSSA area */
1768 if (area->external_routing != OSPF_AREA_NSSA)
1769 continue;
paul718e3742002-12-13 20:15:29 +00001770
paul68980082003-03-25 05:07:42 +00001771 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001772 new = ospf_lsa_dup (lsa);
1773 new->area = area;
1774 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001775
paul68980082003-03-25 05:07:42 +00001776 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001777 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001778 {
pauld4a53d52003-07-12 21:30:57 +00001779 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001780
1781 /* set non-zero FWD ADDR
1782
1783 draft-ietf-ospf-nssa-update-09.txt
1784
1785 if the network between the NSSA AS boundary router and the
1786 adjacent AS is advertised into OSPF as an internal OSPF route,
1787 the forwarding address should be the next op address as is cu
1788 currently done with type-5 LSAs. If the intervening network is
1789 not adversited into OSPF as an internal OSPF route and the
1790 type-7 LSA's P-bit is set a forwarding address should be
1791 selected from one of the router's active OSPF inteface addresses
1792 which belong to the NSSA. If no such addresses exist, then
1793 no type-7 LSA's with the P-bit set should originate from this
1794 router. */
1795
pauld4a53d52003-07-12 21:30:57 +00001796 /* kevinm: not updating lsa anymore, just new */
1797 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001798
1799 if (extlsa->e[0].fwd_addr.s_addr == 0)
1800 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001801
pauld7480322003-05-16 17:31:51 +00001802 if (extlsa->e[0].fwd_addr.s_addr == 0)
1803 {
1804 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001805 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001806 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001807 return;
1808 }
paulf2c80652002-12-13 21:44:27 +00001809 }
paul718e3742002-12-13 20:15:29 +00001810
paul68980082003-03-25 05:07:42 +00001811 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001812 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001813
1814 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001815 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001816 }
paul718e3742002-12-13 20:15:29 +00001817}
pauld4a53d52003-07-12 21:30:57 +00001818
paul4dadc292005-05-06 21:37:42 +00001819static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001820ospf_lsa_translated_nssa_new (struct ospf *ospf,
1821 struct ospf_lsa *type7)
1822{
1823
1824 struct ospf_lsa *new;
1825 struct as_external_lsa *ext, *extnew;
1826 struct external_info ei;
1827
1828 ext = (struct as_external_lsa *)(type7->data);
1829
1830 /* need external_info struct, fill in bare minimum */
1831 ei.p.family = AF_INET;
1832 ei.p.prefix = type7->data->id;
1833 ei.p.prefixlen = ip_masklen (ext->mask);
1834 ei.type = ZEBRA_ROUTE_OSPF;
1835 ei.nexthop = ext->header.adv_router;
1836 ei.route_map_set.metric = -1;
1837 ei.route_map_set.metric_type = -1;
1838 ei.tag = 0;
1839
1840 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1841 {
1842 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001843 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001844 "Translated Type-5 for %s",
1845 inet_ntoa (ei.p.prefix));
1846 return NULL;
1847 }
1848
1849 extnew = (struct as_external_lsa *)(new->data);
1850
1851 /* copy over Type-7 data to new */
1852 extnew->e[0].tos = ext->e[0].tos;
1853 extnew->e[0].route_tag = ext->e[0].route_tag;
1854 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1855 new->data->ls_seqnum = type7->data->ls_seqnum;
1856
1857 /* add translated flag, checksum and lock new lsa */
1858 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
pauld4a53d52003-07-12 21:30:57 +00001859 new = ospf_lsa_lock (new);
1860
1861 return new;
1862}
1863
pauld4a53d52003-07-12 21:30:57 +00001864/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1865struct ospf_lsa *
1866ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1867{
1868 struct ospf_lsa *new;
1869 struct as_external_lsa *extnew;
1870
1871 /* we cant use ospf_external_lsa_originate() as we need to set
1872 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1873 */
1874
1875 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1876 {
1877 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001878 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001879 "Type-7, Id %s, to Type-5",
1880 inet_ntoa (type7->data->id));
1881 return NULL;
1882 }
1883
1884 extnew = (struct as_external_lsa *)new;
1885
1886 if (IS_DEBUG_OSPF_NSSA)
1887 {
ajse588f212004-12-08 18:12:06 +00001888 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001889 "translated Type 7, installed:");
1890 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001891 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1892 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001893 }
1894
1895 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1896 {
1897 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001898 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001899 "Could not install LSA "
1900 "id %s", inet_ntoa (type7->data->id));
1901 return NULL;
1902 }
1903
1904 ospf->lsa_originate_count++;
1905 ospf_flood_through_as (ospf, NULL, new);
1906
1907 return new;
1908}
1909
1910/* Refresh Translated from NSSA AS-external-LSA. */
1911struct ospf_lsa *
1912ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1913 struct ospf_lsa *type5)
1914{
1915 struct ospf_lsa *new = NULL;
1916
1917 /* Sanity checks. */
1918 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00001919 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00001920 return NULL;
pauld4a53d52003-07-12 21:30:57 +00001921 if (type7)
1922 assert (type7->data);
1923 if (type5)
1924 assert (type5->data);
1925 assert (ospf->anyNSSA);
1926
1927 /* get required data according to what has been given */
1928 if (type7 && type5 == NULL)
1929 {
1930 /* find the translated Type-5 for this Type-7 */
1931 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1932 struct prefix_ipv4 p =
1933 {
1934 .prefix = type7->data->id,
1935 .prefixlen = ip_masklen (ext->mask),
1936 .family = AF_INET,
1937 };
1938
1939 type5 = ospf_external_info_find_lsa (ospf, &p);
1940 }
1941 else if (type5 && type7 == NULL)
1942 {
1943 /* find the type-7 from which supplied type-5 was translated,
1944 * ie find first type-7 with same LSA Id.
1945 */
paul1eb8ef22005-04-07 07:30:20 +00001946 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00001947 struct route_node *rn;
1948 struct ospf_lsa *lsa;
1949 struct ospf_area *area;
1950
paul1eb8ef22005-04-07 07:30:20 +00001951 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00001952 {
1953 if (area->external_routing != OSPF_AREA_NSSA
1954 && !type7)
1955 continue;
1956
1957 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
1958 {
1959 if (lsa->data->id.s_addr == type5->data->id.s_addr)
1960 {
1961 type7 = lsa;
1962 break;
1963 }
1964 }
1965 }
1966 }
1967
1968 /* do we have type7? */
1969 if (!type7)
1970 {
1971 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001972 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00001973 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00001974 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00001975 return NULL;
1976 }
1977
1978 /* do we have valid translated type5? */
1979 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
1980 {
1981 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001982 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00001983 "found for Type-7 with Id %s",
1984 inet_ntoa (type7->data->id));
1985 return NULL;
1986 }
1987
1988 /* Delete LSA from neighbor retransmit-list. */
1989 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
1990
1991 /* create new translated LSA */
1992 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1993 {
1994 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001995 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001996 "Type-7 for %s to Type-5",
1997 inet_ntoa (type7->data->id));
1998 return NULL;
1999 }
2000
2001 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
2002 {
2003 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002004 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00002005 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00002006 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00002007 return NULL;
2008 }
2009
2010 /* Flood LSA through area. */
2011 ospf_flood_through_as (ospf, NULL, new);
2012
2013 return new;
2014}
paul718e3742002-12-13 20:15:29 +00002015
2016int
2017is_prefix_default (struct prefix_ipv4 *p)
2018{
2019 struct prefix_ipv4 q;
2020
2021 q.family = AF_INET;
2022 q.prefix.s_addr = 0;
2023 q.prefixlen = 0;
2024
2025 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
2026}
2027
2028/* Originate an AS-external-LSA, install and flood. */
2029struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002030ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00002031{
2032 struct ospf_lsa *new;
2033
2034 /* Added for NSSA project....
2035
2036 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2037 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2038 every area. The Type-7's are flooded to every IR and every ABR; We
2039 install the Type-5 LSDB so that the normal "refresh" code operates
2040 as usual, and flag them as not used during ASE calculations. The
2041 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2042 Address of non-zero.
2043
2044 If an ABR is the elected NSSA translator, following SPF and during
2045 the ABR task it will translate all the scanned Type-7's, with P-bit
2046 ON and not-self generated, and translate to Type-5's throughout the
2047 non-NSSA/STUB AS.
2048
2049 A difference in operation depends whether this ASBR is an ABR
2050 or not. If not an ABR, the P-bit is ON, to indicate that any
2051 elected NSSA-ABR can perform its translation.
2052
2053 If an ABR, the P-bit is OFF; No ABR will perform translation and
2054 this ASBR will flood the Type-5 LSA as usual.
2055
2056 For the case where this ASBR is not an ABR, the ASE calculations
2057 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2058 demonstrate to the user that there are LSA's that belong to any
2059 attached NSSA.
2060
2061 Finally, it just so happens that when the ABR is translating every
2062 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2063 approved Type-5 (translated from Type-7); at the end of translation
2064 if any Translated Type-5's remain unapproved, then they must be
2065 flushed from the AS.
2066
2067 */
2068
2069 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002070 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002071 return NULL;
2072
2073 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002074 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002075 {
2076 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002077 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002078 inet_ntoa (ei->p.prefix));
2079 return NULL;
2080 }
2081
2082 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002083 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002084
2085 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002086 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002087
2088 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002089 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002090
paul718e3742002-12-13 20:15:29 +00002091 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002092 if (ospf->anyNSSA &&
2093 /* stay away from translated LSAs! */
2094 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002095 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002096
2097 /* Debug logging. */
2098 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2099 {
ajse588f212004-12-08 18:12:06 +00002100 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002101 new->data->type, inet_ntoa (new->data->id), new);
2102 ospf_lsa_header_dump (new->data);
2103 }
2104
2105 return new;
2106}
2107
2108/* Originate AS-external-LSA from external info with initial flag. */
2109int
paul68980082003-03-25 05:07:42 +00002110ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002111{
paul68980082003-03-25 05:07:42 +00002112 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002113 struct route_node *rn;
2114 struct external_info *ei;
2115 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002116 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002117
paul68980082003-03-25 05:07:42 +00002118 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002119
2120 /* Originate As-external-LSA from all type of distribute source. */
2121 if ((rt = EXTERNAL_INFO (type)))
2122 for (rn = route_top (rt); rn; rn = route_next (rn))
2123 if ((ei = rn->info) != NULL)
2124 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002125 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002126 zlog_warn ("LSA: AS-external-LSA was not originated.");
2127
2128 return 0;
2129}
2130
paul4dadc292005-05-06 21:37:42 +00002131static struct external_info *
paul020709f2003-04-04 02:44:16 +00002132ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002133{
2134 int type;
2135 struct route_node *rn;
2136 struct prefix_ipv4 p;
2137
2138 p.family = AF_INET;
2139 p.prefix.s_addr = 0;
2140 p.prefixlen = 0;
2141
2142 /* First, lookup redistributed default route. */
2143 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2144 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2145 {
2146 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2147 if (rn != NULL)
2148 {
2149 route_unlock_node (rn);
2150 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002151 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002152 return rn->info;
2153 }
2154 }
2155
2156 return NULL;
2157}
2158
2159int
paul68980082003-03-25 05:07:42 +00002160ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002161{
paul718e3742002-12-13 20:15:29 +00002162 struct prefix_ipv4 p;
2163 struct in_addr nexthop;
2164 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002165 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002166
Paul Jakma4021b602006-05-12 22:55:41 +00002167 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002168
2169 p.family = AF_INET;
2170 p.prefix.s_addr = 0;
2171 p.prefixlen = 0;
2172
Paul Jakma4021b602006-05-12 22:55:41 +00002173 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002174 {
2175 /* If there is no default route via redistribute,
2176 then originate AS-external-LSA with nexthop 0 (self). */
2177 nexthop.s_addr = 0;
2178 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2179 }
2180
paul020709f2003-04-04 02:44:16 +00002181 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002182 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002183
2184 return 0;
2185}
2186
paul645878f2003-04-13 21:42:11 +00002187/* Flush any NSSA LSAs for given prefix */
2188void
2189ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2190{
paul1eb8ef22005-04-07 07:30:20 +00002191 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002192 struct ospf_lsa *lsa;
2193 struct ospf_area *area;
2194
paul1eb8ef22005-04-07 07:30:20 +00002195 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002196 {
paul1eb8ef22005-04-07 07:30:20 +00002197 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002198 {
2199 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2200 ospf->router_id)))
2201 {
2202 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002203 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002204 inet_ntoa (p->prefix), p->prefixlen);
2205 continue;
2206 }
2207 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2208 if (!IS_LSA_MAXAGE (lsa))
2209 {
2210 ospf_refresher_unregister_lsa (ospf, lsa);
2211 ospf_lsa_flush_area (lsa, area);
2212 }
2213 }
paul645878f2003-04-13 21:42:11 +00002214 }
2215}
paul645878f2003-04-13 21:42:11 +00002216
paul718e3742002-12-13 20:15:29 +00002217/* Flush an AS-external-LSA from LSDB and routing domain. */
2218void
paul68980082003-03-25 05:07:42 +00002219ospf_external_lsa_flush (struct ospf *ospf,
2220 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002221 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002222{
2223 struct ospf_lsa *lsa;
2224
2225 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002226 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002227 inet_ntoa (p->prefix), p->prefixlen);
2228
2229 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002230 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002231 {
2232 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002233 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002234 inet_ntoa (p->prefix), p->prefixlen);
2235 return;
2236 }
hassobeebba72004-06-20 21:00:27 +00002237
pauld4a53d52003-07-12 21:30:57 +00002238 /* If LSA is selforiginated, not a translated LSA, and there is
2239 * NSSA area, flush Type-7 LSA's at first.
2240 */
2241 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2242 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002243 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002244
2245 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002246 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002247
2248 /* There must be no self-originated LSA in rtrs_external. */
2249#if 0
2250 /* Remove External route from Zebra. */
2251 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2252#endif
2253
2254 if (!IS_LSA_MAXAGE (lsa))
2255 {
2256 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002257 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002258
2259 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002260 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002261 }
2262
2263 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002264 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002265}
2266
2267void
paul68980082003-03-25 05:07:42 +00002268ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002269{
2270 struct prefix_ipv4 p;
2271 struct external_info *ei;
2272 struct ospf_lsa *lsa;
2273
2274 p.family = AF_INET;
2275 p.prefixlen = 0;
2276 p.prefix.s_addr = 0;
2277
paul020709f2003-04-04 02:44:16 +00002278 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002279 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002280
2281 if (ei)
2282 {
2283 if (lsa)
2284 {
2285 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002286 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002287 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002288 }
2289 else
2290 {
2291 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002292 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002293 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002294 }
2295 }
2296 else
2297 {
2298 if (lsa)
2299 {
2300 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002301 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002302 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002303 }
2304 }
2305}
2306
2307void
paul68980082003-03-25 05:07:42 +00002308ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002309{
2310 struct route_node *rn;
2311 struct external_info *ei;
2312
2313 if (type != DEFAULT_ROUTE)
2314 if (EXTERNAL_INFO(type))
2315 /* Refresh each redistributed AS-external-LSAs. */
2316 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2317 if ((ei = rn->info))
2318 if (!is_prefix_default (&ei->p))
2319 {
2320 struct ospf_lsa *lsa;
2321
paul68980082003-03-25 05:07:42 +00002322 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2323 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002324 else
paul68980082003-03-25 05:07:42 +00002325 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002326 }
2327}
2328
2329/* Refresh AS-external-LSA. */
2330void
paul68980082003-03-25 05:07:42 +00002331ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002332 struct external_info *ei, int force)
2333{
2334 struct ospf_lsa *new;
2335 int changed;
2336
2337 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002338 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002339 {
pauld4a53d52003-07-12 21:30:57 +00002340 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002341 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002342 "redist check fail",
2343 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002344 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002345 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +00002346 return;
2347 }
2348
2349 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002350 {
2351 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002352 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002353 lsa->data->type, inet_ntoa (lsa->data->id));
2354 return;
2355 }
paul718e3742002-12-13 20:15:29 +00002356
2357 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002358 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002359
2360 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002361 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002362
paul68980082003-03-25 05:07:42 +00002363 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002364
2365 if (new == NULL)
2366 {
2367 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002368 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002369 inet_ntoa (lsa->data->id));
2370 return;
2371 }
2372
2373 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2374
paul68980082003-03-25 05:07:42 +00002375 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002376
2377 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002378 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002379
paul718e3742002-12-13 20:15:29 +00002380 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002381 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002382 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002383
pauld4a53d52003-07-12 21:30:57 +00002384 /* Register self-originated LSA to refresh queue.
2385 * Translated LSAs should not be registered, but refreshed upon
2386 * refresh of the Type-7
2387 */
2388 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2389 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002390
2391 /* Debug logging. */
2392 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2393 {
ajse588f212004-12-08 18:12:06 +00002394 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002395 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002396 ospf_lsa_header_dump (new->data);
2397 }
2398
2399 return;
2400}
2401
2402
2403/* LSA installation functions. */
2404
2405/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002406static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002407ospf_router_lsa_install (struct ospf *ospf,
2408 struct ospf_lsa *new, int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002409{
2410 struct ospf_area *area = new->area;
2411
2412 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2413 The entire routing table must be recalculated, starting with
2414 the shortest path calculations for each area (not just the
2415 area whose link-state database has changed).
2416 */
2417 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002418 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002419
Joakim Tjernlundbd246242009-01-05 17:44:46 +01002420 /* Only install LSA if it is originated/refreshed by us.
2421 * If LSA was received by flooding, the RECEIVED flag is set so do
2422 * not link the LSA */
2423 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
paul718e3742002-12-13 20:15:29 +00002424 {
2425 /* Set router-LSA refresh timer. */
2426 OSPF_TIMER_OFF (area->t_router_lsa_self);
2427 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
pauld4a53d52003-07-12 21:30:57 +00002428 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
paul718e3742002-12-13 20:15:29 +00002429
2430 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002431 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002432 area->router_lsa_self = ospf_lsa_lock (new);
2433
2434 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002435 zlog_debug("LSA[Type%d]: ID %s seq 0x%x is self-originated",
paul0c2be262004-05-31 14:16:54 +00002436 new->data->type, inet_ntoa (new->data->id),
2437 ntohl(new->data->ls_seqnum));
paul718e3742002-12-13 20:15:29 +00002438 }
2439
2440 return new;
2441}
2442
2443#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2444 if (!(T)) \
2445 (T) = thread_add_timer (master, (F), oi, (V))
2446
2447/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002448static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002449ospf_network_lsa_install (struct ospf *ospf,
2450 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002451 struct ospf_lsa *new,
2452 int rt_recalc)
2453{
2454
2455 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2456 The entire routing table must be recalculated, starting with
2457 the shortest path calculations for each area (not just the
2458 area whose link-state database has changed).
2459 */
2460 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002461 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002462
2463 /* We supposed that when LSA is originated by us, we pass the int
2464 for which it was originated. If LSA was received by flooding,
2465 the RECEIVED flag is set, so we do not link the LSA to the int. */
2466 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2467 {
2468 /* Set LSRefresh timer. */
2469 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2470
2471 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2472 ospf_network_lsa_refresh_timer,
2473 OSPF_LS_REFRESH_TIME);
2474
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002475 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002476 oi->network_lsa_self = ospf_lsa_lock (new);
2477 }
2478
2479 return new;
2480}
2481
2482/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002483static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002484ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2485 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002486{
paul718e3742002-12-13 20:15:29 +00002487 if (rt_recalc && !IS_LSA_SELF (new))
2488 {
2489 /* RFC 2328 Section 13.2 Summary-LSAs
2490 The best route to the destination described by the summary-
2491 LSA must be recalculated (see Section 16.5). If this
2492 destination is an AS boundary router, it may also be
2493 necessary to re-examine all the AS-external-LSAs.
2494 */
2495
2496#if 0
2497 /* This doesn't exist yet... */
2498 ospf_summary_incremental_update(new); */
2499#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002500 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002501#endif /* #if 0 */
2502
2503 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002504 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002505 }
2506
2507 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002508 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002509
2510 return new;
2511}
2512
2513/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002514static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002515ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2516 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002517{
2518 if (rt_recalc && !IS_LSA_SELF (new))
2519 {
2520 /* RFC 2328 Section 13.2 Summary-LSAs
2521 The best route to the destination described by the summary-
2522 LSA must be recalculated (see Section 16.5). If this
2523 destination is an AS boundary router, it may also be
2524 necessary to re-examine all the AS-external-LSAs.
2525 */
2526#if 0
2527 /* These don't exist yet... */
2528 ospf_summary_incremental_update(new);
2529 /* Isn't this done by the above call?
2530 - RFC 2328 Section 16.5 implies it should be */
2531 /* ospf_ase_calculate_schedule(); */
2532#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002533 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002534#endif /* #if 0 */
2535 }
2536
2537 /* register LSA to refresh-list. */
2538 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002539 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002540
2541 return new;
2542}
2543
2544/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002545static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002546ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2547 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002548{
paul68980082003-03-25 05:07:42 +00002549 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002550 /* If LSA is not self-originated, calculate an external route. */
2551 if (rt_recalc)
2552 {
2553 /* RFC 2328 Section 13.2 AS-external-LSAs
2554 The best route to the destination described by the AS-
2555 external-LSA must be recalculated (see Section 16.6).
2556 */
2557
2558 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002559 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002560 }
2561
pauld4a53d52003-07-12 21:30:57 +00002562 if (new->data->type == OSPF_AS_NSSA_LSA)
2563 {
2564 /* There is no point to register selforiginate Type-7 LSA for
2565 * refreshing. We rely on refreshing Type-5 LSA's
2566 */
2567 if (IS_LSA_SELF (new))
2568 return new;
2569 else
2570 {
2571 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2572 * New translations will be taken care of by the abr_task.
2573 */
2574 ospf_translated_nssa_refresh (ospf, new, NULL);
2575 }
2576 }
pauld7480322003-05-16 17:31:51 +00002577
pauld4a53d52003-07-12 21:30:57 +00002578 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002579 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002580 */
hassobeebba72004-06-20 21:00:27 +00002581 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002582 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002583
2584 return new;
2585}
2586
2587void
paul68980082003-03-25 05:07:42 +00002588ospf_discard_from_db (struct ospf *ospf,
2589 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002590{
2591 struct ospf_lsa *old;
2592
Paul Jakmaac904de2006-06-15 12:04:57 +00002593 if (!lsdb)
2594 {
2595 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2596 if (!lsa)
2597 zlog_warn ("%s: and NULL LSA!", __func__);
2598 else
2599 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2600 lsa->data->type, inet_ntoa (lsa->data->id));
2601 return;
2602 }
2603
paul718e3742002-12-13 20:15:29 +00002604 old = ospf_lsdb_lookup (lsdb, lsa);
2605
2606 if (!old)
2607 return;
2608
2609 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002610 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002611
2612 switch (old->data->type)
2613 {
2614 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002615 ospf_ase_unregister_external_lsa (old, ospf);
2616 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2617 break;
paul718e3742002-12-13 20:15:29 +00002618#ifdef HAVE_OPAQUE_LSA
2619 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002620 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002621 break;
paul69310a62005-05-11 18:09:59 +00002622#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002623 case OSPF_AS_NSSA_LSA:
2624 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2625 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002626 break;
paul718e3742002-12-13 20:15:29 +00002627 default:
paul68980082003-03-25 05:07:42 +00002628 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002629 break;
2630 }
2631
paul68980082003-03-25 05:07:42 +00002632 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002633 ospf_lsa_discard (old);
2634}
2635
paul718e3742002-12-13 20:15:29 +00002636struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002637ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2638 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002639{
2640 struct ospf_lsa *new = NULL;
2641 struct ospf_lsa *old = NULL;
2642 struct ospf_lsdb *lsdb = NULL;
2643 int rt_recalc;
2644
2645 /* Set LSDB. */
2646 switch (lsa->data->type)
2647 {
paulf2c80652002-12-13 21:44:27 +00002648 /* kevinm */
2649 case OSPF_AS_NSSA_LSA:
2650 if (lsa->area)
2651 lsdb = lsa->area->lsdb;
2652 else
paul68980082003-03-25 05:07:42 +00002653 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002654 break;
paul718e3742002-12-13 20:15:29 +00002655 case OSPF_AS_EXTERNAL_LSA:
2656#ifdef HAVE_OPAQUE_LSA
2657 case OSPF_OPAQUE_AS_LSA:
2658#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002659 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002660 break;
2661 default:
2662 lsdb = lsa->area->lsdb;
2663 break;
2664 }
2665
paul718e3742002-12-13 20:15:29 +00002666 assert (lsdb);
2667
2668 /* RFC 2328 13.2. Installing LSAs in the database
2669
2670 Installing a new LSA in the database, either as the result of
2671 flooding or a newly self-originated LSA, may cause the OSPF
2672 routing table structure to be recalculated. The contents of the
2673 new LSA should be compared to the old instance, if present. If
2674 there is no difference, there is no need to recalculate the
2675 routing table. When comparing an LSA to its previous instance,
2676 the following are all considered to be differences in contents:
2677
2678 o The LSA's Options field has changed.
2679
2680 o One of the LSA instances has LS age set to MaxAge, and
2681 the other does not.
2682
2683 o The length field in the LSA header has changed.
2684
2685 o The body of the LSA (i.e., anything outside the 20-byte
2686 LSA header) has changed. Note that this excludes changes
2687 in LS Sequence Number and LS Checksum.
2688
2689 */
2690 /* Look up old LSA and determine if any SPF calculation or incremental
2691 update is needed */
2692 old = ospf_lsdb_lookup (lsdb, lsa);
2693
2694 /* Do comparision and record if recalc needed. */
2695 rt_recalc = 0;
2696 if ( old == NULL || ospf_lsa_different(old, lsa))
2697 rt_recalc = 1;
2698
paul7ddf1d62003-10-13 09:06:46 +00002699 /*
2700 Sequence number check (Section 14.1 of rfc 2328)
2701 "Premature aging is used when it is time for a self-originated
2702 LSA's sequence number field to wrap. At this point, the current
2703 LSA instance (having LS sequence number MaxSequenceNumber) must
2704 be prematurely aged and flushed from the routing domain before a
2705 new instance with sequence number equal to InitialSequenceNumber
2706 can be originated. "
2707 */
2708
Paul Jakmac2b478d2006-03-30 14:16:11 +00002709 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002710 {
2711 if (ospf_lsa_is_self_originated(ospf, lsa))
2712 {
paul0c2be262004-05-31 14:16:54 +00002713 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2714
2715 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002716 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2717 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2718
2719 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2720 {
ajse588f212004-12-08 18:12:06 +00002721 zlog_debug ("ospf_lsa_install() Premature Aging "
paul7ddf1d62003-10-13 09:06:46 +00002722 "lsa 0x%lx", (u_long)lsa);
2723 ospf_lsa_header_dump (lsa->data);
2724 }
2725 }
2726 else
2727 {
2728 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2729 {
ajse588f212004-12-08 18:12:06 +00002730 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002731 "that was not self originated. Ignoring\n");
2732 ospf_lsa_header_dump (lsa->data);
2733 }
2734 return old;
2735 }
2736 }
2737
paul718e3742002-12-13 20:15:29 +00002738 /* discard old LSA from LSDB */
2739 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002740 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002741
paul718e3742002-12-13 20:15:29 +00002742 /* Calculate Checksum if self-originated?. */
2743 if (IS_LSA_SELF (lsa))
2744 ospf_lsa_checksum (lsa->data);
2745
hassofe71a972004-12-22 16:16:02 +00002746 /* Insert LSA to LSDB. */
2747 ospf_lsdb_add (lsdb, lsa);
2748 lsa->lsdb = lsdb;
2749
paul718e3742002-12-13 20:15:29 +00002750 /* Do LSA specific installation process. */
2751 switch (lsa->data->type)
2752 {
2753 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002754 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002755 break;
2756 case OSPF_NETWORK_LSA:
2757 assert (oi);
paul68980082003-03-25 05:07:42 +00002758 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002759 break;
2760 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002761 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002762 break;
2763 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002764 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002765 break;
2766 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002767 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002768 break;
2769#ifdef HAVE_OPAQUE_LSA
2770 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002771 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002772 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002773 else
paul68980082003-03-25 05:07:42 +00002774 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002775 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002776 case OSPF_OPAQUE_AREA_LSA:
2777 case OSPF_OPAQUE_AS_LSA:
2778 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2779 break;
2780#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002781 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002782 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002783 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002784 break;
2785 }
2786
2787 if (new == NULL)
2788 return new; /* Installation failed, cannot proceed further -- endo. */
2789
2790 /* Debug logs. */
2791 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2792 {
2793 char area_str[INET_ADDRSTRLEN];
2794
2795 switch (lsa->data->type)
2796 {
2797 case OSPF_AS_EXTERNAL_LSA:
2798#ifdef HAVE_OPAQUE_LSA
2799 case OSPF_OPAQUE_AS_LSA:
2800#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002801 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002802 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002803 dump_lsa_key (new),
2804 LOOKUP (ospf_lsa_type_msg, new->data->type));
2805 break;
2806 default:
2807 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002808 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002809 dump_lsa_key (new),
2810 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2811 break;
2812 }
2813 }
2814
paul7ddf1d62003-10-13 09:06:46 +00002815 /*
2816 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2817 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2818 */
2819 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2820 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002821 {
paul7ddf1d62003-10-13 09:06:46 +00002822 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002823 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002824 new->data->type,
2825 inet_ntoa (new->data->id),
2826 lsa);
paul68980082003-03-25 05:07:42 +00002827 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002828 }
2829
2830 return new;
2831}
2832
2833
paul4dadc292005-05-06 21:37:42 +00002834static int
paul68980082003-03-25 05:07:42 +00002835ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002836{
paul1eb8ef22005-04-07 07:30:20 +00002837 struct listnode *node, *nnode;
2838 struct ospf_interface *oi;
2839
2840 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002841 {
paul718e3742002-12-13 20:15:29 +00002842 struct route_node *rn;
2843 struct ospf_neighbor *nbr;
2844
2845 if (ospf_if_is_enable (oi))
2846 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2847 if ((nbr = rn->info) != NULL)
2848 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2849 {
2850 route_unlock_node (rn);
2851 return 0;
2852 }
2853 }
2854
2855 return 1;
2856}
2857
2858
2859#ifdef ORIGINAL_CODING
2860/* This function flood the maxaged LSA to DR. */
2861void
2862ospf_maxage_flood (struct ospf_lsa *lsa)
2863{
2864 switch (lsa->data->type)
2865 {
2866 case OSPF_ROUTER_LSA:
2867 case OSPF_NETWORK_LSA:
2868 case OSPF_SUMMARY_LSA:
2869 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00002870 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00002871#ifdef HAVE_OPAQUE_LSA
2872 case OSPF_OPAQUE_LINK_LSA:
2873 case OSPF_OPAQUE_AREA_LSA:
2874#endif /* HAVE_OPAQUE_LSA */
2875 ospf_flood_through_area (lsa->area, NULL, lsa);
2876 break;
2877 case OSPF_AS_EXTERNAL_LSA:
2878#ifdef HAVE_OPAQUE_LSA
2879 case OSPF_OPAQUE_AS_LSA:
2880#endif /* HAVE_OPAQUE_LSA */
2881 ospf_flood_through_as (NULL, lsa);
2882 break;
2883 default:
2884 break;
2885 }
2886}
2887#endif /* ORIGINAL_CODING */
2888
paul4dadc292005-05-06 21:37:42 +00002889static int
paul718e3742002-12-13 20:15:29 +00002890ospf_maxage_lsa_remover (struct thread *thread)
2891{
paul68980082003-03-25 05:07:42 +00002892 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002893 struct ospf_lsa *lsa;
2894 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002895 int reschedule = 0;
2896
paul68980082003-03-25 05:07:42 +00002897 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002898
2899 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002900 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002901
paul68980082003-03-25 05:07:42 +00002902 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002903
2904 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002905 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002906 {
paul718e3742002-12-13 20:15:29 +00002907 if (lsa->retransmit_counter > 0)
2908 {
2909 reschedule = 1;
2910 continue;
2911 }
2912
2913 /* Remove LSA from the LSDB */
2914 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2915 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002916 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
paul7ddf1d62003-10-13 09:06:46 +00002917 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002918
2919 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002920 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002921 lsa->data->type, inet_ntoa (lsa->data->id));
2922
2923 /* Flood max age LSA. */
2924#ifdef ORIGINAL_CODING
2925 ospf_maxage_flood (lsa);
2926#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00002927 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00002928#endif /* ORIGINAL_CODING */
2929
paul7ddf1d62003-10-13 09:06:46 +00002930 if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
2931 {
2932 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002933 zlog_debug ("originating new router lsa for lsa 0x%lx \n",
paul7ddf1d62003-10-13 09:06:46 +00002934 (u_long)lsa);
2935 ospf_router_lsa_originate(lsa->area);
2936 }
2937
paul718e3742002-12-13 20:15:29 +00002938 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002939 if (lsa->lsdb)
2940 {
2941 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2942 ospf_lsdb_delete (lsa->lsdb, lsa);
2943 }
2944 else
2945 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2946 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002947 }
2948
2949 /* A MaxAge LSA must be removed immediately from the router's link
2950 state database as soon as both a) it is no longer contained on any
2951 neighbor Link state retransmission lists and b) none of the router's
2952 neighbors are in states Exchange or Loading. */
2953 if (reschedule)
paul68980082003-03-25 05:07:42 +00002954 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00002955
2956 return 0;
2957}
2958
paul4dadc292005-05-06 21:37:42 +00002959static int
paul68980082003-03-25 05:07:42 +00002960ospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new)
paul718e3742002-12-13 20:15:29 +00002961{
hasso52dc7ee2004-09-23 19:18:23 +00002962 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00002963 struct ospf_lsa *lsa;
2964
2965 for (ALL_LIST_ELEMENTS_RO (ospf->maxage_lsa, node, lsa))
2966 if (lsa == new)
paul718e3742002-12-13 20:15:29 +00002967 return 1;
2968
2969 return 0;
2970}
2971
2972void
paul68980082003-03-25 05:07:42 +00002973ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002974{
hasso52dc7ee2004-09-23 19:18:23 +00002975 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00002976
paul68980082003-03-25 05:07:42 +00002977 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00002978 {
paul68980082003-03-25 05:07:42 +00002979 list_delete_node (ospf->maxage_lsa, n);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002980 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +00002981 }
2982}
2983
2984void
paul68980082003-03-25 05:07:42 +00002985ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002986{
2987 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2988 and schedule the MaxAge LSA remover. */
paul68980082003-03-25 05:07:42 +00002989 if (ospf_lsa_maxage_exist (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002990 {
2991 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002992 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00002993 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2994 return;
2995 }
2996
paul68980082003-03-25 05:07:42 +00002997 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00002998
2999 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003000 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003001
paul68980082003-03-25 05:07:42 +00003002 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003003}
3004
paul4dadc292005-05-06 21:37:42 +00003005static int
paul68980082003-03-25 05:07:42 +00003006ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003007{
paul718e3742002-12-13 20:15:29 +00003008 /* Stay away from any Local Translated Type-7 LSAs */
3009 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3010 return 0;
paul718e3742002-12-13 20:15:29 +00003011
3012 if (IS_LSA_MAXAGE (lsa))
3013 /* Self-originated LSAs should NOT time-out instead,
3014 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00003015 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003016 {
3017 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003018 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003019
3020 switch (lsa->data->type)
3021 {
paul718e3742002-12-13 20:15:29 +00003022#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00003023 case OSPF_OPAQUE_LINK_LSA:
3024 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003025 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003026 /*
3027 * As a general rule, whenever network topology has changed
3028 * (due to an LSA removal in this case), routing recalculation
3029 * should be triggered. However, this is not true for opaque
3030 * LSAs. Even if an opaque LSA instance is going to be removed
3031 * from the routing domain, it does not mean a change in network
3032 * topology, and thus, routing recalculation is not needed here.
3033 */
3034 break;
paul718e3742002-12-13 20:15:29 +00003035#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00003036 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003037 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003038 ospf_ase_incremental_update (ospf, lsa);
3039 break;
paul718e3742002-12-13 20:15:29 +00003040 default:
paul68980082003-03-25 05:07:42 +00003041 ospf_spf_calculate_schedule (ospf);
3042 break;
paul718e3742002-12-13 20:15:29 +00003043 }
paul68980082003-03-25 05:07:42 +00003044 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003045 }
3046
3047 return 0;
3048}
3049
3050/* Periodical check of MaxAge LSA. */
3051int
paul68980082003-03-25 05:07:42 +00003052ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003053{
paul68980082003-03-25 05:07:42 +00003054 struct ospf *ospf = THREAD_ARG (thread);
3055 struct route_node *rn;
3056 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003057 struct ospf_area *area;
3058 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003059
paul68980082003-03-25 05:07:42 +00003060 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003061
paul1eb8ef22005-04-07 07:30:20 +00003062 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003063 {
paul68980082003-03-25 05:07:42 +00003064 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3065 ospf_lsa_maxage_walker_remover (ospf, lsa);
3066 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3067 ospf_lsa_maxage_walker_remover (ospf, lsa);
3068 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3069 ospf_lsa_maxage_walker_remover (ospf, lsa);
3070 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3071 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003072#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003073 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3074 ospf_lsa_maxage_walker_remover (ospf, lsa);
3075 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3076 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003077#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003078 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3079 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003080 }
3081
paul4fb949e2003-05-10 20:06:51 +00003082 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003083 if (ospf->lsdb)
3084 {
3085 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3086 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003087#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003088 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3089 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003090#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003091 }
paul718e3742002-12-13 20:15:29 +00003092
paul68980082003-03-25 05:07:42 +00003093 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3094 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003095 return 0;
3096}
3097
paul68980082003-03-25 05:07:42 +00003098struct ospf_lsa *
3099ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3100 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003101{
paul68980082003-03-25 05:07:42 +00003102 struct ospf_lsa *lsa;
3103 struct in_addr mask, id;
3104 struct lsa_header_mask
3105 {
3106 struct lsa_header header;
3107 struct in_addr mask;
3108 } *hmask;
paul718e3742002-12-13 20:15:29 +00003109
paul68980082003-03-25 05:07:42 +00003110 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3111 if (lsa == NULL)
3112 return NULL;
paul718e3742002-12-13 20:15:29 +00003113
paul68980082003-03-25 05:07:42 +00003114 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003115
paul68980082003-03-25 05:07:42 +00003116 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003117
paul68980082003-03-25 05:07:42 +00003118 if (mask.s_addr != hmask->mask.s_addr)
3119 {
3120 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3121 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3122 if (!lsa)
3123 return NULL;
3124 }
paul718e3742002-12-13 20:15:29 +00003125
paul68980082003-03-25 05:07:42 +00003126 return lsa;
paul718e3742002-12-13 20:15:29 +00003127}
3128
3129struct ospf_lsa *
3130ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3131 struct in_addr id, struct in_addr adv_router)
3132{
paule05fba42003-04-13 20:20:53 +00003133 struct ospf *ospf = ospf_lookup();
3134 assert(ospf);
3135
paul718e3742002-12-13 20:15:29 +00003136 switch (type)
3137 {
3138 case OSPF_ROUTER_LSA:
3139 case OSPF_NETWORK_LSA:
3140 case OSPF_SUMMARY_LSA:
3141 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003142 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003143#ifdef HAVE_OPAQUE_LSA
3144 case OSPF_OPAQUE_LINK_LSA:
3145 case OSPF_OPAQUE_AREA_LSA:
3146#endif /* HAVE_OPAQUE_LSA */
3147 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003148 case OSPF_AS_EXTERNAL_LSA:
3149#ifdef HAVE_OPAQUE_LSA
3150 case OSPF_OPAQUE_AS_LSA:
3151#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003152 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003153 default:
3154 break;
3155 }
3156
3157 return NULL;
3158}
3159
3160struct ospf_lsa *
3161ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3162 struct in_addr id)
3163{
3164 struct ospf_lsa *lsa;
3165 struct route_node *rn;
3166
3167 switch (type)
3168 {
3169 case OSPF_ROUTER_LSA:
3170 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003171 case OSPF_NETWORK_LSA:
3172 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3173 if ((lsa = rn->info))
3174 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3175 {
3176 route_unlock_node (rn);
3177 return lsa;
3178 }
3179 break;
3180 case OSPF_SUMMARY_LSA:
3181 case OSPF_ASBR_SUMMARY_LSA:
3182 /* Currently not used. */
3183 assert (1);
3184 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003185 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003186 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003187#ifdef HAVE_OPAQUE_LSA
3188 case OSPF_OPAQUE_LINK_LSA:
3189 case OSPF_OPAQUE_AREA_LSA:
3190 case OSPF_OPAQUE_AS_LSA:
3191 /* Currently not used. */
3192 break;
3193#endif /* HAVE_OPAQUE_LSA */
3194 default:
3195 break;
3196 }
3197
3198 return NULL;
3199}
3200
3201struct ospf_lsa *
3202ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3203{
3204 struct ospf_lsa *match;
3205
3206#ifdef HAVE_OPAQUE_LSA
3207 /*
3208 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3209 * is redefined to have two subfields; opaque-type and opaque-id.
3210 * However, it is harmless to treat the two sub fields together, as if
3211 * they two were forming a unique LSA-ID.
3212 */
3213#endif /* HAVE_OPAQUE_LSA */
3214
3215 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3216
3217 if (match == NULL)
3218 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003219 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003220 lsah->type, inet_ntoa (lsah->id));
3221
3222 return match;
3223}
3224
3225/* return +n, l1 is more recent.
3226 return -n, l2 is more recent.
3227 return 0, l1 and l2 is identical. */
3228int
3229ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3230{
3231 int r;
3232 int x, y;
3233
3234 if (l1 == NULL && l2 == NULL)
3235 return 0;
3236 if (l1 == NULL)
3237 return -1;
3238 if (l2 == NULL)
3239 return 1;
3240
3241 /* compare LS sequence number. */
3242 x = (int) ntohl (l1->data->ls_seqnum);
3243 y = (int) ntohl (l2->data->ls_seqnum);
3244 if (x > y)
3245 return 1;
3246 if (x < y)
3247 return -1;
3248
3249 /* compare LS checksum. */
3250 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3251 if (r)
3252 return r;
3253
3254 /* compare LS age. */
3255 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3256 return 1;
3257 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3258 return -1;
3259
3260 /* compare LS age with MaxAgeDiff. */
3261 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3262 return -1;
3263 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3264 return 1;
3265
3266 /* LSAs are identical. */
3267 return 0;
3268}
3269
3270/* If two LSAs are different, return 1, otherwise return 0. */
3271int
3272ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3273{
3274 char *p1, *p2;
3275 assert (l1);
3276 assert (l2);
3277 assert (l1->data);
3278 assert (l2->data);
3279
3280 if (l1->data->options != l2->data->options)
3281 return 1;
3282
3283 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3284 return 1;
3285
3286 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3287 return 1;
3288
3289 if (l1->data->length != l2->data->length)
3290 return 1;
3291
3292 if (l1->data->length == 0)
3293 return 1;
3294
pauld1825832003-04-03 01:27:01 +00003295 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003296
3297 p1 = (char *) l1->data;
3298 p2 = (char *) l2->data;
3299
3300 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3301 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3302 return 1;
3303
3304 return 0;
3305}
3306
3307#ifdef ORIGINAL_CODING
3308void
3309ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3310 struct ospf_lsa *self,
3311 struct ospf_lsa *new)
3312{
3313 u_int32_t seqnum;
3314
3315 /* Adjust LS Sequence Number. */
3316 seqnum = ntohl (new->data->ls_seqnum) + 1;
3317 self->data->ls_seqnum = htonl (seqnum);
3318
3319 /* Recalculate LSA checksum. */
3320 ospf_lsa_checksum (self->data);
3321
3322 /* Reflooding LSA. */
3323 /* RFC2328 Section 13.3
3324 On non-broadcast networks, separate Link State Update
3325 packets must be sent, as unicasts, to each adjacent neighbor
3326 (i.e., those in state Exchange or greater). The destination
3327 IP addresses for these packets are the neighbors' IP
3328 addresses. */
3329 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3330 {
3331 struct route_node *rn;
3332 struct ospf_neighbor *onbr;
3333
3334 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3335 if ((onbr = rn->info) != NULL)
3336 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3337 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3338 }
3339 else
3340 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3341
3342 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003343 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003344 self->data->type, inet_ntoa (self->data->id));
3345}
3346#else /* ORIGINAL_CODING */
3347static int
paul68980082003-03-25 05:07:42 +00003348ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003349{
3350 if (lsa == NULL || !IS_LSA_SELF (lsa))
3351 return 0;
3352
3353 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003354 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 +00003355
3356 /* Force given lsa's age to MaxAge. */
3357 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3358
3359 switch (lsa->data->type)
3360 {
3361#ifdef HAVE_OPAQUE_LSA
3362 case OSPF_OPAQUE_LINK_LSA:
3363 case OSPF_OPAQUE_AREA_LSA:
3364 case OSPF_OPAQUE_AS_LSA:
3365 ospf_opaque_lsa_refresh (lsa);
3366 break;
3367#endif /* HAVE_OPAQUE_LSA */
3368 default:
paul68980082003-03-25 05:07:42 +00003369 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003370 break;
3371 }
3372
3373 return 0;
3374}
3375
3376void
paul68980082003-03-25 05:07:42 +00003377ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003378{
paul1eb8ef22005-04-07 07:30:20 +00003379 struct listnode *node, *nnode;
3380 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003381 struct ospf_area *area;
3382 struct ospf_interface *oi;
3383 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003384 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003385 int need_to_flush_ase = 0;
3386
paul1eb8ef22005-04-07 07:30:20 +00003387 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003388 {
paul718e3742002-12-13 20:15:29 +00003389 if ((lsa = area->router_lsa_self) != NULL)
3390 {
3391 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003392 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 +00003393
3394 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003395 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003396 area->router_lsa_self = NULL;
3397 OSPF_TIMER_OFF (area->t_router_lsa_self);
3398 }
3399
paul1eb8ef22005-04-07 07:30:20 +00003400 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003401 {
paul718e3742002-12-13 20:15:29 +00003402 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003403 && oi->state == ISM_DR
3404 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003405 {
3406 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003407 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 +00003408
3409 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003410 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003411 oi->network_lsa_self = NULL;
3412 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3413 }
3414
3415 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3416 && area->external_routing == OSPF_AREA_DEFAULT)
3417 need_to_flush_ase = 1;
3418 }
3419
paul68980082003-03-25 05:07:42 +00003420 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3421 ospf_lsa_flush_schedule (ospf, lsa);
3422 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3423 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003424#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003425 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3426 ospf_lsa_flush_schedule (ospf, lsa);
3427 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3428 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003429#endif /* HAVE_OPAQUE_LSA */
3430 }
3431
3432 if (need_to_flush_ase)
3433 {
paul68980082003-03-25 05:07:42 +00003434 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3435 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003436#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003437 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3438 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003439#endif /* HAVE_OPAQUE_LSA */
3440 }
3441
3442 /*
3443 * Make sure that the MaxAge LSA remover is executed immediately,
3444 * without conflicting to other threads.
3445 */
paul68980082003-03-25 05:07:42 +00003446 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003447 {
paul68980082003-03-25 05:07:42 +00003448 OSPF_TIMER_OFF (ospf->t_maxage);
3449 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003450 }
3451
3452 return;
3453}
3454#endif /* ORIGINAL_CODING */
3455
3456/* If there is self-originated LSA, then return 1, otherwise return 0. */
3457/* An interface-independent version of ospf_lsa_is_self_originated */
3458int
paul68980082003-03-25 05:07:42 +00003459ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003460{
hasso52dc7ee2004-09-23 19:18:23 +00003461 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003462 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003463
3464 /* This LSA is already checked. */
3465 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3466 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3467
3468 /* Make sure LSA is self-checked. */
3469 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3470
3471 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003472 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003473 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3474
3475 /* LSA is router-LSA. */
3476 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003477 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003478 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3479
3480 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3481 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003482 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003483 {
paul718e3742002-12-13 20:15:29 +00003484 /* Ignore virtual link. */
3485 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3486 if (oi->address->family == AF_INET)
3487 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3488 {
3489 /* to make it easier later */
3490 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3491 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3492 }
3493 }
3494
3495 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3496}
3497
3498/* Get unique Link State ID. */
3499struct in_addr
paul68980082003-03-25 05:07:42 +00003500ospf_lsa_unique_id (struct ospf *ospf,
3501 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003502{
3503 struct ospf_lsa *lsa;
3504 struct in_addr mask, id;
3505
3506 id = p->prefix;
3507
3508 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003509 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003510 if (lsa)
3511 {
3512 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3513 if (ip_masklen (al->mask) == p->prefixlen)
3514 {
3515 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003516 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003517 "Can't get Link State ID for %s/%d",
3518 inet_ntoa (p->prefix), p->prefixlen);
3519 /* id.s_addr = 0; */
3520 id.s_addr = 0xffffffff;
3521 return id;
3522 }
3523 /* Masklen differs, then apply wildcard mask to Link State ID. */
3524 else
3525 {
3526 masklen2ip (p->prefixlen, &mask);
3527
3528 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003529 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3530 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003531 if (lsa)
3532 {
3533 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003534 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003535 "Can't get Link State ID for %s/%d",
3536 inet_ntoa (p->prefix), p->prefixlen);
3537 /* id.s_addr = 0; */
3538 id.s_addr = 0xffffffff;
3539 return id;
3540 }
3541 }
3542 }
3543
3544 return id;
3545}
3546
3547
Paul Jakma70461d72006-05-12 22:57:57 +00003548#define LSA_ACTION_FLOOD_AREA 1
3549#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003550
3551struct lsa_action
3552{
3553 u_char action;
3554 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003555 struct ospf_lsa *lsa;
3556};
3557
paul4dadc292005-05-06 21:37:42 +00003558static int
paul718e3742002-12-13 20:15:29 +00003559ospf_lsa_action (struct thread *t)
3560{
3561 struct lsa_action *data;
3562
3563 data = THREAD_ARG (t);
3564
3565 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003566 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003567 data->action);
3568
3569 switch (data->action)
3570 {
paul718e3742002-12-13 20:15:29 +00003571 case LSA_ACTION_FLOOD_AREA:
3572 ospf_flood_through_area (data->area, NULL, data->lsa);
3573 break;
paul718e3742002-12-13 20:15:29 +00003574 case LSA_ACTION_FLUSH_AREA:
3575 ospf_lsa_flush_area (data->lsa, data->area);
3576 break;
paul718e3742002-12-13 20:15:29 +00003577 }
3578
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003579 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003580 XFREE (MTYPE_OSPF_MESSAGE, data);
3581 return 0;
3582}
3583
3584void
3585ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3586{
3587 struct lsa_action *data;
3588
Stephen Hemminger393deb92008-08-18 14:13:29 -07003589 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003590 data->action = LSA_ACTION_FLOOD_AREA;
3591 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003592 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003593
3594 thread_add_event (master, ospf_lsa_action, data, 0);
3595}
3596
3597void
3598ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3599{
3600 struct lsa_action *data;
3601
Stephen Hemminger393deb92008-08-18 14:13:29 -07003602 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003603 data->action = LSA_ACTION_FLUSH_AREA;
3604 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003605 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003606
3607 thread_add_event (master, ospf_lsa_action, data, 0);
3608}
3609
3610
3611/* LSA Refreshment functions. */
paul4dadc292005-05-06 21:37:42 +00003612static void
paul68980082003-03-25 05:07:42 +00003613ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003614{
3615 struct external_info *ei;
3616 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3617
3618 switch (lsa->data->type)
3619 {
3620 /* Router and Network LSAs are processed differently. */
3621 case OSPF_ROUTER_LSA:
3622 case OSPF_NETWORK_LSA:
3623 break;
3624 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003625 ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003626 break;
3627 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003628 ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003629 break;
3630 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003631 /* Translated from NSSA Type-5s are refreshed when
3632 * from refresh of Type-7 - do not refresh these directly.
3633 */
3634 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3635 break;
paul718e3742002-12-13 20:15:29 +00003636 ei = ospf_external_info_check (lsa);
3637 if (ei)
pauld4a53d52003-07-12 21:30:57 +00003638 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003639 else
pauld4a53d52003-07-12 21:30:57 +00003640 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003641 break;
3642#ifdef HAVE_OPAQUE_LSA
3643 case OSPF_OPAQUE_LINK_LSA:
3644 case OSPF_OPAQUE_AREA_LSA:
3645 case OSPF_OPAQUE_AS_LSA:
3646 ospf_opaque_lsa_refresh (lsa);
3647 break;
pauld7480322003-05-16 17:31:51 +00003648#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003649 default:
3650 break;
paul718e3742002-12-13 20:15:29 +00003651 }
3652}
3653
3654void
paul68980082003-03-25 05:07:42 +00003655ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003656{
3657 u_int16_t index, current_index;
3658
3659 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3660
3661 if (lsa->refresh_list < 0)
3662 {
3663 int delay;
3664
3665 if (LS_AGE (lsa) == 0 &&
3666 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3667 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3668 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3669 else
3670 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3671 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3672 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3673
3674 if (delay < 0)
3675 delay = 0;
3676
paul68980082003-03-25 05:07:42 +00003677 current_index = ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003678 (quagga_time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003679
3680 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3681 % (OSPF_LSA_REFRESHER_SLOTS);
3682
3683 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003684 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003685 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003686 if (!ospf->lsa_refresh_queue.qs[index])
3687 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003688 listnode_add (ospf->lsa_refresh_queue.qs[index],
3689 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003690 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003691 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003692 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003693 "setting refresh_list on lsa %p (slod %d)",
3694 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003695 }
3696}
3697
3698void
paul68980082003-03-25 05:07:42 +00003699ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003700{
3701 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3702 if (lsa->refresh_list >= 0)
3703 {
hasso52dc7ee2004-09-23 19:18:23 +00003704 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003705 listnode_delete (refresh_list, lsa);
3706 if (!listcount (refresh_list))
3707 {
3708 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003709 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003710 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003711 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003712 lsa->refresh_list = -1;
3713 }
3714}
3715
3716int
3717ospf_lsa_refresh_walker (struct thread *t)
3718{
hasso52dc7ee2004-09-23 19:18:23 +00003719 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003720 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003721 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003722 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003723 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003724 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003725
3726 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003727 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003728
3729
paul68980082003-03-25 05:07:42 +00003730 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003731
ajs9dbc7972005-03-13 19:27:22 +00003732 /* Note: if clock has jumped backwards, then time change could be negative,
3733 so we are careful to cast the expression to unsigned before taking
3734 modulus. */
paul68980082003-03-25 05:07:42 +00003735 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003736 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003737 (quagga_time (NULL) - ospf->lsa_refresher_started) /
ajs9dbc7972005-03-13 19:27:22 +00003738 OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003739
3740 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003741 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003742 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003743
paul68980082003-03-25 05:07:42 +00003744 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003745 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3746 {
3747 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003748 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003749 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003750
paul68980082003-03-25 05:07:42 +00003751 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003752
paul68980082003-03-25 05:07:42 +00003753 ospf->lsa_refresh_queue.qs [i] = NULL;
3754
paul718e3742002-12-13 20:15:29 +00003755 if (refresh_list)
3756 {
paul1eb8ef22005-04-07 07:30:20 +00003757 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003758 {
paul718e3742002-12-13 20:15:29 +00003759 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003760 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003761 "refresh lsa %p (slot %d)",
3762 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003763
3764 list_delete_node (refresh_list, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003765 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003766 lsa->refresh_list = -1;
3767 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003768 }
3769 list_free (refresh_list);
3770 }
3771 }
3772
paul68980082003-03-25 05:07:42 +00003773 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3774 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003775 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003776
paul1eb8ef22005-04-07 07:30:20 +00003777 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
3778 ospf_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003779
3780 list_delete (lsa_to_refresh);
3781
3782 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003783 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003784
3785 return 0;
3786}
3787