blob: bdc40151a8ef97e705e9a564c6921800d761f26c [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
2 * OSPF Link State Advertisement
3 * Copyright (C) 1999, 2000 Toshiaki Takada
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "linklist.h"
26#include "prefix.h"
27#include "if.h"
28#include "table.h"
29#include "memory.h"
30#include "stream.h"
31#include "log.h"
32#include "thread.h"
33#include "hash.h"
34#include "sockunion.h" /* for inet_aton() */
Jingjing Duan6a270cd2008-08-13 19:09:10 +010035#include "checksum.h"
paul718e3742002-12-13 20:15:29 +000036
37#include "ospfd/ospfd.h"
38#include "ospfd/ospf_interface.h"
39#include "ospfd/ospf_ism.h"
40#include "ospfd/ospf_asbr.h"
41#include "ospfd/ospf_lsa.h"
42#include "ospfd/ospf_lsdb.h"
43#include "ospfd/ospf_neighbor.h"
44#include "ospfd/ospf_nsm.h"
45#include "ospfd/ospf_flood.h"
46#include "ospfd/ospf_packet.h"
47#include "ospfd/ospf_spf.h"
48#include "ospfd/ospf_dump.h"
49#include "ospfd/ospf_route.h"
50#include "ospfd/ospf_ase.h"
51#include "ospfd/ospf_zebra.h"
52
53
54u_int32_t
55get_metric (u_char *metric)
56{
57 u_int32_t m;
58 m = metric[0];
59 m = (m << 8) + metric[1];
60 m = (m << 8) + metric[2];
61 return m;
62}
63
64
65struct timeval
66tv_adjust (struct timeval a)
67{
68 while (a.tv_usec >= 1000000)
69 {
70 a.tv_usec -= 1000000;
71 a.tv_sec++;
72 }
73
74 while (a.tv_usec < 0)
75 {
76 a.tv_usec += 1000000;
77 a.tv_sec--;
78 }
79
80 return a;
81}
82
83int
84tv_ceil (struct timeval a)
85{
86 a = tv_adjust (a);
87
88 return (a.tv_usec ? a.tv_sec + 1 : a.tv_sec);
89}
90
91int
92tv_floor (struct timeval a)
93{
94 a = tv_adjust (a);
95
96 return a.tv_sec;
97}
98
99struct timeval
100int2tv (int a)
101{
102 struct timeval ret;
103
104 ret.tv_sec = a;
105 ret.tv_usec = 0;
106
107 return ret;
108}
109
110struct timeval
111tv_add (struct timeval a, struct timeval b)
112{
113 struct timeval ret;
114
115 ret.tv_sec = a.tv_sec + b.tv_sec;
116 ret.tv_usec = a.tv_usec + b.tv_usec;
117
118 return tv_adjust (ret);
119}
120
121struct timeval
122tv_sub (struct timeval a, struct timeval b)
123{
124 struct timeval ret;
125
126 ret.tv_sec = a.tv_sec - b.tv_sec;
127 ret.tv_usec = a.tv_usec - b.tv_usec;
128
129 return tv_adjust (ret);
130}
131
132int
133tv_cmp (struct timeval a, struct timeval b)
134{
135 return (a.tv_sec == b.tv_sec ?
136 a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
137}
138
139int
140ospf_lsa_refresh_delay (struct ospf_lsa *lsa)
141{
142 struct timeval delta, now;
143 int delay = 0;
144
Paul Jakma2518efd2006-08-27 06:49:29 +0000145 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +0000146 delta = tv_sub (now, lsa->tv_orig);
147
148 if (tv_cmp (delta, int2tv (OSPF_MIN_LS_INTERVAL)) < 0)
149 {
150 delay = tv_ceil (tv_sub (int2tv (OSPF_MIN_LS_INTERVAL), delta));
151
152 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000153 zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
paul718e3742002-12-13 20:15:29 +0000154 lsa->data->type, inet_ntoa (lsa->data->id), delay);
155
156 assert (delay > 0);
157 }
158
159 return delay;
160}
161
162
163int
164get_age (struct ospf_lsa *lsa)
165{
166 int age;
paul718e3742002-12-13 20:15:29 +0000167
Paul Jakma2518efd2006-08-27 06:49:29 +0000168 age = ntohs (lsa->data->ls_age)
169 + tv_floor (tv_sub (recent_relative_time (), lsa->tv_recv));
paul718e3742002-12-13 20:15:29 +0000170
171 return age;
172}
173
174
175/* Fletcher Checksum -- Refer to RFC1008. */
paul718e3742002-12-13 20:15:29 +0000176
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100177/* All the offsets are zero-based. The offsets in the RFC1008 are
178 one-based. */
paul718e3742002-12-13 20:15:29 +0000179u_int16_t
180ospf_lsa_checksum (struct lsa_header *lsa)
181{
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100182 u_char *buffer = (u_char *) &lsa->options;
183 int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */
paul718e3742002-12-13 20:15:29 +0000184
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100185 /* Skip the AGE field */
186 u_int16_t len = ntohs(lsa->length) - options_offset;
paul718e3742002-12-13 20:15:29 +0000187
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100188 /* Checksum offset starts from "options" field, not the beginning of the
189 lsa_header struct. The offset is 14, rather than 16. */
190 int checksum_offset = (u_char *) &lsa->checksum - buffer;
paul718e3742002-12-13 20:15:29 +0000191
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100192 return fletcher_checksum(buffer, len, checksum_offset);
paul718e3742002-12-13 20:15:29 +0000193}
194
195
196
197/* Create OSPF LSA. */
198struct ospf_lsa *
199ospf_lsa_new ()
200{
201 struct ospf_lsa *new;
202
203 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
paul718e3742002-12-13 20:15:29 +0000204
205 new->flags = 0;
206 new->lock = 1;
207 new->retransmit_counter = 0;
Paul Jakma2518efd2006-08-27 06:49:29 +0000208 new->tv_recv = recent_relative_time ();
paul718e3742002-12-13 20:15:29 +0000209 new->tv_orig = new->tv_recv;
210 new->refresh_list = -1;
211
212 return new;
213}
214
215/* Duplicate OSPF LSA. */
216struct ospf_lsa *
217ospf_lsa_dup (struct ospf_lsa *lsa)
218{
219 struct ospf_lsa *new;
220
221 if (lsa == NULL)
222 return NULL;
223
224 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
225
226 memcpy (new, lsa, sizeof (struct ospf_lsa));
227 UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
228 new->lock = 1;
229 new->retransmit_counter = 0;
230 new->data = ospf_lsa_data_dup (lsa->data);
231
paulf2c80652002-12-13 21:44:27 +0000232 /* kevinm: Clear the refresh_list, otherwise there are going
233 to be problems when we try to remove the LSA from the
234 queue (which it's not a member of.)
235 XXX: Should we add the LSA to the refresh_list queue? */
236 new->refresh_list = -1;
237
238 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000239 zlog_debug ("LSA: duplicated %p (new: %p)", lsa, new);
paulf2c80652002-12-13 21:44:27 +0000240
paul718e3742002-12-13 20:15:29 +0000241 return new;
242}
243
244/* Free OSPF LSA. */
245void
246ospf_lsa_free (struct ospf_lsa *lsa)
247{
248 assert (lsa->lock == 0);
249
250 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000251 zlog_debug ("LSA: freed %p", lsa);
paul718e3742002-12-13 20:15:29 +0000252
253 /* Delete LSA data. */
254 if (lsa->data != NULL)
255 ospf_lsa_data_free (lsa->data);
256
257 assert (lsa->refresh_list < 0);
258
259 memset (lsa, 0, sizeof (struct ospf_lsa));
260 XFREE (MTYPE_OSPF_LSA, lsa);
261}
262
263/* Lock LSA. */
264struct ospf_lsa *
265ospf_lsa_lock (struct ospf_lsa *lsa)
266{
267 lsa->lock++;
268 return lsa;
269}
270
271/* Unlock LSA. */
272void
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000273ospf_lsa_unlock (struct ospf_lsa **lsa)
paul718e3742002-12-13 20:15:29 +0000274{
275 /* This is sanity check. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000276 if (!lsa || !*lsa)
paul718e3742002-12-13 20:15:29 +0000277 return;
278
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000279 (*lsa)->lock--;
paul718e3742002-12-13 20:15:29 +0000280
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000281 assert ((*lsa)->lock >= 0);
paul718e3742002-12-13 20:15:29 +0000282
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000283 if ((*lsa)->lock == 0)
paul718e3742002-12-13 20:15:29 +0000284 {
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000285 assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
286 ospf_lsa_free (*lsa);
287 *lsa = NULL;
paul718e3742002-12-13 20:15:29 +0000288 }
289}
290
291/* Check discard flag. */
292void
293ospf_lsa_discard (struct ospf_lsa *lsa)
294{
295 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
296 {
297 SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000298 ospf_lsa_unlock (&lsa);
paul718e3742002-12-13 20:15:29 +0000299 }
300}
301
302/* Create LSA data. */
303struct lsa_header *
304ospf_lsa_data_new (size_t size)
305{
Stephen Hemminger393deb92008-08-18 14:13:29 -0700306 return XCALLOC (MTYPE_OSPF_LSA_DATA, size);
paul718e3742002-12-13 20:15:29 +0000307}
308
309/* Duplicate LSA data. */
310struct lsa_header *
311ospf_lsa_data_dup (struct lsa_header *lsah)
312{
313 struct lsa_header *new;
314
315 new = ospf_lsa_data_new (ntohs (lsah->length));
316 memcpy (new, lsah, ntohs (lsah->length));
317
318 return new;
319}
320
321/* Free LSA data. */
322void
323ospf_lsa_data_free (struct lsa_header *lsah)
324{
325 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000326 zlog_debug ("LSA[Type%d:%s]: data freed %p",
paul718e3742002-12-13 20:15:29 +0000327 lsah->type, inet_ntoa (lsah->id), lsah);
328
329 XFREE (MTYPE_OSPF_LSA_DATA, lsah);
330}
331
332
333/* LSA general functions. */
334
335const char *
336dump_lsa_key (struct ospf_lsa *lsa)
337{
338 static char buf[] = {
hasso52dc7ee2004-09-23 19:18:23 +0000339 "Type255,id(255.255.255.255),ar(255.255.255.255)"
paul718e3742002-12-13 20:15:29 +0000340 };
341 struct lsa_header *lsah;
342
343 if (lsa != NULL && (lsah = lsa->data) != NULL)
344 {
345 char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
346 strcpy (id, inet_ntoa (lsah->id));
347 strcpy (ar, inet_ntoa (lsah->adv_router));
348
349 sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
350 }
351 else
352 strcpy (buf, "NULL");
353
354 return buf;
355}
356
357u_int32_t
358lsa_seqnum_increment (struct ospf_lsa *lsa)
359{
360 u_int32_t seqnum;
361
362 seqnum = ntohl (lsa->data->ls_seqnum) + 1;
363
364 return htonl (seqnum);
365}
366
367void
368lsa_header_set (struct stream *s, u_char options,
paul68980082003-03-25 05:07:42 +0000369 u_char type, struct in_addr id, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +0000370{
371 struct lsa_header *lsah;
372
373 lsah = (struct lsa_header *) STREAM_DATA (s);
374
375 lsah->ls_age = htons (0);
376 lsah->options = options;
377 lsah->type = type;
378 lsah->id = id;
paul68980082003-03-25 05:07:42 +0000379 lsah->adv_router = router_id;
paul718e3742002-12-13 20:15:29 +0000380 lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
381
paul9985f832005-02-09 15:51:56 +0000382 stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000383}
384
paul68980082003-03-25 05:07:42 +0000385
paul718e3742002-12-13 20:15:29 +0000386/* router-LSA related functions. */
387/* Get router-LSA flags. */
paul4dadc292005-05-06 21:37:42 +0000388static u_char
paul718e3742002-12-13 20:15:29 +0000389router_lsa_flags (struct ospf_area *area)
390{
391 u_char flags;
392
paul68980082003-03-25 05:07:42 +0000393 flags = area->ospf->flags;
paul718e3742002-12-13 20:15:29 +0000394
395 /* Set virtual link flag. */
396 if (ospf_full_virtual_nbrs (area))
397 SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
398 else
399 /* Just sanity check */
400 UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);
401
402 /* Set Shortcut ABR behabiour flag. */
403 UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
paul68980082003-03-25 05:07:42 +0000404 if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
paul718e3742002-12-13 20:15:29 +0000405 if (!OSPF_IS_AREA_BACKBONE (area))
406 if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
paul68980082003-03-25 05:07:42 +0000407 area->ospf->backbone == NULL) ||
paul718e3742002-12-13 20:15:29 +0000408 area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
409 SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
410
411 /* ASBR can't exit in stub area. */
Greg Troxelfc787e82007-08-06 15:50:20 +0000412 if (area->external_routing == OSPF_AREA_STUB)
paul942b6c12003-06-22 08:22:18 +0000413 UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
414 /* If ASBR set External flag */
415 else if (IS_OSPF_ASBR (area->ospf))
416 SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
417
418 /* Set ABR dependent flags */
419 if (IS_OSPF_ABR (area->ospf))
420 {
421 SET_FLAG (flags, ROUTER_LSA_BORDER);
paul942b6c12003-06-22 08:22:18 +0000422 /* If Area is NSSA and we are both ABR and unconditional translator,
pauld4a53d52003-07-12 21:30:57 +0000423 * set Nt bit to inform other routers.
paul942b6c12003-06-22 08:22:18 +0000424 */
pauld4a53d52003-07-12 21:30:57 +0000425 if ( (area->external_routing == OSPF_AREA_NSSA)
426 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
427 SET_FLAG (flags, ROUTER_LSA_NT);
paul942b6c12003-06-22 08:22:18 +0000428 }
paul718e3742002-12-13 20:15:29 +0000429 return flags;
430}
431
432/* Lookup neighbor other than myself.
433 And check neighbor count,
434 Point-to-Point link must have only 1 neighbor. */
435struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +0000436ospf_nbr_lookup_ptop (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +0000437{
paul718e3742002-12-13 20:15:29 +0000438 struct ospf_neighbor *nbr = NULL;
paul68980082003-03-25 05:07:42 +0000439 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000440
441 /* Search neighbor, there must be one of two nbrs. */
paul68980082003-03-25 05:07:42 +0000442 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
443 if ((nbr = rn->info))
444 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000445 if (nbr->state == NSM_Full)
paul68980082003-03-25 05:07:42 +0000446 {
447 route_unlock_node (rn);
448 break;
449 }
paul718e3742002-12-13 20:15:29 +0000450
451 /* PtoP link must have only 1 neighbor. */
paul68980082003-03-25 05:07:42 +0000452 if (ospf_nbr_count (oi, 0) > 1)
paul718e3742002-12-13 20:15:29 +0000453 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
454
455 return nbr;
456}
457
paul88d6cf32005-10-29 12:50:09 +0000458/* Determine cost of link, taking RFC3137 stub-router support into
459 * consideration
460 */
461static u_int16_t
462ospf_link_cost (struct ospf_interface *oi)
463{
464 /* RFC3137 stub router support */
465 if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
466 return oi->output_cost;
467 else
468 return OSPF_OUTPUT_COST_INFINITE;
469}
470
paul718e3742002-12-13 20:15:29 +0000471/* Set a link information. */
paul779adb02006-01-18 15:07:38 +0000472static char
paul718e3742002-12-13 20:15:29 +0000473link_info_set (struct stream *s, struct in_addr id,
474 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
475{
paul779adb02006-01-18 15:07:38 +0000476 /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
477 * vast majority of cases. Some rare routers with lots of links need more.
478 * we try accomodate those here.
479 */
480 if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
481 {
482 size_t ret = OSPF_MAX_LSA_SIZE;
483
484 /* Can we enlarge the stream still? */
485 if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
486 {
487 /* we futz the size here for simplicity, really we need to account
488 * for just:
489 * IP Header - (sizeof (struct ip))
490 * OSPF Header - OSPF_HEADER_SIZE
491 * LSA Header - OSPF_LSA_HEADER_SIZE
492 * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
493 *
494 * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
495 */
496 ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
497 }
498
499 if (ret == OSPF_MAX_LSA_SIZE)
500 {
Paul Jakma53725102009-08-03 16:34:16 +0100501 zlog_warn ("%s: Out of space in LSA stream, left %zd, size %zd",
paul779adb02006-01-18 15:07:38 +0000502 __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
503 return 0;
504 }
505 }
506
paul718e3742002-12-13 20:15:29 +0000507 /* TOS based routing is not supported. */
508 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
509 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
510 stream_putc (s, type); /* Link Type. */
511 stream_putc (s, tos); /* TOS = 0. */
512 stream_putw (s, cost); /* Link Cost. */
paul779adb02006-01-18 15:07:38 +0000513
514 return 1;
paul718e3742002-12-13 20:15:29 +0000515}
516
Andrew J. Schorre4529632006-12-12 19:18:21 +0000517/* Describe Point-to-Point link (Section 12.4.1.1). */
paul4dadc292005-05-06 21:37:42 +0000518static int
paul718e3742002-12-13 20:15:29 +0000519lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
520{
521 int links = 0;
522 struct ospf_neighbor *nbr;
523 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000524 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000525
526 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000527 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
paul718e3742002-12-13 20:15:29 +0000528
paul68980082003-03-25 05:07:42 +0000529 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000530 if (nbr->state == NSM_Full)
531 {
532 /* For unnumbered point-to-point networks, the Link Data field
533 should specify the interface's MIB-II ifIndex value. */
paul779adb02006-01-18 15:07:38 +0000534 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
535 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000536 }
537
Andrew J. Schorre4529632006-12-12 19:18:21 +0000538 /* Regardless of the state of the neighboring router, we must
539 add a Type 3 link (stub network).
540 N.B. Options 1 & 2 share basically the same logic. */
541 masklen2ip (oi->address->prefixlen, &mask);
542 id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
543 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
544 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000545 return links;
546}
547
548/* Describe Broadcast Link. */
paul4dadc292005-05-06 21:37:42 +0000549static int
paul718e3742002-12-13 20:15:29 +0000550lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
551{
552 struct ospf_neighbor *dr;
553 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000554 u_int16_t cost = ospf_link_cost (oi);
555
paul718e3742002-12-13 20:15:29 +0000556 /* Describe Type 3 Link. */
557 if (oi->state == ISM_Waiting)
558 {
559 masklen2ip (oi->address->prefixlen, &mask);
560 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000561 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
562 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000563 }
564
565 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
566 /* Describe Type 2 link. */
567 if (dr && (dr->state == NSM_Full ||
568 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000569 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000570 {
paul779adb02006-01-18 15:07:38 +0000571 return link_info_set (s, DR (oi), oi->address->u.prefix4,
572 LSA_LINK_TYPE_TRANSIT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000573 }
574 /* Describe type 3 link. */
575 else
576 {
577 masklen2ip (oi->address->prefixlen, &mask);
578 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000579 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
580 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000581 }
paul718e3742002-12-13 20:15:29 +0000582}
583
paul4dadc292005-05-06 21:37:42 +0000584static int
paul718e3742002-12-13 20:15:29 +0000585lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
586{
587 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000588
paul718e3742002-12-13 20:15:29 +0000589 /* Describe Type 3 Link. */
590 if (oi->state != ISM_Loopback)
591 return 0;
592
593 mask.s_addr = 0xffffffff;
594 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000595 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000596}
597
598/* Describe Virtual Link. */
paul4dadc292005-05-06 21:37:42 +0000599static int
paul718e3742002-12-13 20:15:29 +0000600lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
601{
602 struct ospf_neighbor *nbr;
paul88d6cf32005-10-29 12:50:09 +0000603 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000604
paul718e3742002-12-13 20:15:29 +0000605 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000606 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000607 if (nbr->state == NSM_Full)
608 {
paul779adb02006-01-18 15:07:38 +0000609 return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
610 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
paul718e3742002-12-13 20:15:29 +0000611 }
612
613 return 0;
614}
615
616#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
617
paul7afa08d2002-12-13 20:59:45 +0000618/* this function add for support point-to-multipoint ,see rfc2328
61912.4.1.4.*/
620/* from "edward rrr" <edward_rrr@hotmail.com>
621 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul4dadc292005-05-06 21:37:42 +0000622static int
paul68980082003-03-25 05:07:42 +0000623lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000624{
625 int links = 0;
626 struct route_node *rn;
627 struct ospf_neighbor *nbr = NULL;
628 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000629 u_int16_t cost = ospf_link_cost (oi);
paul7afa08d2002-12-13 20:59:45 +0000630
631 mask.s_addr = 0xffffffff;
632 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000633 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
paul7afa08d2002-12-13 20:59:45 +0000634
paul1cc8f762003-04-05 19:34:32 +0000635 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000636 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000637
638 /* Search neighbor, */
639 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
640 if ((nbr = rn->info) != NULL)
641 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000642 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000643 if (nbr->state == NSM_Full)
644
645 {
paul779adb02006-01-18 15:07:38 +0000646 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
647 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul1cc8f762003-04-05 19:34:32 +0000648 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000649 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000650 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000651 }
652
653 return links;
paul7afa08d2002-12-13 20:59:45 +0000654}
655
paul718e3742002-12-13 20:15:29 +0000656/* Set router-LSA link information. */
paul4dadc292005-05-06 21:37:42 +0000657static int
paul718e3742002-12-13 20:15:29 +0000658router_lsa_link_set (struct stream *s, struct ospf_area *area)
659{
hasso52dc7ee2004-09-23 19:18:23 +0000660 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000661 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000662 int links = 0;
663
paul1eb8ef22005-04-07 07:30:20 +0000664 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +0000665 {
paul718e3742002-12-13 20:15:29 +0000666 struct interface *ifp = oi->ifp;
667
668 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000669 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000670 {
671 if (oi->state != ISM_Down)
672 {
673 /* Describe each link. */
674 switch (oi->type)
675 {
676 case OSPF_IFTYPE_POINTOPOINT:
677 links += lsa_link_ptop_set (s, oi);
678 break;
679 case OSPF_IFTYPE_BROADCAST:
680 links += lsa_link_broadcast_set (s, oi);
681 break;
682 case OSPF_IFTYPE_NBMA:
683 links += lsa_link_nbma_set (s, oi);
684 break;
685 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000686 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000687 break;
688 case OSPF_IFTYPE_VIRTUALLINK:
689 links += lsa_link_virtuallink_set (s, oi);
690 break;
691 case OSPF_IFTYPE_LOOPBACK:
692 links += lsa_link_loopback_set (s, oi);
693 }
694 }
695 }
696 }
697
698 return links;
699}
700
701/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000702static void
paul718e3742002-12-13 20:15:29 +0000703ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
704{
705 unsigned long putp;
706 u_int16_t cnt;
707
708 /* Set flags. */
709 stream_putc (s, router_lsa_flags (area));
710
711 /* Set Zero fields. */
712 stream_putc (s, 0);
713
714 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000715 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000716
717 /* Forward word */
718 stream_putw(s, 0);
719
720 /* Set all link information. */
721 cnt = router_lsa_link_set (s, area);
722
723 /* Set # of links here. */
724 stream_putw_at (s, putp, cnt);
725}
paul88d6cf32005-10-29 12:50:09 +0000726
727static int
728ospf_stub_router_timer (struct thread *t)
729{
730 struct ospf_area *area = THREAD_ARG (t);
731
732 area->t_stub_router = NULL;
733
734 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
735
736 /* clear stub route state and generate router-lsa refresh, don't
737 * clobber an administratively set stub-router state though.
738 */
739 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
740 return 0;
741
742 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
743
Paul Jakmac363d382010-01-24 22:42:13 +0000744 ospf_router_lsa_update_area (area);
paul88d6cf32005-10-29 12:50:09 +0000745
746 return 0;
747}
paul718e3742002-12-13 20:15:29 +0000748
paul88d6cf32005-10-29 12:50:09 +0000749inline static void
750ospf_stub_router_check (struct ospf_area *area)
751{
752 /* area must either be administratively configured to be stub
753 * or startup-time stub-router must be configured and we must in a pre-stub
754 * state.
755 */
756 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
757 {
758 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
759 return;
760 }
761
762 /* not admin-stubbed, check whether startup stubbing is configured and
763 * whether it's not been done yet
764 */
765 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
766 return;
767
768 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
769 {
770 /* stub-router is hence done forever for this area, even if someone
771 * tries configure it (take effect next restart).
772 */
773 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
774 return;
775 }
776
777 /* startup stub-router configured and not yet done */
778 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
779
780 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
781 area->ospf->stub_router_startup_time);
782}
783
paul718e3742002-12-13 20:15:29 +0000784/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000785static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000786ospf_router_lsa_new (struct ospf_area *area)
787{
paul68980082003-03-25 05:07:42 +0000788 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000789 struct stream *s;
790 struct lsa_header *lsah;
791 struct ospf_lsa *new;
792 int length;
793
794 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000795 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000796
paul88d6cf32005-10-29 12:50:09 +0000797 /* check whether stub-router is desired, and if this is the first
798 * router LSA.
799 */
800 ospf_stub_router_check (area);
801
paul718e3742002-12-13 20:15:29 +0000802 /* Create a stream for LSA. */
803 s = stream_new (OSPF_MAX_LSA_SIZE);
paul718e3742002-12-13 20:15:29 +0000804 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000805 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000806 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000807
808 /* Set router-LSA body fields. */
809 ospf_router_lsa_body_set (s, area);
810
811 /* Set length. */
812 length = stream_get_endp (s);
paul779adb02006-01-18 15:07:38 +0000813 lsah = (struct lsa_header *) STREAM_DATA (s);
paul718e3742002-12-13 20:15:29 +0000814 lsah->length = htons (length);
815
816 /* Now, create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000817 if ( (new = ospf_lsa_new ()) == NULL)
818 {
819 zlog_err ("%s: Unable to create new lsa", __func__);
820 return NULL;
821 }
822
paul718e3742002-12-13 20:15:29 +0000823 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +0000824 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +0000825
826 /* Copy LSA data to store, discard stream. */
827 new->data = ospf_lsa_data_new (length);
828 memcpy (new->data, lsah, length);
829 stream_free (s);
830
831 return new;
832}
833
834/* Originate Router-LSA. */
paul88d6cf32005-10-29 12:50:09 +0000835static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000836ospf_router_lsa_originate (struct ospf_area *area)
837{
838 struct ospf_lsa *new;
paul88d6cf32005-10-29 12:50:09 +0000839
paul718e3742002-12-13 20:15:29 +0000840 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000841 if ( (new = ospf_router_lsa_new (area)) == NULL)
842 {
843 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
844 return NULL;
845 }
paul718e3742002-12-13 20:15:29 +0000846
847 /* Sanity check. */
848 if (new->data->adv_router.s_addr == 0)
849 {
850 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000851 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000852 ospf_lsa_discard (new);
853 return NULL;
854 }
855
856 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000857 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000858
859 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000860 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000861
862 /* Flooding new LSA through area. */
863 ospf_flood_through_area (area, NULL, new);
864
865 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
866 {
ajse588f212004-12-08 18:12:06 +0000867 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
paul718e3742002-12-13 20:15:29 +0000868 new->data->type, inet_ntoa (new->data->id), new);
869 ospf_lsa_header_dump (new->data);
870 }
871
872 return new;
873}
874
875/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000876static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000877ospf_router_lsa_refresh (struct ospf_lsa *lsa)
878{
879 struct ospf_area *area = lsa->area;
880 struct ospf_lsa *new;
881
882 /* Sanity check. */
883 assert (lsa->data);
884
885 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000886 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000887
Paul Jakmac363d382010-01-24 22:42:13 +0000888 /* Unregister LSA from refresh-list */
889 ospf_refresher_unregister_lsa (area->ospf, lsa);
890
paul718e3742002-12-13 20:15:29 +0000891 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000892 if ( (new = ospf_router_lsa_new (area)) == NULL)
893 {
894 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
895 return NULL;
896 }
897
paul718e3742002-12-13 20:15:29 +0000898 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
899
paul68980082003-03-25 05:07:42 +0000900 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000901
902 /* Flood LSA through area. */
903 ospf_flood_through_area (area, NULL, new);
904
905 /* Debug logging. */
906 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
907 {
ajse588f212004-12-08 18:12:06 +0000908 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000909 new->data->type, inet_ntoa (new->data->id));
910 ospf_lsa_header_dump (new->data);
911 }
912
913 return NULL;
914}
915
Paul Jakmac363d382010-01-24 22:42:13 +0000916int
917ospf_router_lsa_update_area (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000918{
paul718e3742002-12-13 20:15:29 +0000919 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmac363d382010-01-24 22:42:13 +0000920 zlog_debug ("[router-LSA]: (router-LSA area update)");
paul718e3742002-12-13 20:15:29 +0000921
922 /* Now refresh router-LSA. */
923 if (area->router_lsa_self)
Paul Jakmac363d382010-01-24 22:42:13 +0000924 ospf_lsa_refresh (area->ospf, area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000925 /* Newly originate router-LSA. */
926 else
927 ospf_router_lsa_originate (area);
928
929 return 0;
930}
931
paul718e3742002-12-13 20:15:29 +0000932int
Paul Jakmac363d382010-01-24 22:42:13 +0000933ospf_router_lsa_update (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000934{
paul1eb8ef22005-04-07 07:30:20 +0000935 struct listnode *node, *nnode;
936 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +0000937
938 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000939 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +0000940
paul1eb8ef22005-04-07 07:30:20 +0000941 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000942 {
paul718e3742002-12-13 20:15:29 +0000943 struct ospf_lsa *lsa = area->router_lsa_self;
944 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +0000945 const char *area_str;
paul718e3742002-12-13 20:15:29 +0000946
947 /* Keep Area ID string. */
948 area_str = AREA_NAME (area);
949
950 /* If LSA not exist in this Area, originate new. */
951 if (lsa == NULL)
952 {
953 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000954 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +0000955
956 ospf_router_lsa_originate (area);
957 }
958 /* If router-ID is changed, Link ID must change.
959 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +0000960 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000961 {
962 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000963 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +0000964 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
965 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000966 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000967 area->router_lsa_self = NULL;
968
969 /* Refresh router-LSA, (not install) and flood through area. */
Paul Jakmac363d382010-01-24 22:42:13 +0000970 ospf_router_lsa_update_area (area);
paul718e3742002-12-13 20:15:29 +0000971 }
972 else
973 {
974 rl = (struct router_lsa *) lsa->data;
975 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +0000976 if (rl->flags != ospf->flags)
Paul Jakmac363d382010-01-24 22:42:13 +0000977 ospf_router_lsa_update_area (area);
paul718e3742002-12-13 20:15:29 +0000978 }
979 }
980
981 return 0;
982}
983
984
985/* network-LSA related functions. */
986/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +0000987static void
paul718e3742002-12-13 20:15:29 +0000988ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
989{
990 struct in_addr mask;
991 struct route_node *rn;
992 struct ospf_neighbor *nbr;
993
994 masklen2ip (oi->address->prefixlen, &mask);
995 stream_put_ipv4 (s, mask.s_addr);
996
997 /* The network-LSA lists those routers that are fully adjacent to
998 the Designated Router; each fully adjacent router is identified by
999 its OSPF Router ID. The Designated Router includes itself in this
1000 list. RFC2328, Section 12.4.2 */
1001
1002 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1003 if ((nbr = rn->info) != NULL)
1004 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1005 stream_put_ipv4 (s, nbr->router_id.s_addr);
1006}
1007
paul4dadc292005-05-06 21:37:42 +00001008static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001009ospf_network_lsa_new (struct ospf_interface *oi)
1010{
1011 struct stream *s;
1012 struct ospf_lsa *new;
1013 struct lsa_header *lsah;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001014 struct ospf_if_params *oip;
paul718e3742002-12-13 20:15:29 +00001015 int length;
1016
1017 /* If there are no neighbours on this network (the net is stub),
1018 the router does not originate network-LSA (see RFC 12.4.2) */
1019 if (oi->full_nbrs == 0)
1020 return NULL;
1021
1022 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001023 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001024
1025 /* Create new stream for LSA. */
1026 s = stream_new (OSPF_MAX_LSA_SIZE);
1027 lsah = (struct lsa_header *) STREAM_DATA (s);
1028
1029 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001030 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001031
1032 /* Set network-LSA body fields. */
1033 ospf_network_lsa_body_set (s, oi);
1034
1035 /* Set length. */
1036 length = stream_get_endp (s);
1037 lsah->length = htons (length);
1038
1039 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001040 if ( (new = ospf_lsa_new ()) == NULL)
1041 {
1042 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1043 return NULL;
1044 }
1045
paul718e3742002-12-13 20:15:29 +00001046 new->area = oi->area;
Paul Jakmac363d382010-01-24 22:42:13 +00001047 new->oi = oi;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001048 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001049
1050 /* Copy LSA to store. */
1051 new->data = ospf_lsa_data_new (length);
1052 memcpy (new->data, lsah, length);
1053 stream_free (s);
Paul Jakma7eb5b472009-10-13 16:13:13 +01001054
1055 /* Remember prior network LSA sequence numbers, even if we stop
1056 * originating one for this oi, to try avoid re-originating LSAs with a
1057 * prior sequence number, and thus speed up adjency forming & convergence.
1058 */
1059 if ((oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4)))
1060 {
1061 new->data->ls_seqnum = oip->network_lsa_seqnum;
1062 new->data->ls_seqnum = lsa_seqnum_increment (new);
1063 }
1064 else
1065 {
1066 oip = ospf_get_if_params (oi->ifp, oi->address->u.prefix4);
1067 ospf_if_update_params (oi->ifp, oi->address->u.prefix4);
1068 }
1069 oip->network_lsa_seqnum = new->data->ls_seqnum;
1070
paul718e3742002-12-13 20:15:29 +00001071 return new;
1072}
1073
1074/* Originate network-LSA. */
Paul Jakmac363d382010-01-24 22:42:13 +00001075void
1076ospf_network_lsa_update (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001077{
1078 struct ospf_lsa *new;
Paul Jakmac363d382010-01-24 22:42:13 +00001079
1080 if (oi->network_lsa_self != NULL)
1081 {
1082 ospf_lsa_refresh (oi->ospf, oi->network_lsa_self);
1083 return;
1084 }
1085
paul718e3742002-12-13 20:15:29 +00001086 /* Create new network-LSA instance. */
1087 new = ospf_network_lsa_new (oi);
1088 if (new == NULL)
Paul Jakmac363d382010-01-24 22:42:13 +00001089 return;
paul718e3742002-12-13 20:15:29 +00001090
1091 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001092 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001093
1094 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001095 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001096
1097 /* Flooding new LSA through area. */
1098 ospf_flood_through_area (oi->area, NULL, new);
1099
1100 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1101 {
ajse588f212004-12-08 18:12:06 +00001102 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001103 new->data->type, inet_ntoa (new->data->id), new);
1104 ospf_lsa_header_dump (new->data);
1105 }
1106
Paul Jakmac363d382010-01-24 22:42:13 +00001107 return;
paul718e3742002-12-13 20:15:29 +00001108}
1109
Paul Jakmac363d382010-01-24 22:42:13 +00001110static struct ospf_lsa *
1111ospf_network_lsa_refresh (struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001112{
1113 struct ospf_area *area = lsa->area;
Paul Jakmac363d382010-01-24 22:42:13 +00001114 struct ospf_lsa *new, *new2;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001115 struct ospf_if_params *oip;
Paul Jakmac363d382010-01-24 22:42:13 +00001116 struct ospf_interface *oi = lsa->oi;
1117
paul718e3742002-12-13 20:15:29 +00001118 assert (lsa->data);
1119
1120 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001121 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001122
Paul Jakmac363d382010-01-24 22:42:13 +00001123 /* Unregister LSA from refresh-list */
1124 ospf_refresher_unregister_lsa (area->ospf, lsa);
1125
paul718e3742002-12-13 20:15:29 +00001126 /* Create new network-LSA instance. */
1127 new = ospf_network_lsa_new (oi);
1128 if (new == NULL)
Paul Jakmac363d382010-01-24 22:42:13 +00001129 return NULL;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001130
1131 oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4);
1132 assert (oip != NULL);
1133 oip->network_lsa_seqnum = new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001134
Paul Jakmac363d382010-01-24 22:42:13 +00001135 new2 = ospf_lsa_install (area->ospf, oi, new);
1136
1137 assert (new2 == new);
1138
paul718e3742002-12-13 20:15:29 +00001139 /* Flood LSA through aera. */
1140 ospf_flood_through_area (area, NULL, new);
1141
1142 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1143 {
ajse588f212004-12-08 18:12:06 +00001144 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001145 new->data->type, inet_ntoa (new->data->id));
1146 ospf_lsa_header_dump (new->data);
1147 }
1148
Paul Jakmac363d382010-01-24 22:42:13 +00001149 return new;
paul718e3742002-12-13 20:15:29 +00001150}
paul718e3742002-12-13 20:15:29 +00001151
paul4dadc292005-05-06 21:37:42 +00001152static void
paul718e3742002-12-13 20:15:29 +00001153stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1154{
1155 u_int32_t metric;
1156 char *mp;
1157
1158 /* Put 0 metric. TOS metric is not supported. */
1159 metric = htonl (metric_value);
1160 mp = (char *) &metric;
1161 mp++;
1162 stream_put (s, mp, 3);
1163}
1164
1165/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001166static void
paul718e3742002-12-13 20:15:29 +00001167ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1168 u_int32_t metric)
1169{
1170 struct in_addr mask;
1171
1172 masklen2ip (p->prefixlen, &mask);
1173
1174 /* Put Network Mask. */
1175 stream_put_ipv4 (s, mask.s_addr);
1176
1177 /* Set # TOS. */
1178 stream_putc (s, (u_char) 0);
1179
1180 /* Set metric. */
1181 stream_put_ospf_metric (s, metric);
1182}
1183
paul4dadc292005-05-06 21:37:42 +00001184static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001185ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1186 u_int32_t metric, struct in_addr id)
1187{
1188 struct stream *s;
1189 struct ospf_lsa *new;
1190 struct lsa_header *lsah;
1191 int length;
1192
paulc24d6022005-11-20 14:54:12 +00001193 if (id.s_addr == 0xffffffff)
1194 {
1195 /* Maybe Link State ID not available. */
1196 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1197 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1198 OSPF_SUMMARY_LSA);
1199 return NULL;
1200 }
1201
paul718e3742002-12-13 20:15:29 +00001202 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001203 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001204
1205 /* Create new stream for LSA. */
1206 s = stream_new (OSPF_MAX_LSA_SIZE);
1207 lsah = (struct lsa_header *) STREAM_DATA (s);
1208
paul68980082003-03-25 05:07:42 +00001209 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1210 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001211
1212 /* Set summary-LSA body fields. */
1213 ospf_summary_lsa_body_set (s, p, metric);
1214
1215 /* Set length. */
1216 length = stream_get_endp (s);
1217 lsah->length = htons (length);
1218
1219 /* Create OSPF LSA instance. */
1220 new = ospf_lsa_new ();
1221 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001222 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001223
1224 /* Copy LSA to store. */
1225 new->data = ospf_lsa_data_new (length);
1226 memcpy (new->data, lsah, length);
1227 stream_free (s);
1228
1229 return new;
1230}
1231
1232/* Originate Summary-LSA. */
1233struct ospf_lsa *
1234ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1235 struct ospf_area *area)
1236{
1237 struct ospf_lsa *new;
1238 struct in_addr id;
1239
paul68980082003-03-25 05:07:42 +00001240 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001241
paulc24d6022005-11-20 14:54:12 +00001242 if (id.s_addr == 0xffffffff)
1243 {
1244 /* Maybe Link State ID not available. */
1245 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1246 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1247 OSPF_SUMMARY_LSA);
1248 return NULL;
1249 }
1250
paul718e3742002-12-13 20:15:29 +00001251 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001252 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1253 return NULL;
paul718e3742002-12-13 20:15:29 +00001254
1255 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001256 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001257
1258 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001259 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001260
1261 /* Flooding new LSA through area. */
1262 ospf_flood_through_area (area, NULL, new);
1263
1264 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1265 {
ajse588f212004-12-08 18:12:06 +00001266 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001267 new->data->type, inet_ntoa (new->data->id), new);
1268 ospf_lsa_header_dump (new->data);
1269 }
1270
1271 return new;
1272}
1273
Paul Jakmac363d382010-01-24 22:42:13 +00001274static struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001275ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001276{
1277 struct ospf_lsa *new;
1278 struct summary_lsa *sl;
1279 struct prefix p;
1280
1281 /* Sanity check. */
1282 assert (lsa->data);
1283
1284 sl = (struct summary_lsa *)lsa->data;
1285 p.prefixlen = ip_masklen (sl->mask);
1286 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1287 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001288
1289 if (!new)
1290 return NULL;
1291
paul718e3742002-12-13 20:15:29 +00001292 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001293
paul68980082003-03-25 05:07:42 +00001294 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001295
1296 /* Flood LSA through AS. */
1297 ospf_flood_through_area (new->area, NULL, new);
1298
1299 /* Debug logging. */
1300 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1301 {
ajse588f212004-12-08 18:12:06 +00001302 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001303 new->data->type, inet_ntoa (new->data->id));
1304 ospf_lsa_header_dump (new->data);
1305 }
1306
1307 return new;
1308}
1309
1310
1311/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001312static void
paul718e3742002-12-13 20:15:29 +00001313ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1314 u_int32_t metric)
1315{
1316 struct in_addr mask;
1317
1318 masklen2ip (p->prefixlen, &mask);
1319
1320 /* Put Network Mask. */
1321 stream_put_ipv4 (s, mask.s_addr);
1322
1323 /* Set # TOS. */
1324 stream_putc (s, (u_char) 0);
1325
1326 /* Set metric. */
1327 stream_put_ospf_metric (s, metric);
1328}
1329
paul4dadc292005-05-06 21:37:42 +00001330static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001331ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1332 u_int32_t metric, struct in_addr id)
1333{
1334 struct stream *s;
1335 struct ospf_lsa *new;
1336 struct lsa_header *lsah;
1337 int length;
1338
paulc24d6022005-11-20 14:54:12 +00001339 if (id.s_addr == 0xffffffff)
1340 {
1341 /* Maybe Link State ID not available. */
1342 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1343 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1344 OSPF_ASBR_SUMMARY_LSA);
1345 return NULL;
1346 }
1347
paul718e3742002-12-13 20:15:29 +00001348 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001349 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001350
1351 /* Create new stream for LSA. */
1352 s = stream_new (OSPF_MAX_LSA_SIZE);
1353 lsah = (struct lsa_header *) STREAM_DATA (s);
1354
paul68980082003-03-25 05:07:42 +00001355 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1356 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001357
1358 /* Set summary-LSA body fields. */
1359 ospf_summary_asbr_lsa_body_set (s, p, metric);
1360
1361 /* Set length. */
1362 length = stream_get_endp (s);
1363 lsah->length = htons (length);
1364
1365 /* Create OSPF LSA instance. */
1366 new = ospf_lsa_new ();
1367 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001368 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001369
1370 /* Copy LSA to store. */
1371 new->data = ospf_lsa_data_new (length);
1372 memcpy (new->data, lsah, length);
1373 stream_free (s);
1374
1375 return new;
1376}
1377
1378/* Originate summary-ASBR-LSA. */
1379struct ospf_lsa *
1380ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1381 struct ospf_area *area)
1382{
1383 struct ospf_lsa *new;
1384 struct in_addr id;
1385
paul68980082003-03-25 05:07:42 +00001386 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001387
paulc24d6022005-11-20 14:54:12 +00001388 if (id.s_addr == 0xffffffff)
1389 {
1390 /* Maybe Link State ID not available. */
1391 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1392 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1393 OSPF_ASBR_SUMMARY_LSA);
1394 return NULL;
1395 }
1396
paul718e3742002-12-13 20:15:29 +00001397 /* Create new summary-LSA instance. */
1398 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001399 if (!new)
1400 return NULL;
paul718e3742002-12-13 20:15:29 +00001401
1402 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001403 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001404
1405 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001406 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001407
1408 /* Flooding new LSA through area. */
1409 ospf_flood_through_area (area, NULL, new);
1410
1411 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1412 {
ajse588f212004-12-08 18:12:06 +00001413 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001414 new->data->type, inet_ntoa (new->data->id), new);
1415 ospf_lsa_header_dump (new->data);
1416 }
1417
1418 return new;
1419}
1420
Paul Jakmac363d382010-01-24 22:42:13 +00001421static struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001422ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001423{
1424 struct ospf_lsa *new;
1425 struct summary_lsa *sl;
1426 struct prefix p;
1427
1428 /* Sanity check. */
1429 assert (lsa->data);
1430
1431 sl = (struct summary_lsa *)lsa->data;
1432 p.prefixlen = ip_masklen (sl->mask);
1433 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1434 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001435 if (!new)
1436 return NULL;
paul718e3742002-12-13 20:15:29 +00001437
1438 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001439
paul68980082003-03-25 05:07:42 +00001440 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001441
1442 /* Flood LSA through area. */
1443 ospf_flood_through_area (new->area, NULL, new);
1444
1445 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1446 {
ajse588f212004-12-08 18:12:06 +00001447 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001448 new->data->type, inet_ntoa (new->data->id));
1449 ospf_lsa_header_dump (new->data);
1450 }
1451
1452 return new;
1453}
1454
1455/* AS-external-LSA related functions. */
1456
1457/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1458 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001459static struct in_addr
paul68980082003-03-25 05:07:42 +00001460ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001461{
1462 struct in_addr fwd;
1463 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001464 struct listnode *node;
1465 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001466
1467 fwd.s_addr = 0;
1468
1469 if (!nexthop.s_addr)
1470 return fwd;
1471
1472 /* Check whether nexthop is covered by OSPF network. */
1473 nh.family = AF_INET;
1474 nh.u.prefix4 = nexthop;
1475 nh.prefixlen = IPV4_MAX_BITLEN;
Paul Jakma4ca15d42009-08-03 15:16:41 +01001476
1477 /* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be
1478 * better to make use of the per-ifp table of ois.
1479 */
paul1eb8ef22005-04-07 07:30:20 +00001480 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1481 if (if_is_operative (oi->ifp))
1482 if (oi->address->family == AF_INET)
1483 if (prefix_match (oi->address, &nh))
1484 return nexthop;
paul718e3742002-12-13 20:15:29 +00001485
1486 return fwd;
1487}
1488
paul718e3742002-12-13 20:15:29 +00001489/* NSSA-external-LSA related functions. */
1490
1491/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001492
paul718e3742002-12-13 20:15:29 +00001493struct in_addr
1494ospf_get_ip_from_ifp (struct ospf_interface *oi)
1495{
1496 struct in_addr fwd;
1497
1498 fwd.s_addr = 0;
1499
paul2e3b2e42002-12-13 21:03:13 +00001500 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001501 return oi->address->u.prefix4;
1502
1503 return fwd;
1504}
1505
1506/* Get 1st IP connection for Forward Addr */
1507struct in_addr
paulf2c80652002-12-13 21:44:27 +00001508ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001509{
1510 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001511 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001512 struct listnode *node;
1513 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001514
1515 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001516 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001517
paul1eb8ef22005-04-07 07:30:20 +00001518 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001519 {
paul2e3b2e42002-12-13 21:03:13 +00001520 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001521 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001522 if (oi->address && oi->address->family == AF_INET)
1523 {
1524 if (best_default.s_addr == 0)
1525 best_default = oi->address->u.prefix4;
1526 if (oi->area == area)
1527 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001528 }
paul718e3742002-12-13 20:15:29 +00001529 }
paulf2c80652002-12-13 21:44:27 +00001530 if (best_default.s_addr != 0)
1531 return best_default;
paul718e3742002-12-13 20:15:29 +00001532
paul68980082003-03-25 05:07:42 +00001533 if (best_default.s_addr != 0)
1534 return best_default;
1535
paul718e3742002-12-13 20:15:29 +00001536 return fwd;
1537}
hassobeebba72004-06-20 21:00:27 +00001538
paul718e3742002-12-13 20:15:29 +00001539#define DEFAULT_DEFAULT_METRIC 20
1540#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1541#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1542
1543#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1544
1545int
paul68980082003-03-25 05:07:42 +00001546metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001547{
paul68980082003-03-25 05:07:42 +00001548 return (ospf->dmetric[src].type < 0 ?
1549 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001550}
1551
1552int
paul68980082003-03-25 05:07:42 +00001553metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001554{
paul68980082003-03-25 05:07:42 +00001555 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001556 {
1557 if (src == DEFAULT_ROUTE)
1558 {
paul68980082003-03-25 05:07:42 +00001559 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001560 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1561 else
1562 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1563 }
paul68980082003-03-25 05:07:42 +00001564 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001565 return DEFAULT_DEFAULT_METRIC;
1566 else
paul68980082003-03-25 05:07:42 +00001567 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001568 }
1569
paul68980082003-03-25 05:07:42 +00001570 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001571}
1572
1573/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001574static void
paul68980082003-03-25 05:07:42 +00001575ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1576 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001577{
1578 struct prefix_ipv4 *p = &ei->p;
1579 struct in_addr mask, fwd_addr;
1580 u_int32_t mvalue;
1581 int mtype;
1582 int type;
1583
1584 /* Put Network Mask. */
1585 masklen2ip (p->prefixlen, &mask);
1586 stream_put_ipv4 (s, mask.s_addr);
1587
1588 /* If prefix is default, specify DEFAULT_ROUTE. */
1589 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1590
1591 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001592 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001593
1594 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001595 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001596
1597 /* Put type of external metric. */
1598 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1599
1600 /* Put 0 metric. TOS metric is not supported. */
1601 stream_put_ospf_metric (s, mvalue);
1602
1603 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001604 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001605
1606 /* Put forwarding address. */
1607 stream_put_ipv4 (s, fwd_addr.s_addr);
1608
1609 /* Put route tag -- This value should be introduced from configuration. */
1610 stream_putl (s, 0);
1611}
1612
1613/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001614static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001615ospf_external_lsa_new (struct ospf *ospf,
1616 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001617{
1618 struct stream *s;
1619 struct lsa_header *lsah;
1620 struct ospf_lsa *new;
1621 struct in_addr id;
1622 int length;
1623
1624 if (ei == NULL)
1625 {
1626 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001627 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
paul718e3742002-12-13 20:15:29 +00001628 return NULL;
1629 }
1630
1631 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001632 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001633
1634 /* If old Link State ID is specified, refresh LSA with same ID. */
1635 if (old_id)
1636 id = *old_id;
1637 /* Get Link State with unique ID. */
1638 else
1639 {
paul68980082003-03-25 05:07:42 +00001640 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001641 if (id.s_addr == 0xffffffff)
1642 {
1643 /* Maybe Link State ID not available. */
1644 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001645 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001646 return NULL;
1647 }
1648 }
1649
1650 /* Create new stream for LSA. */
1651 s = stream_new (OSPF_MAX_LSA_SIZE);
1652 lsah = (struct lsa_header *) STREAM_DATA (s);
1653
1654 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001655 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1656 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001657
1658 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001659 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001660
1661 /* Set length. */
1662 length = stream_get_endp (s);
1663 lsah->length = htons (length);
1664
1665 /* Now, create OSPF LSA instance. */
1666 new = ospf_lsa_new ();
1667 new->area = NULL;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001668 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001669
1670 /* Copy LSA data to store, discard stream. */
1671 new->data = ospf_lsa_data_new (length);
1672 memcpy (new->data, lsah, length);
1673 stream_free (s);
1674
1675 return new;
1676}
1677
paul718e3742002-12-13 20:15:29 +00001678/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001679static void
paul68980082003-03-25 05:07:42 +00001680ospf_install_flood_nssa (struct ospf *ospf,
1681 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001682{
pauld4a53d52003-07-12 21:30:57 +00001683 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001684 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001685 struct ospf_area *area;
1686 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001687
pauld4a53d52003-07-12 21:30:57 +00001688 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1689 * which originated from an NSSA area. In which case it should not be
1690 * flooded back to NSSA areas.
1691 */
1692 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1693 return;
1694
paul718e3742002-12-13 20:15:29 +00001695 /* NSSA Originate or Refresh (If anyNSSA)
1696
1697 LSA is self-originated. And just installed as Type-5.
1698 Additionally, install as Type-7 LSDB for every attached NSSA.
1699
1700 P-Bit controls which ABR performs translation to outside world; If
1701 we are an ABR....do not set the P-bit, because we send the Type-5,
1702 not as the ABR Translator, but as the ASBR owner within the AS!
1703
1704 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1705 elected ABR Translator will see the P-bit, Translate, and re-flood.
1706
1707 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1708 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1709
paul1eb8ef22005-04-07 07:30:20 +00001710 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001711 {
hasso0c14ad82003-07-03 08:36:02 +00001712 /* Don't install Type-7 LSA's into nonNSSA area */
1713 if (area->external_routing != OSPF_AREA_NSSA)
1714 continue;
paul718e3742002-12-13 20:15:29 +00001715
paul68980082003-03-25 05:07:42 +00001716 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001717 new = ospf_lsa_dup (lsa);
1718 new->area = area;
1719 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001720
paul68980082003-03-25 05:07:42 +00001721 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001722 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001723 {
pauld4a53d52003-07-12 21:30:57 +00001724 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001725
1726 /* set non-zero FWD ADDR
1727
1728 draft-ietf-ospf-nssa-update-09.txt
1729
1730 if the network between the NSSA AS boundary router and the
1731 adjacent AS is advertised into OSPF as an internal OSPF route,
1732 the forwarding address should be the next op address as is cu
1733 currently done with type-5 LSAs. If the intervening network is
1734 not adversited into OSPF as an internal OSPF route and the
1735 type-7 LSA's P-bit is set a forwarding address should be
1736 selected from one of the router's active OSPF inteface addresses
1737 which belong to the NSSA. If no such addresses exist, then
1738 no type-7 LSA's with the P-bit set should originate from this
1739 router. */
1740
pauld4a53d52003-07-12 21:30:57 +00001741 /* kevinm: not updating lsa anymore, just new */
1742 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001743
1744 if (extlsa->e[0].fwd_addr.s_addr == 0)
1745 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001746
pauld7480322003-05-16 17:31:51 +00001747 if (extlsa->e[0].fwd_addr.s_addr == 0)
1748 {
1749 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001750 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001751 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001752 return;
1753 }
paulf2c80652002-12-13 21:44:27 +00001754 }
paul718e3742002-12-13 20:15:29 +00001755
paul68980082003-03-25 05:07:42 +00001756 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001757 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001758
1759 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001760 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001761 }
paul718e3742002-12-13 20:15:29 +00001762}
pauld4a53d52003-07-12 21:30:57 +00001763
paul4dadc292005-05-06 21:37:42 +00001764static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001765ospf_lsa_translated_nssa_new (struct ospf *ospf,
1766 struct ospf_lsa *type7)
1767{
1768
1769 struct ospf_lsa *new;
1770 struct as_external_lsa *ext, *extnew;
1771 struct external_info ei;
1772
1773 ext = (struct as_external_lsa *)(type7->data);
1774
1775 /* need external_info struct, fill in bare minimum */
1776 ei.p.family = AF_INET;
1777 ei.p.prefix = type7->data->id;
1778 ei.p.prefixlen = ip_masklen (ext->mask);
1779 ei.type = ZEBRA_ROUTE_OSPF;
1780 ei.nexthop = ext->header.adv_router;
1781 ei.route_map_set.metric = -1;
1782 ei.route_map_set.metric_type = -1;
1783 ei.tag = 0;
1784
1785 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1786 {
1787 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001788 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001789 "Translated Type-5 for %s",
1790 inet_ntoa (ei.p.prefix));
1791 return NULL;
1792 }
1793
1794 extnew = (struct as_external_lsa *)(new->data);
1795
1796 /* copy over Type-7 data to new */
1797 extnew->e[0].tos = ext->e[0].tos;
1798 extnew->e[0].route_tag = ext->e[0].route_tag;
1799 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1800 new->data->ls_seqnum = type7->data->ls_seqnum;
1801
1802 /* add translated flag, checksum and lock new lsa */
1803 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
pauld4a53d52003-07-12 21:30:57 +00001804 new = ospf_lsa_lock (new);
1805
1806 return new;
1807}
1808
pauld4a53d52003-07-12 21:30:57 +00001809/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1810struct ospf_lsa *
1811ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1812{
1813 struct ospf_lsa *new;
1814 struct as_external_lsa *extnew;
1815
1816 /* we cant use ospf_external_lsa_originate() as we need to set
1817 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1818 */
1819
1820 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1821 {
1822 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001823 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001824 "Type-7, Id %s, to Type-5",
1825 inet_ntoa (type7->data->id));
1826 return NULL;
1827 }
1828
1829 extnew = (struct as_external_lsa *)new;
1830
1831 if (IS_DEBUG_OSPF_NSSA)
1832 {
ajse588f212004-12-08 18:12:06 +00001833 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001834 "translated Type 7, installed:");
1835 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001836 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1837 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001838 }
1839
1840 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1841 {
1842 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001843 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001844 "Could not install LSA "
1845 "id %s", inet_ntoa (type7->data->id));
1846 return NULL;
1847 }
1848
1849 ospf->lsa_originate_count++;
1850 ospf_flood_through_as (ospf, NULL, new);
1851
1852 return new;
1853}
1854
1855/* Refresh Translated from NSSA AS-external-LSA. */
1856struct ospf_lsa *
1857ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1858 struct ospf_lsa *type5)
1859{
1860 struct ospf_lsa *new = NULL;
1861
1862 /* Sanity checks. */
1863 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00001864 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00001865 return NULL;
pauld4a53d52003-07-12 21:30:57 +00001866 if (type7)
1867 assert (type7->data);
1868 if (type5)
1869 assert (type5->data);
1870 assert (ospf->anyNSSA);
1871
1872 /* get required data according to what has been given */
1873 if (type7 && type5 == NULL)
1874 {
1875 /* find the translated Type-5 for this Type-7 */
1876 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1877 struct prefix_ipv4 p =
1878 {
1879 .prefix = type7->data->id,
1880 .prefixlen = ip_masklen (ext->mask),
1881 .family = AF_INET,
1882 };
1883
1884 type5 = ospf_external_info_find_lsa (ospf, &p);
1885 }
1886 else if (type5 && type7 == NULL)
1887 {
1888 /* find the type-7 from which supplied type-5 was translated,
1889 * ie find first type-7 with same LSA Id.
1890 */
paul1eb8ef22005-04-07 07:30:20 +00001891 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00001892 struct route_node *rn;
1893 struct ospf_lsa *lsa;
1894 struct ospf_area *area;
1895
paul1eb8ef22005-04-07 07:30:20 +00001896 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00001897 {
1898 if (area->external_routing != OSPF_AREA_NSSA
1899 && !type7)
1900 continue;
1901
1902 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
1903 {
1904 if (lsa->data->id.s_addr == type5->data->id.s_addr)
1905 {
1906 type7 = lsa;
1907 break;
1908 }
1909 }
1910 }
1911 }
1912
1913 /* do we have type7? */
1914 if (!type7)
1915 {
1916 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001917 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00001918 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00001919 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00001920 return NULL;
1921 }
1922
1923 /* do we have valid translated type5? */
1924 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
1925 {
1926 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001927 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00001928 "found for Type-7 with Id %s",
1929 inet_ntoa (type7->data->id));
1930 return NULL;
1931 }
1932
1933 /* Delete LSA from neighbor retransmit-list. */
1934 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
1935
1936 /* create new translated LSA */
1937 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1938 {
1939 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001940 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001941 "Type-7 for %s to Type-5",
1942 inet_ntoa (type7->data->id));
1943 return NULL;
1944 }
1945
1946 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
1947 {
1948 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001949 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00001950 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00001951 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00001952 return NULL;
1953 }
1954
1955 /* Flood LSA through area. */
1956 ospf_flood_through_as (ospf, NULL, new);
1957
1958 return new;
1959}
paul718e3742002-12-13 20:15:29 +00001960
1961int
1962is_prefix_default (struct prefix_ipv4 *p)
1963{
1964 struct prefix_ipv4 q;
1965
1966 q.family = AF_INET;
1967 q.prefix.s_addr = 0;
1968 q.prefixlen = 0;
1969
1970 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
1971}
1972
1973/* Originate an AS-external-LSA, install and flood. */
1974struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001975ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001976{
1977 struct ospf_lsa *new;
1978
1979 /* Added for NSSA project....
1980
1981 External LSAs are originated in ASBRs as usual, but for NSSA systems.
1982 there is the global Type-5 LSDB and a Type-7 LSDB installed for
1983 every area. The Type-7's are flooded to every IR and every ABR; We
1984 install the Type-5 LSDB so that the normal "refresh" code operates
1985 as usual, and flag them as not used during ASE calculations. The
1986 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
1987 Address of non-zero.
1988
1989 If an ABR is the elected NSSA translator, following SPF and during
1990 the ABR task it will translate all the scanned Type-7's, with P-bit
1991 ON and not-self generated, and translate to Type-5's throughout the
1992 non-NSSA/STUB AS.
1993
1994 A difference in operation depends whether this ASBR is an ABR
1995 or not. If not an ABR, the P-bit is ON, to indicate that any
1996 elected NSSA-ABR can perform its translation.
1997
1998 If an ABR, the P-bit is OFF; No ABR will perform translation and
1999 this ASBR will flood the Type-5 LSA as usual.
2000
2001 For the case where this ASBR is not an ABR, the ASE calculations
2002 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2003 demonstrate to the user that there are LSA's that belong to any
2004 attached NSSA.
2005
2006 Finally, it just so happens that when the ABR is translating every
2007 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2008 approved Type-5 (translated from Type-7); at the end of translation
2009 if any Translated Type-5's remain unapproved, then they must be
2010 flushed from the AS.
2011
2012 */
2013
2014 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002015 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002016 return NULL;
2017
2018 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002019 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002020 {
2021 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002022 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002023 inet_ntoa (ei->p.prefix));
2024 return NULL;
2025 }
2026
2027 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002028 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002029
2030 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002031 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002032
2033 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002034 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002035
paul718e3742002-12-13 20:15:29 +00002036 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002037 if (ospf->anyNSSA &&
2038 /* stay away from translated LSAs! */
2039 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002040 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002041
2042 /* Debug logging. */
2043 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2044 {
ajse588f212004-12-08 18:12:06 +00002045 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002046 new->data->type, inet_ntoa (new->data->id), new);
2047 ospf_lsa_header_dump (new->data);
2048 }
2049
2050 return new;
2051}
2052
2053/* Originate AS-external-LSA from external info with initial flag. */
2054int
paul68980082003-03-25 05:07:42 +00002055ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002056{
paul68980082003-03-25 05:07:42 +00002057 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002058 struct route_node *rn;
2059 struct external_info *ei;
2060 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002061 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002062
paul68980082003-03-25 05:07:42 +00002063 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002064
2065 /* Originate As-external-LSA from all type of distribute source. */
2066 if ((rt = EXTERNAL_INFO (type)))
2067 for (rn = route_top (rt); rn; rn = route_next (rn))
2068 if ((ei = rn->info) != NULL)
2069 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002070 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002071 zlog_warn ("LSA: AS-external-LSA was not originated.");
2072
2073 return 0;
2074}
2075
paul4dadc292005-05-06 21:37:42 +00002076static struct external_info *
paul020709f2003-04-04 02:44:16 +00002077ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002078{
2079 int type;
2080 struct route_node *rn;
2081 struct prefix_ipv4 p;
2082
2083 p.family = AF_INET;
2084 p.prefix.s_addr = 0;
2085 p.prefixlen = 0;
2086
2087 /* First, lookup redistributed default route. */
2088 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2089 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2090 {
2091 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2092 if (rn != NULL)
2093 {
2094 route_unlock_node (rn);
2095 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002096 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002097 return rn->info;
2098 }
2099 }
2100
2101 return NULL;
2102}
2103
2104int
paul68980082003-03-25 05:07:42 +00002105ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002106{
paul718e3742002-12-13 20:15:29 +00002107 struct prefix_ipv4 p;
2108 struct in_addr nexthop;
2109 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002110 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002111
Paul Jakma4021b602006-05-12 22:55:41 +00002112 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002113
2114 p.family = AF_INET;
2115 p.prefix.s_addr = 0;
2116 p.prefixlen = 0;
2117
Paul Jakma4021b602006-05-12 22:55:41 +00002118 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002119 {
2120 /* If there is no default route via redistribute,
2121 then originate AS-external-LSA with nexthop 0 (self). */
2122 nexthop.s_addr = 0;
2123 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2124 }
2125
paul020709f2003-04-04 02:44:16 +00002126 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002127 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002128
2129 return 0;
2130}
2131
paul645878f2003-04-13 21:42:11 +00002132/* Flush any NSSA LSAs for given prefix */
2133void
2134ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2135{
paul1eb8ef22005-04-07 07:30:20 +00002136 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002137 struct ospf_lsa *lsa;
2138 struct ospf_area *area;
2139
paul1eb8ef22005-04-07 07:30:20 +00002140 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002141 {
paul1eb8ef22005-04-07 07:30:20 +00002142 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002143 {
2144 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2145 ospf->router_id)))
2146 {
2147 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002148 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002149 inet_ntoa (p->prefix), p->prefixlen);
2150 continue;
2151 }
2152 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2153 if (!IS_LSA_MAXAGE (lsa))
2154 {
2155 ospf_refresher_unregister_lsa (ospf, lsa);
2156 ospf_lsa_flush_area (lsa, area);
2157 }
2158 }
paul645878f2003-04-13 21:42:11 +00002159 }
2160}
paul645878f2003-04-13 21:42:11 +00002161
paul718e3742002-12-13 20:15:29 +00002162/* Flush an AS-external-LSA from LSDB and routing domain. */
2163void
paul68980082003-03-25 05:07:42 +00002164ospf_external_lsa_flush (struct ospf *ospf,
2165 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002166 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002167{
2168 struct ospf_lsa *lsa;
2169
2170 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002171 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002172 inet_ntoa (p->prefix), p->prefixlen);
2173
2174 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002175 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002176 {
2177 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002178 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002179 inet_ntoa (p->prefix), p->prefixlen);
2180 return;
2181 }
hassobeebba72004-06-20 21:00:27 +00002182
pauld4a53d52003-07-12 21:30:57 +00002183 /* If LSA is selforiginated, not a translated LSA, and there is
2184 * NSSA area, flush Type-7 LSA's at first.
2185 */
2186 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2187 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002188 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002189
2190 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002191 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002192
2193 /* There must be no self-originated LSA in rtrs_external. */
2194#if 0
2195 /* Remove External route from Zebra. */
2196 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2197#endif
2198
2199 if (!IS_LSA_MAXAGE (lsa))
2200 {
2201 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002202 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002203
2204 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002205 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002206 }
2207
2208 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002209 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002210}
2211
2212void
paul68980082003-03-25 05:07:42 +00002213ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002214{
2215 struct prefix_ipv4 p;
2216 struct external_info *ei;
2217 struct ospf_lsa *lsa;
2218
2219 p.family = AF_INET;
2220 p.prefixlen = 0;
2221 p.prefix.s_addr = 0;
2222
paul020709f2003-04-04 02:44:16 +00002223 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002224 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002225
2226 if (ei)
2227 {
2228 if (lsa)
2229 {
2230 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002231 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002232 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002233 }
2234 else
2235 {
2236 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002237 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002238 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002239 }
2240 }
2241 else
2242 {
2243 if (lsa)
2244 {
2245 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002246 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002247 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002248 }
2249 }
2250}
2251
2252void
paul68980082003-03-25 05:07:42 +00002253ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002254{
2255 struct route_node *rn;
2256 struct external_info *ei;
2257
2258 if (type != DEFAULT_ROUTE)
2259 if (EXTERNAL_INFO(type))
2260 /* Refresh each redistributed AS-external-LSAs. */
2261 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2262 if ((ei = rn->info))
2263 if (!is_prefix_default (&ei->p))
2264 {
2265 struct ospf_lsa *lsa;
2266
paul68980082003-03-25 05:07:42 +00002267 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2268 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002269 else
paul68980082003-03-25 05:07:42 +00002270 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002271 }
2272}
2273
2274/* Refresh AS-external-LSA. */
Paul Jakmac363d382010-01-24 22:42:13 +00002275struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002276ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002277 struct external_info *ei, int force)
2278{
2279 struct ospf_lsa *new;
2280 int changed;
2281
2282 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002283 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002284 {
pauld4a53d52003-07-12 21:30:57 +00002285 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002286 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002287 "redist check fail",
2288 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002289 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002290 ei->ifindex /*, ei->nexthop */);
Paul Jakmac363d382010-01-24 22:42:13 +00002291 return NULL;
paul718e3742002-12-13 20:15:29 +00002292 }
2293
2294 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002295 {
2296 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002297 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002298 lsa->data->type, inet_ntoa (lsa->data->id));
Paul Jakmac363d382010-01-24 22:42:13 +00002299 return NULL;
pauld4a53d52003-07-12 21:30:57 +00002300 }
paul718e3742002-12-13 20:15:29 +00002301
2302 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002303 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002304
2305 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002306 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002307
paul68980082003-03-25 05:07:42 +00002308 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002309
2310 if (new == NULL)
2311 {
2312 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002313 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002314 inet_ntoa (lsa->data->id));
Paul Jakmac363d382010-01-24 22:42:13 +00002315 return NULL;
paul718e3742002-12-13 20:15:29 +00002316 }
2317
2318 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2319
paul68980082003-03-25 05:07:42 +00002320 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002321
2322 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002323 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002324
paul718e3742002-12-13 20:15:29 +00002325 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002326 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002327 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002328
pauld4a53d52003-07-12 21:30:57 +00002329 /* Register self-originated LSA to refresh queue.
2330 * Translated LSAs should not be registered, but refreshed upon
2331 * refresh of the Type-7
2332 */
2333 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2334 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002335
2336 /* Debug logging. */
2337 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2338 {
ajse588f212004-12-08 18:12:06 +00002339 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002340 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002341 ospf_lsa_header_dump (new->data);
2342 }
2343
Paul Jakmac363d382010-01-24 22:42:13 +00002344 return new;
paul718e3742002-12-13 20:15:29 +00002345}
2346
2347
2348/* LSA installation functions. */
2349
2350/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002351static struct ospf_lsa *
Paul Jakmac363d382010-01-24 22:42:13 +00002352ospf_router_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2353 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002354{
2355 struct ospf_area *area = new->area;
2356
2357 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2358 The entire routing table must be recalculated, starting with
2359 the shortest path calculations for each area (not just the
2360 area whose link-state database has changed).
2361 */
paul718e3742002-12-13 20:15:29 +00002362
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002363 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002364 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002365
2366 /* Only install LSA if it is originated/refreshed by us.
2367 * If LSA was received by flooding, the RECEIVED flag is set so do
2368 * not link the LSA */
2369 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2370 return new; /* ignore stale LSA */
2371
paul718e3742002-12-13 20:15:29 +00002372 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002373 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002374 area->router_lsa_self = ospf_lsa_lock (new);
2375
Paul Jakmac363d382010-01-24 22:42:13 +00002376 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002377 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002378 if (rt_recalc)
2379 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002380
2381 return new;
2382}
2383
2384#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2385 if (!(T)) \
2386 (T) = thread_add_timer (master, (F), oi, (V))
2387
2388/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002389static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002390ospf_network_lsa_install (struct ospf *ospf,
2391 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002392 struct ospf_lsa *new,
2393 int rt_recalc)
2394{
2395
2396 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2397 The entire routing table must be recalculated, starting with
2398 the shortest path calculations for each area (not just the
2399 area whose link-state database has changed).
2400 */
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002401 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002402 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002403 /* We supposed that when LSA is originated by us, we pass the int
2404 for which it was originated. If LSA was received by flooding,
2405 the RECEIVED flag is set, so we do not link the LSA to the int. */
2406 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2407 return new; /* ignore stale LSA */
2408
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002409 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002410 oi->network_lsa_self = ospf_lsa_lock (new);
Paul Jakmac363d382010-01-24 22:42:13 +00002411 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002412 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002413 if (rt_recalc)
2414 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002415
2416 return new;
2417}
2418
2419/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002420static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002421ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2422 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002423{
paul718e3742002-12-13 20:15:29 +00002424 if (rt_recalc && !IS_LSA_SELF (new))
2425 {
2426 /* RFC 2328 Section 13.2 Summary-LSAs
2427 The best route to the destination described by the summary-
2428 LSA must be recalculated (see Section 16.5). If this
2429 destination is an AS boundary router, it may also be
2430 necessary to re-examine all the AS-external-LSAs.
2431 */
2432
2433#if 0
2434 /* This doesn't exist yet... */
2435 ospf_summary_incremental_update(new); */
2436#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002437 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002438#endif /* #if 0 */
2439
2440 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002441 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002442 }
2443
2444 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002445 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002446
2447 return new;
2448}
2449
2450/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002451static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002452ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2453 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002454{
2455 if (rt_recalc && !IS_LSA_SELF (new))
2456 {
2457 /* RFC 2328 Section 13.2 Summary-LSAs
2458 The best route to the destination described by the summary-
2459 LSA must be recalculated (see Section 16.5). If this
2460 destination is an AS boundary router, it may also be
2461 necessary to re-examine all the AS-external-LSAs.
2462 */
2463#if 0
2464 /* These don't exist yet... */
2465 ospf_summary_incremental_update(new);
2466 /* Isn't this done by the above call?
2467 - RFC 2328 Section 16.5 implies it should be */
2468 /* ospf_ase_calculate_schedule(); */
2469#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002470 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002471#endif /* #if 0 */
2472 }
2473
2474 /* register LSA to refresh-list. */
2475 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002476 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002477
2478 return new;
2479}
2480
2481/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002482static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002483ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2484 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002485{
paul68980082003-03-25 05:07:42 +00002486 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002487 /* If LSA is not self-originated, calculate an external route. */
2488 if (rt_recalc)
2489 {
2490 /* RFC 2328 Section 13.2 AS-external-LSAs
2491 The best route to the destination described by the AS-
2492 external-LSA must be recalculated (see Section 16.6).
2493 */
2494
2495 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002496 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002497 }
2498
pauld4a53d52003-07-12 21:30:57 +00002499 if (new->data->type == OSPF_AS_NSSA_LSA)
2500 {
2501 /* There is no point to register selforiginate Type-7 LSA for
2502 * refreshing. We rely on refreshing Type-5 LSA's
2503 */
2504 if (IS_LSA_SELF (new))
2505 return new;
2506 else
2507 {
2508 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2509 * New translations will be taken care of by the abr_task.
2510 */
2511 ospf_translated_nssa_refresh (ospf, new, NULL);
2512 }
2513 }
pauld7480322003-05-16 17:31:51 +00002514
pauld4a53d52003-07-12 21:30:57 +00002515 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002516 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002517 */
hassobeebba72004-06-20 21:00:27 +00002518 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002519 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002520
2521 return new;
2522}
2523
2524void
paul68980082003-03-25 05:07:42 +00002525ospf_discard_from_db (struct ospf *ospf,
2526 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002527{
2528 struct ospf_lsa *old;
2529
Paul Jakmaac904de2006-06-15 12:04:57 +00002530 if (!lsdb)
2531 {
2532 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2533 if (!lsa)
2534 zlog_warn ("%s: and NULL LSA!", __func__);
2535 else
2536 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2537 lsa->data->type, inet_ntoa (lsa->data->id));
2538 return;
2539 }
2540
paul718e3742002-12-13 20:15:29 +00002541 old = ospf_lsdb_lookup (lsdb, lsa);
2542
2543 if (!old)
2544 return;
2545
2546 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002547 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002548
2549 switch (old->data->type)
2550 {
2551 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002552 ospf_ase_unregister_external_lsa (old, ospf);
2553 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2554 break;
paul718e3742002-12-13 20:15:29 +00002555#ifdef HAVE_OPAQUE_LSA
2556 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002557 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002558 break;
paul69310a62005-05-11 18:09:59 +00002559#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002560 case OSPF_AS_NSSA_LSA:
2561 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2562 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002563 break;
paul718e3742002-12-13 20:15:29 +00002564 default:
paul68980082003-03-25 05:07:42 +00002565 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002566 break;
2567 }
2568
paul68980082003-03-25 05:07:42 +00002569 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002570 ospf_lsa_discard (old);
2571}
2572
paul718e3742002-12-13 20:15:29 +00002573struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002574ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2575 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002576{
2577 struct ospf_lsa *new = NULL;
2578 struct ospf_lsa *old = NULL;
2579 struct ospf_lsdb *lsdb = NULL;
2580 int rt_recalc;
2581
2582 /* Set LSDB. */
2583 switch (lsa->data->type)
2584 {
paulf2c80652002-12-13 21:44:27 +00002585 /* kevinm */
2586 case OSPF_AS_NSSA_LSA:
2587 if (lsa->area)
2588 lsdb = lsa->area->lsdb;
2589 else
paul68980082003-03-25 05:07:42 +00002590 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002591 break;
paul718e3742002-12-13 20:15:29 +00002592 case OSPF_AS_EXTERNAL_LSA:
2593#ifdef HAVE_OPAQUE_LSA
2594 case OSPF_OPAQUE_AS_LSA:
2595#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002596 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002597 break;
2598 default:
2599 lsdb = lsa->area->lsdb;
2600 break;
2601 }
2602
paul718e3742002-12-13 20:15:29 +00002603 assert (lsdb);
2604
2605 /* RFC 2328 13.2. Installing LSAs in the database
2606
2607 Installing a new LSA in the database, either as the result of
2608 flooding or a newly self-originated LSA, may cause the OSPF
2609 routing table structure to be recalculated. The contents of the
2610 new LSA should be compared to the old instance, if present. If
2611 there is no difference, there is no need to recalculate the
2612 routing table. When comparing an LSA to its previous instance,
2613 the following are all considered to be differences in contents:
2614
2615 o The LSA's Options field has changed.
2616
2617 o One of the LSA instances has LS age set to MaxAge, and
2618 the other does not.
2619
2620 o The length field in the LSA header has changed.
2621
2622 o The body of the LSA (i.e., anything outside the 20-byte
2623 LSA header) has changed. Note that this excludes changes
2624 in LS Sequence Number and LS Checksum.
2625
2626 */
2627 /* Look up old LSA and determine if any SPF calculation or incremental
2628 update is needed */
2629 old = ospf_lsdb_lookup (lsdb, lsa);
2630
2631 /* Do comparision and record if recalc needed. */
2632 rt_recalc = 0;
2633 if ( old == NULL || ospf_lsa_different(old, lsa))
2634 rt_recalc = 1;
2635
paul7ddf1d62003-10-13 09:06:46 +00002636 /*
2637 Sequence number check (Section 14.1 of rfc 2328)
2638 "Premature aging is used when it is time for a self-originated
2639 LSA's sequence number field to wrap. At this point, the current
2640 LSA instance (having LS sequence number MaxSequenceNumber) must
2641 be prematurely aged and flushed from the routing domain before a
2642 new instance with sequence number equal to InitialSequenceNumber
2643 can be originated. "
2644 */
2645
Paul Jakmac2b478d2006-03-30 14:16:11 +00002646 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002647 {
2648 if (ospf_lsa_is_self_originated(ospf, lsa))
2649 {
paul0c2be262004-05-31 14:16:54 +00002650 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2651
2652 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002653 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2654 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2655
2656 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2657 {
ajse588f212004-12-08 18:12:06 +00002658 zlog_debug ("ospf_lsa_install() Premature Aging "
Paul Jakmac363d382010-01-24 22:42:13 +00002659 "lsa 0x%p, seqnum 0x%x",
2660 lsa, ntohl(lsa->data->ls_seqnum));
paul7ddf1d62003-10-13 09:06:46 +00002661 ospf_lsa_header_dump (lsa->data);
2662 }
2663 }
2664 else
2665 {
2666 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2667 {
ajse588f212004-12-08 18:12:06 +00002668 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002669 "that was not self originated. Ignoring\n");
2670 ospf_lsa_header_dump (lsa->data);
2671 }
2672 return old;
2673 }
2674 }
2675
paul718e3742002-12-13 20:15:29 +00002676 /* discard old LSA from LSDB */
2677 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002678 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002679
paul718e3742002-12-13 20:15:29 +00002680 /* Calculate Checksum if self-originated?. */
2681 if (IS_LSA_SELF (lsa))
2682 ospf_lsa_checksum (lsa->data);
2683
hassofe71a972004-12-22 16:16:02 +00002684 /* Insert LSA to LSDB. */
2685 ospf_lsdb_add (lsdb, lsa);
2686 lsa->lsdb = lsdb;
2687
paul718e3742002-12-13 20:15:29 +00002688 /* Do LSA specific installation process. */
2689 switch (lsa->data->type)
2690 {
2691 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002692 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002693 break;
2694 case OSPF_NETWORK_LSA:
2695 assert (oi);
paul68980082003-03-25 05:07:42 +00002696 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002697 break;
2698 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002699 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002700 break;
2701 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002702 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002703 break;
2704 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002705 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002706 break;
2707#ifdef HAVE_OPAQUE_LSA
2708 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002709 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002710 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002711 else
paul68980082003-03-25 05:07:42 +00002712 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002713 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002714 case OSPF_OPAQUE_AREA_LSA:
2715 case OSPF_OPAQUE_AS_LSA:
2716 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2717 break;
2718#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002719 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002720 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002721 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002722 break;
2723 }
2724
2725 if (new == NULL)
2726 return new; /* Installation failed, cannot proceed further -- endo. */
2727
2728 /* Debug logs. */
2729 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2730 {
2731 char area_str[INET_ADDRSTRLEN];
2732
2733 switch (lsa->data->type)
2734 {
2735 case OSPF_AS_EXTERNAL_LSA:
2736#ifdef HAVE_OPAQUE_LSA
2737 case OSPF_OPAQUE_AS_LSA:
2738#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002739 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002740 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002741 dump_lsa_key (new),
2742 LOOKUP (ospf_lsa_type_msg, new->data->type));
2743 break;
2744 default:
2745 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002746 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002747 dump_lsa_key (new),
2748 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2749 break;
2750 }
2751 }
2752
paul7ddf1d62003-10-13 09:06:46 +00002753 /*
2754 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2755 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2756 */
2757 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2758 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002759 {
paul7ddf1d62003-10-13 09:06:46 +00002760 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002761 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002762 new->data->type,
2763 inet_ntoa (new->data->id),
2764 lsa);
paul68980082003-03-25 05:07:42 +00002765 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002766 }
2767
2768 return new;
2769}
2770
2771
paul4dadc292005-05-06 21:37:42 +00002772static int
paul68980082003-03-25 05:07:42 +00002773ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002774{
paul1eb8ef22005-04-07 07:30:20 +00002775 struct listnode *node, *nnode;
2776 struct ospf_interface *oi;
2777
2778 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002779 {
paul718e3742002-12-13 20:15:29 +00002780 struct route_node *rn;
2781 struct ospf_neighbor *nbr;
2782
2783 if (ospf_if_is_enable (oi))
2784 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2785 if ((nbr = rn->info) != NULL)
2786 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2787 {
2788 route_unlock_node (rn);
2789 return 0;
2790 }
2791 }
2792
2793 return 1;
2794}
2795
2796
2797#ifdef ORIGINAL_CODING
2798/* This function flood the maxaged LSA to DR. */
2799void
2800ospf_maxage_flood (struct ospf_lsa *lsa)
2801{
2802 switch (lsa->data->type)
2803 {
2804 case OSPF_ROUTER_LSA:
2805 case OSPF_NETWORK_LSA:
2806 case OSPF_SUMMARY_LSA:
2807 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00002808 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00002809#ifdef HAVE_OPAQUE_LSA
2810 case OSPF_OPAQUE_LINK_LSA:
2811 case OSPF_OPAQUE_AREA_LSA:
2812#endif /* HAVE_OPAQUE_LSA */
2813 ospf_flood_through_area (lsa->area, NULL, lsa);
2814 break;
2815 case OSPF_AS_EXTERNAL_LSA:
2816#ifdef HAVE_OPAQUE_LSA
2817 case OSPF_OPAQUE_AS_LSA:
2818#endif /* HAVE_OPAQUE_LSA */
2819 ospf_flood_through_as (NULL, lsa);
2820 break;
2821 default:
2822 break;
2823 }
2824}
2825#endif /* ORIGINAL_CODING */
2826
paul4dadc292005-05-06 21:37:42 +00002827static int
paul718e3742002-12-13 20:15:29 +00002828ospf_maxage_lsa_remover (struct thread *thread)
2829{
paul68980082003-03-25 05:07:42 +00002830 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002831 struct ospf_lsa *lsa;
2832 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002833 int reschedule = 0;
2834
paul68980082003-03-25 05:07:42 +00002835 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002836
2837 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002838 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002839
paul68980082003-03-25 05:07:42 +00002840 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002841
2842 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002843 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002844 {
paul718e3742002-12-13 20:15:29 +00002845 if (lsa->retransmit_counter > 0)
2846 {
2847 reschedule = 1;
2848 continue;
2849 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002850
2851 /* TODO: maybe convert this function to a work-queue */
2852 if (thread_should_yield (thread))
2853 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);
2854
paul718e3742002-12-13 20:15:29 +00002855 /* Remove LSA from the LSDB */
2856 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2857 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002858 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
paul7ddf1d62003-10-13 09:06:46 +00002859 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002860
2861 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002862 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002863 lsa->data->type, inet_ntoa (lsa->data->id));
2864
2865 /* Flood max age LSA. */
2866#ifdef ORIGINAL_CODING
2867 ospf_maxage_flood (lsa);
2868#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00002869 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00002870#endif /* ORIGINAL_CODING */
2871
Paul Jakmac363d382010-01-24 22:42:13 +00002872 if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))
paul7ddf1d62003-10-13 09:06:46 +00002873 {
2874 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
Paul Jakmac363d382010-01-24 22:42:13 +00002875 zlog_debug ("originating new lsa for lsa 0x%p\n", lsa);
2876 ospf_lsa_refresh (ospf, lsa);
paul7ddf1d62003-10-13 09:06:46 +00002877 }
2878
paul718e3742002-12-13 20:15:29 +00002879 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002880 if (lsa->lsdb)
2881 {
2882 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2883 ospf_lsdb_delete (lsa->lsdb, lsa);
2884 }
2885 else
2886 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2887 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002888 }
2889
2890 /* A MaxAge LSA must be removed immediately from the router's link
2891 state database as soon as both a) it is no longer contained on any
2892 neighbor Link state retransmission lists and b) none of the router's
2893 neighbors are in states Exchange or Loading. */
2894 if (reschedule)
paul68980082003-03-25 05:07:42 +00002895 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00002896
2897 return 0;
2898}
2899
paul718e3742002-12-13 20:15:29 +00002900void
paul68980082003-03-25 05:07:42 +00002901ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002902{
hasso52dc7ee2004-09-23 19:18:23 +00002903 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00002904
paul68980082003-03-25 05:07:42 +00002905 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00002906 {
paul68980082003-03-25 05:07:42 +00002907 list_delete_node (ospf->maxage_lsa, n);
Stephen Hemminger3106a032009-08-06 12:58:05 -07002908 UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002909 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +00002910 }
2911}
2912
2913void
paul68980082003-03-25 05:07:42 +00002914ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002915{
2916 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2917 and schedule the MaxAge LSA remover. */
Stephen Hemminger3106a032009-08-06 12:58:05 -07002918 if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
paul718e3742002-12-13 20:15:29 +00002919 {
2920 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002921 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00002922 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2923 return;
2924 }
2925
paul68980082003-03-25 05:07:42 +00002926 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
Stephen Hemminger3106a032009-08-06 12:58:05 -07002927 SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
paul718e3742002-12-13 20:15:29 +00002928
2929 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002930 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002931
paul68980082003-03-25 05:07:42 +00002932 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00002933}
2934
paul4dadc292005-05-06 21:37:42 +00002935static int
paul68980082003-03-25 05:07:42 +00002936ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002937{
paul718e3742002-12-13 20:15:29 +00002938 /* Stay away from any Local Translated Type-7 LSAs */
2939 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2940 return 0;
paul718e3742002-12-13 20:15:29 +00002941
2942 if (IS_LSA_MAXAGE (lsa))
2943 /* Self-originated LSAs should NOT time-out instead,
2944 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00002945 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002946 {
2947 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002948 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002949
2950 switch (lsa->data->type)
2951 {
paul718e3742002-12-13 20:15:29 +00002952#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00002953 case OSPF_OPAQUE_LINK_LSA:
2954 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00002955 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00002956 /*
2957 * As a general rule, whenever network topology has changed
2958 * (due to an LSA removal in this case), routing recalculation
2959 * should be triggered. However, this is not true for opaque
2960 * LSAs. Even if an opaque LSA instance is going to be removed
2961 * from the routing domain, it does not mean a change in network
2962 * topology, and thus, routing recalculation is not needed here.
2963 */
2964 break;
paul718e3742002-12-13 20:15:29 +00002965#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00002966 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00002967 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002968 ospf_ase_incremental_update (ospf, lsa);
2969 break;
paul718e3742002-12-13 20:15:29 +00002970 default:
paul68980082003-03-25 05:07:42 +00002971 ospf_spf_calculate_schedule (ospf);
2972 break;
paul718e3742002-12-13 20:15:29 +00002973 }
paul68980082003-03-25 05:07:42 +00002974 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002975 }
2976
Paul Jakmac363d382010-01-24 22:42:13 +00002977 if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa))
2978 if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30)
2979 printf ("Eek! Shouldn't happen!\n");
2980
paul718e3742002-12-13 20:15:29 +00002981 return 0;
2982}
2983
2984/* Periodical check of MaxAge LSA. */
2985int
paul68980082003-03-25 05:07:42 +00002986ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002987{
paul68980082003-03-25 05:07:42 +00002988 struct ospf *ospf = THREAD_ARG (thread);
2989 struct route_node *rn;
2990 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00002991 struct ospf_area *area;
2992 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002993
paul68980082003-03-25 05:07:42 +00002994 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00002995
paul1eb8ef22005-04-07 07:30:20 +00002996 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00002997 {
paul68980082003-03-25 05:07:42 +00002998 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
2999 ospf_lsa_maxage_walker_remover (ospf, lsa);
3000 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3001 ospf_lsa_maxage_walker_remover (ospf, lsa);
3002 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3003 ospf_lsa_maxage_walker_remover (ospf, lsa);
3004 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3005 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003006#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003007 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3008 ospf_lsa_maxage_walker_remover (ospf, lsa);
3009 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3010 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003011#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003012 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3013 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003014 }
3015
paul4fb949e2003-05-10 20:06:51 +00003016 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003017 if (ospf->lsdb)
3018 {
3019 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3020 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003021#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003022 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3023 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003024#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003025 }
paul718e3742002-12-13 20:15:29 +00003026
paul68980082003-03-25 05:07:42 +00003027 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3028 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003029 return 0;
3030}
3031
paul68980082003-03-25 05:07:42 +00003032struct ospf_lsa *
3033ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3034 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003035{
paul68980082003-03-25 05:07:42 +00003036 struct ospf_lsa *lsa;
3037 struct in_addr mask, id;
3038 struct lsa_header_mask
3039 {
3040 struct lsa_header header;
3041 struct in_addr mask;
3042 } *hmask;
paul718e3742002-12-13 20:15:29 +00003043
paul68980082003-03-25 05:07:42 +00003044 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3045 if (lsa == NULL)
3046 return NULL;
paul718e3742002-12-13 20:15:29 +00003047
paul68980082003-03-25 05:07:42 +00003048 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003049
paul68980082003-03-25 05:07:42 +00003050 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003051
paul68980082003-03-25 05:07:42 +00003052 if (mask.s_addr != hmask->mask.s_addr)
3053 {
3054 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3055 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3056 if (!lsa)
3057 return NULL;
3058 }
paul718e3742002-12-13 20:15:29 +00003059
paul68980082003-03-25 05:07:42 +00003060 return lsa;
paul718e3742002-12-13 20:15:29 +00003061}
3062
3063struct ospf_lsa *
3064ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3065 struct in_addr id, struct in_addr adv_router)
3066{
paule05fba42003-04-13 20:20:53 +00003067 struct ospf *ospf = ospf_lookup();
3068 assert(ospf);
3069
paul718e3742002-12-13 20:15:29 +00003070 switch (type)
3071 {
3072 case OSPF_ROUTER_LSA:
3073 case OSPF_NETWORK_LSA:
3074 case OSPF_SUMMARY_LSA:
3075 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003076 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003077#ifdef HAVE_OPAQUE_LSA
3078 case OSPF_OPAQUE_LINK_LSA:
3079 case OSPF_OPAQUE_AREA_LSA:
3080#endif /* HAVE_OPAQUE_LSA */
3081 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003082 case OSPF_AS_EXTERNAL_LSA:
3083#ifdef HAVE_OPAQUE_LSA
3084 case OSPF_OPAQUE_AS_LSA:
3085#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003086 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003087 default:
3088 break;
3089 }
3090
3091 return NULL;
3092}
3093
3094struct ospf_lsa *
3095ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3096 struct in_addr id)
3097{
3098 struct ospf_lsa *lsa;
3099 struct route_node *rn;
3100
3101 switch (type)
3102 {
3103 case OSPF_ROUTER_LSA:
3104 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003105 case OSPF_NETWORK_LSA:
3106 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3107 if ((lsa = rn->info))
3108 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3109 {
3110 route_unlock_node (rn);
3111 return lsa;
3112 }
3113 break;
3114 case OSPF_SUMMARY_LSA:
3115 case OSPF_ASBR_SUMMARY_LSA:
3116 /* Currently not used. */
3117 assert (1);
3118 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003119 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003120 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003121#ifdef HAVE_OPAQUE_LSA
3122 case OSPF_OPAQUE_LINK_LSA:
3123 case OSPF_OPAQUE_AREA_LSA:
3124 case OSPF_OPAQUE_AS_LSA:
3125 /* Currently not used. */
3126 break;
3127#endif /* HAVE_OPAQUE_LSA */
3128 default:
3129 break;
3130 }
3131
3132 return NULL;
3133}
3134
3135struct ospf_lsa *
3136ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3137{
3138 struct ospf_lsa *match;
3139
3140#ifdef HAVE_OPAQUE_LSA
3141 /*
3142 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3143 * is redefined to have two subfields; opaque-type and opaque-id.
3144 * However, it is harmless to treat the two sub fields together, as if
3145 * they two were forming a unique LSA-ID.
3146 */
3147#endif /* HAVE_OPAQUE_LSA */
3148
3149 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3150
3151 if (match == NULL)
3152 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003153 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003154 lsah->type, inet_ntoa (lsah->id));
3155
3156 return match;
3157}
3158
3159/* return +n, l1 is more recent.
3160 return -n, l2 is more recent.
3161 return 0, l1 and l2 is identical. */
3162int
3163ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3164{
3165 int r;
3166 int x, y;
3167
3168 if (l1 == NULL && l2 == NULL)
3169 return 0;
3170 if (l1 == NULL)
3171 return -1;
3172 if (l2 == NULL)
3173 return 1;
3174
3175 /* compare LS sequence number. */
3176 x = (int) ntohl (l1->data->ls_seqnum);
3177 y = (int) ntohl (l2->data->ls_seqnum);
3178 if (x > y)
3179 return 1;
3180 if (x < y)
3181 return -1;
3182
3183 /* compare LS checksum. */
3184 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3185 if (r)
3186 return r;
3187
3188 /* compare LS age. */
3189 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3190 return 1;
3191 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3192 return -1;
3193
3194 /* compare LS age with MaxAgeDiff. */
3195 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3196 return -1;
3197 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3198 return 1;
3199
3200 /* LSAs are identical. */
3201 return 0;
3202}
3203
3204/* If two LSAs are different, return 1, otherwise return 0. */
3205int
3206ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3207{
3208 char *p1, *p2;
3209 assert (l1);
3210 assert (l2);
3211 assert (l1->data);
3212 assert (l2->data);
3213
3214 if (l1->data->options != l2->data->options)
3215 return 1;
3216
3217 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3218 return 1;
3219
3220 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3221 return 1;
3222
3223 if (l1->data->length != l2->data->length)
3224 return 1;
3225
3226 if (l1->data->length == 0)
3227 return 1;
3228
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02003229 if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
3230 return 1; /* May be a stale LSA in the LSBD */
3231
pauld1825832003-04-03 01:27:01 +00003232 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003233
3234 p1 = (char *) l1->data;
3235 p2 = (char *) l2->data;
3236
3237 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3238 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3239 return 1;
3240
3241 return 0;
3242}
3243
3244#ifdef ORIGINAL_CODING
3245void
3246ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3247 struct ospf_lsa *self,
3248 struct ospf_lsa *new)
3249{
3250 u_int32_t seqnum;
3251
3252 /* Adjust LS Sequence Number. */
3253 seqnum = ntohl (new->data->ls_seqnum) + 1;
3254 self->data->ls_seqnum = htonl (seqnum);
3255
3256 /* Recalculate LSA checksum. */
3257 ospf_lsa_checksum (self->data);
3258
3259 /* Reflooding LSA. */
3260 /* RFC2328 Section 13.3
3261 On non-broadcast networks, separate Link State Update
3262 packets must be sent, as unicasts, to each adjacent neighbor
3263 (i.e., those in state Exchange or greater). The destination
3264 IP addresses for these packets are the neighbors' IP
3265 addresses. */
3266 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3267 {
3268 struct route_node *rn;
3269 struct ospf_neighbor *onbr;
3270
3271 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3272 if ((onbr = rn->info) != NULL)
3273 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3274 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3275 }
3276 else
3277 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3278
3279 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003280 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003281 self->data->type, inet_ntoa (self->data->id));
3282}
3283#else /* ORIGINAL_CODING */
3284static int
paul68980082003-03-25 05:07:42 +00003285ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003286{
3287 if (lsa == NULL || !IS_LSA_SELF (lsa))
3288 return 0;
3289
3290 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003291 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 +00003292
3293 /* Force given lsa's age to MaxAge. */
3294 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3295
3296 switch (lsa->data->type)
3297 {
3298#ifdef HAVE_OPAQUE_LSA
3299 case OSPF_OPAQUE_LINK_LSA:
3300 case OSPF_OPAQUE_AREA_LSA:
3301 case OSPF_OPAQUE_AS_LSA:
3302 ospf_opaque_lsa_refresh (lsa);
3303 break;
3304#endif /* HAVE_OPAQUE_LSA */
3305 default:
paul68980082003-03-25 05:07:42 +00003306 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003307 break;
3308 }
3309
3310 return 0;
3311}
3312
3313void
paul68980082003-03-25 05:07:42 +00003314ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003315{
paul1eb8ef22005-04-07 07:30:20 +00003316 struct listnode *node, *nnode;
3317 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003318 struct ospf_area *area;
3319 struct ospf_interface *oi;
3320 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003321 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003322 int need_to_flush_ase = 0;
3323
paul1eb8ef22005-04-07 07:30:20 +00003324 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003325 {
paul718e3742002-12-13 20:15:29 +00003326 if ((lsa = area->router_lsa_self) != NULL)
3327 {
3328 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003329 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 +00003330
3331 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003332 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003333 area->router_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003334 }
3335
paul1eb8ef22005-04-07 07:30:20 +00003336 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003337 {
paul718e3742002-12-13 20:15:29 +00003338 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003339 && oi->state == ISM_DR
3340 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003341 {
3342 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003343 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 +00003344
3345 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003346 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003347 oi->network_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003348 }
3349
3350 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3351 && area->external_routing == OSPF_AREA_DEFAULT)
3352 need_to_flush_ase = 1;
3353 }
3354
paul68980082003-03-25 05:07:42 +00003355 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3356 ospf_lsa_flush_schedule (ospf, lsa);
3357 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3358 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003359#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003360 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3361 ospf_lsa_flush_schedule (ospf, lsa);
3362 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3363 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003364#endif /* HAVE_OPAQUE_LSA */
3365 }
3366
3367 if (need_to_flush_ase)
3368 {
paul68980082003-03-25 05:07:42 +00003369 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3370 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003371#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003372 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3373 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003374#endif /* HAVE_OPAQUE_LSA */
3375 }
3376
3377 /*
3378 * Make sure that the MaxAge LSA remover is executed immediately,
3379 * without conflicting to other threads.
3380 */
paul68980082003-03-25 05:07:42 +00003381 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003382 {
paul68980082003-03-25 05:07:42 +00003383 OSPF_TIMER_OFF (ospf->t_maxage);
3384 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003385 }
3386
3387 return;
3388}
3389#endif /* ORIGINAL_CODING */
3390
3391/* If there is self-originated LSA, then return 1, otherwise return 0. */
3392/* An interface-independent version of ospf_lsa_is_self_originated */
3393int
paul68980082003-03-25 05:07:42 +00003394ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003395{
hasso52dc7ee2004-09-23 19:18:23 +00003396 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003397 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003398
3399 /* This LSA is already checked. */
3400 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3401 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3402
3403 /* Make sure LSA is self-checked. */
3404 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3405
3406 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003407 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003408 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3409
3410 /* LSA is router-LSA. */
3411 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003412 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003413 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3414
3415 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3416 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003417 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003418 {
paul718e3742002-12-13 20:15:29 +00003419 /* Ignore virtual link. */
3420 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3421 if (oi->address->family == AF_INET)
3422 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3423 {
3424 /* to make it easier later */
3425 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3426 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3427 }
3428 }
3429
3430 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3431}
3432
3433/* Get unique Link State ID. */
3434struct in_addr
paul68980082003-03-25 05:07:42 +00003435ospf_lsa_unique_id (struct ospf *ospf,
3436 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003437{
3438 struct ospf_lsa *lsa;
3439 struct in_addr mask, id;
3440
3441 id = p->prefix;
3442
3443 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003444 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003445 if (lsa)
3446 {
3447 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3448 if (ip_masklen (al->mask) == p->prefixlen)
3449 {
3450 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003451 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003452 "Can't get Link State ID for %s/%d",
3453 inet_ntoa (p->prefix), p->prefixlen);
3454 /* id.s_addr = 0; */
3455 id.s_addr = 0xffffffff;
3456 return id;
3457 }
3458 /* Masklen differs, then apply wildcard mask to Link State ID. */
3459 else
3460 {
3461 masklen2ip (p->prefixlen, &mask);
3462
3463 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003464 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3465 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003466 if (lsa)
3467 {
3468 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003469 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003470 "Can't get Link State ID for %s/%d",
3471 inet_ntoa (p->prefix), p->prefixlen);
3472 /* id.s_addr = 0; */
3473 id.s_addr = 0xffffffff;
3474 return id;
3475 }
3476 }
3477 }
3478
3479 return id;
3480}
3481
3482
Paul Jakma70461d72006-05-12 22:57:57 +00003483#define LSA_ACTION_FLOOD_AREA 1
3484#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003485
3486struct lsa_action
3487{
3488 u_char action;
3489 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003490 struct ospf_lsa *lsa;
3491};
3492
paul4dadc292005-05-06 21:37:42 +00003493static int
paul718e3742002-12-13 20:15:29 +00003494ospf_lsa_action (struct thread *t)
3495{
3496 struct lsa_action *data;
3497
3498 data = THREAD_ARG (t);
3499
3500 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003501 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003502 data->action);
3503
3504 switch (data->action)
3505 {
paul718e3742002-12-13 20:15:29 +00003506 case LSA_ACTION_FLOOD_AREA:
3507 ospf_flood_through_area (data->area, NULL, data->lsa);
3508 break;
paul718e3742002-12-13 20:15:29 +00003509 case LSA_ACTION_FLUSH_AREA:
3510 ospf_lsa_flush_area (data->lsa, data->area);
3511 break;
paul718e3742002-12-13 20:15:29 +00003512 }
3513
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003514 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003515 XFREE (MTYPE_OSPF_MESSAGE, data);
3516 return 0;
3517}
3518
3519void
3520ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3521{
3522 struct lsa_action *data;
3523
Stephen Hemminger393deb92008-08-18 14:13:29 -07003524 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003525 data->action = LSA_ACTION_FLOOD_AREA;
3526 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003527 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003528
3529 thread_add_event (master, ospf_lsa_action, data, 0);
3530}
3531
3532void
3533ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3534{
3535 struct lsa_action *data;
3536
Stephen Hemminger393deb92008-08-18 14:13:29 -07003537 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003538 data->action = LSA_ACTION_FLUSH_AREA;
3539 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003540 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003541
3542 thread_add_event (master, ospf_lsa_action, data, 0);
3543}
3544
3545
3546/* LSA Refreshment functions. */
Paul Jakmac363d382010-01-24 22:42:13 +00003547struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00003548ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003549{
3550 struct external_info *ei;
Paul Jakmac363d382010-01-24 22:42:13 +00003551 struct ospf_lsa *new = NULL;
paul718e3742002-12-13 20:15:29 +00003552 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
Paul Jakma66349742010-04-13 22:33:54 +01003553 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003554
3555 switch (lsa->data->type)
3556 {
3557 /* Router and Network LSAs are processed differently. */
3558 case OSPF_ROUTER_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003559 new = ospf_router_lsa_refresh (lsa);
3560 break;
paul718e3742002-12-13 20:15:29 +00003561 case OSPF_NETWORK_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003562 new = ospf_network_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003563 break;
3564 case OSPF_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003565 new = ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003566 break;
3567 case OSPF_ASBR_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003568 new = ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003569 break;
3570 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003571 /* Translated from NSSA Type-5s are refreshed when
3572 * from refresh of Type-7 - do not refresh these directly.
3573 */
3574 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3575 break;
paul718e3742002-12-13 20:15:29 +00003576 ei = ospf_external_info_check (lsa);
3577 if (ei)
Paul Jakmac363d382010-01-24 22:42:13 +00003578 new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003579 else
pauld4a53d52003-07-12 21:30:57 +00003580 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003581 break;
3582#ifdef HAVE_OPAQUE_LSA
3583 case OSPF_OPAQUE_LINK_LSA:
3584 case OSPF_OPAQUE_AREA_LSA:
3585 case OSPF_OPAQUE_AS_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003586 new = ospf_opaque_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003587 break;
pauld7480322003-05-16 17:31:51 +00003588#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003589 default:
3590 break;
paul718e3742002-12-13 20:15:29 +00003591 }
Paul Jakmac363d382010-01-24 22:42:13 +00003592 return new;
paul718e3742002-12-13 20:15:29 +00003593}
3594
3595void
paul68980082003-03-25 05:07:42 +00003596ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003597{
3598 u_int16_t index, current_index;
3599
Paul Jakma66349742010-04-13 22:33:54 +01003600 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003601 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3602
3603 if (lsa->refresh_list < 0)
3604 {
3605 int delay;
3606
3607 if (LS_AGE (lsa) == 0 &&
3608 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3609 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3610 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3611 else
3612 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3613 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3614 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3615
3616 if (delay < 0)
3617 delay = 0;
3618
Paul Jakmac363d382010-01-24 22:42:13 +00003619 current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL)
3620 - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003621
3622 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
Paul Jakmac363d382010-01-24 22:42:13 +00003623 % (OSPF_LSA_REFRESHER_SLOTS);
paul718e3742002-12-13 20:15:29 +00003624
3625 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003626 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003627 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003628 if (!ospf->lsa_refresh_queue.qs[index])
3629 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003630 listnode_add (ospf->lsa_refresh_queue.qs[index],
3631 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003632 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003633 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003634 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003635 "setting refresh_list on lsa %p (slod %d)",
3636 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003637 }
3638}
3639
3640void
paul68980082003-03-25 05:07:42 +00003641ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003642{
Paul Jakma66349742010-04-13 22:33:54 +01003643 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003644 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3645 if (lsa->refresh_list >= 0)
3646 {
hasso52dc7ee2004-09-23 19:18:23 +00003647 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003648 listnode_delete (refresh_list, lsa);
3649 if (!listcount (refresh_list))
3650 {
3651 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003652 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003653 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003654 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003655 lsa->refresh_list = -1;
3656 }
3657}
3658
3659int
3660ospf_lsa_refresh_walker (struct thread *t)
3661{
hasso52dc7ee2004-09-23 19:18:23 +00003662 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003663 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003664 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003665 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003666 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003667 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003668
3669 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003670 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003671
3672
paul68980082003-03-25 05:07:42 +00003673 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003674
ajs9dbc7972005-03-13 19:27:22 +00003675 /* Note: if clock has jumped backwards, then time change could be negative,
3676 so we are careful to cast the expression to unsigned before taking
3677 modulus. */
paul68980082003-03-25 05:07:42 +00003678 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003679 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakmac363d382010-01-24 22:42:13 +00003680 (quagga_time (NULL) - ospf->lsa_refresher_started)
3681 / OSPF_LSA_REFRESHER_GRANULARITY))
3682 % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003683
3684 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003685 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003686 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003687
paul68980082003-03-25 05:07:42 +00003688 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003689 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3690 {
3691 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003692 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003693 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003694
paul68980082003-03-25 05:07:42 +00003695 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003696
Paul Jakma66349742010-04-13 22:33:54 +01003697 assert (i >= 0);
3698
paul68980082003-03-25 05:07:42 +00003699 ospf->lsa_refresh_queue.qs [i] = NULL;
3700
paul718e3742002-12-13 20:15:29 +00003701 if (refresh_list)
3702 {
paul1eb8ef22005-04-07 07:30:20 +00003703 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003704 {
paul718e3742002-12-13 20:15:29 +00003705 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003706 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003707 "refresh lsa %p (slot %d)",
3708 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003709
Paul Jakma66349742010-04-13 22:33:54 +01003710 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003711 list_delete_node (refresh_list, node);
paul718e3742002-12-13 20:15:29 +00003712 lsa->refresh_list = -1;
3713 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003714 }
3715 list_free (refresh_list);
3716 }
3717 }
3718
paul68980082003-03-25 05:07:42 +00003719 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3720 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003721 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003722
paul1eb8ef22005-04-07 07:30:20 +00003723 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
Paul Jakma66349742010-04-13 22:33:54 +01003724 {
3725 ospf_lsa_refresh (ospf, lsa);
3726 assert (lsa->lock > 0);
3727 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
3728 }
paul718e3742002-12-13 20:15:29 +00003729
3730 list_delete (lsa_to_refresh);
3731
3732 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003733 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003734
3735 return 0;
3736}
3737