blob: 7e71b5d78c1b0e3f6ee6a207e33fabacccaeb71b [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
Paul Jakma02d942c2010-01-24 23:36:20 +0000375 lsah->ls_age = htons (OSPF_LSA_INITIAL_AGE);
paul718e3742002-12-13 20:15:29 +0000376 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);
Paul Jakmadfbd5172010-04-14 10:32:12 +0100965 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +0000966 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000967 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000968 area->router_lsa_self = NULL;
969
970 /* Refresh router-LSA, (not install) and flood through area. */
Paul Jakmac363d382010-01-24 22:42:13 +0000971 ospf_router_lsa_update_area (area);
paul718e3742002-12-13 20:15:29 +0000972 }
973 else
974 {
975 rl = (struct router_lsa *) lsa->data;
976 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +0000977 if (rl->flags != ospf->flags)
Paul Jakmac363d382010-01-24 22:42:13 +0000978 ospf_router_lsa_update_area (area);
paul718e3742002-12-13 20:15:29 +0000979 }
980 }
981
982 return 0;
983}
984
985
986/* network-LSA related functions. */
987/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +0000988static void
paul718e3742002-12-13 20:15:29 +0000989ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
990{
991 struct in_addr mask;
992 struct route_node *rn;
993 struct ospf_neighbor *nbr;
994
995 masklen2ip (oi->address->prefixlen, &mask);
996 stream_put_ipv4 (s, mask.s_addr);
997
998 /* The network-LSA lists those routers that are fully adjacent to
999 the Designated Router; each fully adjacent router is identified by
1000 its OSPF Router ID. The Designated Router includes itself in this
1001 list. RFC2328, Section 12.4.2 */
1002
1003 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1004 if ((nbr = rn->info) != NULL)
1005 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1006 stream_put_ipv4 (s, nbr->router_id.s_addr);
1007}
1008
paul4dadc292005-05-06 21:37:42 +00001009static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001010ospf_network_lsa_new (struct ospf_interface *oi)
1011{
1012 struct stream *s;
1013 struct ospf_lsa *new;
1014 struct lsa_header *lsah;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001015 struct ospf_if_params *oip;
paul718e3742002-12-13 20:15:29 +00001016 int length;
1017
1018 /* If there are no neighbours on this network (the net is stub),
1019 the router does not originate network-LSA (see RFC 12.4.2) */
1020 if (oi->full_nbrs == 0)
1021 return NULL;
1022
1023 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001024 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001025
1026 /* Create new stream for LSA. */
1027 s = stream_new (OSPF_MAX_LSA_SIZE);
1028 lsah = (struct lsa_header *) STREAM_DATA (s);
1029
1030 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001031 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001032
1033 /* Set network-LSA body fields. */
1034 ospf_network_lsa_body_set (s, oi);
1035
1036 /* Set length. */
1037 length = stream_get_endp (s);
1038 lsah->length = htons (length);
1039
1040 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001041 if ( (new = ospf_lsa_new ()) == NULL)
1042 {
1043 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1044 return NULL;
1045 }
1046
paul718e3742002-12-13 20:15:29 +00001047 new->area = oi->area;
Paul Jakmac363d382010-01-24 22:42:13 +00001048 new->oi = oi;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001049 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001050
1051 /* Copy LSA to store. */
1052 new->data = ospf_lsa_data_new (length);
1053 memcpy (new->data, lsah, length);
1054 stream_free (s);
Paul Jakma7eb5b472009-10-13 16:13:13 +01001055
1056 /* Remember prior network LSA sequence numbers, even if we stop
1057 * originating one for this oi, to try avoid re-originating LSAs with a
1058 * prior sequence number, and thus speed up adjency forming & convergence.
1059 */
1060 if ((oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4)))
1061 {
1062 new->data->ls_seqnum = oip->network_lsa_seqnum;
1063 new->data->ls_seqnum = lsa_seqnum_increment (new);
1064 }
1065 else
1066 {
1067 oip = ospf_get_if_params (oi->ifp, oi->address->u.prefix4);
1068 ospf_if_update_params (oi->ifp, oi->address->u.prefix4);
1069 }
1070 oip->network_lsa_seqnum = new->data->ls_seqnum;
1071
paul718e3742002-12-13 20:15:29 +00001072 return new;
1073}
1074
1075/* Originate network-LSA. */
Paul Jakmac363d382010-01-24 22:42:13 +00001076void
1077ospf_network_lsa_update (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001078{
1079 struct ospf_lsa *new;
Paul Jakmac363d382010-01-24 22:42:13 +00001080
1081 if (oi->network_lsa_self != NULL)
1082 {
1083 ospf_lsa_refresh (oi->ospf, oi->network_lsa_self);
1084 return;
1085 }
1086
paul718e3742002-12-13 20:15:29 +00001087 /* Create new network-LSA instance. */
1088 new = ospf_network_lsa_new (oi);
1089 if (new == NULL)
Paul Jakmac363d382010-01-24 22:42:13 +00001090 return;
paul718e3742002-12-13 20:15:29 +00001091
1092 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001093 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001094
1095 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001096 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001097
1098 /* Flooding new LSA through area. */
1099 ospf_flood_through_area (oi->area, NULL, new);
1100
1101 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1102 {
ajse588f212004-12-08 18:12:06 +00001103 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001104 new->data->type, inet_ntoa (new->data->id), new);
1105 ospf_lsa_header_dump (new->data);
1106 }
1107
Paul Jakmac363d382010-01-24 22:42:13 +00001108 return;
paul718e3742002-12-13 20:15:29 +00001109}
1110
Paul Jakmac363d382010-01-24 22:42:13 +00001111static struct ospf_lsa *
1112ospf_network_lsa_refresh (struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001113{
1114 struct ospf_area *area = lsa->area;
Paul Jakmac363d382010-01-24 22:42:13 +00001115 struct ospf_lsa *new, *new2;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001116 struct ospf_if_params *oip;
Paul Jakmac363d382010-01-24 22:42:13 +00001117 struct ospf_interface *oi = lsa->oi;
1118
paul718e3742002-12-13 20:15:29 +00001119 assert (lsa->data);
1120
1121 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001122 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001123
Paul Jakmac363d382010-01-24 22:42:13 +00001124 /* Unregister LSA from refresh-list */
1125 ospf_refresher_unregister_lsa (area->ospf, lsa);
1126
paul718e3742002-12-13 20:15:29 +00001127 /* Create new network-LSA instance. */
1128 new = ospf_network_lsa_new (oi);
1129 if (new == NULL)
Paul Jakmac363d382010-01-24 22:42:13 +00001130 return NULL;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001131
1132 oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4);
1133 assert (oip != NULL);
1134 oip->network_lsa_seqnum = new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001135
Paul Jakmac363d382010-01-24 22:42:13 +00001136 new2 = ospf_lsa_install (area->ospf, oi, new);
1137
1138 assert (new2 == new);
1139
paul718e3742002-12-13 20:15:29 +00001140 /* Flood LSA through aera. */
1141 ospf_flood_through_area (area, NULL, new);
1142
1143 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1144 {
ajse588f212004-12-08 18:12:06 +00001145 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001146 new->data->type, inet_ntoa (new->data->id));
1147 ospf_lsa_header_dump (new->data);
1148 }
1149
Paul Jakmac363d382010-01-24 22:42:13 +00001150 return new;
paul718e3742002-12-13 20:15:29 +00001151}
paul718e3742002-12-13 20:15:29 +00001152
paul4dadc292005-05-06 21:37:42 +00001153static void
paul718e3742002-12-13 20:15:29 +00001154stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1155{
1156 u_int32_t metric;
1157 char *mp;
1158
1159 /* Put 0 metric. TOS metric is not supported. */
1160 metric = htonl (metric_value);
1161 mp = (char *) &metric;
1162 mp++;
1163 stream_put (s, mp, 3);
1164}
1165
1166/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001167static void
paul718e3742002-12-13 20:15:29 +00001168ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1169 u_int32_t metric)
1170{
1171 struct in_addr mask;
1172
1173 masklen2ip (p->prefixlen, &mask);
1174
1175 /* Put Network Mask. */
1176 stream_put_ipv4 (s, mask.s_addr);
1177
1178 /* Set # TOS. */
1179 stream_putc (s, (u_char) 0);
1180
1181 /* Set metric. */
1182 stream_put_ospf_metric (s, metric);
1183}
1184
paul4dadc292005-05-06 21:37:42 +00001185static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001186ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1187 u_int32_t metric, struct in_addr id)
1188{
1189 struct stream *s;
1190 struct ospf_lsa *new;
1191 struct lsa_header *lsah;
1192 int length;
1193
paulc24d6022005-11-20 14:54:12 +00001194 if (id.s_addr == 0xffffffff)
1195 {
1196 /* Maybe Link State ID not available. */
1197 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1198 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1199 OSPF_SUMMARY_LSA);
1200 return NULL;
1201 }
1202
paul718e3742002-12-13 20:15:29 +00001203 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001204 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001205
1206 /* Create new stream for LSA. */
1207 s = stream_new (OSPF_MAX_LSA_SIZE);
1208 lsah = (struct lsa_header *) STREAM_DATA (s);
1209
paul68980082003-03-25 05:07:42 +00001210 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1211 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001212
1213 /* Set summary-LSA body fields. */
1214 ospf_summary_lsa_body_set (s, p, metric);
1215
1216 /* Set length. */
1217 length = stream_get_endp (s);
1218 lsah->length = htons (length);
1219
1220 /* Create OSPF LSA instance. */
1221 new = ospf_lsa_new ();
1222 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001223 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001224
1225 /* Copy LSA to store. */
1226 new->data = ospf_lsa_data_new (length);
1227 memcpy (new->data, lsah, length);
1228 stream_free (s);
1229
1230 return new;
1231}
1232
1233/* Originate Summary-LSA. */
1234struct ospf_lsa *
1235ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1236 struct ospf_area *area)
1237{
1238 struct ospf_lsa *new;
1239 struct in_addr id;
1240
paul68980082003-03-25 05:07:42 +00001241 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001242
paulc24d6022005-11-20 14:54:12 +00001243 if (id.s_addr == 0xffffffff)
1244 {
1245 /* Maybe Link State ID not available. */
1246 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1247 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1248 OSPF_SUMMARY_LSA);
1249 return NULL;
1250 }
1251
paul718e3742002-12-13 20:15:29 +00001252 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001253 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1254 return NULL;
paul718e3742002-12-13 20:15:29 +00001255
1256 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001257 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001258
1259 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001260 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001261
1262 /* Flooding new LSA through area. */
1263 ospf_flood_through_area (area, NULL, new);
1264
1265 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1266 {
ajse588f212004-12-08 18:12:06 +00001267 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001268 new->data->type, inet_ntoa (new->data->id), new);
1269 ospf_lsa_header_dump (new->data);
1270 }
1271
1272 return new;
1273}
1274
Paul Jakmac363d382010-01-24 22:42:13 +00001275static struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001276ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001277{
1278 struct ospf_lsa *new;
1279 struct summary_lsa *sl;
1280 struct prefix p;
1281
1282 /* Sanity check. */
1283 assert (lsa->data);
1284
1285 sl = (struct summary_lsa *)lsa->data;
1286 p.prefixlen = ip_masklen (sl->mask);
1287 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1288 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001289
1290 if (!new)
1291 return NULL;
1292
paul718e3742002-12-13 20:15:29 +00001293 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001294
paul68980082003-03-25 05:07:42 +00001295 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001296
1297 /* Flood LSA through AS. */
1298 ospf_flood_through_area (new->area, NULL, new);
1299
1300 /* Debug logging. */
1301 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1302 {
ajse588f212004-12-08 18:12:06 +00001303 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001304 new->data->type, inet_ntoa (new->data->id));
1305 ospf_lsa_header_dump (new->data);
1306 }
1307
1308 return new;
1309}
1310
1311
1312/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001313static void
paul718e3742002-12-13 20:15:29 +00001314ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1315 u_int32_t metric)
1316{
1317 struct in_addr mask;
1318
1319 masklen2ip (p->prefixlen, &mask);
1320
1321 /* Put Network Mask. */
1322 stream_put_ipv4 (s, mask.s_addr);
1323
1324 /* Set # TOS. */
1325 stream_putc (s, (u_char) 0);
1326
1327 /* Set metric. */
1328 stream_put_ospf_metric (s, metric);
1329}
1330
paul4dadc292005-05-06 21:37:42 +00001331static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001332ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1333 u_int32_t metric, struct in_addr id)
1334{
1335 struct stream *s;
1336 struct ospf_lsa *new;
1337 struct lsa_header *lsah;
1338 int length;
1339
paulc24d6022005-11-20 14:54:12 +00001340 if (id.s_addr == 0xffffffff)
1341 {
1342 /* Maybe Link State ID not available. */
1343 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1344 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1345 OSPF_ASBR_SUMMARY_LSA);
1346 return NULL;
1347 }
1348
paul718e3742002-12-13 20:15:29 +00001349 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001350 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001351
1352 /* Create new stream for LSA. */
1353 s = stream_new (OSPF_MAX_LSA_SIZE);
1354 lsah = (struct lsa_header *) STREAM_DATA (s);
1355
paul68980082003-03-25 05:07:42 +00001356 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1357 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001358
1359 /* Set summary-LSA body fields. */
1360 ospf_summary_asbr_lsa_body_set (s, p, metric);
1361
1362 /* Set length. */
1363 length = stream_get_endp (s);
1364 lsah->length = htons (length);
1365
1366 /* Create OSPF LSA instance. */
1367 new = ospf_lsa_new ();
1368 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001369 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001370
1371 /* Copy LSA to store. */
1372 new->data = ospf_lsa_data_new (length);
1373 memcpy (new->data, lsah, length);
1374 stream_free (s);
1375
1376 return new;
1377}
1378
1379/* Originate summary-ASBR-LSA. */
1380struct ospf_lsa *
1381ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1382 struct ospf_area *area)
1383{
1384 struct ospf_lsa *new;
1385 struct in_addr id;
1386
paul68980082003-03-25 05:07:42 +00001387 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001388
paulc24d6022005-11-20 14:54:12 +00001389 if (id.s_addr == 0xffffffff)
1390 {
1391 /* Maybe Link State ID not available. */
1392 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1393 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1394 OSPF_ASBR_SUMMARY_LSA);
1395 return NULL;
1396 }
1397
paul718e3742002-12-13 20:15:29 +00001398 /* Create new summary-LSA instance. */
1399 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001400 if (!new)
1401 return NULL;
paul718e3742002-12-13 20:15:29 +00001402
1403 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001404 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001405
1406 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001407 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001408
1409 /* Flooding new LSA through area. */
1410 ospf_flood_through_area (area, NULL, new);
1411
1412 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1413 {
ajse588f212004-12-08 18:12:06 +00001414 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001415 new->data->type, inet_ntoa (new->data->id), new);
1416 ospf_lsa_header_dump (new->data);
1417 }
1418
1419 return new;
1420}
1421
Paul Jakmac363d382010-01-24 22:42:13 +00001422static struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001423ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001424{
1425 struct ospf_lsa *new;
1426 struct summary_lsa *sl;
1427 struct prefix p;
1428
1429 /* Sanity check. */
1430 assert (lsa->data);
1431
1432 sl = (struct summary_lsa *)lsa->data;
1433 p.prefixlen = ip_masklen (sl->mask);
1434 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1435 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001436 if (!new)
1437 return NULL;
paul718e3742002-12-13 20:15:29 +00001438
1439 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001440
paul68980082003-03-25 05:07:42 +00001441 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001442
1443 /* Flood LSA through area. */
1444 ospf_flood_through_area (new->area, NULL, new);
1445
1446 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1447 {
ajse588f212004-12-08 18:12:06 +00001448 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001449 new->data->type, inet_ntoa (new->data->id));
1450 ospf_lsa_header_dump (new->data);
1451 }
1452
1453 return new;
1454}
1455
1456/* AS-external-LSA related functions. */
1457
1458/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1459 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001460static struct in_addr
paul68980082003-03-25 05:07:42 +00001461ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001462{
1463 struct in_addr fwd;
1464 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001465 struct listnode *node;
1466 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001467
1468 fwd.s_addr = 0;
1469
1470 if (!nexthop.s_addr)
1471 return fwd;
1472
1473 /* Check whether nexthop is covered by OSPF network. */
1474 nh.family = AF_INET;
1475 nh.u.prefix4 = nexthop;
1476 nh.prefixlen = IPV4_MAX_BITLEN;
Paul Jakma4ca15d42009-08-03 15:16:41 +01001477
1478 /* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be
1479 * better to make use of the per-ifp table of ois.
1480 */
paul1eb8ef22005-04-07 07:30:20 +00001481 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1482 if (if_is_operative (oi->ifp))
1483 if (oi->address->family == AF_INET)
1484 if (prefix_match (oi->address, &nh))
1485 return nexthop;
paul718e3742002-12-13 20:15:29 +00001486
1487 return fwd;
1488}
1489
paul718e3742002-12-13 20:15:29 +00001490/* NSSA-external-LSA related functions. */
1491
1492/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001493
paul718e3742002-12-13 20:15:29 +00001494struct in_addr
1495ospf_get_ip_from_ifp (struct ospf_interface *oi)
1496{
1497 struct in_addr fwd;
1498
1499 fwd.s_addr = 0;
1500
paul2e3b2e42002-12-13 21:03:13 +00001501 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001502 return oi->address->u.prefix4;
1503
1504 return fwd;
1505}
1506
1507/* Get 1st IP connection for Forward Addr */
1508struct in_addr
paulf2c80652002-12-13 21:44:27 +00001509ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001510{
1511 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001512 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001513 struct listnode *node;
1514 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001515
1516 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001517 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001518
paul1eb8ef22005-04-07 07:30:20 +00001519 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001520 {
paul2e3b2e42002-12-13 21:03:13 +00001521 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001522 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001523 if (oi->address && oi->address->family == AF_INET)
1524 {
1525 if (best_default.s_addr == 0)
1526 best_default = oi->address->u.prefix4;
1527 if (oi->area == area)
1528 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001529 }
paul718e3742002-12-13 20:15:29 +00001530 }
paulf2c80652002-12-13 21:44:27 +00001531 if (best_default.s_addr != 0)
1532 return best_default;
paul718e3742002-12-13 20:15:29 +00001533
paul68980082003-03-25 05:07:42 +00001534 if (best_default.s_addr != 0)
1535 return best_default;
1536
paul718e3742002-12-13 20:15:29 +00001537 return fwd;
1538}
hassobeebba72004-06-20 21:00:27 +00001539
paul718e3742002-12-13 20:15:29 +00001540#define DEFAULT_DEFAULT_METRIC 20
1541#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1542#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1543
1544#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1545
1546int
paul68980082003-03-25 05:07:42 +00001547metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001548{
paul68980082003-03-25 05:07:42 +00001549 return (ospf->dmetric[src].type < 0 ?
1550 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001551}
1552
1553int
paul68980082003-03-25 05:07:42 +00001554metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001555{
paul68980082003-03-25 05:07:42 +00001556 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001557 {
1558 if (src == DEFAULT_ROUTE)
1559 {
paul68980082003-03-25 05:07:42 +00001560 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001561 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1562 else
1563 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1564 }
paul68980082003-03-25 05:07:42 +00001565 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001566 return DEFAULT_DEFAULT_METRIC;
1567 else
paul68980082003-03-25 05:07:42 +00001568 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001569 }
1570
paul68980082003-03-25 05:07:42 +00001571 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001572}
1573
1574/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001575static void
paul68980082003-03-25 05:07:42 +00001576ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1577 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001578{
1579 struct prefix_ipv4 *p = &ei->p;
1580 struct in_addr mask, fwd_addr;
1581 u_int32_t mvalue;
1582 int mtype;
1583 int type;
1584
1585 /* Put Network Mask. */
1586 masklen2ip (p->prefixlen, &mask);
1587 stream_put_ipv4 (s, mask.s_addr);
1588
1589 /* If prefix is default, specify DEFAULT_ROUTE. */
1590 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1591
1592 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001593 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001594
1595 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001596 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001597
1598 /* Put type of external metric. */
1599 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1600
1601 /* Put 0 metric. TOS metric is not supported. */
1602 stream_put_ospf_metric (s, mvalue);
1603
1604 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001605 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001606
1607 /* Put forwarding address. */
1608 stream_put_ipv4 (s, fwd_addr.s_addr);
1609
1610 /* Put route tag -- This value should be introduced from configuration. */
1611 stream_putl (s, 0);
1612}
1613
1614/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001615static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001616ospf_external_lsa_new (struct ospf *ospf,
1617 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001618{
1619 struct stream *s;
1620 struct lsa_header *lsah;
1621 struct ospf_lsa *new;
1622 struct in_addr id;
1623 int length;
1624
1625 if (ei == NULL)
1626 {
1627 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001628 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
paul718e3742002-12-13 20:15:29 +00001629 return NULL;
1630 }
1631
1632 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001633 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001634
1635 /* If old Link State ID is specified, refresh LSA with same ID. */
1636 if (old_id)
1637 id = *old_id;
1638 /* Get Link State with unique ID. */
1639 else
1640 {
paul68980082003-03-25 05:07:42 +00001641 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001642 if (id.s_addr == 0xffffffff)
1643 {
1644 /* Maybe Link State ID not available. */
1645 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001646 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001647 return NULL;
1648 }
1649 }
1650
1651 /* Create new stream for LSA. */
1652 s = stream_new (OSPF_MAX_LSA_SIZE);
1653 lsah = (struct lsa_header *) STREAM_DATA (s);
1654
1655 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001656 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1657 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001658
1659 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001660 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001661
1662 /* Set length. */
1663 length = stream_get_endp (s);
1664 lsah->length = htons (length);
1665
1666 /* Now, create OSPF LSA instance. */
1667 new = ospf_lsa_new ();
1668 new->area = NULL;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001669 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001670
1671 /* Copy LSA data to store, discard stream. */
1672 new->data = ospf_lsa_data_new (length);
1673 memcpy (new->data, lsah, length);
1674 stream_free (s);
1675
1676 return new;
1677}
1678
paul718e3742002-12-13 20:15:29 +00001679/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001680static void
paul68980082003-03-25 05:07:42 +00001681ospf_install_flood_nssa (struct ospf *ospf,
1682 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001683{
pauld4a53d52003-07-12 21:30:57 +00001684 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001685 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001686 struct ospf_area *area;
1687 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001688
pauld4a53d52003-07-12 21:30:57 +00001689 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1690 * which originated from an NSSA area. In which case it should not be
1691 * flooded back to NSSA areas.
1692 */
1693 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1694 return;
1695
paul718e3742002-12-13 20:15:29 +00001696 /* NSSA Originate or Refresh (If anyNSSA)
1697
1698 LSA is self-originated. And just installed as Type-5.
1699 Additionally, install as Type-7 LSDB for every attached NSSA.
1700
1701 P-Bit controls which ABR performs translation to outside world; If
1702 we are an ABR....do not set the P-bit, because we send the Type-5,
1703 not as the ABR Translator, but as the ASBR owner within the AS!
1704
1705 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1706 elected ABR Translator will see the P-bit, Translate, and re-flood.
1707
1708 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1709 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1710
paul1eb8ef22005-04-07 07:30:20 +00001711 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001712 {
hasso0c14ad82003-07-03 08:36:02 +00001713 /* Don't install Type-7 LSA's into nonNSSA area */
1714 if (area->external_routing != OSPF_AREA_NSSA)
1715 continue;
paul718e3742002-12-13 20:15:29 +00001716
paul68980082003-03-25 05:07:42 +00001717 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001718 new = ospf_lsa_dup (lsa);
1719 new->area = area;
1720 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001721
paul68980082003-03-25 05:07:42 +00001722 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001723 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001724 {
pauld4a53d52003-07-12 21:30:57 +00001725 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001726
1727 /* set non-zero FWD ADDR
1728
1729 draft-ietf-ospf-nssa-update-09.txt
1730
1731 if the network between the NSSA AS boundary router and the
1732 adjacent AS is advertised into OSPF as an internal OSPF route,
1733 the forwarding address should be the next op address as is cu
1734 currently done with type-5 LSAs. If the intervening network is
1735 not adversited into OSPF as an internal OSPF route and the
1736 type-7 LSA's P-bit is set a forwarding address should be
1737 selected from one of the router's active OSPF inteface addresses
1738 which belong to the NSSA. If no such addresses exist, then
1739 no type-7 LSA's with the P-bit set should originate from this
1740 router. */
1741
pauld4a53d52003-07-12 21:30:57 +00001742 /* kevinm: not updating lsa anymore, just new */
1743 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001744
1745 if (extlsa->e[0].fwd_addr.s_addr == 0)
1746 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001747
pauld7480322003-05-16 17:31:51 +00001748 if (extlsa->e[0].fwd_addr.s_addr == 0)
1749 {
1750 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001751 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001752 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001753 return;
1754 }
paulf2c80652002-12-13 21:44:27 +00001755 }
paul718e3742002-12-13 20:15:29 +00001756
paul68980082003-03-25 05:07:42 +00001757 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001758 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001759
1760 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001761 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001762 }
paul718e3742002-12-13 20:15:29 +00001763}
pauld4a53d52003-07-12 21:30:57 +00001764
paul4dadc292005-05-06 21:37:42 +00001765static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001766ospf_lsa_translated_nssa_new (struct ospf *ospf,
1767 struct ospf_lsa *type7)
1768{
1769
1770 struct ospf_lsa *new;
1771 struct as_external_lsa *ext, *extnew;
1772 struct external_info ei;
1773
1774 ext = (struct as_external_lsa *)(type7->data);
1775
1776 /* need external_info struct, fill in bare minimum */
1777 ei.p.family = AF_INET;
1778 ei.p.prefix = type7->data->id;
1779 ei.p.prefixlen = ip_masklen (ext->mask);
1780 ei.type = ZEBRA_ROUTE_OSPF;
1781 ei.nexthop = ext->header.adv_router;
1782 ei.route_map_set.metric = -1;
1783 ei.route_map_set.metric_type = -1;
1784 ei.tag = 0;
1785
1786 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1787 {
1788 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001789 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001790 "Translated Type-5 for %s",
1791 inet_ntoa (ei.p.prefix));
1792 return NULL;
1793 }
1794
1795 extnew = (struct as_external_lsa *)(new->data);
1796
1797 /* copy over Type-7 data to new */
1798 extnew->e[0].tos = ext->e[0].tos;
1799 extnew->e[0].route_tag = ext->e[0].route_tag;
1800 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1801 new->data->ls_seqnum = type7->data->ls_seqnum;
1802
1803 /* add translated flag, checksum and lock new lsa */
1804 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
pauld4a53d52003-07-12 21:30:57 +00001805 new = ospf_lsa_lock (new);
1806
1807 return new;
1808}
1809
pauld4a53d52003-07-12 21:30:57 +00001810/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1811struct ospf_lsa *
1812ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1813{
1814 struct ospf_lsa *new;
1815 struct as_external_lsa *extnew;
1816
1817 /* we cant use ospf_external_lsa_originate() as we need to set
1818 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1819 */
1820
1821 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1822 {
1823 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001824 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001825 "Type-7, Id %s, to Type-5",
1826 inet_ntoa (type7->data->id));
1827 return NULL;
1828 }
1829
1830 extnew = (struct as_external_lsa *)new;
1831
1832 if (IS_DEBUG_OSPF_NSSA)
1833 {
ajse588f212004-12-08 18:12:06 +00001834 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001835 "translated Type 7, installed:");
1836 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001837 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1838 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001839 }
1840
1841 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1842 {
1843 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001844 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001845 "Could not install LSA "
1846 "id %s", inet_ntoa (type7->data->id));
1847 return NULL;
1848 }
1849
1850 ospf->lsa_originate_count++;
1851 ospf_flood_through_as (ospf, NULL, new);
1852
1853 return new;
1854}
1855
1856/* Refresh Translated from NSSA AS-external-LSA. */
1857struct ospf_lsa *
1858ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1859 struct ospf_lsa *type5)
1860{
1861 struct ospf_lsa *new = NULL;
1862
1863 /* Sanity checks. */
1864 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00001865 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00001866 return NULL;
pauld4a53d52003-07-12 21:30:57 +00001867 if (type7)
1868 assert (type7->data);
1869 if (type5)
1870 assert (type5->data);
1871 assert (ospf->anyNSSA);
1872
1873 /* get required data according to what has been given */
1874 if (type7 && type5 == NULL)
1875 {
1876 /* find the translated Type-5 for this Type-7 */
1877 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1878 struct prefix_ipv4 p =
1879 {
1880 .prefix = type7->data->id,
1881 .prefixlen = ip_masklen (ext->mask),
1882 .family = AF_INET,
1883 };
1884
1885 type5 = ospf_external_info_find_lsa (ospf, &p);
1886 }
1887 else if (type5 && type7 == NULL)
1888 {
1889 /* find the type-7 from which supplied type-5 was translated,
1890 * ie find first type-7 with same LSA Id.
1891 */
paul1eb8ef22005-04-07 07:30:20 +00001892 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00001893 struct route_node *rn;
1894 struct ospf_lsa *lsa;
1895 struct ospf_area *area;
1896
paul1eb8ef22005-04-07 07:30:20 +00001897 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00001898 {
1899 if (area->external_routing != OSPF_AREA_NSSA
1900 && !type7)
1901 continue;
1902
1903 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
1904 {
1905 if (lsa->data->id.s_addr == type5->data->id.s_addr)
1906 {
1907 type7 = lsa;
1908 break;
1909 }
1910 }
1911 }
1912 }
1913
1914 /* do we have type7? */
1915 if (!type7)
1916 {
1917 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001918 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00001919 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00001920 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00001921 return NULL;
1922 }
1923
1924 /* do we have valid translated type5? */
1925 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
1926 {
1927 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001928 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00001929 "found for Type-7 with Id %s",
1930 inet_ntoa (type7->data->id));
1931 return NULL;
1932 }
1933
1934 /* Delete LSA from neighbor retransmit-list. */
1935 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
1936
1937 /* create new translated LSA */
1938 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1939 {
1940 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001941 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001942 "Type-7 for %s to Type-5",
1943 inet_ntoa (type7->data->id));
1944 return NULL;
1945 }
1946
1947 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
1948 {
1949 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001950 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00001951 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00001952 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00001953 return NULL;
1954 }
1955
1956 /* Flood LSA through area. */
1957 ospf_flood_through_as (ospf, NULL, new);
1958
1959 return new;
1960}
paul718e3742002-12-13 20:15:29 +00001961
1962int
1963is_prefix_default (struct prefix_ipv4 *p)
1964{
1965 struct prefix_ipv4 q;
1966
1967 q.family = AF_INET;
1968 q.prefix.s_addr = 0;
1969 q.prefixlen = 0;
1970
1971 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
1972}
1973
1974/* Originate an AS-external-LSA, install and flood. */
1975struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001976ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001977{
1978 struct ospf_lsa *new;
1979
1980 /* Added for NSSA project....
1981
1982 External LSAs are originated in ASBRs as usual, but for NSSA systems.
1983 there is the global Type-5 LSDB and a Type-7 LSDB installed for
1984 every area. The Type-7's are flooded to every IR and every ABR; We
1985 install the Type-5 LSDB so that the normal "refresh" code operates
1986 as usual, and flag them as not used during ASE calculations. The
1987 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
1988 Address of non-zero.
1989
1990 If an ABR is the elected NSSA translator, following SPF and during
1991 the ABR task it will translate all the scanned Type-7's, with P-bit
1992 ON and not-self generated, and translate to Type-5's throughout the
1993 non-NSSA/STUB AS.
1994
1995 A difference in operation depends whether this ASBR is an ABR
1996 or not. If not an ABR, the P-bit is ON, to indicate that any
1997 elected NSSA-ABR can perform its translation.
1998
1999 If an ABR, the P-bit is OFF; No ABR will perform translation and
2000 this ASBR will flood the Type-5 LSA as usual.
2001
2002 For the case where this ASBR is not an ABR, the ASE calculations
2003 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2004 demonstrate to the user that there are LSA's that belong to any
2005 attached NSSA.
2006
2007 Finally, it just so happens that when the ABR is translating every
2008 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2009 approved Type-5 (translated from Type-7); at the end of translation
2010 if any Translated Type-5's remain unapproved, then they must be
2011 flushed from the AS.
2012
2013 */
2014
2015 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002016 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002017 return NULL;
2018
2019 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002020 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002021 {
2022 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002023 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002024 inet_ntoa (ei->p.prefix));
2025 return NULL;
2026 }
2027
2028 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002029 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002030
2031 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002032 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002033
2034 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002035 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002036
paul718e3742002-12-13 20:15:29 +00002037 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002038 if (ospf->anyNSSA &&
2039 /* stay away from translated LSAs! */
2040 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002041 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002042
2043 /* Debug logging. */
2044 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2045 {
ajse588f212004-12-08 18:12:06 +00002046 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002047 new->data->type, inet_ntoa (new->data->id), new);
2048 ospf_lsa_header_dump (new->data);
2049 }
2050
2051 return new;
2052}
2053
2054/* Originate AS-external-LSA from external info with initial flag. */
2055int
paul68980082003-03-25 05:07:42 +00002056ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002057{
paul68980082003-03-25 05:07:42 +00002058 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002059 struct route_node *rn;
2060 struct external_info *ei;
2061 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002062 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002063
paul68980082003-03-25 05:07:42 +00002064 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002065
2066 /* Originate As-external-LSA from all type of distribute source. */
2067 if ((rt = EXTERNAL_INFO (type)))
2068 for (rn = route_top (rt); rn; rn = route_next (rn))
2069 if ((ei = rn->info) != NULL)
2070 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002071 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002072 zlog_warn ("LSA: AS-external-LSA was not originated.");
2073
2074 return 0;
2075}
2076
paul4dadc292005-05-06 21:37:42 +00002077static struct external_info *
paul020709f2003-04-04 02:44:16 +00002078ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002079{
2080 int type;
2081 struct route_node *rn;
2082 struct prefix_ipv4 p;
2083
2084 p.family = AF_INET;
2085 p.prefix.s_addr = 0;
2086 p.prefixlen = 0;
2087
2088 /* First, lookup redistributed default route. */
2089 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2090 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2091 {
2092 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2093 if (rn != NULL)
2094 {
2095 route_unlock_node (rn);
2096 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002097 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002098 return rn->info;
2099 }
2100 }
2101
2102 return NULL;
2103}
2104
2105int
paul68980082003-03-25 05:07:42 +00002106ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002107{
paul718e3742002-12-13 20:15:29 +00002108 struct prefix_ipv4 p;
2109 struct in_addr nexthop;
2110 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002111 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002112
Paul Jakma4021b602006-05-12 22:55:41 +00002113 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002114
2115 p.family = AF_INET;
2116 p.prefix.s_addr = 0;
2117 p.prefixlen = 0;
2118
Paul Jakma4021b602006-05-12 22:55:41 +00002119 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002120 {
2121 /* If there is no default route via redistribute,
2122 then originate AS-external-LSA with nexthop 0 (self). */
2123 nexthop.s_addr = 0;
2124 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2125 }
2126
paul020709f2003-04-04 02:44:16 +00002127 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002128 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002129
2130 return 0;
2131}
2132
paul645878f2003-04-13 21:42:11 +00002133/* Flush any NSSA LSAs for given prefix */
2134void
2135ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2136{
paul1eb8ef22005-04-07 07:30:20 +00002137 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002138 struct ospf_lsa *lsa;
2139 struct ospf_area *area;
2140
paul1eb8ef22005-04-07 07:30:20 +00002141 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002142 {
paul1eb8ef22005-04-07 07:30:20 +00002143 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002144 {
2145 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2146 ospf->router_id)))
2147 {
2148 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002149 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002150 inet_ntoa (p->prefix), p->prefixlen);
2151 continue;
2152 }
2153 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2154 if (!IS_LSA_MAXAGE (lsa))
2155 {
2156 ospf_refresher_unregister_lsa (ospf, lsa);
2157 ospf_lsa_flush_area (lsa, area);
2158 }
2159 }
paul645878f2003-04-13 21:42:11 +00002160 }
2161}
paul645878f2003-04-13 21:42:11 +00002162
paul718e3742002-12-13 20:15:29 +00002163/* Flush an AS-external-LSA from LSDB and routing domain. */
2164void
paul68980082003-03-25 05:07:42 +00002165ospf_external_lsa_flush (struct ospf *ospf,
2166 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002167 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002168{
2169 struct ospf_lsa *lsa;
2170
2171 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002172 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002173 inet_ntoa (p->prefix), p->prefixlen);
2174
2175 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002176 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002177 {
2178 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002179 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002180 inet_ntoa (p->prefix), p->prefixlen);
2181 return;
2182 }
hassobeebba72004-06-20 21:00:27 +00002183
pauld4a53d52003-07-12 21:30:57 +00002184 /* If LSA is selforiginated, not a translated LSA, and there is
2185 * NSSA area, flush Type-7 LSA's at first.
2186 */
2187 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2188 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002189 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002190
2191 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002192 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002193
2194 /* There must be no self-originated LSA in rtrs_external. */
2195#if 0
2196 /* Remove External route from Zebra. */
2197 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2198#endif
2199
2200 if (!IS_LSA_MAXAGE (lsa))
2201 {
2202 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002203 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002204
2205 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002206 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002207 }
2208
2209 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002210 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002211}
2212
2213void
paul68980082003-03-25 05:07:42 +00002214ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002215{
2216 struct prefix_ipv4 p;
2217 struct external_info *ei;
2218 struct ospf_lsa *lsa;
2219
2220 p.family = AF_INET;
2221 p.prefixlen = 0;
2222 p.prefix.s_addr = 0;
2223
paul020709f2003-04-04 02:44:16 +00002224 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002225 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002226
2227 if (ei)
2228 {
2229 if (lsa)
2230 {
2231 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002232 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002233 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002234 }
2235 else
2236 {
2237 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002238 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002239 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002240 }
2241 }
2242 else
2243 {
2244 if (lsa)
2245 {
2246 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002247 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
Paul Jakmadfbd5172010-04-14 10:32:12 +01002248 ospf_refresher_unregister_lsa (ospf, lsa);
paul68980082003-03-25 05:07:42 +00002249 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002250 }
2251 }
2252}
2253
2254void
paul68980082003-03-25 05:07:42 +00002255ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002256{
2257 struct route_node *rn;
2258 struct external_info *ei;
2259
2260 if (type != DEFAULT_ROUTE)
2261 if (EXTERNAL_INFO(type))
2262 /* Refresh each redistributed AS-external-LSAs. */
2263 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2264 if ((ei = rn->info))
2265 if (!is_prefix_default (&ei->p))
2266 {
2267 struct ospf_lsa *lsa;
2268
paul68980082003-03-25 05:07:42 +00002269 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2270 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002271 else
paul68980082003-03-25 05:07:42 +00002272 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002273 }
2274}
2275
2276/* Refresh AS-external-LSA. */
Paul Jakmac363d382010-01-24 22:42:13 +00002277struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002278ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002279 struct external_info *ei, int force)
2280{
2281 struct ospf_lsa *new;
2282 int changed;
2283
2284 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002285 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002286 {
pauld4a53d52003-07-12 21:30:57 +00002287 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002288 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002289 "redist check fail",
2290 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002291 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002292 ei->ifindex /*, ei->nexthop */);
Paul Jakmac363d382010-01-24 22:42:13 +00002293 return NULL;
paul718e3742002-12-13 20:15:29 +00002294 }
2295
2296 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002297 {
2298 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002299 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002300 lsa->data->type, inet_ntoa (lsa->data->id));
Paul Jakmac363d382010-01-24 22:42:13 +00002301 return NULL;
pauld4a53d52003-07-12 21:30:57 +00002302 }
paul718e3742002-12-13 20:15:29 +00002303
2304 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002305 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002306
2307 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002308 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002309
paul68980082003-03-25 05:07:42 +00002310 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002311
2312 if (new == NULL)
2313 {
2314 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002315 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002316 inet_ntoa (lsa->data->id));
Paul Jakmac363d382010-01-24 22:42:13 +00002317 return NULL;
paul718e3742002-12-13 20:15:29 +00002318 }
2319
2320 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2321
paul68980082003-03-25 05:07:42 +00002322 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002323
2324 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002325 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002326
paul718e3742002-12-13 20:15:29 +00002327 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002328 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002329 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002330
pauld4a53d52003-07-12 21:30:57 +00002331 /* Register self-originated LSA to refresh queue.
2332 * Translated LSAs should not be registered, but refreshed upon
2333 * refresh of the Type-7
2334 */
2335 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2336 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002337
2338 /* Debug logging. */
2339 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2340 {
ajse588f212004-12-08 18:12:06 +00002341 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002342 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002343 ospf_lsa_header_dump (new->data);
2344 }
2345
Paul Jakmac363d382010-01-24 22:42:13 +00002346 return new;
paul718e3742002-12-13 20:15:29 +00002347}
2348
2349
2350/* LSA installation functions. */
2351
2352/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002353static struct ospf_lsa *
Paul Jakmac363d382010-01-24 22:42:13 +00002354ospf_router_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2355 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002356{
2357 struct ospf_area *area = new->area;
2358
2359 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2360 The entire routing table must be recalculated, starting with
2361 the shortest path calculations for each area (not just the
2362 area whose link-state database has changed).
2363 */
paul718e3742002-12-13 20:15:29 +00002364
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002365 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002366 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002367
2368 /* Only install LSA if it is originated/refreshed by us.
2369 * If LSA was received by flooding, the RECEIVED flag is set so do
2370 * not link the LSA */
2371 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2372 return new; /* ignore stale LSA */
2373
paul718e3742002-12-13 20:15:29 +00002374 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002375 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002376 area->router_lsa_self = ospf_lsa_lock (new);
2377
Paul Jakmac363d382010-01-24 22:42:13 +00002378 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002379 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002380 if (rt_recalc)
2381 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002382
2383 return new;
2384}
2385
2386#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2387 if (!(T)) \
2388 (T) = thread_add_timer (master, (F), oi, (V))
2389
2390/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002391static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002392ospf_network_lsa_install (struct ospf *ospf,
2393 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002394 struct ospf_lsa *new,
2395 int rt_recalc)
2396{
2397
2398 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2399 The entire routing table must be recalculated, starting with
2400 the shortest path calculations for each area (not just the
2401 area whose link-state database has changed).
2402 */
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002403 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002404 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002405 /* We supposed that when LSA is originated by us, we pass the int
2406 for which it was originated. If LSA was received by flooding,
2407 the RECEIVED flag is set, so we do not link the LSA to the int. */
2408 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2409 return new; /* ignore stale LSA */
2410
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002411 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002412 oi->network_lsa_self = ospf_lsa_lock (new);
Paul Jakmac363d382010-01-24 22:42:13 +00002413 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002414 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002415 if (rt_recalc)
2416 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002417
2418 return new;
2419}
2420
2421/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002422static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002423ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2424 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002425{
paul718e3742002-12-13 20:15:29 +00002426 if (rt_recalc && !IS_LSA_SELF (new))
2427 {
2428 /* RFC 2328 Section 13.2 Summary-LSAs
2429 The best route to the destination described by the summary-
2430 LSA must be recalculated (see Section 16.5). If this
2431 destination is an AS boundary router, it may also be
2432 necessary to re-examine all the AS-external-LSAs.
2433 */
2434
2435#if 0
2436 /* This doesn't exist yet... */
2437 ospf_summary_incremental_update(new); */
2438#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002439 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002440#endif /* #if 0 */
2441
2442 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002443 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002444 }
2445
2446 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002447 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002448
2449 return new;
2450}
2451
2452/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002453static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002454ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2455 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002456{
2457 if (rt_recalc && !IS_LSA_SELF (new))
2458 {
2459 /* RFC 2328 Section 13.2 Summary-LSAs
2460 The best route to the destination described by the summary-
2461 LSA must be recalculated (see Section 16.5). If this
2462 destination is an AS boundary router, it may also be
2463 necessary to re-examine all the AS-external-LSAs.
2464 */
2465#if 0
2466 /* These don't exist yet... */
2467 ospf_summary_incremental_update(new);
2468 /* Isn't this done by the above call?
2469 - RFC 2328 Section 16.5 implies it should be */
2470 /* ospf_ase_calculate_schedule(); */
2471#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002472 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002473#endif /* #if 0 */
2474 }
2475
2476 /* register LSA to refresh-list. */
2477 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002478 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002479
2480 return new;
2481}
2482
2483/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002484static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002485ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2486 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002487{
paul68980082003-03-25 05:07:42 +00002488 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002489 /* If LSA is not self-originated, calculate an external route. */
2490 if (rt_recalc)
2491 {
2492 /* RFC 2328 Section 13.2 AS-external-LSAs
2493 The best route to the destination described by the AS-
2494 external-LSA must be recalculated (see Section 16.6).
2495 */
2496
2497 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002498 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002499 }
2500
pauld4a53d52003-07-12 21:30:57 +00002501 if (new->data->type == OSPF_AS_NSSA_LSA)
2502 {
2503 /* There is no point to register selforiginate Type-7 LSA for
2504 * refreshing. We rely on refreshing Type-5 LSA's
2505 */
2506 if (IS_LSA_SELF (new))
2507 return new;
2508 else
2509 {
2510 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2511 * New translations will be taken care of by the abr_task.
2512 */
2513 ospf_translated_nssa_refresh (ospf, new, NULL);
2514 }
2515 }
pauld7480322003-05-16 17:31:51 +00002516
pauld4a53d52003-07-12 21:30:57 +00002517 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002518 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002519 */
hassobeebba72004-06-20 21:00:27 +00002520 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002521 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002522
2523 return new;
2524}
2525
2526void
paul68980082003-03-25 05:07:42 +00002527ospf_discard_from_db (struct ospf *ospf,
2528 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002529{
2530 struct ospf_lsa *old;
2531
Paul Jakmaac904de2006-06-15 12:04:57 +00002532 if (!lsdb)
2533 {
2534 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2535 if (!lsa)
2536 zlog_warn ("%s: and NULL LSA!", __func__);
2537 else
2538 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2539 lsa->data->type, inet_ntoa (lsa->data->id));
2540 return;
2541 }
2542
paul718e3742002-12-13 20:15:29 +00002543 old = ospf_lsdb_lookup (lsdb, lsa);
2544
2545 if (!old)
2546 return;
2547
2548 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002549 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002550
2551 switch (old->data->type)
2552 {
2553 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002554 ospf_ase_unregister_external_lsa (old, ospf);
2555 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2556 break;
paul718e3742002-12-13 20:15:29 +00002557#ifdef HAVE_OPAQUE_LSA
2558 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002559 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002560 break;
paul69310a62005-05-11 18:09:59 +00002561#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002562 case OSPF_AS_NSSA_LSA:
2563 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2564 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002565 break;
paul718e3742002-12-13 20:15:29 +00002566 default:
paul68980082003-03-25 05:07:42 +00002567 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002568 break;
2569 }
2570
paul68980082003-03-25 05:07:42 +00002571 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002572 ospf_lsa_discard (old);
2573}
2574
paul718e3742002-12-13 20:15:29 +00002575struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002576ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2577 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002578{
2579 struct ospf_lsa *new = NULL;
2580 struct ospf_lsa *old = NULL;
2581 struct ospf_lsdb *lsdb = NULL;
2582 int rt_recalc;
2583
2584 /* Set LSDB. */
2585 switch (lsa->data->type)
2586 {
paulf2c80652002-12-13 21:44:27 +00002587 /* kevinm */
2588 case OSPF_AS_NSSA_LSA:
2589 if (lsa->area)
2590 lsdb = lsa->area->lsdb;
2591 else
paul68980082003-03-25 05:07:42 +00002592 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002593 break;
paul718e3742002-12-13 20:15:29 +00002594 case OSPF_AS_EXTERNAL_LSA:
2595#ifdef HAVE_OPAQUE_LSA
2596 case OSPF_OPAQUE_AS_LSA:
2597#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002598 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002599 break;
2600 default:
2601 lsdb = lsa->area->lsdb;
2602 break;
2603 }
2604
paul718e3742002-12-13 20:15:29 +00002605 assert (lsdb);
2606
2607 /* RFC 2328 13.2. Installing LSAs in the database
2608
2609 Installing a new LSA in the database, either as the result of
2610 flooding or a newly self-originated LSA, may cause the OSPF
2611 routing table structure to be recalculated. The contents of the
2612 new LSA should be compared to the old instance, if present. If
2613 there is no difference, there is no need to recalculate the
2614 routing table. When comparing an LSA to its previous instance,
2615 the following are all considered to be differences in contents:
2616
2617 o The LSA's Options field has changed.
2618
2619 o One of the LSA instances has LS age set to MaxAge, and
2620 the other does not.
2621
2622 o The length field in the LSA header has changed.
2623
2624 o The body of the LSA (i.e., anything outside the 20-byte
2625 LSA header) has changed. Note that this excludes changes
2626 in LS Sequence Number and LS Checksum.
2627
2628 */
2629 /* Look up old LSA and determine if any SPF calculation or incremental
2630 update is needed */
2631 old = ospf_lsdb_lookup (lsdb, lsa);
2632
2633 /* Do comparision and record if recalc needed. */
2634 rt_recalc = 0;
2635 if ( old == NULL || ospf_lsa_different(old, lsa))
2636 rt_recalc = 1;
2637
paul7ddf1d62003-10-13 09:06:46 +00002638 /*
2639 Sequence number check (Section 14.1 of rfc 2328)
2640 "Premature aging is used when it is time for a self-originated
2641 LSA's sequence number field to wrap. At this point, the current
2642 LSA instance (having LS sequence number MaxSequenceNumber) must
2643 be prematurely aged and flushed from the routing domain before a
2644 new instance with sequence number equal to InitialSequenceNumber
2645 can be originated. "
2646 */
2647
Paul Jakmac2b478d2006-03-30 14:16:11 +00002648 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002649 {
2650 if (ospf_lsa_is_self_originated(ospf, lsa))
2651 {
paul0c2be262004-05-31 14:16:54 +00002652 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2653
2654 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002655 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2656 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2657
2658 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2659 {
ajse588f212004-12-08 18:12:06 +00002660 zlog_debug ("ospf_lsa_install() Premature Aging "
Paul Jakmac363d382010-01-24 22:42:13 +00002661 "lsa 0x%p, seqnum 0x%x",
2662 lsa, ntohl(lsa->data->ls_seqnum));
paul7ddf1d62003-10-13 09:06:46 +00002663 ospf_lsa_header_dump (lsa->data);
2664 }
2665 }
2666 else
2667 {
2668 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2669 {
ajse588f212004-12-08 18:12:06 +00002670 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002671 "that was not self originated. Ignoring\n");
2672 ospf_lsa_header_dump (lsa->data);
2673 }
2674 return old;
2675 }
2676 }
2677
paul718e3742002-12-13 20:15:29 +00002678 /* discard old LSA from LSDB */
2679 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002680 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002681
paul718e3742002-12-13 20:15:29 +00002682 /* Calculate Checksum if self-originated?. */
2683 if (IS_LSA_SELF (lsa))
2684 ospf_lsa_checksum (lsa->data);
2685
hassofe71a972004-12-22 16:16:02 +00002686 /* Insert LSA to LSDB. */
2687 ospf_lsdb_add (lsdb, lsa);
2688 lsa->lsdb = lsdb;
2689
paul718e3742002-12-13 20:15:29 +00002690 /* Do LSA specific installation process. */
2691 switch (lsa->data->type)
2692 {
2693 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002694 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002695 break;
2696 case OSPF_NETWORK_LSA:
2697 assert (oi);
paul68980082003-03-25 05:07:42 +00002698 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002699 break;
2700 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002701 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002702 break;
2703 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002704 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002705 break;
2706 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002707 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002708 break;
2709#ifdef HAVE_OPAQUE_LSA
2710 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002711 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002712 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002713 else
paul68980082003-03-25 05:07:42 +00002714 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002715 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002716 case OSPF_OPAQUE_AREA_LSA:
2717 case OSPF_OPAQUE_AS_LSA:
2718 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2719 break;
2720#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002721 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002722 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002723 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002724 break;
2725 }
2726
2727 if (new == NULL)
2728 return new; /* Installation failed, cannot proceed further -- endo. */
2729
2730 /* Debug logs. */
2731 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2732 {
2733 char area_str[INET_ADDRSTRLEN];
2734
2735 switch (lsa->data->type)
2736 {
2737 case OSPF_AS_EXTERNAL_LSA:
2738#ifdef HAVE_OPAQUE_LSA
2739 case OSPF_OPAQUE_AS_LSA:
2740#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002741 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002742 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002743 dump_lsa_key (new),
2744 LOOKUP (ospf_lsa_type_msg, new->data->type));
2745 break;
2746 default:
2747 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002748 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002749 dump_lsa_key (new),
2750 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2751 break;
2752 }
2753 }
2754
paul7ddf1d62003-10-13 09:06:46 +00002755 /*
2756 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2757 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2758 */
2759 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2760 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002761 {
paul7ddf1d62003-10-13 09:06:46 +00002762 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002763 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002764 new->data->type,
2765 inet_ntoa (new->data->id),
2766 lsa);
Paul Jakma02d942c2010-01-24 23:36:20 +00002767 ospf_lsa_flush (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002768 }
2769
2770 return new;
2771}
2772
2773
paul4dadc292005-05-06 21:37:42 +00002774static int
paul68980082003-03-25 05:07:42 +00002775ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002776{
paul1eb8ef22005-04-07 07:30:20 +00002777 struct listnode *node, *nnode;
2778 struct ospf_interface *oi;
2779
2780 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002781 {
paul718e3742002-12-13 20:15:29 +00002782 struct route_node *rn;
2783 struct ospf_neighbor *nbr;
2784
2785 if (ospf_if_is_enable (oi))
2786 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2787 if ((nbr = rn->info) != NULL)
2788 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2789 {
2790 route_unlock_node (rn);
2791 return 0;
2792 }
2793 }
2794
2795 return 1;
2796}
2797
2798
paul718e3742002-12-13 20:15:29 +00002799
paul4dadc292005-05-06 21:37:42 +00002800static int
paul718e3742002-12-13 20:15:29 +00002801ospf_maxage_lsa_remover (struct thread *thread)
2802{
paul68980082003-03-25 05:07:42 +00002803 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002804 struct ospf_lsa *lsa;
2805 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002806 int reschedule = 0;
2807
paul68980082003-03-25 05:07:42 +00002808 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002809
2810 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002811 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002812
paul68980082003-03-25 05:07:42 +00002813 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002814
2815 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002816 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002817 {
paul718e3742002-12-13 20:15:29 +00002818 if (lsa->retransmit_counter > 0)
2819 {
2820 reschedule = 1;
2821 continue;
2822 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002823
2824 /* TODO: maybe convert this function to a work-queue */
2825 if (thread_should_yield (thread))
2826 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);
2827
paul718e3742002-12-13 20:15:29 +00002828 /* Remove LSA from the LSDB */
2829 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2830 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002831 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
paul7ddf1d62003-10-13 09:06:46 +00002832 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002833
2834 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002835 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002836 lsa->data->type, inet_ntoa (lsa->data->id));
2837
Paul Jakmac363d382010-01-24 22:42:13 +00002838 if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))
paul7ddf1d62003-10-13 09:06:46 +00002839 {
2840 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
Paul Jakmac363d382010-01-24 22:42:13 +00002841 zlog_debug ("originating new lsa for lsa 0x%p\n", lsa);
2842 ospf_lsa_refresh (ospf, lsa);
paul7ddf1d62003-10-13 09:06:46 +00002843 }
2844
paul718e3742002-12-13 20:15:29 +00002845 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002846 if (lsa->lsdb)
2847 {
2848 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2849 ospf_lsdb_delete (lsa->lsdb, lsa);
2850 }
2851 else
2852 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2853 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002854 }
2855
2856 /* A MaxAge LSA must be removed immediately from the router's link
2857 state database as soon as both a) it is no longer contained on any
2858 neighbor Link state retransmission lists and b) none of the router's
2859 neighbors are in states Exchange or Loading. */
2860 if (reschedule)
Paul Jakma02d942c2010-01-24 23:36:20 +00002861 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2862 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002863
2864 return 0;
2865}
2866
paul718e3742002-12-13 20:15:29 +00002867void
paul68980082003-03-25 05:07:42 +00002868ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002869{
hasso52dc7ee2004-09-23 19:18:23 +00002870 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00002871
paul68980082003-03-25 05:07:42 +00002872 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00002873 {
paul68980082003-03-25 05:07:42 +00002874 list_delete_node (ospf->maxage_lsa, n);
Stephen Hemminger3106a032009-08-06 12:58:05 -07002875 UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002876 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +00002877 }
2878}
2879
Paul Jakma02d942c2010-01-24 23:36:20 +00002880/* Add LSA onto the MaxAge list, and schedule for removal.
2881 * This does *not* lead to the LSA being flooded, that must be taken
2882 * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
2883 * function).
2884 */
paul718e3742002-12-13 20:15:29 +00002885void
paul68980082003-03-25 05:07:42 +00002886ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002887{
2888 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2889 and schedule the MaxAge LSA remover. */
Stephen Hemminger3106a032009-08-06 12:58:05 -07002890 if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
paul718e3742002-12-13 20:15:29 +00002891 {
2892 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002893 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00002894 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2895 return;
2896 }
2897
paul68980082003-03-25 05:07:42 +00002898 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
Stephen Hemminger3106a032009-08-06 12:58:05 -07002899 SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
paul718e3742002-12-13 20:15:29 +00002900
2901 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002902 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002903
Paul Jakma02d942c2010-01-24 23:36:20 +00002904 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2905 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002906}
2907
paul4dadc292005-05-06 21:37:42 +00002908static int
paul68980082003-03-25 05:07:42 +00002909ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002910{
paul718e3742002-12-13 20:15:29 +00002911 /* Stay away from any Local Translated Type-7 LSAs */
2912 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2913 return 0;
paul718e3742002-12-13 20:15:29 +00002914
2915 if (IS_LSA_MAXAGE (lsa))
2916 /* Self-originated LSAs should NOT time-out instead,
2917 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00002918 if (!ospf_lsa_is_self_originated (ospf, lsa))
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[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002922
2923 switch (lsa->data->type)
2924 {
paul718e3742002-12-13 20:15:29 +00002925#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00002926 case OSPF_OPAQUE_LINK_LSA:
2927 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00002928 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00002929 /*
2930 * As a general rule, whenever network topology has changed
2931 * (due to an LSA removal in this case), routing recalculation
2932 * should be triggered. However, this is not true for opaque
2933 * LSAs. Even if an opaque LSA instance is going to be removed
2934 * from the routing domain, it does not mean a change in network
2935 * topology, and thus, routing recalculation is not needed here.
2936 */
2937 break;
paul718e3742002-12-13 20:15:29 +00002938#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00002939 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00002940 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002941 ospf_ase_incremental_update (ospf, lsa);
2942 break;
paul718e3742002-12-13 20:15:29 +00002943 default:
paul68980082003-03-25 05:07:42 +00002944 ospf_spf_calculate_schedule (ospf);
2945 break;
paul718e3742002-12-13 20:15:29 +00002946 }
paul68980082003-03-25 05:07:42 +00002947 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002948 }
2949
Paul Jakmac363d382010-01-24 22:42:13 +00002950 if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa))
2951 if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30)
2952 printf ("Eek! Shouldn't happen!\n");
2953
paul718e3742002-12-13 20:15:29 +00002954 return 0;
2955}
2956
2957/* Periodical check of MaxAge LSA. */
2958int
paul68980082003-03-25 05:07:42 +00002959ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002960{
paul68980082003-03-25 05:07:42 +00002961 struct ospf *ospf = THREAD_ARG (thread);
2962 struct route_node *rn;
2963 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00002964 struct ospf_area *area;
2965 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002966
paul68980082003-03-25 05:07:42 +00002967 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00002968
paul1eb8ef22005-04-07 07:30:20 +00002969 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00002970 {
paul68980082003-03-25 05:07:42 +00002971 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
2972 ospf_lsa_maxage_walker_remover (ospf, lsa);
2973 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
2974 ospf_lsa_maxage_walker_remover (ospf, lsa);
2975 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
2976 ospf_lsa_maxage_walker_remover (ospf, lsa);
2977 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
2978 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002979#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002980 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
2981 ospf_lsa_maxage_walker_remover (ospf, lsa);
2982 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
2983 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002984#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00002985 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
2986 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002987 }
2988
paul4fb949e2003-05-10 20:06:51 +00002989 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00002990 if (ospf->lsdb)
2991 {
2992 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
2993 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002994#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002995 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
2996 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002997#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002998 }
paul718e3742002-12-13 20:15:29 +00002999
paul68980082003-03-25 05:07:42 +00003000 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3001 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003002 return 0;
3003}
3004
paul68980082003-03-25 05:07:42 +00003005struct ospf_lsa *
3006ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3007 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003008{
paul68980082003-03-25 05:07:42 +00003009 struct ospf_lsa *lsa;
3010 struct in_addr mask, id;
3011 struct lsa_header_mask
3012 {
3013 struct lsa_header header;
3014 struct in_addr mask;
3015 } *hmask;
paul718e3742002-12-13 20:15:29 +00003016
paul68980082003-03-25 05:07:42 +00003017 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3018 if (lsa == NULL)
3019 return NULL;
paul718e3742002-12-13 20:15:29 +00003020
paul68980082003-03-25 05:07:42 +00003021 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003022
paul68980082003-03-25 05:07:42 +00003023 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003024
paul68980082003-03-25 05:07:42 +00003025 if (mask.s_addr != hmask->mask.s_addr)
3026 {
3027 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3028 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3029 if (!lsa)
3030 return NULL;
3031 }
paul718e3742002-12-13 20:15:29 +00003032
paul68980082003-03-25 05:07:42 +00003033 return lsa;
paul718e3742002-12-13 20:15:29 +00003034}
3035
3036struct ospf_lsa *
3037ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3038 struct in_addr id, struct in_addr adv_router)
3039{
paule05fba42003-04-13 20:20:53 +00003040 struct ospf *ospf = ospf_lookup();
3041 assert(ospf);
3042
paul718e3742002-12-13 20:15:29 +00003043 switch (type)
3044 {
3045 case OSPF_ROUTER_LSA:
3046 case OSPF_NETWORK_LSA:
3047 case OSPF_SUMMARY_LSA:
3048 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003049 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003050#ifdef HAVE_OPAQUE_LSA
3051 case OSPF_OPAQUE_LINK_LSA:
3052 case OSPF_OPAQUE_AREA_LSA:
3053#endif /* HAVE_OPAQUE_LSA */
3054 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003055 case OSPF_AS_EXTERNAL_LSA:
3056#ifdef HAVE_OPAQUE_LSA
3057 case OSPF_OPAQUE_AS_LSA:
3058#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003059 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003060 default:
3061 break;
3062 }
3063
3064 return NULL;
3065}
3066
3067struct ospf_lsa *
3068ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3069 struct in_addr id)
3070{
3071 struct ospf_lsa *lsa;
3072 struct route_node *rn;
3073
3074 switch (type)
3075 {
3076 case OSPF_ROUTER_LSA:
3077 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003078 case OSPF_NETWORK_LSA:
3079 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3080 if ((lsa = rn->info))
3081 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3082 {
3083 route_unlock_node (rn);
3084 return lsa;
3085 }
3086 break;
3087 case OSPF_SUMMARY_LSA:
3088 case OSPF_ASBR_SUMMARY_LSA:
3089 /* Currently not used. */
3090 assert (1);
3091 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003092 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003093 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003094#ifdef HAVE_OPAQUE_LSA
3095 case OSPF_OPAQUE_LINK_LSA:
3096 case OSPF_OPAQUE_AREA_LSA:
3097 case OSPF_OPAQUE_AS_LSA:
3098 /* Currently not used. */
3099 break;
3100#endif /* HAVE_OPAQUE_LSA */
3101 default:
3102 break;
3103 }
3104
3105 return NULL;
3106}
3107
3108struct ospf_lsa *
3109ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3110{
3111 struct ospf_lsa *match;
3112
3113#ifdef HAVE_OPAQUE_LSA
3114 /*
3115 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3116 * is redefined to have two subfields; opaque-type and opaque-id.
3117 * However, it is harmless to treat the two sub fields together, as if
3118 * they two were forming a unique LSA-ID.
3119 */
3120#endif /* HAVE_OPAQUE_LSA */
3121
3122 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3123
3124 if (match == NULL)
3125 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003126 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003127 lsah->type, inet_ntoa (lsah->id));
3128
3129 return match;
3130}
3131
3132/* return +n, l1 is more recent.
3133 return -n, l2 is more recent.
3134 return 0, l1 and l2 is identical. */
3135int
3136ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3137{
3138 int r;
3139 int x, y;
3140
3141 if (l1 == NULL && l2 == NULL)
3142 return 0;
3143 if (l1 == NULL)
3144 return -1;
3145 if (l2 == NULL)
3146 return 1;
3147
3148 /* compare LS sequence number. */
3149 x = (int) ntohl (l1->data->ls_seqnum);
3150 y = (int) ntohl (l2->data->ls_seqnum);
3151 if (x > y)
3152 return 1;
3153 if (x < y)
3154 return -1;
3155
3156 /* compare LS checksum. */
3157 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3158 if (r)
3159 return r;
3160
3161 /* compare LS age. */
3162 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3163 return 1;
3164 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3165 return -1;
3166
3167 /* compare LS age with MaxAgeDiff. */
3168 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3169 return -1;
3170 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3171 return 1;
3172
3173 /* LSAs are identical. */
3174 return 0;
3175}
3176
3177/* If two LSAs are different, return 1, otherwise return 0. */
3178int
3179ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3180{
3181 char *p1, *p2;
3182 assert (l1);
3183 assert (l2);
3184 assert (l1->data);
3185 assert (l2->data);
3186
3187 if (l1->data->options != l2->data->options)
3188 return 1;
3189
3190 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3191 return 1;
3192
3193 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3194 return 1;
3195
3196 if (l1->data->length != l2->data->length)
3197 return 1;
3198
3199 if (l1->data->length == 0)
3200 return 1;
3201
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02003202 if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
3203 return 1; /* May be a stale LSA in the LSBD */
3204
pauld1825832003-04-03 01:27:01 +00003205 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003206
3207 p1 = (char *) l1->data;
3208 p2 = (char *) l2->data;
3209
3210 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3211 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3212 return 1;
3213
3214 return 0;
3215}
3216
3217#ifdef ORIGINAL_CODING
3218void
3219ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3220 struct ospf_lsa *self,
3221 struct ospf_lsa *new)
3222{
3223 u_int32_t seqnum;
3224
3225 /* Adjust LS Sequence Number. */
3226 seqnum = ntohl (new->data->ls_seqnum) + 1;
3227 self->data->ls_seqnum = htonl (seqnum);
3228
3229 /* Recalculate LSA checksum. */
3230 ospf_lsa_checksum (self->data);
3231
3232 /* Reflooding LSA. */
3233 /* RFC2328 Section 13.3
3234 On non-broadcast networks, separate Link State Update
3235 packets must be sent, as unicasts, to each adjacent neighbor
3236 (i.e., those in state Exchange or greater). The destination
3237 IP addresses for these packets are the neighbors' IP
3238 addresses. */
3239 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3240 {
3241 struct route_node *rn;
3242 struct ospf_neighbor *onbr;
3243
3244 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3245 if ((onbr = rn->info) != NULL)
3246 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3247 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3248 }
3249 else
3250 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3251
3252 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003253 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003254 self->data->type, inet_ntoa (self->data->id));
3255}
3256#else /* ORIGINAL_CODING */
3257static int
paul68980082003-03-25 05:07:42 +00003258ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003259{
3260 if (lsa == NULL || !IS_LSA_SELF (lsa))
3261 return 0;
3262
3263 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003264 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 +00003265
3266 /* Force given lsa's age to MaxAge. */
3267 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3268
3269 switch (lsa->data->type)
3270 {
3271#ifdef HAVE_OPAQUE_LSA
Paul Jakma02d942c2010-01-24 23:36:20 +00003272 /* Opaque wants to be notified of flushes */
paul718e3742002-12-13 20:15:29 +00003273 case OSPF_OPAQUE_LINK_LSA:
3274 case OSPF_OPAQUE_AREA_LSA:
3275 case OSPF_OPAQUE_AS_LSA:
3276 ospf_opaque_lsa_refresh (lsa);
3277 break;
3278#endif /* HAVE_OPAQUE_LSA */
3279 default:
Paul Jakmadfbd5172010-04-14 10:32:12 +01003280 ospf_refresher_unregister_lsa (ospf, lsa);
Paul Jakma02d942c2010-01-24 23:36:20 +00003281 ospf_lsa_flush (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003282 break;
3283 }
3284
3285 return 0;
3286}
3287
3288void
paul68980082003-03-25 05:07:42 +00003289ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003290{
paul1eb8ef22005-04-07 07:30:20 +00003291 struct listnode *node, *nnode;
3292 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003293 struct ospf_area *area;
3294 struct ospf_interface *oi;
3295 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003296 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003297 int need_to_flush_ase = 0;
3298
paul1eb8ef22005-04-07 07:30:20 +00003299 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003300 {
paul718e3742002-12-13 20:15:29 +00003301 if ((lsa = area->router_lsa_self) != NULL)
3302 {
3303 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003304 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3305 lsa->data->type, inet_ntoa (lsa->data->id));
3306
3307 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003308 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003309 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003310 area->router_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003311 }
3312
paul1eb8ef22005-04-07 07:30:20 +00003313 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003314 {
paul718e3742002-12-13 20:15:29 +00003315 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003316 && oi->state == ISM_DR
3317 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003318 {
3319 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003320 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3321 lsa->data->type, inet_ntoa (lsa->data->id));
3322
3323 ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003324 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003325 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003326 oi->network_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003327 }
3328
3329 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3330 && area->external_routing == OSPF_AREA_DEFAULT)
3331 need_to_flush_ase = 1;
3332 }
3333
paul68980082003-03-25 05:07:42 +00003334 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3335 ospf_lsa_flush_schedule (ospf, lsa);
3336 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3337 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003338#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003339 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3340 ospf_lsa_flush_schedule (ospf, lsa);
3341 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3342 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003343#endif /* HAVE_OPAQUE_LSA */
3344 }
3345
3346 if (need_to_flush_ase)
3347 {
paul68980082003-03-25 05:07:42 +00003348 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3349 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003350#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003351 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3352 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003353#endif /* HAVE_OPAQUE_LSA */
3354 }
3355
3356 /*
3357 * Make sure that the MaxAge LSA remover is executed immediately,
3358 * without conflicting to other threads.
3359 */
paul68980082003-03-25 05:07:42 +00003360 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003361 {
paul68980082003-03-25 05:07:42 +00003362 OSPF_TIMER_OFF (ospf->t_maxage);
3363 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003364 }
3365
3366 return;
3367}
3368#endif /* ORIGINAL_CODING */
3369
3370/* If there is self-originated LSA, then return 1, otherwise return 0. */
3371/* An interface-independent version of ospf_lsa_is_self_originated */
3372int
paul68980082003-03-25 05:07:42 +00003373ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003374{
hasso52dc7ee2004-09-23 19:18:23 +00003375 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003376 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003377
3378 /* This LSA is already checked. */
3379 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3380 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3381
3382 /* Make sure LSA is self-checked. */
3383 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3384
3385 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003386 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003387 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3388
3389 /* LSA is router-LSA. */
3390 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003391 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003392 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3393
3394 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3395 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003396 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003397 {
paul718e3742002-12-13 20:15:29 +00003398 /* Ignore virtual link. */
3399 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3400 if (oi->address->family == AF_INET)
3401 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3402 {
3403 /* to make it easier later */
3404 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3405 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3406 }
3407 }
3408
3409 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3410}
3411
3412/* Get unique Link State ID. */
3413struct in_addr
paul68980082003-03-25 05:07:42 +00003414ospf_lsa_unique_id (struct ospf *ospf,
3415 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003416{
3417 struct ospf_lsa *lsa;
3418 struct in_addr mask, id;
3419
3420 id = p->prefix;
3421
3422 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003423 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003424 if (lsa)
3425 {
3426 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3427 if (ip_masklen (al->mask) == p->prefixlen)
3428 {
3429 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003430 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003431 "Can't get Link State ID for %s/%d",
3432 inet_ntoa (p->prefix), p->prefixlen);
3433 /* id.s_addr = 0; */
3434 id.s_addr = 0xffffffff;
3435 return id;
3436 }
3437 /* Masklen differs, then apply wildcard mask to Link State ID. */
3438 else
3439 {
3440 masklen2ip (p->prefixlen, &mask);
3441
3442 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003443 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3444 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003445 if (lsa)
3446 {
3447 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003448 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003449 "Can't get Link State ID for %s/%d",
3450 inet_ntoa (p->prefix), p->prefixlen);
3451 /* id.s_addr = 0; */
3452 id.s_addr = 0xffffffff;
3453 return id;
3454 }
3455 }
3456 }
3457
3458 return id;
3459}
3460
3461
Paul Jakma70461d72006-05-12 22:57:57 +00003462#define LSA_ACTION_FLOOD_AREA 1
3463#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003464
3465struct lsa_action
3466{
3467 u_char action;
3468 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003469 struct ospf_lsa *lsa;
3470};
3471
paul4dadc292005-05-06 21:37:42 +00003472static int
paul718e3742002-12-13 20:15:29 +00003473ospf_lsa_action (struct thread *t)
3474{
3475 struct lsa_action *data;
3476
3477 data = THREAD_ARG (t);
3478
3479 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003480 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003481 data->action);
3482
3483 switch (data->action)
3484 {
paul718e3742002-12-13 20:15:29 +00003485 case LSA_ACTION_FLOOD_AREA:
3486 ospf_flood_through_area (data->area, NULL, data->lsa);
3487 break;
paul718e3742002-12-13 20:15:29 +00003488 case LSA_ACTION_FLUSH_AREA:
3489 ospf_lsa_flush_area (data->lsa, data->area);
3490 break;
paul718e3742002-12-13 20:15:29 +00003491 }
3492
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003493 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003494 XFREE (MTYPE_OSPF_MESSAGE, data);
3495 return 0;
3496}
3497
3498void
3499ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3500{
3501 struct lsa_action *data;
3502
Stephen Hemminger393deb92008-08-18 14:13:29 -07003503 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003504 data->action = LSA_ACTION_FLOOD_AREA;
3505 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003506 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003507
3508 thread_add_event (master, ospf_lsa_action, data, 0);
3509}
3510
3511void
3512ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3513{
3514 struct lsa_action *data;
3515
Stephen Hemminger393deb92008-08-18 14:13:29 -07003516 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003517 data->action = LSA_ACTION_FLUSH_AREA;
3518 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003519 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003520
3521 thread_add_event (master, ospf_lsa_action, data, 0);
3522}
3523
3524
3525/* LSA Refreshment functions. */
Paul Jakmac363d382010-01-24 22:42:13 +00003526struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00003527ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003528{
3529 struct external_info *ei;
Paul Jakmac363d382010-01-24 22:42:13 +00003530 struct ospf_lsa *new = NULL;
paul718e3742002-12-13 20:15:29 +00003531 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
Paul Jakma66349742010-04-13 22:33:54 +01003532 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003533
3534 switch (lsa->data->type)
3535 {
3536 /* Router and Network LSAs are processed differently. */
3537 case OSPF_ROUTER_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003538 new = ospf_router_lsa_refresh (lsa);
3539 break;
paul718e3742002-12-13 20:15:29 +00003540 case OSPF_NETWORK_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003541 new = ospf_network_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003542 break;
3543 case OSPF_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003544 new = ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003545 break;
3546 case OSPF_ASBR_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003547 new = ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003548 break;
3549 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003550 /* Translated from NSSA Type-5s are refreshed when
3551 * from refresh of Type-7 - do not refresh these directly.
3552 */
3553 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3554 break;
paul718e3742002-12-13 20:15:29 +00003555 ei = ospf_external_info_check (lsa);
3556 if (ei)
Paul Jakmac363d382010-01-24 22:42:13 +00003557 new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003558 else
pauld4a53d52003-07-12 21:30:57 +00003559 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003560 break;
3561#ifdef HAVE_OPAQUE_LSA
3562 case OSPF_OPAQUE_LINK_LSA:
3563 case OSPF_OPAQUE_AREA_LSA:
3564 case OSPF_OPAQUE_AS_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003565 new = ospf_opaque_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003566 break;
pauld7480322003-05-16 17:31:51 +00003567#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003568 default:
3569 break;
paul718e3742002-12-13 20:15:29 +00003570 }
Paul Jakmac363d382010-01-24 22:42:13 +00003571 return new;
paul718e3742002-12-13 20:15:29 +00003572}
3573
3574void
paul68980082003-03-25 05:07:42 +00003575ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003576{
3577 u_int16_t index, current_index;
3578
Paul Jakma66349742010-04-13 22:33:54 +01003579 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003580 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3581
3582 if (lsa->refresh_list < 0)
3583 {
3584 int delay;
3585
3586 if (LS_AGE (lsa) == 0 &&
3587 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3588 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3589 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3590 else
3591 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3592 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3593 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3594
3595 if (delay < 0)
3596 delay = 0;
3597
Paul Jakmac363d382010-01-24 22:42:13 +00003598 current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL)
3599 - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003600
3601 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
Paul Jakmac363d382010-01-24 22:42:13 +00003602 % (OSPF_LSA_REFRESHER_SLOTS);
paul718e3742002-12-13 20:15:29 +00003603
3604 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003605 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003606 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003607 if (!ospf->lsa_refresh_queue.qs[index])
3608 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003609 listnode_add (ospf->lsa_refresh_queue.qs[index],
3610 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003611 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003612 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003613 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003614 "setting refresh_list on lsa %p (slod %d)",
3615 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003616 }
3617}
3618
3619void
paul68980082003-03-25 05:07:42 +00003620ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003621{
Paul Jakma66349742010-04-13 22:33:54 +01003622 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003623 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3624 if (lsa->refresh_list >= 0)
3625 {
hasso52dc7ee2004-09-23 19:18:23 +00003626 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003627 listnode_delete (refresh_list, lsa);
3628 if (!listcount (refresh_list))
3629 {
3630 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003631 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003632 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003633 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003634 lsa->refresh_list = -1;
3635 }
3636}
3637
3638int
3639ospf_lsa_refresh_walker (struct thread *t)
3640{
hasso52dc7ee2004-09-23 19:18:23 +00003641 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003642 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003643 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003644 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003645 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003646 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003647
3648 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003649 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003650
3651
paul68980082003-03-25 05:07:42 +00003652 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003653
ajs9dbc7972005-03-13 19:27:22 +00003654 /* Note: if clock has jumped backwards, then time change could be negative,
3655 so we are careful to cast the expression to unsigned before taking
3656 modulus. */
paul68980082003-03-25 05:07:42 +00003657 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003658 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakmac363d382010-01-24 22:42:13 +00003659 (quagga_time (NULL) - ospf->lsa_refresher_started)
3660 / OSPF_LSA_REFRESHER_GRANULARITY))
3661 % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003662
3663 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003664 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003665 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003666
paul68980082003-03-25 05:07:42 +00003667 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003668 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3669 {
3670 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003671 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003672 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003673
paul68980082003-03-25 05:07:42 +00003674 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003675
Paul Jakma66349742010-04-13 22:33:54 +01003676 assert (i >= 0);
3677
paul68980082003-03-25 05:07:42 +00003678 ospf->lsa_refresh_queue.qs [i] = NULL;
3679
paul718e3742002-12-13 20:15:29 +00003680 if (refresh_list)
3681 {
paul1eb8ef22005-04-07 07:30:20 +00003682 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003683 {
paul718e3742002-12-13 20:15:29 +00003684 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003685 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003686 "refresh lsa %p (slot %d)",
3687 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003688
Paul Jakma66349742010-04-13 22:33:54 +01003689 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003690 list_delete_node (refresh_list, node);
paul718e3742002-12-13 20:15:29 +00003691 lsa->refresh_list = -1;
3692 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003693 }
3694 list_free (refresh_list);
3695 }
3696 }
3697
paul68980082003-03-25 05:07:42 +00003698 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3699 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003700 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003701
paul1eb8ef22005-04-07 07:30:20 +00003702 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
Paul Jakma66349742010-04-13 22:33:54 +01003703 {
3704 ospf_lsa_refresh (ospf, lsa);
3705 assert (lsa->lock > 0);
3706 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
3707 }
paul718e3742002-12-13 20:15:29 +00003708
3709 list_delete (lsa_to_refresh);
3710
3711 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003712 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003713
3714 return 0;
3715}
3716