blob: f453353dd6e33bc0d86d0d5f63a46de9490426eb [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));
204 memset (new, 0, sizeof (struct ospf_lsa));
205
206 new->flags = 0;
207 new->lock = 1;
208 new->retransmit_counter = 0;
Paul Jakma2518efd2006-08-27 06:49:29 +0000209 new->tv_recv = recent_relative_time ();
paul718e3742002-12-13 20:15:29 +0000210 new->tv_orig = new->tv_recv;
211 new->refresh_list = -1;
212
213 return new;
214}
215
216/* Duplicate OSPF LSA. */
217struct ospf_lsa *
218ospf_lsa_dup (struct ospf_lsa *lsa)
219{
220 struct ospf_lsa *new;
221
222 if (lsa == NULL)
223 return NULL;
224
225 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
226
227 memcpy (new, lsa, sizeof (struct ospf_lsa));
228 UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
229 new->lock = 1;
230 new->retransmit_counter = 0;
231 new->data = ospf_lsa_data_dup (lsa->data);
232
paulf2c80652002-12-13 21:44:27 +0000233 /* kevinm: Clear the refresh_list, otherwise there are going
234 to be problems when we try to remove the LSA from the
235 queue (which it's not a member of.)
236 XXX: Should we add the LSA to the refresh_list queue? */
237 new->refresh_list = -1;
238
239 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000240 zlog_debug ("LSA: duplicated %p (new: %p)", lsa, new);
paulf2c80652002-12-13 21:44:27 +0000241
paul718e3742002-12-13 20:15:29 +0000242 return new;
243}
244
245/* Free OSPF LSA. */
246void
247ospf_lsa_free (struct ospf_lsa *lsa)
248{
249 assert (lsa->lock == 0);
250
251 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000252 zlog_debug ("LSA: freed %p", lsa);
paul718e3742002-12-13 20:15:29 +0000253
254 /* Delete LSA data. */
255 if (lsa->data != NULL)
256 ospf_lsa_data_free (lsa->data);
257
258 assert (lsa->refresh_list < 0);
259
260 memset (lsa, 0, sizeof (struct ospf_lsa));
261 XFREE (MTYPE_OSPF_LSA, lsa);
262}
263
264/* Lock LSA. */
265struct ospf_lsa *
266ospf_lsa_lock (struct ospf_lsa *lsa)
267{
268 lsa->lock++;
269 return lsa;
270}
271
272/* Unlock LSA. */
273void
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000274ospf_lsa_unlock (struct ospf_lsa **lsa)
paul718e3742002-12-13 20:15:29 +0000275{
276 /* This is sanity check. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000277 if (!lsa || !*lsa)
paul718e3742002-12-13 20:15:29 +0000278 return;
279
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000280 (*lsa)->lock--;
paul718e3742002-12-13 20:15:29 +0000281
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000282 assert ((*lsa)->lock >= 0);
paul718e3742002-12-13 20:15:29 +0000283
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000284 if ((*lsa)->lock == 0)
paul718e3742002-12-13 20:15:29 +0000285 {
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000286 assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
287 ospf_lsa_free (*lsa);
288 *lsa = NULL;
paul718e3742002-12-13 20:15:29 +0000289 }
290}
291
292/* Check discard flag. */
293void
294ospf_lsa_discard (struct ospf_lsa *lsa)
295{
296 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
297 {
298 SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000299 ospf_lsa_unlock (&lsa);
paul718e3742002-12-13 20:15:29 +0000300 }
301}
302
303/* Create LSA data. */
304struct lsa_header *
305ospf_lsa_data_new (size_t size)
306{
307 struct lsa_header *new;
308
309 new = (struct lsa_header *) XMALLOC (MTYPE_OSPF_LSA_DATA, size);
310 memset (new, 0, size);
311
312 return new;
313}
314
315/* Duplicate LSA data. */
316struct lsa_header *
317ospf_lsa_data_dup (struct lsa_header *lsah)
318{
319 struct lsa_header *new;
320
321 new = ospf_lsa_data_new (ntohs (lsah->length));
322 memcpy (new, lsah, ntohs (lsah->length));
323
324 return new;
325}
326
327/* Free LSA data. */
328void
329ospf_lsa_data_free (struct lsa_header *lsah)
330{
331 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000332 zlog_debug ("LSA[Type%d:%s]: data freed %p",
paul718e3742002-12-13 20:15:29 +0000333 lsah->type, inet_ntoa (lsah->id), lsah);
334
335 XFREE (MTYPE_OSPF_LSA_DATA, lsah);
336}
337
338
339/* LSA general functions. */
340
341const char *
342dump_lsa_key (struct ospf_lsa *lsa)
343{
344 static char buf[] = {
hasso52dc7ee2004-09-23 19:18:23 +0000345 "Type255,id(255.255.255.255),ar(255.255.255.255)"
paul718e3742002-12-13 20:15:29 +0000346 };
347 struct lsa_header *lsah;
348
349 if (lsa != NULL && (lsah = lsa->data) != NULL)
350 {
351 char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
352 strcpy (id, inet_ntoa (lsah->id));
353 strcpy (ar, inet_ntoa (lsah->adv_router));
354
355 sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
356 }
357 else
358 strcpy (buf, "NULL");
359
360 return buf;
361}
362
363u_int32_t
364lsa_seqnum_increment (struct ospf_lsa *lsa)
365{
366 u_int32_t seqnum;
367
368 seqnum = ntohl (lsa->data->ls_seqnum) + 1;
369
370 return htonl (seqnum);
371}
372
373void
374lsa_header_set (struct stream *s, u_char options,
paul68980082003-03-25 05:07:42 +0000375 u_char type, struct in_addr id, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +0000376{
377 struct lsa_header *lsah;
378
379 lsah = (struct lsa_header *) STREAM_DATA (s);
380
381 lsah->ls_age = htons (0);
382 lsah->options = options;
383 lsah->type = type;
384 lsah->id = id;
paul68980082003-03-25 05:07:42 +0000385 lsah->adv_router = router_id;
paul718e3742002-12-13 20:15:29 +0000386 lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
387
paul9985f832005-02-09 15:51:56 +0000388 stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000389}
390
paul68980082003-03-25 05:07:42 +0000391
paul718e3742002-12-13 20:15:29 +0000392/* router-LSA related functions. */
393/* Get router-LSA flags. */
paul4dadc292005-05-06 21:37:42 +0000394static u_char
paul718e3742002-12-13 20:15:29 +0000395router_lsa_flags (struct ospf_area *area)
396{
397 u_char flags;
398
paul68980082003-03-25 05:07:42 +0000399 flags = area->ospf->flags;
paul718e3742002-12-13 20:15:29 +0000400
401 /* Set virtual link flag. */
402 if (ospf_full_virtual_nbrs (area))
403 SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
404 else
405 /* Just sanity check */
406 UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);
407
408 /* Set Shortcut ABR behabiour flag. */
409 UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
paul68980082003-03-25 05:07:42 +0000410 if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
paul718e3742002-12-13 20:15:29 +0000411 if (!OSPF_IS_AREA_BACKBONE (area))
412 if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
paul68980082003-03-25 05:07:42 +0000413 area->ospf->backbone == NULL) ||
paul718e3742002-12-13 20:15:29 +0000414 area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
415 SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
416
417 /* ASBR can't exit in stub area. */
Greg Troxelfc787e82007-08-06 15:50:20 +0000418 if (area->external_routing == OSPF_AREA_STUB)
paul942b6c12003-06-22 08:22:18 +0000419 UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
420 /* If ASBR set External flag */
421 else if (IS_OSPF_ASBR (area->ospf))
422 SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
423
424 /* Set ABR dependent flags */
425 if (IS_OSPF_ABR (area->ospf))
426 {
427 SET_FLAG (flags, ROUTER_LSA_BORDER);
paul942b6c12003-06-22 08:22:18 +0000428 /* If Area is NSSA and we are both ABR and unconditional translator,
pauld4a53d52003-07-12 21:30:57 +0000429 * set Nt bit to inform other routers.
paul942b6c12003-06-22 08:22:18 +0000430 */
pauld4a53d52003-07-12 21:30:57 +0000431 if ( (area->external_routing == OSPF_AREA_NSSA)
432 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
433 SET_FLAG (flags, ROUTER_LSA_NT);
paul942b6c12003-06-22 08:22:18 +0000434 }
paul718e3742002-12-13 20:15:29 +0000435 return flags;
436}
437
438/* Lookup neighbor other than myself.
439 And check neighbor count,
440 Point-to-Point link must have only 1 neighbor. */
441struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +0000442ospf_nbr_lookup_ptop (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +0000443{
paul718e3742002-12-13 20:15:29 +0000444 struct ospf_neighbor *nbr = NULL;
paul68980082003-03-25 05:07:42 +0000445 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000446
447 /* Search neighbor, there must be one of two nbrs. */
paul68980082003-03-25 05:07:42 +0000448 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
449 if ((nbr = rn->info))
450 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000451 if (nbr->state == NSM_Full)
paul68980082003-03-25 05:07:42 +0000452 {
453 route_unlock_node (rn);
454 break;
455 }
paul718e3742002-12-13 20:15:29 +0000456
457 /* PtoP link must have only 1 neighbor. */
paul68980082003-03-25 05:07:42 +0000458 if (ospf_nbr_count (oi, 0) > 1)
paul718e3742002-12-13 20:15:29 +0000459 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
460
461 return nbr;
462}
463
paul88d6cf32005-10-29 12:50:09 +0000464/* Determine cost of link, taking RFC3137 stub-router support into
465 * consideration
466 */
467static u_int16_t
468ospf_link_cost (struct ospf_interface *oi)
469{
470 /* RFC3137 stub router support */
471 if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
472 return oi->output_cost;
473 else
474 return OSPF_OUTPUT_COST_INFINITE;
475}
476
paul718e3742002-12-13 20:15:29 +0000477/* Set a link information. */
paul779adb02006-01-18 15:07:38 +0000478static char
paul718e3742002-12-13 20:15:29 +0000479link_info_set (struct stream *s, struct in_addr id,
480 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
481{
paul779adb02006-01-18 15:07:38 +0000482 /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
483 * vast majority of cases. Some rare routers with lots of links need more.
484 * we try accomodate those here.
485 */
486 if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
487 {
488 size_t ret = OSPF_MAX_LSA_SIZE;
489
490 /* Can we enlarge the stream still? */
491 if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
492 {
493 /* we futz the size here for simplicity, really we need to account
494 * for just:
495 * IP Header - (sizeof (struct ip))
496 * OSPF Header - OSPF_HEADER_SIZE
497 * LSA Header - OSPF_LSA_HEADER_SIZE
498 * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
499 *
500 * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
501 */
502 ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
503 }
504
505 if (ret == OSPF_MAX_LSA_SIZE)
506 {
507 zlog_warn ("%s: Out of space in LSA stream, left %ld, size %ld",
508 __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
509 return 0;
510 }
511 }
512
paul718e3742002-12-13 20:15:29 +0000513 /* TOS based routing is not supported. */
514 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
515 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
516 stream_putc (s, type); /* Link Type. */
517 stream_putc (s, tos); /* TOS = 0. */
518 stream_putw (s, cost); /* Link Cost. */
paul779adb02006-01-18 15:07:38 +0000519
520 return 1;
paul718e3742002-12-13 20:15:29 +0000521}
522
Andrew J. Schorre4529632006-12-12 19:18:21 +0000523/* Describe Point-to-Point link (Section 12.4.1.1). */
paul4dadc292005-05-06 21:37:42 +0000524static int
paul718e3742002-12-13 20:15:29 +0000525lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
526{
527 int links = 0;
528 struct ospf_neighbor *nbr;
529 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000530 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000531
532 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000533 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
paul718e3742002-12-13 20:15:29 +0000534
paul68980082003-03-25 05:07:42 +0000535 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000536 if (nbr->state == NSM_Full)
537 {
538 /* For unnumbered point-to-point networks, the Link Data field
539 should specify the interface's MIB-II ifIndex value. */
paul779adb02006-01-18 15:07:38 +0000540 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
541 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000542 }
543
Andrew J. Schorre4529632006-12-12 19:18:21 +0000544 /* Regardless of the state of the neighboring router, we must
545 add a Type 3 link (stub network).
546 N.B. Options 1 & 2 share basically the same logic. */
547 masklen2ip (oi->address->prefixlen, &mask);
548 id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
549 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
550 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000551 return links;
552}
553
554/* Describe Broadcast Link. */
paul4dadc292005-05-06 21:37:42 +0000555static int
paul718e3742002-12-13 20:15:29 +0000556lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
557{
558 struct ospf_neighbor *dr;
559 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000560 u_int16_t cost = ospf_link_cost (oi);
561
paul718e3742002-12-13 20:15:29 +0000562 /* Describe Type 3 Link. */
563 if (oi->state == ISM_Waiting)
564 {
565 masklen2ip (oi->address->prefixlen, &mask);
566 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000567 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
568 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000569 }
570
571 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
572 /* Describe Type 2 link. */
573 if (dr && (dr->state == NSM_Full ||
574 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000575 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000576 {
paul779adb02006-01-18 15:07:38 +0000577 return link_info_set (s, DR (oi), oi->address->u.prefix4,
578 LSA_LINK_TYPE_TRANSIT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000579 }
580 /* Describe type 3 link. */
581 else
582 {
583 masklen2ip (oi->address->prefixlen, &mask);
584 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000585 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
586 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000587 }
paul718e3742002-12-13 20:15:29 +0000588}
589
paul4dadc292005-05-06 21:37:42 +0000590static int
paul718e3742002-12-13 20:15:29 +0000591lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
592{
593 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000594
paul718e3742002-12-13 20:15:29 +0000595 /* Describe Type 3 Link. */
596 if (oi->state != ISM_Loopback)
597 return 0;
598
599 mask.s_addr = 0xffffffff;
600 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000601 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000602}
603
604/* Describe Virtual Link. */
paul4dadc292005-05-06 21:37:42 +0000605static int
paul718e3742002-12-13 20:15:29 +0000606lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
607{
608 struct ospf_neighbor *nbr;
paul88d6cf32005-10-29 12:50:09 +0000609 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000610
paul718e3742002-12-13 20:15:29 +0000611 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000612 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000613 if (nbr->state == NSM_Full)
614 {
paul779adb02006-01-18 15:07:38 +0000615 return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
616 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
paul718e3742002-12-13 20:15:29 +0000617 }
618
619 return 0;
620}
621
622#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
623
paul7afa08d2002-12-13 20:59:45 +0000624/* this function add for support point-to-multipoint ,see rfc2328
62512.4.1.4.*/
626/* from "edward rrr" <edward_rrr@hotmail.com>
627 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul4dadc292005-05-06 21:37:42 +0000628static int
paul68980082003-03-25 05:07:42 +0000629lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000630{
631 int links = 0;
632 struct route_node *rn;
633 struct ospf_neighbor *nbr = NULL;
634 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000635 u_int16_t cost = ospf_link_cost (oi);
paul7afa08d2002-12-13 20:59:45 +0000636
637 mask.s_addr = 0xffffffff;
638 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000639 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
paul7afa08d2002-12-13 20:59:45 +0000640
paul1cc8f762003-04-05 19:34:32 +0000641 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000642 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000643
644 /* Search neighbor, */
645 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
646 if ((nbr = rn->info) != NULL)
647 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000648 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000649 if (nbr->state == NSM_Full)
650
651 {
paul779adb02006-01-18 15:07:38 +0000652 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
653 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul1cc8f762003-04-05 19:34:32 +0000654 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000655 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000656 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000657 }
658
659 return links;
paul7afa08d2002-12-13 20:59:45 +0000660}
661
paul718e3742002-12-13 20:15:29 +0000662/* Set router-LSA link information. */
paul4dadc292005-05-06 21:37:42 +0000663static int
paul718e3742002-12-13 20:15:29 +0000664router_lsa_link_set (struct stream *s, struct ospf_area *area)
665{
hasso52dc7ee2004-09-23 19:18:23 +0000666 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000667 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000668 int links = 0;
669
paul1eb8ef22005-04-07 07:30:20 +0000670 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +0000671 {
paul718e3742002-12-13 20:15:29 +0000672 struct interface *ifp = oi->ifp;
673
674 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000675 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000676 {
677 if (oi->state != ISM_Down)
678 {
679 /* Describe each link. */
680 switch (oi->type)
681 {
682 case OSPF_IFTYPE_POINTOPOINT:
683 links += lsa_link_ptop_set (s, oi);
684 break;
685 case OSPF_IFTYPE_BROADCAST:
686 links += lsa_link_broadcast_set (s, oi);
687 break;
688 case OSPF_IFTYPE_NBMA:
689 links += lsa_link_nbma_set (s, oi);
690 break;
691 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000692 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000693 break;
694 case OSPF_IFTYPE_VIRTUALLINK:
695 links += lsa_link_virtuallink_set (s, oi);
696 break;
697 case OSPF_IFTYPE_LOOPBACK:
698 links += lsa_link_loopback_set (s, oi);
699 }
700 }
701 }
702 }
703
704 return links;
705}
706
707/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000708static void
paul718e3742002-12-13 20:15:29 +0000709ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
710{
711 unsigned long putp;
712 u_int16_t cnt;
713
714 /* Set flags. */
715 stream_putc (s, router_lsa_flags (area));
716
717 /* Set Zero fields. */
718 stream_putc (s, 0);
719
720 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000721 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000722
723 /* Forward word */
724 stream_putw(s, 0);
725
726 /* Set all link information. */
727 cnt = router_lsa_link_set (s, area);
728
729 /* Set # of links here. */
730 stream_putw_at (s, putp, cnt);
731}
paul88d6cf32005-10-29 12:50:09 +0000732
733static int
734ospf_stub_router_timer (struct thread *t)
735{
736 struct ospf_area *area = THREAD_ARG (t);
737
738 area->t_stub_router = NULL;
739
740 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
741
742 /* clear stub route state and generate router-lsa refresh, don't
743 * clobber an administratively set stub-router state though.
744 */
745 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
746 return 0;
747
748 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
749
750 ospf_router_lsa_timer_add (area);
751
752 return 0;
753}
paul718e3742002-12-13 20:15:29 +0000754
paul88d6cf32005-10-29 12:50:09 +0000755inline static void
756ospf_stub_router_check (struct ospf_area *area)
757{
758 /* area must either be administratively configured to be stub
759 * or startup-time stub-router must be configured and we must in a pre-stub
760 * state.
761 */
762 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
763 {
764 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
765 return;
766 }
767
768 /* not admin-stubbed, check whether startup stubbing is configured and
769 * whether it's not been done yet
770 */
771 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
772 return;
773
774 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
775 {
776 /* stub-router is hence done forever for this area, even if someone
777 * tries configure it (take effect next restart).
778 */
779 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
780 return;
781 }
782
783 /* startup stub-router configured and not yet done */
784 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
785
786 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
787 area->ospf->stub_router_startup_time);
788}
789
paul718e3742002-12-13 20:15:29 +0000790/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000791static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000792ospf_router_lsa_new (struct ospf_area *area)
793{
paul68980082003-03-25 05:07:42 +0000794 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000795 struct stream *s;
796 struct lsa_header *lsah;
797 struct ospf_lsa *new;
798 int length;
799
800 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000801 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000802
paul88d6cf32005-10-29 12:50:09 +0000803 /* check whether stub-router is desired, and if this is the first
804 * router LSA.
805 */
806 ospf_stub_router_check (area);
807
paul718e3742002-12-13 20:15:29 +0000808 /* Create a stream for LSA. */
809 s = stream_new (OSPF_MAX_LSA_SIZE);
paul718e3742002-12-13 20:15:29 +0000810 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000811 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000812 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000813
814 /* Set router-LSA body fields. */
815 ospf_router_lsa_body_set (s, area);
816
817 /* Set length. */
818 length = stream_get_endp (s);
paul779adb02006-01-18 15:07:38 +0000819 lsah = (struct lsa_header *) STREAM_DATA (s);
paul718e3742002-12-13 20:15:29 +0000820 lsah->length = htons (length);
821
822 /* Now, create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000823 if ( (new = ospf_lsa_new ()) == NULL)
824 {
825 zlog_err ("%s: Unable to create new lsa", __func__);
826 return NULL;
827 }
828
paul718e3742002-12-13 20:15:29 +0000829 new->area = area;
830 SET_FLAG (new->flags, OSPF_LSA_SELF);
831
832 /* Copy LSA data to store, discard stream. */
833 new->data = ospf_lsa_data_new (length);
834 memcpy (new->data, lsah, length);
835 stream_free (s);
836
837 return new;
838}
839
840/* Originate Router-LSA. */
paul88d6cf32005-10-29 12:50:09 +0000841static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000842ospf_router_lsa_originate (struct ospf_area *area)
843{
844 struct ospf_lsa *new;
paul88d6cf32005-10-29 12:50:09 +0000845
paul718e3742002-12-13 20:15:29 +0000846 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000847 if ( (new = ospf_router_lsa_new (area)) == NULL)
848 {
849 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
850 return NULL;
851 }
paul718e3742002-12-13 20:15:29 +0000852
853 /* Sanity check. */
854 if (new->data->adv_router.s_addr == 0)
855 {
856 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000857 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000858 ospf_lsa_discard (new);
859 return NULL;
860 }
861
862 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000863 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000864
865 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000866 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000867
868 /* Flooding new LSA through area. */
869 ospf_flood_through_area (area, NULL, new);
870
871 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
872 {
ajse588f212004-12-08 18:12:06 +0000873 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
paul718e3742002-12-13 20:15:29 +0000874 new->data->type, inet_ntoa (new->data->id), new);
875 ospf_lsa_header_dump (new->data);
876 }
877
878 return new;
879}
880
881/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000882static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000883ospf_router_lsa_refresh (struct ospf_lsa *lsa)
884{
885 struct ospf_area *area = lsa->area;
886 struct ospf_lsa *new;
887
888 /* Sanity check. */
889 assert (lsa->data);
890
891 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000892 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000893
894 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000895 if ( (new = ospf_router_lsa_new (area)) == NULL)
896 {
897 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
898 return NULL;
899 }
900
paul718e3742002-12-13 20:15:29 +0000901 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
902
paul68980082003-03-25 05:07:42 +0000903 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000904
905 /* Flood LSA through area. */
906 ospf_flood_through_area (area, NULL, new);
907
908 /* Debug logging. */
909 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
910 {
ajse588f212004-12-08 18:12:06 +0000911 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000912 new->data->type, inet_ntoa (new->data->id));
913 ospf_lsa_header_dump (new->data);
914 }
915
916 return NULL;
917}
918
paul4dadc292005-05-06 21:37:42 +0000919static int
paul718e3742002-12-13 20:15:29 +0000920ospf_router_lsa_timer (struct thread *t)
921{
922 struct ospf_area *area;
923
924 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000925 zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
paul718e3742002-12-13 20:15:29 +0000926
927 area = THREAD_ARG (t);
928 area->t_router_lsa_self = NULL;
929
930 /* Now refresh router-LSA. */
931 if (area->router_lsa_self)
932 ospf_router_lsa_refresh (area->router_lsa_self);
933 /* Newly originate router-LSA. */
934 else
935 ospf_router_lsa_originate (area);
936
937 return 0;
938}
939
940void
941ospf_router_lsa_timer_add (struct ospf_area *area)
942{
943 /* Keep area's self-originated router-LSA. */
944 struct ospf_lsa *lsa = area->router_lsa_self;
945
946 /* Cancel previously scheduled router-LSA timer. */
947 if (area->t_router_lsa_self)
948 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000949 zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
paul718e3742002-12-13 20:15:29 +0000950
951 OSPF_TIMER_OFF (area->t_router_lsa_self);
952
953 /* If router-LSA is originated previously, check the interval time. */
954 if (lsa)
955 {
956 int delay;
957 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
958 {
959 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
960 ospf_router_lsa_timer, delay);
961 return;
962 }
963 }
964
965 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000966 zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
paul718e3742002-12-13 20:15:29 +0000967
968 /* Immediately refresh router-LSA. */
969 OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
970}
971
972int
paul68980082003-03-25 05:07:42 +0000973ospf_router_lsa_update_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000974{
paul68980082003-03-25 05:07:42 +0000975 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +0000976 struct listnode *node, *nnode;
977 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +0000978
979 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000980 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +0000981
paul68980082003-03-25 05:07:42 +0000982 ospf->t_router_lsa_update = NULL;
paul718e3742002-12-13 20:15:29 +0000983
paul1eb8ef22005-04-07 07:30:20 +0000984 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000985 {
paul718e3742002-12-13 20:15:29 +0000986 struct ospf_lsa *lsa = area->router_lsa_self;
987 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +0000988 const char *area_str;
paul718e3742002-12-13 20:15:29 +0000989
990 /* Keep Area ID string. */
991 area_str = AREA_NAME (area);
992
993 /* If LSA not exist in this Area, originate new. */
994 if (lsa == NULL)
995 {
996 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000997 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +0000998
999 ospf_router_lsa_originate (area);
1000 }
1001 /* If router-ID is changed, Link ID must change.
1002 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +00001003 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001004 {
1005 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001006 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +00001007 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
1008 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001009 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00001010 area->router_lsa_self = NULL;
1011
1012 /* Refresh router-LSA, (not install) and flood through area. */
1013 ospf_router_lsa_timer_add (area);
1014 }
1015 else
1016 {
1017 rl = (struct router_lsa *) lsa->data;
1018 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +00001019 if (rl->flags != ospf->flags)
paul718e3742002-12-13 20:15:29 +00001020 ospf_router_lsa_timer_add (area);
1021 }
1022 }
1023
1024 return 0;
1025}
1026
1027
1028/* network-LSA related functions. */
1029/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001030static void
paul718e3742002-12-13 20:15:29 +00001031ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1032{
1033 struct in_addr mask;
1034 struct route_node *rn;
1035 struct ospf_neighbor *nbr;
1036
1037 masklen2ip (oi->address->prefixlen, &mask);
1038 stream_put_ipv4 (s, mask.s_addr);
1039
1040 /* The network-LSA lists those routers that are fully adjacent to
1041 the Designated Router; each fully adjacent router is identified by
1042 its OSPF Router ID. The Designated Router includes itself in this
1043 list. RFC2328, Section 12.4.2 */
1044
1045 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1046 if ((nbr = rn->info) != NULL)
1047 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1048 stream_put_ipv4 (s, nbr->router_id.s_addr);
1049}
1050
paul4dadc292005-05-06 21:37:42 +00001051static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001052ospf_network_lsa_new (struct ospf_interface *oi)
1053{
1054 struct stream *s;
1055 struct ospf_lsa *new;
1056 struct lsa_header *lsah;
1057 int length;
1058
1059 /* If there are no neighbours on this network (the net is stub),
1060 the router does not originate network-LSA (see RFC 12.4.2) */
1061 if (oi->full_nbrs == 0)
1062 return NULL;
1063
1064 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001065 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001066
1067 /* Create new stream for LSA. */
1068 s = stream_new (OSPF_MAX_LSA_SIZE);
1069 lsah = (struct lsa_header *) STREAM_DATA (s);
1070
1071 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001072 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001073
1074 /* Set network-LSA body fields. */
1075 ospf_network_lsa_body_set (s, oi);
1076
1077 /* Set length. */
1078 length = stream_get_endp (s);
1079 lsah->length = htons (length);
1080
1081 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001082 if ( (new = ospf_lsa_new ()) == NULL)
1083 {
1084 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1085 return NULL;
1086 }
1087
paul718e3742002-12-13 20:15:29 +00001088 new->area = oi->area;
1089 SET_FLAG (new->flags, OSPF_LSA_SELF);
1090
1091 /* Copy LSA to store. */
1092 new->data = ospf_lsa_data_new (length);
1093 memcpy (new->data, lsah, length);
1094 stream_free (s);
1095
1096 return new;
1097}
1098
1099/* Originate network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001100static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001101ospf_network_lsa_originate (struct ospf_interface *oi)
1102{
1103 struct ospf_lsa *new;
1104
1105 /* Create new network-LSA instance. */
1106 new = ospf_network_lsa_new (oi);
1107 if (new == NULL)
1108 return NULL;
1109
1110 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001111 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001112
1113 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001114 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001115
1116 /* Flooding new LSA through area. */
1117 ospf_flood_through_area (oi->area, NULL, new);
1118
1119 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1120 {
ajse588f212004-12-08 18:12:06 +00001121 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001122 new->data->type, inet_ntoa (new->data->id), new);
1123 ospf_lsa_header_dump (new->data);
1124 }
1125
1126 return new;
1127}
1128
1129int
1130ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1131{
1132 struct ospf_area *area = lsa->area;
1133 struct ospf_lsa *new;
1134
1135 assert (lsa->data);
1136
1137 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001138 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001139
1140 /* Create new network-LSA instance. */
1141 new = ospf_network_lsa_new (oi);
1142 if (new == NULL)
1143 return -1;
1144 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1145
paul68980082003-03-25 05:07:42 +00001146 ospf_lsa_install (area->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001147
1148 /* Flood LSA through aera. */
1149 ospf_flood_through_area (area, NULL, new);
1150
1151 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1152 {
ajse588f212004-12-08 18:12:06 +00001153 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001154 new->data->type, inet_ntoa (new->data->id));
1155 ospf_lsa_header_dump (new->data);
1156 }
1157
1158 return 0;
1159}
1160
paul4dadc292005-05-06 21:37:42 +00001161static int
paul718e3742002-12-13 20:15:29 +00001162ospf_network_lsa_refresh_timer (struct thread *t)
1163{
1164 struct ospf_interface *oi;
1165
1166 oi = THREAD_ARG (t);
1167 oi->t_network_lsa_self = NULL;
1168
1169 if (oi->network_lsa_self)
1170 /* Now refresh network-LSA. */
1171 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1172 else
1173 /* Newly create network-LSA. */
1174 ospf_network_lsa_originate (oi);
1175
1176 return 0;
1177}
1178
1179void
1180ospf_network_lsa_timer_add (struct ospf_interface *oi)
1181{
1182 /* Keep interface's self-originated network-LSA. */
1183 struct ospf_lsa *lsa = oi->network_lsa_self;
1184
1185 /* Cancel previously schedules network-LSA timer. */
1186 if (oi->t_network_lsa_self)
1187 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001188 zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
paul718e3742002-12-13 20:15:29 +00001189 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1190
1191 /* If network-LSA is originated previously, check the interval time. */
1192 if (lsa)
1193 {
1194 int delay;
1195 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1196 {
1197 oi->t_network_lsa_self =
1198 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1199 oi, delay);
1200 return;
1201 }
1202 }
1203
1204 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001205 zlog_debug ("Scheduling network-LSA origination right away");
paul718e3742002-12-13 20:15:29 +00001206
1207 /* Immediately refresh network-LSA. */
1208 oi->t_network_lsa_self =
1209 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1210}
1211
1212
paul4dadc292005-05-06 21:37:42 +00001213static void
paul718e3742002-12-13 20:15:29 +00001214stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1215{
1216 u_int32_t metric;
1217 char *mp;
1218
1219 /* Put 0 metric. TOS metric is not supported. */
1220 metric = htonl (metric_value);
1221 mp = (char *) &metric;
1222 mp++;
1223 stream_put (s, mp, 3);
1224}
1225
1226/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001227static void
paul718e3742002-12-13 20:15:29 +00001228ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1229 u_int32_t metric)
1230{
1231 struct in_addr mask;
1232
1233 masklen2ip (p->prefixlen, &mask);
1234
1235 /* Put Network Mask. */
1236 stream_put_ipv4 (s, mask.s_addr);
1237
1238 /* Set # TOS. */
1239 stream_putc (s, (u_char) 0);
1240
1241 /* Set metric. */
1242 stream_put_ospf_metric (s, metric);
1243}
1244
paul4dadc292005-05-06 21:37:42 +00001245static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001246ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1247 u_int32_t metric, struct in_addr id)
1248{
1249 struct stream *s;
1250 struct ospf_lsa *new;
1251 struct lsa_header *lsah;
1252 int length;
1253
paulc24d6022005-11-20 14:54:12 +00001254 if (id.s_addr == 0xffffffff)
1255 {
1256 /* Maybe Link State ID not available. */
1257 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1258 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1259 OSPF_SUMMARY_LSA);
1260 return NULL;
1261 }
1262
paul718e3742002-12-13 20:15:29 +00001263 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001264 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001265
1266 /* Create new stream for LSA. */
1267 s = stream_new (OSPF_MAX_LSA_SIZE);
1268 lsah = (struct lsa_header *) STREAM_DATA (s);
1269
paul68980082003-03-25 05:07:42 +00001270 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1271 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001272
1273 /* Set summary-LSA body fields. */
1274 ospf_summary_lsa_body_set (s, p, metric);
1275
1276 /* Set length. */
1277 length = stream_get_endp (s);
1278 lsah->length = htons (length);
1279
1280 /* Create OSPF LSA instance. */
1281 new = ospf_lsa_new ();
1282 new->area = area;
1283 SET_FLAG (new->flags, OSPF_LSA_SELF);
1284
1285 /* Copy LSA to store. */
1286 new->data = ospf_lsa_data_new (length);
1287 memcpy (new->data, lsah, length);
1288 stream_free (s);
1289
1290 return new;
1291}
1292
1293/* Originate Summary-LSA. */
1294struct ospf_lsa *
1295ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1296 struct ospf_area *area)
1297{
1298 struct ospf_lsa *new;
1299 struct in_addr id;
1300
paul68980082003-03-25 05:07:42 +00001301 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001302
paulc24d6022005-11-20 14:54:12 +00001303 if (id.s_addr == 0xffffffff)
1304 {
1305 /* Maybe Link State ID not available. */
1306 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1307 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1308 OSPF_SUMMARY_LSA);
1309 return NULL;
1310 }
1311
paul718e3742002-12-13 20:15:29 +00001312 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001313 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1314 return NULL;
paul718e3742002-12-13 20:15:29 +00001315
1316 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001317 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001318
1319 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001320 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001321
1322 /* Flooding new LSA through area. */
1323 ospf_flood_through_area (area, NULL, new);
1324
1325 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1326 {
ajse588f212004-12-08 18:12:06 +00001327 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001328 new->data->type, inet_ntoa (new->data->id), new);
1329 ospf_lsa_header_dump (new->data);
1330 }
1331
1332 return new;
1333}
1334
1335struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001336ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001337{
1338 struct ospf_lsa *new;
1339 struct summary_lsa *sl;
1340 struct prefix p;
1341
1342 /* Sanity check. */
1343 assert (lsa->data);
1344
1345 sl = (struct summary_lsa *)lsa->data;
1346 p.prefixlen = ip_masklen (sl->mask);
1347 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1348 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001349
1350 if (!new)
1351 return NULL;
1352
paul718e3742002-12-13 20:15:29 +00001353 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1354
1355 /* Re-calculate checksum. */
1356 ospf_lsa_checksum (new->data);
1357
paul68980082003-03-25 05:07:42 +00001358 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001359
1360 /* Flood LSA through AS. */
1361 ospf_flood_through_area (new->area, NULL, new);
1362
1363 /* Debug logging. */
1364 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1365 {
ajse588f212004-12-08 18:12:06 +00001366 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001367 new->data->type, inet_ntoa (new->data->id));
1368 ospf_lsa_header_dump (new->data);
1369 }
1370
1371 return new;
1372}
1373
1374
1375/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001376static void
paul718e3742002-12-13 20:15:29 +00001377ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1378 u_int32_t metric)
1379{
1380 struct in_addr mask;
1381
1382 masklen2ip (p->prefixlen, &mask);
1383
1384 /* Put Network Mask. */
1385 stream_put_ipv4 (s, mask.s_addr);
1386
1387 /* Set # TOS. */
1388 stream_putc (s, (u_char) 0);
1389
1390 /* Set metric. */
1391 stream_put_ospf_metric (s, metric);
1392}
1393
paul4dadc292005-05-06 21:37:42 +00001394static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001395ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1396 u_int32_t metric, struct in_addr id)
1397{
1398 struct stream *s;
1399 struct ospf_lsa *new;
1400 struct lsa_header *lsah;
1401 int length;
1402
paulc24d6022005-11-20 14:54:12 +00001403 if (id.s_addr == 0xffffffff)
1404 {
1405 /* Maybe Link State ID not available. */
1406 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1407 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1408 OSPF_ASBR_SUMMARY_LSA);
1409 return NULL;
1410 }
1411
paul718e3742002-12-13 20:15:29 +00001412 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001413 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001414
1415 /* Create new stream for LSA. */
1416 s = stream_new (OSPF_MAX_LSA_SIZE);
1417 lsah = (struct lsa_header *) STREAM_DATA (s);
1418
paul68980082003-03-25 05:07:42 +00001419 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1420 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001421
1422 /* Set summary-LSA body fields. */
1423 ospf_summary_asbr_lsa_body_set (s, p, metric);
1424
1425 /* Set length. */
1426 length = stream_get_endp (s);
1427 lsah->length = htons (length);
1428
1429 /* Create OSPF LSA instance. */
1430 new = ospf_lsa_new ();
1431 new->area = area;
1432 SET_FLAG (new->flags, OSPF_LSA_SELF);
1433
1434 /* Copy LSA to store. */
1435 new->data = ospf_lsa_data_new (length);
1436 memcpy (new->data, lsah, length);
1437 stream_free (s);
1438
1439 return new;
1440}
1441
1442/* Originate summary-ASBR-LSA. */
1443struct ospf_lsa *
1444ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1445 struct ospf_area *area)
1446{
1447 struct ospf_lsa *new;
1448 struct in_addr id;
1449
paul68980082003-03-25 05:07:42 +00001450 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001451
paulc24d6022005-11-20 14:54:12 +00001452 if (id.s_addr == 0xffffffff)
1453 {
1454 /* Maybe Link State ID not available. */
1455 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1456 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1457 OSPF_ASBR_SUMMARY_LSA);
1458 return NULL;
1459 }
1460
paul718e3742002-12-13 20:15:29 +00001461 /* Create new summary-LSA instance. */
1462 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001463 if (!new)
1464 return NULL;
paul718e3742002-12-13 20:15:29 +00001465
1466 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001467 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001468
1469 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001470 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001471
1472 /* Flooding new LSA through area. */
1473 ospf_flood_through_area (area, NULL, new);
1474
1475 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1476 {
ajse588f212004-12-08 18:12:06 +00001477 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001478 new->data->type, inet_ntoa (new->data->id), new);
1479 ospf_lsa_header_dump (new->data);
1480 }
1481
1482 return new;
1483}
1484
1485struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001486ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001487{
1488 struct ospf_lsa *new;
1489 struct summary_lsa *sl;
1490 struct prefix p;
1491
1492 /* Sanity check. */
1493 assert (lsa->data);
1494
1495 sl = (struct summary_lsa *)lsa->data;
1496 p.prefixlen = ip_masklen (sl->mask);
1497 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1498 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001499 if (!new)
1500 return NULL;
paul718e3742002-12-13 20:15:29 +00001501
1502 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1503
1504 /* Re-calculate checksum. */
1505 ospf_lsa_checksum (new->data);
1506
paul68980082003-03-25 05:07:42 +00001507 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001508
1509 /* Flood LSA through area. */
1510 ospf_flood_through_area (new->area, NULL, new);
1511
1512 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1513 {
ajse588f212004-12-08 18:12:06 +00001514 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001515 new->data->type, inet_ntoa (new->data->id));
1516 ospf_lsa_header_dump (new->data);
1517 }
1518
1519 return new;
1520}
1521
1522/* AS-external-LSA related functions. */
1523
1524/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1525 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001526static struct in_addr
paul68980082003-03-25 05:07:42 +00001527ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001528{
1529 struct in_addr fwd;
1530 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001531 struct listnode *node;
1532 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001533
1534 fwd.s_addr = 0;
1535
1536 if (!nexthop.s_addr)
1537 return fwd;
1538
1539 /* Check whether nexthop is covered by OSPF network. */
1540 nh.family = AF_INET;
1541 nh.u.prefix4 = nexthop;
1542 nh.prefixlen = IPV4_MAX_BITLEN;
1543
paul1eb8ef22005-04-07 07:30:20 +00001544 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1545 if (if_is_operative (oi->ifp))
1546 if (oi->address->family == AF_INET)
1547 if (prefix_match (oi->address, &nh))
1548 return nexthop;
paul718e3742002-12-13 20:15:29 +00001549
1550 return fwd;
1551}
1552
paul718e3742002-12-13 20:15:29 +00001553/* NSSA-external-LSA related functions. */
1554
1555/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001556
paul718e3742002-12-13 20:15:29 +00001557struct in_addr
1558ospf_get_ip_from_ifp (struct ospf_interface *oi)
1559{
1560 struct in_addr fwd;
1561
1562 fwd.s_addr = 0;
1563
paul2e3b2e42002-12-13 21:03:13 +00001564 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001565 return oi->address->u.prefix4;
1566
1567 return fwd;
1568}
1569
1570/* Get 1st IP connection for Forward Addr */
1571struct in_addr
paulf2c80652002-12-13 21:44:27 +00001572ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001573{
1574 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001575 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001576 struct listnode *node;
1577 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001578
1579 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001580 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001581
paul1eb8ef22005-04-07 07:30:20 +00001582 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001583 {
paul2e3b2e42002-12-13 21:03:13 +00001584 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001585 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001586 if (oi->address && oi->address->family == AF_INET)
1587 {
1588 if (best_default.s_addr == 0)
1589 best_default = oi->address->u.prefix4;
1590 if (oi->area == area)
1591 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001592 }
paul718e3742002-12-13 20:15:29 +00001593 }
paulf2c80652002-12-13 21:44:27 +00001594 if (best_default.s_addr != 0)
1595 return best_default;
paul718e3742002-12-13 20:15:29 +00001596
paul68980082003-03-25 05:07:42 +00001597 if (best_default.s_addr != 0)
1598 return best_default;
1599
paul718e3742002-12-13 20:15:29 +00001600 return fwd;
1601}
hassobeebba72004-06-20 21:00:27 +00001602
paul718e3742002-12-13 20:15:29 +00001603#define DEFAULT_DEFAULT_METRIC 20
1604#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1605#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1606
1607#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1608
1609int
paul68980082003-03-25 05:07:42 +00001610metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001611{
paul68980082003-03-25 05:07:42 +00001612 return (ospf->dmetric[src].type < 0 ?
1613 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001614}
1615
1616int
paul68980082003-03-25 05:07:42 +00001617metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001618{
paul68980082003-03-25 05:07:42 +00001619 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001620 {
1621 if (src == DEFAULT_ROUTE)
1622 {
paul68980082003-03-25 05:07:42 +00001623 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001624 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1625 else
1626 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1627 }
paul68980082003-03-25 05:07:42 +00001628 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001629 return DEFAULT_DEFAULT_METRIC;
1630 else
paul68980082003-03-25 05:07:42 +00001631 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001632 }
1633
paul68980082003-03-25 05:07:42 +00001634 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001635}
1636
1637/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001638static void
paul68980082003-03-25 05:07:42 +00001639ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1640 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001641{
1642 struct prefix_ipv4 *p = &ei->p;
1643 struct in_addr mask, fwd_addr;
1644 u_int32_t mvalue;
1645 int mtype;
1646 int type;
1647
1648 /* Put Network Mask. */
1649 masklen2ip (p->prefixlen, &mask);
1650 stream_put_ipv4 (s, mask.s_addr);
1651
1652 /* If prefix is default, specify DEFAULT_ROUTE. */
1653 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1654
1655 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001656 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001657
1658 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001659 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001660
1661 /* Put type of external metric. */
1662 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1663
1664 /* Put 0 metric. TOS metric is not supported. */
1665 stream_put_ospf_metric (s, mvalue);
1666
1667 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001668 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001669
1670 /* Put forwarding address. */
1671 stream_put_ipv4 (s, fwd_addr.s_addr);
1672
1673 /* Put route tag -- This value should be introduced from configuration. */
1674 stream_putl (s, 0);
1675}
1676
1677/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001678static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001679ospf_external_lsa_new (struct ospf *ospf,
1680 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001681{
1682 struct stream *s;
1683 struct lsa_header *lsah;
1684 struct ospf_lsa *new;
1685 struct in_addr id;
1686 int length;
1687
1688 if (ei == NULL)
1689 {
1690 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001691 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
paul718e3742002-12-13 20:15:29 +00001692 return NULL;
1693 }
1694
1695 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001696 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001697
1698 /* If old Link State ID is specified, refresh LSA with same ID. */
1699 if (old_id)
1700 id = *old_id;
1701 /* Get Link State with unique ID. */
1702 else
1703 {
paul68980082003-03-25 05:07:42 +00001704 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001705 if (id.s_addr == 0xffffffff)
1706 {
1707 /* Maybe Link State ID not available. */
1708 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001709 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001710 return NULL;
1711 }
1712 }
1713
1714 /* Create new stream for LSA. */
1715 s = stream_new (OSPF_MAX_LSA_SIZE);
1716 lsah = (struct lsa_header *) STREAM_DATA (s);
1717
1718 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001719 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1720 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001721
1722 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001723 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001724
1725 /* Set length. */
1726 length = stream_get_endp (s);
1727 lsah->length = htons (length);
1728
1729 /* Now, create OSPF LSA instance. */
1730 new = ospf_lsa_new ();
1731 new->area = NULL;
1732 SET_FLAG (new->flags, OSPF_LSA_SELF|OSPF_LSA_APPROVED);
1733
1734 /* Copy LSA data to store, discard stream. */
1735 new->data = ospf_lsa_data_new (length);
1736 memcpy (new->data, lsah, length);
1737 stream_free (s);
1738
1739 return new;
1740}
1741
paul718e3742002-12-13 20:15:29 +00001742/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001743static void
paul68980082003-03-25 05:07:42 +00001744ospf_install_flood_nssa (struct ospf *ospf,
1745 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001746{
pauld4a53d52003-07-12 21:30:57 +00001747 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001748 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001749 struct ospf_area *area;
1750 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001751
pauld4a53d52003-07-12 21:30:57 +00001752 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1753 * which originated from an NSSA area. In which case it should not be
1754 * flooded back to NSSA areas.
1755 */
1756 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1757 return;
1758
paul718e3742002-12-13 20:15:29 +00001759 /* NSSA Originate or Refresh (If anyNSSA)
1760
1761 LSA is self-originated. And just installed as Type-5.
1762 Additionally, install as Type-7 LSDB for every attached NSSA.
1763
1764 P-Bit controls which ABR performs translation to outside world; If
1765 we are an ABR....do not set the P-bit, because we send the Type-5,
1766 not as the ABR Translator, but as the ASBR owner within the AS!
1767
1768 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1769 elected ABR Translator will see the P-bit, Translate, and re-flood.
1770
1771 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1772 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1773
paul1eb8ef22005-04-07 07:30:20 +00001774 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001775 {
hasso0c14ad82003-07-03 08:36:02 +00001776 /* Don't install Type-7 LSA's into nonNSSA area */
1777 if (area->external_routing != OSPF_AREA_NSSA)
1778 continue;
paul718e3742002-12-13 20:15:29 +00001779
paul68980082003-03-25 05:07:42 +00001780 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001781 new = ospf_lsa_dup (lsa);
1782 new->area = area;
1783 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001784
paul68980082003-03-25 05:07:42 +00001785 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001786 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001787 {
pauld4a53d52003-07-12 21:30:57 +00001788 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001789
1790 /* set non-zero FWD ADDR
1791
1792 draft-ietf-ospf-nssa-update-09.txt
1793
1794 if the network between the NSSA AS boundary router and the
1795 adjacent AS is advertised into OSPF as an internal OSPF route,
1796 the forwarding address should be the next op address as is cu
1797 currently done with type-5 LSAs. If the intervening network is
1798 not adversited into OSPF as an internal OSPF route and the
1799 type-7 LSA's P-bit is set a forwarding address should be
1800 selected from one of the router's active OSPF inteface addresses
1801 which belong to the NSSA. If no such addresses exist, then
1802 no type-7 LSA's with the P-bit set should originate from this
1803 router. */
1804
pauld4a53d52003-07-12 21:30:57 +00001805 /* kevinm: not updating lsa anymore, just new */
1806 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001807
1808 if (extlsa->e[0].fwd_addr.s_addr == 0)
1809 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001810
pauld7480322003-05-16 17:31:51 +00001811 if (extlsa->e[0].fwd_addr.s_addr == 0)
1812 {
1813 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001814 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001815 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001816 return;
1817 }
paulf2c80652002-12-13 21:44:27 +00001818 }
paul68980082003-03-25 05:07:42 +00001819 /* Re-calculate checksum. */
pauld4a53d52003-07-12 21:30:57 +00001820 ospf_lsa_checksum (new->data);
paul718e3742002-12-13 20:15:29 +00001821
paul68980082003-03-25 05:07:42 +00001822 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001823 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001824
1825 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001826 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001827 }
paul718e3742002-12-13 20:15:29 +00001828}
pauld4a53d52003-07-12 21:30:57 +00001829
paul4dadc292005-05-06 21:37:42 +00001830static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001831ospf_lsa_translated_nssa_new (struct ospf *ospf,
1832 struct ospf_lsa *type7)
1833{
1834
1835 struct ospf_lsa *new;
1836 struct as_external_lsa *ext, *extnew;
1837 struct external_info ei;
1838
1839 ext = (struct as_external_lsa *)(type7->data);
1840
1841 /* need external_info struct, fill in bare minimum */
1842 ei.p.family = AF_INET;
1843 ei.p.prefix = type7->data->id;
1844 ei.p.prefixlen = ip_masklen (ext->mask);
1845 ei.type = ZEBRA_ROUTE_OSPF;
1846 ei.nexthop = ext->header.adv_router;
1847 ei.route_map_set.metric = -1;
1848 ei.route_map_set.metric_type = -1;
1849 ei.tag = 0;
1850
1851 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1852 {
1853 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001854 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001855 "Translated Type-5 for %s",
1856 inet_ntoa (ei.p.prefix));
1857 return NULL;
1858 }
1859
1860 extnew = (struct as_external_lsa *)(new->data);
1861
1862 /* copy over Type-7 data to new */
1863 extnew->e[0].tos = ext->e[0].tos;
1864 extnew->e[0].route_tag = ext->e[0].route_tag;
1865 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1866 new->data->ls_seqnum = type7->data->ls_seqnum;
1867
1868 /* add translated flag, checksum and lock new lsa */
1869 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
1870 ospf_lsa_checksum (new->data);
1871 new = ospf_lsa_lock (new);
1872
1873 return new;
1874}
1875
1876/* compare type-5 to type-7
1877 * -1: err, 0: same, 1: different
1878 */
paul4dadc292005-05-06 21:37:42 +00001879static int
pauld4a53d52003-07-12 21:30:57 +00001880ospf_lsa_translated_nssa_compare (struct ospf_lsa *t7, struct ospf_lsa *t5)
1881{
1882
1883 struct as_external_lsa *e5 = (struct as_external_lsa *)t5,
1884 *e7 = (struct as_external_lsa *)t7;
1885
1886
1887 /* sanity checks */
1888 if (! ((t5->data->type == OSPF_AS_EXTERNAL_LSA)
1889 && (t7->data->type == OSPF_AS_NSSA_LSA)))
1890 return -1;
1891
1892 if (t5->data->id.s_addr != t7->data->id.s_addr)
1893 return -1;
1894
1895 if (t5->data->ls_seqnum != t7->data->ls_seqnum)
1896 return LSA_REFRESH_FORCE;
1897
1898 if (e5->mask.s_addr != e7->mask.s_addr)
1899 return LSA_REFRESH_FORCE;
1900
1901 if (e5->e[0].fwd_addr.s_addr != e7->e[0].fwd_addr.s_addr)
1902 return LSA_REFRESH_FORCE;
1903
1904 if (e5->e[0].route_tag != e7->e[0].route_tag)
1905 return LSA_REFRESH_FORCE;
1906
1907 if (GET_METRIC (e5->e[0].metric) != GET_METRIC (e7->e[0].metric))
1908 return LSA_REFRESH_FORCE;
1909
1910 return LSA_REFRESH_IF_CHANGED;
1911}
1912
1913/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1914struct ospf_lsa *
1915ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1916{
1917 struct ospf_lsa *new;
1918 struct as_external_lsa *extnew;
1919
1920 /* we cant use ospf_external_lsa_originate() as we need to set
1921 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1922 */
1923
1924 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1925 {
1926 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001927 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001928 "Type-7, Id %s, to Type-5",
1929 inet_ntoa (type7->data->id));
1930 return NULL;
1931 }
1932
1933 extnew = (struct as_external_lsa *)new;
1934
1935 if (IS_DEBUG_OSPF_NSSA)
1936 {
ajse588f212004-12-08 18:12:06 +00001937 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001938 "translated Type 7, installed:");
1939 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001940 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1941 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001942 }
1943
1944 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1945 {
1946 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001947 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001948 "Could not install LSA "
1949 "id %s", inet_ntoa (type7->data->id));
1950 return NULL;
1951 }
1952
1953 ospf->lsa_originate_count++;
1954 ospf_flood_through_as (ospf, NULL, new);
1955
1956 return new;
1957}
1958
1959/* Refresh Translated from NSSA AS-external-LSA. */
1960struct ospf_lsa *
1961ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1962 struct ospf_lsa *type5)
1963{
1964 struct ospf_lsa *new = NULL;
1965
1966 /* Sanity checks. */
1967 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00001968 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00001969 return NULL;
pauld4a53d52003-07-12 21:30:57 +00001970 if (type7)
1971 assert (type7->data);
1972 if (type5)
1973 assert (type5->data);
1974 assert (ospf->anyNSSA);
1975
1976 /* get required data according to what has been given */
1977 if (type7 && type5 == NULL)
1978 {
1979 /* find the translated Type-5 for this Type-7 */
1980 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1981 struct prefix_ipv4 p =
1982 {
1983 .prefix = type7->data->id,
1984 .prefixlen = ip_masklen (ext->mask),
1985 .family = AF_INET,
1986 };
1987
1988 type5 = ospf_external_info_find_lsa (ospf, &p);
1989 }
1990 else if (type5 && type7 == NULL)
1991 {
1992 /* find the type-7 from which supplied type-5 was translated,
1993 * ie find first type-7 with same LSA Id.
1994 */
paul1eb8ef22005-04-07 07:30:20 +00001995 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00001996 struct route_node *rn;
1997 struct ospf_lsa *lsa;
1998 struct ospf_area *area;
1999
paul1eb8ef22005-04-07 07:30:20 +00002000 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00002001 {
2002 if (area->external_routing != OSPF_AREA_NSSA
2003 && !type7)
2004 continue;
2005
2006 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
2007 {
2008 if (lsa->data->id.s_addr == type5->data->id.s_addr)
2009 {
2010 type7 = lsa;
2011 break;
2012 }
2013 }
2014 }
2015 }
2016
2017 /* do we have type7? */
2018 if (!type7)
2019 {
2020 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002021 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00002022 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00002023 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00002024 return NULL;
2025 }
2026
2027 /* do we have valid translated type5? */
2028 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
2029 {
2030 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002031 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00002032 "found for Type-7 with Id %s",
2033 inet_ntoa (type7->data->id));
2034 return NULL;
2035 }
2036
2037 /* Delete LSA from neighbor retransmit-list. */
2038 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
2039
2040 /* create new translated LSA */
2041 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
2042 {
2043 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002044 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00002045 "Type-7 for %s to Type-5",
2046 inet_ntoa (type7->data->id));
2047 return NULL;
2048 }
2049
2050 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
2051 {
2052 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002053 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00002054 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00002055 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00002056 return NULL;
2057 }
2058
2059 /* Flood LSA through area. */
2060 ospf_flood_through_as (ospf, NULL, new);
2061
2062 return new;
2063}
paul718e3742002-12-13 20:15:29 +00002064
2065int
2066is_prefix_default (struct prefix_ipv4 *p)
2067{
2068 struct prefix_ipv4 q;
2069
2070 q.family = AF_INET;
2071 q.prefix.s_addr = 0;
2072 q.prefixlen = 0;
2073
2074 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
2075}
2076
2077/* Originate an AS-external-LSA, install and flood. */
2078struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002079ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00002080{
2081 struct ospf_lsa *new;
2082
2083 /* Added for NSSA project....
2084
2085 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2086 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2087 every area. The Type-7's are flooded to every IR and every ABR; We
2088 install the Type-5 LSDB so that the normal "refresh" code operates
2089 as usual, and flag them as not used during ASE calculations. The
2090 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2091 Address of non-zero.
2092
2093 If an ABR is the elected NSSA translator, following SPF and during
2094 the ABR task it will translate all the scanned Type-7's, with P-bit
2095 ON and not-self generated, and translate to Type-5's throughout the
2096 non-NSSA/STUB AS.
2097
2098 A difference in operation depends whether this ASBR is an ABR
2099 or not. If not an ABR, the P-bit is ON, to indicate that any
2100 elected NSSA-ABR can perform its translation.
2101
2102 If an ABR, the P-bit is OFF; No ABR will perform translation and
2103 this ASBR will flood the Type-5 LSA as usual.
2104
2105 For the case where this ASBR is not an ABR, the ASE calculations
2106 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2107 demonstrate to the user that there are LSA's that belong to any
2108 attached NSSA.
2109
2110 Finally, it just so happens that when the ABR is translating every
2111 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2112 approved Type-5 (translated from Type-7); at the end of translation
2113 if any Translated Type-5's remain unapproved, then they must be
2114 flushed from the AS.
2115
2116 */
2117
2118 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002119 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002120 return NULL;
2121
2122 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002123 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002124 {
2125 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002126 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002127 inet_ntoa (ei->p.prefix));
2128 return NULL;
2129 }
2130
2131 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002132 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002133
2134 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002135 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002136
2137 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002138 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002139
paul718e3742002-12-13 20:15:29 +00002140 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002141 if (ospf->anyNSSA &&
2142 /* stay away from translated LSAs! */
2143 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002144 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002145
2146 /* Debug logging. */
2147 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2148 {
ajse588f212004-12-08 18:12:06 +00002149 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002150 new->data->type, inet_ntoa (new->data->id), new);
2151 ospf_lsa_header_dump (new->data);
2152 }
2153
2154 return new;
2155}
2156
2157/* Originate AS-external-LSA from external info with initial flag. */
2158int
paul68980082003-03-25 05:07:42 +00002159ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002160{
paul68980082003-03-25 05:07:42 +00002161 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002162 struct route_node *rn;
2163 struct external_info *ei;
2164 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002165 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002166
paul68980082003-03-25 05:07:42 +00002167 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002168
2169 /* Originate As-external-LSA from all type of distribute source. */
2170 if ((rt = EXTERNAL_INFO (type)))
2171 for (rn = route_top (rt); rn; rn = route_next (rn))
2172 if ((ei = rn->info) != NULL)
2173 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002174 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002175 zlog_warn ("LSA: AS-external-LSA was not originated.");
2176
2177 return 0;
2178}
2179
paul4dadc292005-05-06 21:37:42 +00002180static struct external_info *
paul020709f2003-04-04 02:44:16 +00002181ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002182{
2183 int type;
2184 struct route_node *rn;
2185 struct prefix_ipv4 p;
2186
2187 p.family = AF_INET;
2188 p.prefix.s_addr = 0;
2189 p.prefixlen = 0;
2190
2191 /* First, lookup redistributed default route. */
2192 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2193 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2194 {
2195 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2196 if (rn != NULL)
2197 {
2198 route_unlock_node (rn);
2199 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002200 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002201 return rn->info;
2202 }
2203 }
2204
2205 return NULL;
2206}
2207
2208int
paul68980082003-03-25 05:07:42 +00002209ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002210{
paul718e3742002-12-13 20:15:29 +00002211 struct prefix_ipv4 p;
2212 struct in_addr nexthop;
2213 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002214 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002215
Paul Jakma4021b602006-05-12 22:55:41 +00002216 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002217
2218 p.family = AF_INET;
2219 p.prefix.s_addr = 0;
2220 p.prefixlen = 0;
2221
Paul Jakma4021b602006-05-12 22:55:41 +00002222 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002223 {
2224 /* If there is no default route via redistribute,
2225 then originate AS-external-LSA with nexthop 0 (self). */
2226 nexthop.s_addr = 0;
2227 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2228 }
2229
paul020709f2003-04-04 02:44:16 +00002230 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002231 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002232
2233 return 0;
2234}
2235
paul645878f2003-04-13 21:42:11 +00002236/* Flush any NSSA LSAs for given prefix */
2237void
2238ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2239{
paul1eb8ef22005-04-07 07:30:20 +00002240 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002241 struct ospf_lsa *lsa;
2242 struct ospf_area *area;
2243
paul1eb8ef22005-04-07 07:30:20 +00002244 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002245 {
paul1eb8ef22005-04-07 07:30:20 +00002246 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002247 {
2248 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2249 ospf->router_id)))
2250 {
2251 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002252 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002253 inet_ntoa (p->prefix), p->prefixlen);
2254 continue;
2255 }
2256 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2257 if (!IS_LSA_MAXAGE (lsa))
2258 {
2259 ospf_refresher_unregister_lsa (ospf, lsa);
2260 ospf_lsa_flush_area (lsa, area);
2261 }
2262 }
paul645878f2003-04-13 21:42:11 +00002263 }
2264}
paul645878f2003-04-13 21:42:11 +00002265
paul718e3742002-12-13 20:15:29 +00002266/* Flush an AS-external-LSA from LSDB and routing domain. */
2267void
paul68980082003-03-25 05:07:42 +00002268ospf_external_lsa_flush (struct ospf *ospf,
2269 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002270 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002271{
2272 struct ospf_lsa *lsa;
2273
2274 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002275 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002276 inet_ntoa (p->prefix), p->prefixlen);
2277
2278 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002279 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002280 {
2281 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002282 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002283 inet_ntoa (p->prefix), p->prefixlen);
2284 return;
2285 }
hassobeebba72004-06-20 21:00:27 +00002286
pauld4a53d52003-07-12 21:30:57 +00002287 /* If LSA is selforiginated, not a translated LSA, and there is
2288 * NSSA area, flush Type-7 LSA's at first.
2289 */
2290 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2291 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002292 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002293
2294 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002295 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002296
2297 /* There must be no self-originated LSA in rtrs_external. */
2298#if 0
2299 /* Remove External route from Zebra. */
2300 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2301#endif
2302
2303 if (!IS_LSA_MAXAGE (lsa))
2304 {
2305 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002306 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002307
2308 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002309 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002310 }
2311
2312 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002313 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002314}
2315
2316void
paul68980082003-03-25 05:07:42 +00002317ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002318{
2319 struct prefix_ipv4 p;
2320 struct external_info *ei;
2321 struct ospf_lsa *lsa;
2322
2323 p.family = AF_INET;
2324 p.prefixlen = 0;
2325 p.prefix.s_addr = 0;
2326
paul020709f2003-04-04 02:44:16 +00002327 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002328 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002329
2330 if (ei)
2331 {
2332 if (lsa)
2333 {
2334 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002335 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002336 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002337 }
2338 else
2339 {
2340 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002341 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002342 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002343 }
2344 }
2345 else
2346 {
2347 if (lsa)
2348 {
2349 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002350 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002351 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002352 }
2353 }
2354}
2355
2356void
paul68980082003-03-25 05:07:42 +00002357ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002358{
2359 struct route_node *rn;
2360 struct external_info *ei;
2361
2362 if (type != DEFAULT_ROUTE)
2363 if (EXTERNAL_INFO(type))
2364 /* Refresh each redistributed AS-external-LSAs. */
2365 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2366 if ((ei = rn->info))
2367 if (!is_prefix_default (&ei->p))
2368 {
2369 struct ospf_lsa *lsa;
2370
paul68980082003-03-25 05:07:42 +00002371 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2372 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002373 else
paul68980082003-03-25 05:07:42 +00002374 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002375 }
2376}
2377
2378/* Refresh AS-external-LSA. */
2379void
paul68980082003-03-25 05:07:42 +00002380ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002381 struct external_info *ei, int force)
2382{
2383 struct ospf_lsa *new;
2384 int changed;
2385
2386 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002387 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002388 {
pauld4a53d52003-07-12 21:30:57 +00002389 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002390 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002391 "redist check fail",
2392 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002393 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002394 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +00002395 return;
2396 }
2397
2398 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002399 {
2400 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002401 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002402 lsa->data->type, inet_ntoa (lsa->data->id));
2403 return;
2404 }
paul718e3742002-12-13 20:15:29 +00002405
2406 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002407 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002408
2409 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002410 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002411
paul68980082003-03-25 05:07:42 +00002412 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002413
2414 if (new == NULL)
2415 {
2416 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002417 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002418 inet_ntoa (lsa->data->id));
2419 return;
2420 }
2421
2422 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2423
paul718e3742002-12-13 20:15:29 +00002424 /* Re-calculate checksum. */
2425 ospf_lsa_checksum (new->data);
2426
paul68980082003-03-25 05:07:42 +00002427 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002428
2429 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002430 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002431
paul718e3742002-12-13 20:15:29 +00002432 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002433 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002434 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002435
pauld4a53d52003-07-12 21:30:57 +00002436 /* Register self-originated LSA to refresh queue.
2437 * Translated LSAs should not be registered, but refreshed upon
2438 * refresh of the Type-7
2439 */
2440 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2441 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002442
2443 /* Debug logging. */
2444 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2445 {
ajse588f212004-12-08 18:12:06 +00002446 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002447 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002448 ospf_lsa_header_dump (new->data);
2449 }
2450
2451 return;
2452}
2453
2454
2455/* LSA installation functions. */
2456
2457/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002458static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002459ospf_router_lsa_install (struct ospf *ospf,
2460 struct ospf_lsa *new, int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002461{
2462 struct ospf_area *area = new->area;
2463
2464 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2465 The entire routing table must be recalculated, starting with
2466 the shortest path calculations for each area (not just the
2467 area whose link-state database has changed).
2468 */
2469 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002470 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002471
2472 if (IS_LSA_SELF (new))
2473 {
2474 /* Set router-LSA refresh timer. */
2475 OSPF_TIMER_OFF (area->t_router_lsa_self);
2476 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
pauld4a53d52003-07-12 21:30:57 +00002477 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
paul718e3742002-12-13 20:15:29 +00002478
2479 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002480 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002481 area->router_lsa_self = ospf_lsa_lock (new);
2482
2483 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002484 zlog_debug("LSA[Type%d]: ID %s seq 0x%x is self-originated",
paul0c2be262004-05-31 14:16:54 +00002485 new->data->type, inet_ntoa (new->data->id),
2486 ntohl(new->data->ls_seqnum));
paul718e3742002-12-13 20:15:29 +00002487 }
2488
2489 return new;
2490}
2491
2492#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2493 if (!(T)) \
2494 (T) = thread_add_timer (master, (F), oi, (V))
2495
2496/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002497static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002498ospf_network_lsa_install (struct ospf *ospf,
2499 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002500 struct ospf_lsa *new,
2501 int rt_recalc)
2502{
2503
2504 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2505 The entire routing table must be recalculated, starting with
2506 the shortest path calculations for each area (not just the
2507 area whose link-state database has changed).
2508 */
2509 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002510 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002511
2512 /* We supposed that when LSA is originated by us, we pass the int
2513 for which it was originated. If LSA was received by flooding,
2514 the RECEIVED flag is set, so we do not link the LSA to the int. */
2515 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2516 {
2517 /* Set LSRefresh timer. */
2518 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2519
2520 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2521 ospf_network_lsa_refresh_timer,
2522 OSPF_LS_REFRESH_TIME);
2523
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002524 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002525 oi->network_lsa_self = ospf_lsa_lock (new);
2526 }
2527
2528 return new;
2529}
2530
2531/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002532static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002533ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2534 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002535{
paul718e3742002-12-13 20:15:29 +00002536 if (rt_recalc && !IS_LSA_SELF (new))
2537 {
2538 /* RFC 2328 Section 13.2 Summary-LSAs
2539 The best route to the destination described by the summary-
2540 LSA must be recalculated (see Section 16.5). If this
2541 destination is an AS boundary router, it may also be
2542 necessary to re-examine all the AS-external-LSAs.
2543 */
2544
2545#if 0
2546 /* This doesn't exist yet... */
2547 ospf_summary_incremental_update(new); */
2548#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002549 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002550#endif /* #if 0 */
2551
2552 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002553 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002554 }
2555
2556 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002557 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002558
2559 return new;
2560}
2561
2562/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002563static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002564ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2565 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002566{
2567 if (rt_recalc && !IS_LSA_SELF (new))
2568 {
2569 /* RFC 2328 Section 13.2 Summary-LSAs
2570 The best route to the destination described by the summary-
2571 LSA must be recalculated (see Section 16.5). If this
2572 destination is an AS boundary router, it may also be
2573 necessary to re-examine all the AS-external-LSAs.
2574 */
2575#if 0
2576 /* These don't exist yet... */
2577 ospf_summary_incremental_update(new);
2578 /* Isn't this done by the above call?
2579 - RFC 2328 Section 16.5 implies it should be */
2580 /* ospf_ase_calculate_schedule(); */
2581#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002582 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002583#endif /* #if 0 */
2584 }
2585
2586 /* register LSA to refresh-list. */
2587 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002588 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002589
2590 return new;
2591}
2592
2593/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002594static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002595ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2596 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002597{
paul68980082003-03-25 05:07:42 +00002598 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002599 /* If LSA is not self-originated, calculate an external route. */
2600 if (rt_recalc)
2601 {
2602 /* RFC 2328 Section 13.2 AS-external-LSAs
2603 The best route to the destination described by the AS-
2604 external-LSA must be recalculated (see Section 16.6).
2605 */
2606
2607 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002608 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002609 }
2610
pauld4a53d52003-07-12 21:30:57 +00002611 if (new->data->type == OSPF_AS_NSSA_LSA)
2612 {
2613 /* There is no point to register selforiginate Type-7 LSA for
2614 * refreshing. We rely on refreshing Type-5 LSA's
2615 */
2616 if (IS_LSA_SELF (new))
2617 return new;
2618 else
2619 {
2620 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2621 * New translations will be taken care of by the abr_task.
2622 */
2623 ospf_translated_nssa_refresh (ospf, new, NULL);
2624 }
2625 }
pauld7480322003-05-16 17:31:51 +00002626
pauld4a53d52003-07-12 21:30:57 +00002627 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002628 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002629 */
hassobeebba72004-06-20 21:00:27 +00002630 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002631 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002632
2633 return new;
2634}
2635
2636void
paul68980082003-03-25 05:07:42 +00002637ospf_discard_from_db (struct ospf *ospf,
2638 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002639{
2640 struct ospf_lsa *old;
2641
Paul Jakmaac904de2006-06-15 12:04:57 +00002642 if (!lsdb)
2643 {
2644 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2645 if (!lsa)
2646 zlog_warn ("%s: and NULL LSA!", __func__);
2647 else
2648 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2649 lsa->data->type, inet_ntoa (lsa->data->id));
2650 return;
2651 }
2652
paul718e3742002-12-13 20:15:29 +00002653 old = ospf_lsdb_lookup (lsdb, lsa);
2654
2655 if (!old)
2656 return;
2657
2658 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002659 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002660
2661 switch (old->data->type)
2662 {
2663 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002664 ospf_ase_unregister_external_lsa (old, ospf);
2665 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2666 break;
paul718e3742002-12-13 20:15:29 +00002667#ifdef HAVE_OPAQUE_LSA
2668 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002669 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002670 break;
paul69310a62005-05-11 18:09:59 +00002671#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002672 case OSPF_AS_NSSA_LSA:
2673 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2674 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002675 break;
paul718e3742002-12-13 20:15:29 +00002676 default:
paul68980082003-03-25 05:07:42 +00002677 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002678 break;
2679 }
2680
paul68980082003-03-25 05:07:42 +00002681 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002682 ospf_lsa_discard (old);
2683}
2684
paul718e3742002-12-13 20:15:29 +00002685struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002686ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2687 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002688{
2689 struct ospf_lsa *new = NULL;
2690 struct ospf_lsa *old = NULL;
2691 struct ospf_lsdb *lsdb = NULL;
2692 int rt_recalc;
2693
2694 /* Set LSDB. */
2695 switch (lsa->data->type)
2696 {
paulf2c80652002-12-13 21:44:27 +00002697 /* kevinm */
2698 case OSPF_AS_NSSA_LSA:
2699 if (lsa->area)
2700 lsdb = lsa->area->lsdb;
2701 else
paul68980082003-03-25 05:07:42 +00002702 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002703 break;
paul718e3742002-12-13 20:15:29 +00002704 case OSPF_AS_EXTERNAL_LSA:
2705#ifdef HAVE_OPAQUE_LSA
2706 case OSPF_OPAQUE_AS_LSA:
2707#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002708 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002709 break;
2710 default:
2711 lsdb = lsa->area->lsdb;
2712 break;
2713 }
2714
paul718e3742002-12-13 20:15:29 +00002715 assert (lsdb);
2716
2717 /* RFC 2328 13.2. Installing LSAs in the database
2718
2719 Installing a new LSA in the database, either as the result of
2720 flooding or a newly self-originated LSA, may cause the OSPF
2721 routing table structure to be recalculated. The contents of the
2722 new LSA should be compared to the old instance, if present. If
2723 there is no difference, there is no need to recalculate the
2724 routing table. When comparing an LSA to its previous instance,
2725 the following are all considered to be differences in contents:
2726
2727 o The LSA's Options field has changed.
2728
2729 o One of the LSA instances has LS age set to MaxAge, and
2730 the other does not.
2731
2732 o The length field in the LSA header has changed.
2733
2734 o The body of the LSA (i.e., anything outside the 20-byte
2735 LSA header) has changed. Note that this excludes changes
2736 in LS Sequence Number and LS Checksum.
2737
2738 */
2739 /* Look up old LSA and determine if any SPF calculation or incremental
2740 update is needed */
2741 old = ospf_lsdb_lookup (lsdb, lsa);
2742
2743 /* Do comparision and record if recalc needed. */
2744 rt_recalc = 0;
2745 if ( old == NULL || ospf_lsa_different(old, lsa))
2746 rt_recalc = 1;
2747
paul7ddf1d62003-10-13 09:06:46 +00002748 /*
2749 Sequence number check (Section 14.1 of rfc 2328)
2750 "Premature aging is used when it is time for a self-originated
2751 LSA's sequence number field to wrap. At this point, the current
2752 LSA instance (having LS sequence number MaxSequenceNumber) must
2753 be prematurely aged and flushed from the routing domain before a
2754 new instance with sequence number equal to InitialSequenceNumber
2755 can be originated. "
2756 */
2757
Paul Jakmac2b478d2006-03-30 14:16:11 +00002758 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002759 {
2760 if (ospf_lsa_is_self_originated(ospf, lsa))
2761 {
paul0c2be262004-05-31 14:16:54 +00002762 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2763
2764 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002765 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2766 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2767
2768 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2769 {
ajse588f212004-12-08 18:12:06 +00002770 zlog_debug ("ospf_lsa_install() Premature Aging "
paul7ddf1d62003-10-13 09:06:46 +00002771 "lsa 0x%lx", (u_long)lsa);
2772 ospf_lsa_header_dump (lsa->data);
2773 }
2774 }
2775 else
2776 {
2777 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2778 {
ajse588f212004-12-08 18:12:06 +00002779 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002780 "that was not self originated. Ignoring\n");
2781 ospf_lsa_header_dump (lsa->data);
2782 }
2783 return old;
2784 }
2785 }
2786
paul718e3742002-12-13 20:15:29 +00002787 /* discard old LSA from LSDB */
2788 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002789 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002790
paul718e3742002-12-13 20:15:29 +00002791 /* Calculate Checksum if self-originated?. */
2792 if (IS_LSA_SELF (lsa))
2793 ospf_lsa_checksum (lsa->data);
2794
hassofe71a972004-12-22 16:16:02 +00002795 /* Insert LSA to LSDB. */
2796 ospf_lsdb_add (lsdb, lsa);
2797 lsa->lsdb = lsdb;
2798
paul718e3742002-12-13 20:15:29 +00002799 /* Do LSA specific installation process. */
2800 switch (lsa->data->type)
2801 {
2802 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002803 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002804 break;
2805 case OSPF_NETWORK_LSA:
2806 assert (oi);
paul68980082003-03-25 05:07:42 +00002807 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002808 break;
2809 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002810 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002811 break;
2812 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002813 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002814 break;
2815 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002816 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002817 break;
2818#ifdef HAVE_OPAQUE_LSA
2819 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002820 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002821 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002822 else
paul68980082003-03-25 05:07:42 +00002823 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002824 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002825 case OSPF_OPAQUE_AREA_LSA:
2826 case OSPF_OPAQUE_AS_LSA:
2827 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2828 break;
2829#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002830 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002831 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002832 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002833 break;
2834 }
2835
2836 if (new == NULL)
2837 return new; /* Installation failed, cannot proceed further -- endo. */
2838
2839 /* Debug logs. */
2840 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2841 {
2842 char area_str[INET_ADDRSTRLEN];
2843
2844 switch (lsa->data->type)
2845 {
2846 case OSPF_AS_EXTERNAL_LSA:
2847#ifdef HAVE_OPAQUE_LSA
2848 case OSPF_OPAQUE_AS_LSA:
2849#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002850 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002851 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002852 dump_lsa_key (new),
2853 LOOKUP (ospf_lsa_type_msg, new->data->type));
2854 break;
2855 default:
2856 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002857 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002858 dump_lsa_key (new),
2859 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2860 break;
2861 }
2862 }
2863
paul7ddf1d62003-10-13 09:06:46 +00002864 /*
2865 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2866 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2867 */
2868 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2869 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002870 {
paul7ddf1d62003-10-13 09:06:46 +00002871 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002872 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002873 new->data->type,
2874 inet_ntoa (new->data->id),
2875 lsa);
paul68980082003-03-25 05:07:42 +00002876 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002877 }
2878
2879 return new;
2880}
2881
2882
paul4dadc292005-05-06 21:37:42 +00002883static int
paul68980082003-03-25 05:07:42 +00002884ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002885{
paul1eb8ef22005-04-07 07:30:20 +00002886 struct listnode *node, *nnode;
2887 struct ospf_interface *oi;
2888
2889 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002890 {
paul718e3742002-12-13 20:15:29 +00002891 struct route_node *rn;
2892 struct ospf_neighbor *nbr;
2893
2894 if (ospf_if_is_enable (oi))
2895 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2896 if ((nbr = rn->info) != NULL)
2897 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2898 {
2899 route_unlock_node (rn);
2900 return 0;
2901 }
2902 }
2903
2904 return 1;
2905}
2906
2907
2908#ifdef ORIGINAL_CODING
2909/* This function flood the maxaged LSA to DR. */
2910void
2911ospf_maxage_flood (struct ospf_lsa *lsa)
2912{
2913 switch (lsa->data->type)
2914 {
2915 case OSPF_ROUTER_LSA:
2916 case OSPF_NETWORK_LSA:
2917 case OSPF_SUMMARY_LSA:
2918 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00002919 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00002920#ifdef HAVE_OPAQUE_LSA
2921 case OSPF_OPAQUE_LINK_LSA:
2922 case OSPF_OPAQUE_AREA_LSA:
2923#endif /* HAVE_OPAQUE_LSA */
2924 ospf_flood_through_area (lsa->area, NULL, lsa);
2925 break;
2926 case OSPF_AS_EXTERNAL_LSA:
2927#ifdef HAVE_OPAQUE_LSA
2928 case OSPF_OPAQUE_AS_LSA:
2929#endif /* HAVE_OPAQUE_LSA */
2930 ospf_flood_through_as (NULL, lsa);
2931 break;
2932 default:
2933 break;
2934 }
2935}
2936#endif /* ORIGINAL_CODING */
2937
paul4dadc292005-05-06 21:37:42 +00002938static int
paul718e3742002-12-13 20:15:29 +00002939ospf_maxage_lsa_remover (struct thread *thread)
2940{
paul68980082003-03-25 05:07:42 +00002941 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002942 struct ospf_lsa *lsa;
2943 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002944 int reschedule = 0;
2945
paul68980082003-03-25 05:07:42 +00002946 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002947
2948 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002949 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002950
paul68980082003-03-25 05:07:42 +00002951 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002952
2953 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002954 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002955 {
paul718e3742002-12-13 20:15:29 +00002956 if (lsa->retransmit_counter > 0)
2957 {
2958 reschedule = 1;
2959 continue;
2960 }
2961
2962 /* Remove LSA from the LSDB */
2963 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2964 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002965 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
paul7ddf1d62003-10-13 09:06:46 +00002966 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002967
2968 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002969 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002970 lsa->data->type, inet_ntoa (lsa->data->id));
2971
2972 /* Flood max age LSA. */
2973#ifdef ORIGINAL_CODING
2974 ospf_maxage_flood (lsa);
2975#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00002976 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00002977#endif /* ORIGINAL_CODING */
2978
paul7ddf1d62003-10-13 09:06:46 +00002979 if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
2980 {
2981 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002982 zlog_debug ("originating new router lsa for lsa 0x%lx \n",
paul7ddf1d62003-10-13 09:06:46 +00002983 (u_long)lsa);
2984 ospf_router_lsa_originate(lsa->area);
2985 }
2986
paul718e3742002-12-13 20:15:29 +00002987 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002988 if (lsa->lsdb)
2989 {
2990 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2991 ospf_lsdb_delete (lsa->lsdb, lsa);
2992 }
2993 else
2994 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2995 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002996 }
2997
2998 /* A MaxAge LSA must be removed immediately from the router's link
2999 state database as soon as both a) it is no longer contained on any
3000 neighbor Link state retransmission lists and b) none of the router's
3001 neighbors are in states Exchange or Loading. */
3002 if (reschedule)
paul68980082003-03-25 05:07:42 +00003003 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003004
3005 return 0;
3006}
3007
paul4dadc292005-05-06 21:37:42 +00003008static int
paul68980082003-03-25 05:07:42 +00003009ospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new)
paul718e3742002-12-13 20:15:29 +00003010{
hasso52dc7ee2004-09-23 19:18:23 +00003011 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003012 struct ospf_lsa *lsa;
3013
3014 for (ALL_LIST_ELEMENTS_RO (ospf->maxage_lsa, node, lsa))
3015 if (lsa == new)
paul718e3742002-12-13 20:15:29 +00003016 return 1;
3017
3018 return 0;
3019}
3020
3021void
paul68980082003-03-25 05:07:42 +00003022ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003023{
hasso52dc7ee2004-09-23 19:18:23 +00003024 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003025
paul68980082003-03-25 05:07:42 +00003026 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00003027 {
paul68980082003-03-25 05:07:42 +00003028 list_delete_node (ospf->maxage_lsa, n);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003029 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +00003030 }
3031}
3032
3033void
paul68980082003-03-25 05:07:42 +00003034ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003035{
3036 /* When we saw a MaxAge LSA flooded to us, we put it on the list
3037 and schedule the MaxAge LSA remover. */
paul68980082003-03-25 05:07:42 +00003038 if (ospf_lsa_maxage_exist (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003039 {
3040 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003041 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00003042 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
3043 return;
3044 }
3045
paul68980082003-03-25 05:07:42 +00003046 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00003047
3048 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003049 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003050
paul68980082003-03-25 05:07:42 +00003051 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003052}
3053
paul4dadc292005-05-06 21:37:42 +00003054static int
paul68980082003-03-25 05:07:42 +00003055ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003056{
paul718e3742002-12-13 20:15:29 +00003057 /* Stay away from any Local Translated Type-7 LSAs */
3058 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3059 return 0;
paul718e3742002-12-13 20:15:29 +00003060
3061 if (IS_LSA_MAXAGE (lsa))
3062 /* Self-originated LSAs should NOT time-out instead,
3063 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00003064 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003065 {
3066 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003067 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003068
3069 switch (lsa->data->type)
3070 {
paul718e3742002-12-13 20:15:29 +00003071#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00003072 case OSPF_OPAQUE_LINK_LSA:
3073 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003074 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003075 /*
3076 * As a general rule, whenever network topology has changed
3077 * (due to an LSA removal in this case), routing recalculation
3078 * should be triggered. However, this is not true for opaque
3079 * LSAs. Even if an opaque LSA instance is going to be removed
3080 * from the routing domain, it does not mean a change in network
3081 * topology, and thus, routing recalculation is not needed here.
3082 */
3083 break;
paul718e3742002-12-13 20:15:29 +00003084#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00003085 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003086 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003087 ospf_ase_incremental_update (ospf, lsa);
3088 break;
paul718e3742002-12-13 20:15:29 +00003089 default:
paul68980082003-03-25 05:07:42 +00003090 ospf_spf_calculate_schedule (ospf);
3091 break;
paul718e3742002-12-13 20:15:29 +00003092 }
paul68980082003-03-25 05:07:42 +00003093 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003094 }
3095
3096 return 0;
3097}
3098
3099/* Periodical check of MaxAge LSA. */
3100int
paul68980082003-03-25 05:07:42 +00003101ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003102{
paul68980082003-03-25 05:07:42 +00003103 struct ospf *ospf = THREAD_ARG (thread);
3104 struct route_node *rn;
3105 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003106 struct ospf_area *area;
3107 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003108
paul68980082003-03-25 05:07:42 +00003109 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003110
paul1eb8ef22005-04-07 07:30:20 +00003111 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003112 {
paul68980082003-03-25 05:07:42 +00003113 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3114 ospf_lsa_maxage_walker_remover (ospf, lsa);
3115 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3116 ospf_lsa_maxage_walker_remover (ospf, lsa);
3117 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3118 ospf_lsa_maxage_walker_remover (ospf, lsa);
3119 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3120 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003121#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003122 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3123 ospf_lsa_maxage_walker_remover (ospf, lsa);
3124 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3125 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003126#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003127 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3128 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003129 }
3130
paul4fb949e2003-05-10 20:06:51 +00003131 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003132 if (ospf->lsdb)
3133 {
3134 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3135 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003136#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003137 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3138 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003139#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003140 }
paul718e3742002-12-13 20:15:29 +00003141
paul68980082003-03-25 05:07:42 +00003142 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3143 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003144 return 0;
3145}
3146
paul68980082003-03-25 05:07:42 +00003147struct ospf_lsa *
3148ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3149 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003150{
paul68980082003-03-25 05:07:42 +00003151 struct ospf_lsa *lsa;
3152 struct in_addr mask, id;
3153 struct lsa_header_mask
3154 {
3155 struct lsa_header header;
3156 struct in_addr mask;
3157 } *hmask;
paul718e3742002-12-13 20:15:29 +00003158
paul68980082003-03-25 05:07:42 +00003159 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3160 if (lsa == NULL)
3161 return NULL;
paul718e3742002-12-13 20:15:29 +00003162
paul68980082003-03-25 05:07:42 +00003163 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003164
paul68980082003-03-25 05:07:42 +00003165 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003166
paul68980082003-03-25 05:07:42 +00003167 if (mask.s_addr != hmask->mask.s_addr)
3168 {
3169 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3170 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3171 if (!lsa)
3172 return NULL;
3173 }
paul718e3742002-12-13 20:15:29 +00003174
paul68980082003-03-25 05:07:42 +00003175 return lsa;
paul718e3742002-12-13 20:15:29 +00003176}
3177
3178struct ospf_lsa *
3179ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3180 struct in_addr id, struct in_addr adv_router)
3181{
paule05fba42003-04-13 20:20:53 +00003182 struct ospf *ospf = ospf_lookup();
3183 assert(ospf);
3184
paul718e3742002-12-13 20:15:29 +00003185 switch (type)
3186 {
3187 case OSPF_ROUTER_LSA:
3188 case OSPF_NETWORK_LSA:
3189 case OSPF_SUMMARY_LSA:
3190 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003191 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003192#ifdef HAVE_OPAQUE_LSA
3193 case OSPF_OPAQUE_LINK_LSA:
3194 case OSPF_OPAQUE_AREA_LSA:
3195#endif /* HAVE_OPAQUE_LSA */
3196 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003197 case OSPF_AS_EXTERNAL_LSA:
3198#ifdef HAVE_OPAQUE_LSA
3199 case OSPF_OPAQUE_AS_LSA:
3200#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003201 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003202 default:
3203 break;
3204 }
3205
3206 return NULL;
3207}
3208
3209struct ospf_lsa *
3210ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3211 struct in_addr id)
3212{
3213 struct ospf_lsa *lsa;
3214 struct route_node *rn;
3215
3216 switch (type)
3217 {
3218 case OSPF_ROUTER_LSA:
3219 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003220 case OSPF_NETWORK_LSA:
3221 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3222 if ((lsa = rn->info))
3223 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3224 {
3225 route_unlock_node (rn);
3226 return lsa;
3227 }
3228 break;
3229 case OSPF_SUMMARY_LSA:
3230 case OSPF_ASBR_SUMMARY_LSA:
3231 /* Currently not used. */
3232 assert (1);
3233 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003234 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003235 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003236#ifdef HAVE_OPAQUE_LSA
3237 case OSPF_OPAQUE_LINK_LSA:
3238 case OSPF_OPAQUE_AREA_LSA:
3239 case OSPF_OPAQUE_AS_LSA:
3240 /* Currently not used. */
3241 break;
3242#endif /* HAVE_OPAQUE_LSA */
3243 default:
3244 break;
3245 }
3246
3247 return NULL;
3248}
3249
3250struct ospf_lsa *
3251ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3252{
3253 struct ospf_lsa *match;
3254
3255#ifdef HAVE_OPAQUE_LSA
3256 /*
3257 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3258 * is redefined to have two subfields; opaque-type and opaque-id.
3259 * However, it is harmless to treat the two sub fields together, as if
3260 * they two were forming a unique LSA-ID.
3261 */
3262#endif /* HAVE_OPAQUE_LSA */
3263
3264 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3265
3266 if (match == NULL)
3267 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003268 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003269 lsah->type, inet_ntoa (lsah->id));
3270
3271 return match;
3272}
3273
3274/* return +n, l1 is more recent.
3275 return -n, l2 is more recent.
3276 return 0, l1 and l2 is identical. */
3277int
3278ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3279{
3280 int r;
3281 int x, y;
3282
3283 if (l1 == NULL && l2 == NULL)
3284 return 0;
3285 if (l1 == NULL)
3286 return -1;
3287 if (l2 == NULL)
3288 return 1;
3289
3290 /* compare LS sequence number. */
3291 x = (int) ntohl (l1->data->ls_seqnum);
3292 y = (int) ntohl (l2->data->ls_seqnum);
3293 if (x > y)
3294 return 1;
3295 if (x < y)
3296 return -1;
3297
3298 /* compare LS checksum. */
3299 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3300 if (r)
3301 return r;
3302
3303 /* compare LS age. */
3304 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3305 return 1;
3306 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3307 return -1;
3308
3309 /* compare LS age with MaxAgeDiff. */
3310 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3311 return -1;
3312 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3313 return 1;
3314
3315 /* LSAs are identical. */
3316 return 0;
3317}
3318
3319/* If two LSAs are different, return 1, otherwise return 0. */
3320int
3321ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3322{
3323 char *p1, *p2;
3324 assert (l1);
3325 assert (l2);
3326 assert (l1->data);
3327 assert (l2->data);
3328
3329 if (l1->data->options != l2->data->options)
3330 return 1;
3331
3332 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3333 return 1;
3334
3335 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3336 return 1;
3337
3338 if (l1->data->length != l2->data->length)
3339 return 1;
3340
3341 if (l1->data->length == 0)
3342 return 1;
3343
pauld1825832003-04-03 01:27:01 +00003344 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003345
3346 p1 = (char *) l1->data;
3347 p2 = (char *) l2->data;
3348
3349 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3350 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3351 return 1;
3352
3353 return 0;
3354}
3355
3356#ifdef ORIGINAL_CODING
3357void
3358ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3359 struct ospf_lsa *self,
3360 struct ospf_lsa *new)
3361{
3362 u_int32_t seqnum;
3363
3364 /* Adjust LS Sequence Number. */
3365 seqnum = ntohl (new->data->ls_seqnum) + 1;
3366 self->data->ls_seqnum = htonl (seqnum);
3367
3368 /* Recalculate LSA checksum. */
3369 ospf_lsa_checksum (self->data);
3370
3371 /* Reflooding LSA. */
3372 /* RFC2328 Section 13.3
3373 On non-broadcast networks, separate Link State Update
3374 packets must be sent, as unicasts, to each adjacent neighbor
3375 (i.e., those in state Exchange or greater). The destination
3376 IP addresses for these packets are the neighbors' IP
3377 addresses. */
3378 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3379 {
3380 struct route_node *rn;
3381 struct ospf_neighbor *onbr;
3382
3383 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3384 if ((onbr = rn->info) != NULL)
3385 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3386 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3387 }
3388 else
3389 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3390
3391 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003392 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003393 self->data->type, inet_ntoa (self->data->id));
3394}
3395#else /* ORIGINAL_CODING */
3396static int
paul68980082003-03-25 05:07:42 +00003397ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003398{
3399 if (lsa == NULL || !IS_LSA_SELF (lsa))
3400 return 0;
3401
3402 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003403 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 +00003404
3405 /* Force given lsa's age to MaxAge. */
3406 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3407
3408 switch (lsa->data->type)
3409 {
3410#ifdef HAVE_OPAQUE_LSA
3411 case OSPF_OPAQUE_LINK_LSA:
3412 case OSPF_OPAQUE_AREA_LSA:
3413 case OSPF_OPAQUE_AS_LSA:
3414 ospf_opaque_lsa_refresh (lsa);
3415 break;
3416#endif /* HAVE_OPAQUE_LSA */
3417 default:
paul68980082003-03-25 05:07:42 +00003418 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003419 break;
3420 }
3421
3422 return 0;
3423}
3424
3425void
paul68980082003-03-25 05:07:42 +00003426ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003427{
paul1eb8ef22005-04-07 07:30:20 +00003428 struct listnode *node, *nnode;
3429 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003430 struct ospf_area *area;
3431 struct ospf_interface *oi;
3432 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003433 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003434 int need_to_flush_ase = 0;
3435
paul1eb8ef22005-04-07 07:30:20 +00003436 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003437 {
paul718e3742002-12-13 20:15:29 +00003438 if ((lsa = area->router_lsa_self) != NULL)
3439 {
3440 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003441 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 +00003442
3443 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003444 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003445 area->router_lsa_self = NULL;
3446 OSPF_TIMER_OFF (area->t_router_lsa_self);
3447 }
3448
paul1eb8ef22005-04-07 07:30:20 +00003449 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003450 {
paul718e3742002-12-13 20:15:29 +00003451 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003452 && oi->state == ISM_DR
3453 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003454 {
3455 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003456 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 +00003457
3458 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003459 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003460 oi->network_lsa_self = NULL;
3461 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3462 }
3463
3464 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3465 && area->external_routing == OSPF_AREA_DEFAULT)
3466 need_to_flush_ase = 1;
3467 }
3468
paul68980082003-03-25 05:07:42 +00003469 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3470 ospf_lsa_flush_schedule (ospf, lsa);
3471 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3472 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003473#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003474 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3475 ospf_lsa_flush_schedule (ospf, lsa);
3476 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3477 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003478#endif /* HAVE_OPAQUE_LSA */
3479 }
3480
3481 if (need_to_flush_ase)
3482 {
paul68980082003-03-25 05:07:42 +00003483 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3484 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003485#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003486 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3487 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003488#endif /* HAVE_OPAQUE_LSA */
3489 }
3490
3491 /*
3492 * Make sure that the MaxAge LSA remover is executed immediately,
3493 * without conflicting to other threads.
3494 */
paul68980082003-03-25 05:07:42 +00003495 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003496 {
paul68980082003-03-25 05:07:42 +00003497 OSPF_TIMER_OFF (ospf->t_maxage);
3498 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003499 }
3500
3501 return;
3502}
3503#endif /* ORIGINAL_CODING */
3504
3505/* If there is self-originated LSA, then return 1, otherwise return 0. */
3506/* An interface-independent version of ospf_lsa_is_self_originated */
3507int
paul68980082003-03-25 05:07:42 +00003508ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003509{
hasso52dc7ee2004-09-23 19:18:23 +00003510 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003511 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003512
3513 /* This LSA is already checked. */
3514 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3515 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3516
3517 /* Make sure LSA is self-checked. */
3518 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3519
3520 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003521 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003522 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3523
3524 /* LSA is router-LSA. */
3525 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003526 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003527 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3528
3529 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3530 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003531 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003532 {
paul718e3742002-12-13 20:15:29 +00003533 /* Ignore virtual link. */
3534 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3535 if (oi->address->family == AF_INET)
3536 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3537 {
3538 /* to make it easier later */
3539 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3540 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3541 }
3542 }
3543
3544 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3545}
3546
3547/* Get unique Link State ID. */
3548struct in_addr
paul68980082003-03-25 05:07:42 +00003549ospf_lsa_unique_id (struct ospf *ospf,
3550 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003551{
3552 struct ospf_lsa *lsa;
3553 struct in_addr mask, id;
3554
3555 id = p->prefix;
3556
3557 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003558 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003559 if (lsa)
3560 {
3561 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3562 if (ip_masklen (al->mask) == p->prefixlen)
3563 {
3564 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003565 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003566 "Can't get Link State ID for %s/%d",
3567 inet_ntoa (p->prefix), p->prefixlen);
3568 /* id.s_addr = 0; */
3569 id.s_addr = 0xffffffff;
3570 return id;
3571 }
3572 /* Masklen differs, then apply wildcard mask to Link State ID. */
3573 else
3574 {
3575 masklen2ip (p->prefixlen, &mask);
3576
3577 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003578 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3579 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003580 if (lsa)
3581 {
3582 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003583 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003584 "Can't get Link State ID for %s/%d",
3585 inet_ntoa (p->prefix), p->prefixlen);
3586 /* id.s_addr = 0; */
3587 id.s_addr = 0xffffffff;
3588 return id;
3589 }
3590 }
3591 }
3592
3593 return id;
3594}
3595
3596
Paul Jakma70461d72006-05-12 22:57:57 +00003597#define LSA_ACTION_FLOOD_AREA 1
3598#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003599
3600struct lsa_action
3601{
3602 u_char action;
3603 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003604 struct ospf_lsa *lsa;
3605};
3606
paul4dadc292005-05-06 21:37:42 +00003607static int
paul718e3742002-12-13 20:15:29 +00003608ospf_lsa_action (struct thread *t)
3609{
3610 struct lsa_action *data;
3611
3612 data = THREAD_ARG (t);
3613
3614 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003615 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003616 data->action);
3617
3618 switch (data->action)
3619 {
paul718e3742002-12-13 20:15:29 +00003620 case LSA_ACTION_FLOOD_AREA:
3621 ospf_flood_through_area (data->area, NULL, data->lsa);
3622 break;
paul718e3742002-12-13 20:15:29 +00003623 case LSA_ACTION_FLUSH_AREA:
3624 ospf_lsa_flush_area (data->lsa, data->area);
3625 break;
paul718e3742002-12-13 20:15:29 +00003626 }
3627
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003628 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003629 XFREE (MTYPE_OSPF_MESSAGE, data);
3630 return 0;
3631}
3632
3633void
3634ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3635{
3636 struct lsa_action *data;
3637
3638 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3639 memset (data, 0, sizeof (struct lsa_action));
3640
3641 data->action = LSA_ACTION_FLOOD_AREA;
3642 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003643 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003644
3645 thread_add_event (master, ospf_lsa_action, data, 0);
3646}
3647
3648void
3649ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3650{
3651 struct lsa_action *data;
3652
3653 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3654 memset (data, 0, sizeof (struct lsa_action));
3655
3656 data->action = LSA_ACTION_FLUSH_AREA;
3657 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003658 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003659
3660 thread_add_event (master, ospf_lsa_action, data, 0);
3661}
3662
3663
3664/* LSA Refreshment functions. */
paul4dadc292005-05-06 21:37:42 +00003665static void
paul68980082003-03-25 05:07:42 +00003666ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003667{
3668 struct external_info *ei;
3669 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3670
3671 switch (lsa->data->type)
3672 {
3673 /* Router and Network LSAs are processed differently. */
3674 case OSPF_ROUTER_LSA:
3675 case OSPF_NETWORK_LSA:
3676 break;
3677 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003678 ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003679 break;
3680 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003681 ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003682 break;
3683 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003684 /* Translated from NSSA Type-5s are refreshed when
3685 * from refresh of Type-7 - do not refresh these directly.
3686 */
3687 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3688 break;
paul718e3742002-12-13 20:15:29 +00003689 ei = ospf_external_info_check (lsa);
3690 if (ei)
pauld4a53d52003-07-12 21:30:57 +00003691 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003692 else
pauld4a53d52003-07-12 21:30:57 +00003693 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003694 break;
3695#ifdef HAVE_OPAQUE_LSA
3696 case OSPF_OPAQUE_LINK_LSA:
3697 case OSPF_OPAQUE_AREA_LSA:
3698 case OSPF_OPAQUE_AS_LSA:
3699 ospf_opaque_lsa_refresh (lsa);
3700 break;
pauld7480322003-05-16 17:31:51 +00003701#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003702 default:
3703 break;
paul718e3742002-12-13 20:15:29 +00003704 }
3705}
3706
3707void
paul68980082003-03-25 05:07:42 +00003708ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003709{
3710 u_int16_t index, current_index;
3711
3712 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3713
3714 if (lsa->refresh_list < 0)
3715 {
3716 int delay;
3717
3718 if (LS_AGE (lsa) == 0 &&
3719 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3720 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3721 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3722 else
3723 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3724 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3725 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3726
3727 if (delay < 0)
3728 delay = 0;
3729
paul68980082003-03-25 05:07:42 +00003730 current_index = ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003731 (quagga_time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003732
3733 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3734 % (OSPF_LSA_REFRESHER_SLOTS);
3735
3736 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003737 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003738 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003739 if (!ospf->lsa_refresh_queue.qs[index])
3740 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003741 listnode_add (ospf->lsa_refresh_queue.qs[index],
3742 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003743 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003744 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003745 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003746 "setting refresh_list on lsa %p (slod %d)",
3747 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003748 }
3749}
3750
3751void
paul68980082003-03-25 05:07:42 +00003752ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003753{
3754 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3755 if (lsa->refresh_list >= 0)
3756 {
hasso52dc7ee2004-09-23 19:18:23 +00003757 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003758 listnode_delete (refresh_list, lsa);
3759 if (!listcount (refresh_list))
3760 {
3761 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003762 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003763 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003764 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003765 lsa->refresh_list = -1;
3766 }
3767}
3768
3769int
3770ospf_lsa_refresh_walker (struct thread *t)
3771{
hasso52dc7ee2004-09-23 19:18:23 +00003772 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003773 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003774 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003775 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003776 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003777 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003778
3779 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003780 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003781
3782
paul68980082003-03-25 05:07:42 +00003783 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003784
ajs9dbc7972005-03-13 19:27:22 +00003785 /* Note: if clock has jumped backwards, then time change could be negative,
3786 so we are careful to cast the expression to unsigned before taking
3787 modulus. */
paul68980082003-03-25 05:07:42 +00003788 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003789 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003790 (quagga_time (NULL) - ospf->lsa_refresher_started) /
ajs9dbc7972005-03-13 19:27:22 +00003791 OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003792
3793 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003794 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003795 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003796
paul68980082003-03-25 05:07:42 +00003797 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003798 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3799 {
3800 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003801 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003802 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003803
paul68980082003-03-25 05:07:42 +00003804 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003805
paul68980082003-03-25 05:07:42 +00003806 ospf->lsa_refresh_queue.qs [i] = NULL;
3807
paul718e3742002-12-13 20:15:29 +00003808 if (refresh_list)
3809 {
paul1eb8ef22005-04-07 07:30:20 +00003810 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003811 {
paul718e3742002-12-13 20:15:29 +00003812 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003813 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003814 "refresh lsa %p (slot %d)",
3815 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003816
3817 list_delete_node (refresh_list, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003818 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003819 lsa->refresh_list = -1;
3820 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003821 }
3822 list_free (refresh_list);
3823 }
3824 }
3825
paul68980082003-03-25 05:07:42 +00003826 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3827 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003828 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003829
paul1eb8ef22005-04-07 07:30:20 +00003830 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
3831 ospf_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003832
3833 list_delete (lsa_to_refresh);
3834
3835 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003836 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003837
3838 return 0;
3839}
3840