blob: 15a6a4c4b6097bf58bae1753fe01c8fad4e9eb9c [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
2 * OSPF Link State Advertisement
3 * Copyright (C) 1999, 2000 Toshiaki Takada
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "linklist.h"
26#include "prefix.h"
27#include "if.h"
28#include "table.h"
29#include "memory.h"
30#include "stream.h"
31#include "log.h"
32#include "thread.h"
33#include "hash.h"
34#include "sockunion.h" /* for inet_aton() */
Jingjing Duan6a270cd2008-08-13 19:09:10 +010035#include "checksum.h"
paul718e3742002-12-13 20:15:29 +000036
37#include "ospfd/ospfd.h"
38#include "ospfd/ospf_interface.h"
39#include "ospfd/ospf_ism.h"
40#include "ospfd/ospf_asbr.h"
41#include "ospfd/ospf_lsa.h"
42#include "ospfd/ospf_lsdb.h"
43#include "ospfd/ospf_neighbor.h"
44#include "ospfd/ospf_nsm.h"
45#include "ospfd/ospf_flood.h"
46#include "ospfd/ospf_packet.h"
47#include "ospfd/ospf_spf.h"
48#include "ospfd/ospf_dump.h"
49#include "ospfd/ospf_route.h"
50#include "ospfd/ospf_ase.h"
51#include "ospfd/ospf_zebra.h"
52
53
54u_int32_t
55get_metric (u_char *metric)
56{
57 u_int32_t m;
58 m = metric[0];
59 m = (m << 8) + metric[1];
60 m = (m << 8) + metric[2];
61 return m;
62}
63
64
65struct timeval
66tv_adjust (struct timeval a)
67{
68 while (a.tv_usec >= 1000000)
69 {
70 a.tv_usec -= 1000000;
71 a.tv_sec++;
72 }
73
74 while (a.tv_usec < 0)
75 {
76 a.tv_usec += 1000000;
77 a.tv_sec--;
78 }
79
80 return a;
81}
82
83int
84tv_ceil (struct timeval a)
85{
86 a = tv_adjust (a);
87
88 return (a.tv_usec ? a.tv_sec + 1 : a.tv_sec);
89}
90
91int
92tv_floor (struct timeval a)
93{
94 a = tv_adjust (a);
95
96 return a.tv_sec;
97}
98
99struct timeval
100int2tv (int a)
101{
102 struct timeval ret;
103
104 ret.tv_sec = a;
105 ret.tv_usec = 0;
106
107 return ret;
108}
109
110struct timeval
111tv_add (struct timeval a, struct timeval b)
112{
113 struct timeval ret;
114
115 ret.tv_sec = a.tv_sec + b.tv_sec;
116 ret.tv_usec = a.tv_usec + b.tv_usec;
117
118 return tv_adjust (ret);
119}
120
121struct timeval
122tv_sub (struct timeval a, struct timeval b)
123{
124 struct timeval ret;
125
126 ret.tv_sec = a.tv_sec - b.tv_sec;
127 ret.tv_usec = a.tv_usec - b.tv_usec;
128
129 return tv_adjust (ret);
130}
131
132int
133tv_cmp (struct timeval a, struct timeval b)
134{
135 return (a.tv_sec == b.tv_sec ?
136 a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
137}
138
139int
140ospf_lsa_refresh_delay (struct ospf_lsa *lsa)
141{
142 struct timeval delta, now;
143 int delay = 0;
144
Paul Jakma2518efd2006-08-27 06:49:29 +0000145 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +0000146 delta = tv_sub (now, lsa->tv_orig);
147
148 if (tv_cmp (delta, int2tv (OSPF_MIN_LS_INTERVAL)) < 0)
149 {
150 delay = tv_ceil (tv_sub (int2tv (OSPF_MIN_LS_INTERVAL), delta));
151
152 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000153 zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
paul718e3742002-12-13 20:15:29 +0000154 lsa->data->type, inet_ntoa (lsa->data->id), delay);
155
156 assert (delay > 0);
157 }
158
159 return delay;
160}
161
162
163int
164get_age (struct ospf_lsa *lsa)
165{
166 int age;
paul718e3742002-12-13 20:15:29 +0000167
Paul Jakma2518efd2006-08-27 06:49:29 +0000168 age = ntohs (lsa->data->ls_age)
169 + tv_floor (tv_sub (recent_relative_time (), lsa->tv_recv));
paul718e3742002-12-13 20:15:29 +0000170
171 return age;
172}
173
174
175/* Fletcher Checksum -- Refer to RFC1008. */
paul718e3742002-12-13 20:15:29 +0000176
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100177/* All the offsets are zero-based. The offsets in the RFC1008 are
178 one-based. */
paul718e3742002-12-13 20:15:29 +0000179u_int16_t
180ospf_lsa_checksum (struct lsa_header *lsa)
181{
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100182 u_char *buffer = (u_char *) &lsa->options;
183 int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */
paul718e3742002-12-13 20:15:29 +0000184
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100185 /* Skip the AGE field */
186 u_int16_t len = ntohs(lsa->length) - options_offset;
paul718e3742002-12-13 20:15:29 +0000187
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100188 /* Checksum offset starts from "options" field, not the beginning of the
189 lsa_header struct. The offset is 14, rather than 16. */
190 int checksum_offset = (u_char *) &lsa->checksum - buffer;
paul718e3742002-12-13 20:15:29 +0000191
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100192 return fletcher_checksum(buffer, len, checksum_offset);
paul718e3742002-12-13 20:15:29 +0000193}
194
195
196
197/* Create OSPF LSA. */
198struct ospf_lsa *
199ospf_lsa_new ()
200{
201 struct ospf_lsa *new;
202
203 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
paul718e3742002-12-13 20:15:29 +0000204
205 new->flags = 0;
206 new->lock = 1;
207 new->retransmit_counter = 0;
Paul Jakma2518efd2006-08-27 06:49:29 +0000208 new->tv_recv = recent_relative_time ();
paul718e3742002-12-13 20:15:29 +0000209 new->tv_orig = new->tv_recv;
210 new->refresh_list = -1;
211
212 return new;
213}
214
215/* Duplicate OSPF LSA. */
216struct ospf_lsa *
217ospf_lsa_dup (struct ospf_lsa *lsa)
218{
219 struct ospf_lsa *new;
220
221 if (lsa == NULL)
222 return NULL;
223
224 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
225
226 memcpy (new, lsa, sizeof (struct ospf_lsa));
227 UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
228 new->lock = 1;
229 new->retransmit_counter = 0;
230 new->data = ospf_lsa_data_dup (lsa->data);
231
paulf2c80652002-12-13 21:44:27 +0000232 /* kevinm: Clear the refresh_list, otherwise there are going
233 to be problems when we try to remove the LSA from the
234 queue (which it's not a member of.)
235 XXX: Should we add the LSA to the refresh_list queue? */
236 new->refresh_list = -1;
237
238 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000239 zlog_debug ("LSA: duplicated %p (new: %p)", lsa, new);
paulf2c80652002-12-13 21:44:27 +0000240
paul718e3742002-12-13 20:15:29 +0000241 return new;
242}
243
244/* Free OSPF LSA. */
245void
246ospf_lsa_free (struct ospf_lsa *lsa)
247{
248 assert (lsa->lock == 0);
249
250 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000251 zlog_debug ("LSA: freed %p", lsa);
paul718e3742002-12-13 20:15:29 +0000252
253 /* Delete LSA data. */
254 if (lsa->data != NULL)
255 ospf_lsa_data_free (lsa->data);
256
257 assert (lsa->refresh_list < 0);
258
259 memset (lsa, 0, sizeof (struct ospf_lsa));
260 XFREE (MTYPE_OSPF_LSA, lsa);
261}
262
263/* Lock LSA. */
264struct ospf_lsa *
265ospf_lsa_lock (struct ospf_lsa *lsa)
266{
267 lsa->lock++;
268 return lsa;
269}
270
271/* Unlock LSA. */
272void
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000273ospf_lsa_unlock (struct ospf_lsa **lsa)
paul718e3742002-12-13 20:15:29 +0000274{
275 /* This is sanity check. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000276 if (!lsa || !*lsa)
paul718e3742002-12-13 20:15:29 +0000277 return;
278
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000279 (*lsa)->lock--;
paul718e3742002-12-13 20:15:29 +0000280
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000281 assert ((*lsa)->lock >= 0);
paul718e3742002-12-13 20:15:29 +0000282
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000283 if ((*lsa)->lock == 0)
paul718e3742002-12-13 20:15:29 +0000284 {
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000285 assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
286 ospf_lsa_free (*lsa);
287 *lsa = NULL;
paul718e3742002-12-13 20:15:29 +0000288 }
289}
290
291/* Check discard flag. */
292void
293ospf_lsa_discard (struct ospf_lsa *lsa)
294{
295 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
296 {
297 SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000298 ospf_lsa_unlock (&lsa);
paul718e3742002-12-13 20:15:29 +0000299 }
300}
301
302/* Create LSA data. */
303struct lsa_header *
304ospf_lsa_data_new (size_t size)
305{
Stephen Hemminger393deb92008-08-18 14:13:29 -0700306 return XCALLOC (MTYPE_OSPF_LSA_DATA, size);
paul718e3742002-12-13 20:15:29 +0000307}
308
309/* Duplicate LSA data. */
310struct lsa_header *
311ospf_lsa_data_dup (struct lsa_header *lsah)
312{
313 struct lsa_header *new;
314
315 new = ospf_lsa_data_new (ntohs (lsah->length));
316 memcpy (new, lsah, ntohs (lsah->length));
317
318 return new;
319}
320
321/* Free LSA data. */
322void
323ospf_lsa_data_free (struct lsa_header *lsah)
324{
325 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000326 zlog_debug ("LSA[Type%d:%s]: data freed %p",
paul718e3742002-12-13 20:15:29 +0000327 lsah->type, inet_ntoa (lsah->id), lsah);
328
329 XFREE (MTYPE_OSPF_LSA_DATA, lsah);
330}
331
332
333/* LSA general functions. */
334
335const char *
336dump_lsa_key (struct ospf_lsa *lsa)
337{
338 static char buf[] = {
hasso52dc7ee2004-09-23 19:18:23 +0000339 "Type255,id(255.255.255.255),ar(255.255.255.255)"
paul718e3742002-12-13 20:15:29 +0000340 };
341 struct lsa_header *lsah;
342
343 if (lsa != NULL && (lsah = lsa->data) != NULL)
344 {
345 char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
346 strcpy (id, inet_ntoa (lsah->id));
347 strcpy (ar, inet_ntoa (lsah->adv_router));
348
349 sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
350 }
351 else
352 strcpy (buf, "NULL");
353
354 return buf;
355}
356
357u_int32_t
358lsa_seqnum_increment (struct ospf_lsa *lsa)
359{
360 u_int32_t seqnum;
361
362 seqnum = ntohl (lsa->data->ls_seqnum) + 1;
363
364 return htonl (seqnum);
365}
366
367void
368lsa_header_set (struct stream *s, u_char options,
paul68980082003-03-25 05:07:42 +0000369 u_char type, struct in_addr id, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +0000370{
371 struct lsa_header *lsah;
372
373 lsah = (struct lsa_header *) STREAM_DATA (s);
374
375 lsah->ls_age = htons (0);
376 lsah->options = options;
377 lsah->type = type;
378 lsah->id = id;
paul68980082003-03-25 05:07:42 +0000379 lsah->adv_router = router_id;
paul718e3742002-12-13 20:15:29 +0000380 lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
381
paul9985f832005-02-09 15:51:56 +0000382 stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000383}
384
paul68980082003-03-25 05:07:42 +0000385
paul718e3742002-12-13 20:15:29 +0000386/* router-LSA related functions. */
387/* Get router-LSA flags. */
paul4dadc292005-05-06 21:37:42 +0000388static u_char
paul718e3742002-12-13 20:15:29 +0000389router_lsa_flags (struct ospf_area *area)
390{
391 u_char flags;
392
paul68980082003-03-25 05:07:42 +0000393 flags = area->ospf->flags;
paul718e3742002-12-13 20:15:29 +0000394
395 /* Set virtual link flag. */
396 if (ospf_full_virtual_nbrs (area))
397 SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
398 else
399 /* Just sanity check */
400 UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);
401
402 /* Set Shortcut ABR behabiour flag. */
403 UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
paul68980082003-03-25 05:07:42 +0000404 if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
paul718e3742002-12-13 20:15:29 +0000405 if (!OSPF_IS_AREA_BACKBONE (area))
406 if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
paul68980082003-03-25 05:07:42 +0000407 area->ospf->backbone == NULL) ||
paul718e3742002-12-13 20:15:29 +0000408 area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
409 SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
410
411 /* ASBR can't exit in stub area. */
Greg Troxelfc787e82007-08-06 15:50:20 +0000412 if (area->external_routing == OSPF_AREA_STUB)
paul942b6c12003-06-22 08:22:18 +0000413 UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
414 /* If ASBR set External flag */
415 else if (IS_OSPF_ASBR (area->ospf))
416 SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
417
418 /* Set ABR dependent flags */
419 if (IS_OSPF_ABR (area->ospf))
420 {
421 SET_FLAG (flags, ROUTER_LSA_BORDER);
paul942b6c12003-06-22 08:22:18 +0000422 /* If Area is NSSA and we are both ABR and unconditional translator,
pauld4a53d52003-07-12 21:30:57 +0000423 * set Nt bit to inform other routers.
paul942b6c12003-06-22 08:22:18 +0000424 */
pauld4a53d52003-07-12 21:30:57 +0000425 if ( (area->external_routing == OSPF_AREA_NSSA)
426 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
427 SET_FLAG (flags, ROUTER_LSA_NT);
paul942b6c12003-06-22 08:22:18 +0000428 }
paul718e3742002-12-13 20:15:29 +0000429 return flags;
430}
431
432/* Lookup neighbor other than myself.
433 And check neighbor count,
434 Point-to-Point link must have only 1 neighbor. */
435struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +0000436ospf_nbr_lookup_ptop (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +0000437{
paul718e3742002-12-13 20:15:29 +0000438 struct ospf_neighbor *nbr = NULL;
paul68980082003-03-25 05:07:42 +0000439 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000440
441 /* Search neighbor, there must be one of two nbrs. */
paul68980082003-03-25 05:07:42 +0000442 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
443 if ((nbr = rn->info))
444 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000445 if (nbr->state == NSM_Full)
paul68980082003-03-25 05:07:42 +0000446 {
447 route_unlock_node (rn);
448 break;
449 }
paul718e3742002-12-13 20:15:29 +0000450
451 /* PtoP link must have only 1 neighbor. */
paul68980082003-03-25 05:07:42 +0000452 if (ospf_nbr_count (oi, 0) > 1)
paul718e3742002-12-13 20:15:29 +0000453 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
454
455 return nbr;
456}
457
paul88d6cf32005-10-29 12:50:09 +0000458/* Determine cost of link, taking RFC3137 stub-router support into
459 * consideration
460 */
461static u_int16_t
462ospf_link_cost (struct ospf_interface *oi)
463{
464 /* RFC3137 stub router support */
465 if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
466 return oi->output_cost;
467 else
468 return OSPF_OUTPUT_COST_INFINITE;
469}
470
paul718e3742002-12-13 20:15:29 +0000471/* Set a link information. */
paul779adb02006-01-18 15:07:38 +0000472static char
paul718e3742002-12-13 20:15:29 +0000473link_info_set (struct stream *s, struct in_addr id,
474 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
475{
paul779adb02006-01-18 15:07:38 +0000476 /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
477 * vast majority of cases. Some rare routers with lots of links need more.
478 * we try accomodate those here.
479 */
480 if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
481 {
482 size_t ret = OSPF_MAX_LSA_SIZE;
483
484 /* Can we enlarge the stream still? */
485 if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
486 {
487 /* we futz the size here for simplicity, really we need to account
488 * for just:
489 * IP Header - (sizeof (struct ip))
490 * OSPF Header - OSPF_HEADER_SIZE
491 * LSA Header - OSPF_LSA_HEADER_SIZE
492 * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
493 *
494 * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
495 */
496 ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
497 }
498
499 if (ret == OSPF_MAX_LSA_SIZE)
500 {
501 zlog_warn ("%s: Out of space in LSA stream, left %ld, size %ld",
502 __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
503 return 0;
504 }
505 }
506
paul718e3742002-12-13 20:15:29 +0000507 /* TOS based routing is not supported. */
508 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
509 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
510 stream_putc (s, type); /* Link Type. */
511 stream_putc (s, tos); /* TOS = 0. */
512 stream_putw (s, cost); /* Link Cost. */
paul779adb02006-01-18 15:07:38 +0000513
514 return 1;
paul718e3742002-12-13 20:15:29 +0000515}
516
Andrew J. Schorre4529632006-12-12 19:18:21 +0000517/* Describe Point-to-Point link (Section 12.4.1.1). */
paul4dadc292005-05-06 21:37:42 +0000518static int
paul718e3742002-12-13 20:15:29 +0000519lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
520{
521 int links = 0;
522 struct ospf_neighbor *nbr;
523 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000524 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000525
526 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000527 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
paul718e3742002-12-13 20:15:29 +0000528
paul68980082003-03-25 05:07:42 +0000529 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000530 if (nbr->state == NSM_Full)
531 {
532 /* For unnumbered point-to-point networks, the Link Data field
533 should specify the interface's MIB-II ifIndex value. */
paul779adb02006-01-18 15:07:38 +0000534 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
535 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000536 }
537
Andrew J. Schorre4529632006-12-12 19:18:21 +0000538 /* Regardless of the state of the neighboring router, we must
539 add a Type 3 link (stub network).
540 N.B. Options 1 & 2 share basically the same logic. */
541 masklen2ip (oi->address->prefixlen, &mask);
542 id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
543 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
544 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000545 return links;
546}
547
548/* Describe Broadcast Link. */
paul4dadc292005-05-06 21:37:42 +0000549static int
paul718e3742002-12-13 20:15:29 +0000550lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
551{
552 struct ospf_neighbor *dr;
553 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000554 u_int16_t cost = ospf_link_cost (oi);
555
paul718e3742002-12-13 20:15:29 +0000556 /* Describe Type 3 Link. */
557 if (oi->state == ISM_Waiting)
558 {
559 masklen2ip (oi->address->prefixlen, &mask);
560 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000561 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
562 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000563 }
564
565 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
566 /* Describe Type 2 link. */
567 if (dr && (dr->state == NSM_Full ||
568 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000569 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000570 {
paul779adb02006-01-18 15:07:38 +0000571 return link_info_set (s, DR (oi), oi->address->u.prefix4,
572 LSA_LINK_TYPE_TRANSIT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000573 }
574 /* Describe type 3 link. */
575 else
576 {
577 masklen2ip (oi->address->prefixlen, &mask);
578 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000579 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
580 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000581 }
paul718e3742002-12-13 20:15:29 +0000582}
583
paul4dadc292005-05-06 21:37:42 +0000584static int
paul718e3742002-12-13 20:15:29 +0000585lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
586{
587 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000588
paul718e3742002-12-13 20:15:29 +0000589 /* Describe Type 3 Link. */
590 if (oi->state != ISM_Loopback)
591 return 0;
592
593 mask.s_addr = 0xffffffff;
594 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000595 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000596}
597
598/* Describe Virtual Link. */
paul4dadc292005-05-06 21:37:42 +0000599static int
paul718e3742002-12-13 20:15:29 +0000600lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
601{
602 struct ospf_neighbor *nbr;
paul88d6cf32005-10-29 12:50:09 +0000603 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000604
paul718e3742002-12-13 20:15:29 +0000605 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000606 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000607 if (nbr->state == NSM_Full)
608 {
paul779adb02006-01-18 15:07:38 +0000609 return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
610 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
paul718e3742002-12-13 20:15:29 +0000611 }
612
613 return 0;
614}
615
616#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
617
paul7afa08d2002-12-13 20:59:45 +0000618/* this function add for support point-to-multipoint ,see rfc2328
61912.4.1.4.*/
620/* from "edward rrr" <edward_rrr@hotmail.com>
621 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul4dadc292005-05-06 21:37:42 +0000622static int
paul68980082003-03-25 05:07:42 +0000623lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000624{
625 int links = 0;
626 struct route_node *rn;
627 struct ospf_neighbor *nbr = NULL;
628 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000629 u_int16_t cost = ospf_link_cost (oi);
paul7afa08d2002-12-13 20:59:45 +0000630
631 mask.s_addr = 0xffffffff;
632 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000633 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
paul7afa08d2002-12-13 20:59:45 +0000634
paul1cc8f762003-04-05 19:34:32 +0000635 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000636 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000637
638 /* Search neighbor, */
639 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
640 if ((nbr = rn->info) != NULL)
641 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000642 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000643 if (nbr->state == NSM_Full)
644
645 {
paul779adb02006-01-18 15:07:38 +0000646 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
647 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul1cc8f762003-04-05 19:34:32 +0000648 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000649 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000650 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000651 }
652
653 return links;
paul7afa08d2002-12-13 20:59:45 +0000654}
655
paul718e3742002-12-13 20:15:29 +0000656/* Set router-LSA link information. */
paul4dadc292005-05-06 21:37:42 +0000657static int
paul718e3742002-12-13 20:15:29 +0000658router_lsa_link_set (struct stream *s, struct ospf_area *area)
659{
hasso52dc7ee2004-09-23 19:18:23 +0000660 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000661 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000662 int links = 0;
663
paul1eb8ef22005-04-07 07:30:20 +0000664 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +0000665 {
paul718e3742002-12-13 20:15:29 +0000666 struct interface *ifp = oi->ifp;
667
668 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000669 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000670 {
671 if (oi->state != ISM_Down)
672 {
673 /* Describe each link. */
674 switch (oi->type)
675 {
676 case OSPF_IFTYPE_POINTOPOINT:
677 links += lsa_link_ptop_set (s, oi);
678 break;
679 case OSPF_IFTYPE_BROADCAST:
680 links += lsa_link_broadcast_set (s, oi);
681 break;
682 case OSPF_IFTYPE_NBMA:
683 links += lsa_link_nbma_set (s, oi);
684 break;
685 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000686 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000687 break;
688 case OSPF_IFTYPE_VIRTUALLINK:
689 links += lsa_link_virtuallink_set (s, oi);
690 break;
691 case OSPF_IFTYPE_LOOPBACK:
692 links += lsa_link_loopback_set (s, oi);
693 }
694 }
695 }
696 }
697
698 return links;
699}
700
701/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000702static void
paul718e3742002-12-13 20:15:29 +0000703ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
704{
705 unsigned long putp;
706 u_int16_t cnt;
707
708 /* Set flags. */
709 stream_putc (s, router_lsa_flags (area));
710
711 /* Set Zero fields. */
712 stream_putc (s, 0);
713
714 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000715 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000716
717 /* Forward word */
718 stream_putw(s, 0);
719
720 /* Set all link information. */
721 cnt = router_lsa_link_set (s, area);
722
723 /* Set # of links here. */
724 stream_putw_at (s, putp, cnt);
725}
paul88d6cf32005-10-29 12:50:09 +0000726
727static int
728ospf_stub_router_timer (struct thread *t)
729{
730 struct ospf_area *area = THREAD_ARG (t);
731
732 area->t_stub_router = NULL;
733
734 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
735
736 /* clear stub route state and generate router-lsa refresh, don't
737 * clobber an administratively set stub-router state though.
738 */
739 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
740 return 0;
741
742 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
743
744 ospf_router_lsa_timer_add (area);
745
746 return 0;
747}
paul718e3742002-12-13 20:15:29 +0000748
paul88d6cf32005-10-29 12:50:09 +0000749inline static void
750ospf_stub_router_check (struct ospf_area *area)
751{
752 /* area must either be administratively configured to be stub
753 * or startup-time stub-router must be configured and we must in a pre-stub
754 * state.
755 */
756 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
757 {
758 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
759 return;
760 }
761
762 /* not admin-stubbed, check whether startup stubbing is configured and
763 * whether it's not been done yet
764 */
765 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
766 return;
767
768 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
769 {
770 /* stub-router is hence done forever for this area, even if someone
771 * tries configure it (take effect next restart).
772 */
773 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
774 return;
775 }
776
777 /* startup stub-router configured and not yet done */
778 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
779
780 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
781 area->ospf->stub_router_startup_time);
782}
783
paul718e3742002-12-13 20:15:29 +0000784/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000785static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000786ospf_router_lsa_new (struct ospf_area *area)
787{
paul68980082003-03-25 05:07:42 +0000788 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000789 struct stream *s;
790 struct lsa_header *lsah;
791 struct ospf_lsa *new;
792 int length;
793
794 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000795 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000796
paul88d6cf32005-10-29 12:50:09 +0000797 /* check whether stub-router is desired, and if this is the first
798 * router LSA.
799 */
800 ospf_stub_router_check (area);
801
paul718e3742002-12-13 20:15:29 +0000802 /* Create a stream for LSA. */
803 s = stream_new (OSPF_MAX_LSA_SIZE);
paul718e3742002-12-13 20:15:29 +0000804 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000805 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000806 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000807
808 /* Set router-LSA body fields. */
809 ospf_router_lsa_body_set (s, area);
810
811 /* Set length. */
812 length = stream_get_endp (s);
paul779adb02006-01-18 15:07:38 +0000813 lsah = (struct lsa_header *) STREAM_DATA (s);
paul718e3742002-12-13 20:15:29 +0000814 lsah->length = htons (length);
815
816 /* Now, create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000817 if ( (new = ospf_lsa_new ()) == NULL)
818 {
819 zlog_err ("%s: Unable to create new lsa", __func__);
820 return NULL;
821 }
822
paul718e3742002-12-13 20:15:29 +0000823 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +0000824 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +0000825
826 /* Copy LSA data to store, discard stream. */
827 new->data = ospf_lsa_data_new (length);
828 memcpy (new->data, lsah, length);
829 stream_free (s);
830
831 return new;
832}
833
834/* Originate Router-LSA. */
paul88d6cf32005-10-29 12:50:09 +0000835static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000836ospf_router_lsa_originate (struct ospf_area *area)
837{
838 struct ospf_lsa *new;
paul88d6cf32005-10-29 12:50:09 +0000839
paul718e3742002-12-13 20:15:29 +0000840 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000841 if ( (new = ospf_router_lsa_new (area)) == NULL)
842 {
843 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
844 return NULL;
845 }
paul718e3742002-12-13 20:15:29 +0000846
847 /* Sanity check. */
848 if (new->data->adv_router.s_addr == 0)
849 {
850 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000851 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000852 ospf_lsa_discard (new);
853 return NULL;
854 }
855
856 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000857 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000858
859 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000860 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000861
862 /* Flooding new LSA through area. */
863 ospf_flood_through_area (area, NULL, new);
864
865 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
866 {
ajse588f212004-12-08 18:12:06 +0000867 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
paul718e3742002-12-13 20:15:29 +0000868 new->data->type, inet_ntoa (new->data->id), new);
869 ospf_lsa_header_dump (new->data);
870 }
871
872 return new;
873}
874
875/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000876static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000877ospf_router_lsa_refresh (struct ospf_lsa *lsa)
878{
879 struct ospf_area *area = lsa->area;
880 struct ospf_lsa *new;
881
882 /* Sanity check. */
883 assert (lsa->data);
884
885 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000886 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000887
888 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000889 if ( (new = ospf_router_lsa_new (area)) == NULL)
890 {
891 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
892 return NULL;
893 }
894
paul718e3742002-12-13 20:15:29 +0000895 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
896
paul68980082003-03-25 05:07:42 +0000897 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000898
899 /* Flood LSA through area. */
900 ospf_flood_through_area (area, NULL, new);
901
902 /* Debug logging. */
903 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
904 {
ajse588f212004-12-08 18:12:06 +0000905 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000906 new->data->type, inet_ntoa (new->data->id));
907 ospf_lsa_header_dump (new->data);
908 }
909
910 return NULL;
911}
912
paul4dadc292005-05-06 21:37:42 +0000913static int
paul718e3742002-12-13 20:15:29 +0000914ospf_router_lsa_timer (struct thread *t)
915{
916 struct ospf_area *area;
917
918 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000919 zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
paul718e3742002-12-13 20:15:29 +0000920
921 area = THREAD_ARG (t);
922 area->t_router_lsa_self = NULL;
923
924 /* Now refresh router-LSA. */
925 if (area->router_lsa_self)
926 ospf_router_lsa_refresh (area->router_lsa_self);
927 /* Newly originate router-LSA. */
928 else
929 ospf_router_lsa_originate (area);
930
931 return 0;
932}
933
934void
935ospf_router_lsa_timer_add (struct ospf_area *area)
936{
937 /* Keep area's self-originated router-LSA. */
938 struct ospf_lsa *lsa = area->router_lsa_self;
939
940 /* Cancel previously scheduled router-LSA timer. */
941 if (area->t_router_lsa_self)
942 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000943 zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
paul718e3742002-12-13 20:15:29 +0000944
945 OSPF_TIMER_OFF (area->t_router_lsa_self);
946
947 /* If router-LSA is originated previously, check the interval time. */
948 if (lsa)
949 {
950 int delay;
951 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
952 {
953 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
954 ospf_router_lsa_timer, delay);
955 return;
956 }
957 }
958
959 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000960 zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
paul718e3742002-12-13 20:15:29 +0000961
962 /* Immediately refresh router-LSA. */
963 OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
964}
965
966int
paul68980082003-03-25 05:07:42 +0000967ospf_router_lsa_update_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000968{
paul68980082003-03-25 05:07:42 +0000969 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +0000970 struct listnode *node, *nnode;
971 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +0000972
973 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000974 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +0000975
paul68980082003-03-25 05:07:42 +0000976 ospf->t_router_lsa_update = NULL;
paul718e3742002-12-13 20:15:29 +0000977
paul1eb8ef22005-04-07 07:30:20 +0000978 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000979 {
paul718e3742002-12-13 20:15:29 +0000980 struct ospf_lsa *lsa = area->router_lsa_self;
981 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +0000982 const char *area_str;
paul718e3742002-12-13 20:15:29 +0000983
984 /* Keep Area ID string. */
985 area_str = AREA_NAME (area);
986
987 /* If LSA not exist in this Area, originate new. */
988 if (lsa == NULL)
989 {
990 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000991 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +0000992
993 ospf_router_lsa_originate (area);
994 }
995 /* If router-ID is changed, Link ID must change.
996 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +0000997 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000998 {
999 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001000 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +00001001 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
1002 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001003 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00001004 area->router_lsa_self = NULL;
1005
1006 /* Refresh router-LSA, (not install) and flood through area. */
1007 ospf_router_lsa_timer_add (area);
1008 }
1009 else
1010 {
1011 rl = (struct router_lsa *) lsa->data;
1012 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +00001013 if (rl->flags != ospf->flags)
paul718e3742002-12-13 20:15:29 +00001014 ospf_router_lsa_timer_add (area);
1015 }
1016 }
1017
1018 return 0;
1019}
1020
1021
1022/* network-LSA related functions. */
1023/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001024static void
paul718e3742002-12-13 20:15:29 +00001025ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1026{
1027 struct in_addr mask;
1028 struct route_node *rn;
1029 struct ospf_neighbor *nbr;
1030
1031 masklen2ip (oi->address->prefixlen, &mask);
1032 stream_put_ipv4 (s, mask.s_addr);
1033
1034 /* The network-LSA lists those routers that are fully adjacent to
1035 the Designated Router; each fully adjacent router is identified by
1036 its OSPF Router ID. The Designated Router includes itself in this
1037 list. RFC2328, Section 12.4.2 */
1038
1039 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1040 if ((nbr = rn->info) != NULL)
1041 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1042 stream_put_ipv4 (s, nbr->router_id.s_addr);
1043}
1044
paul4dadc292005-05-06 21:37:42 +00001045static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001046ospf_network_lsa_new (struct ospf_interface *oi)
1047{
1048 struct stream *s;
1049 struct ospf_lsa *new;
1050 struct lsa_header *lsah;
1051 int length;
1052
1053 /* If there are no neighbours on this network (the net is stub),
1054 the router does not originate network-LSA (see RFC 12.4.2) */
1055 if (oi->full_nbrs == 0)
1056 return NULL;
1057
1058 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001059 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001060
1061 /* Create new stream for LSA. */
1062 s = stream_new (OSPF_MAX_LSA_SIZE);
1063 lsah = (struct lsa_header *) STREAM_DATA (s);
1064
1065 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001066 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001067
1068 /* Set network-LSA body fields. */
1069 ospf_network_lsa_body_set (s, oi);
1070
1071 /* Set length. */
1072 length = stream_get_endp (s);
1073 lsah->length = htons (length);
1074
1075 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001076 if ( (new = ospf_lsa_new ()) == NULL)
1077 {
1078 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1079 return NULL;
1080 }
1081
paul718e3742002-12-13 20:15:29 +00001082 new->area = oi->area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001083 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001084
1085 /* Copy LSA to store. */
1086 new->data = ospf_lsa_data_new (length);
1087 memcpy (new->data, lsah, length);
1088 stream_free (s);
1089
1090 return new;
1091}
1092
1093/* Originate network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001094static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001095ospf_network_lsa_originate (struct ospf_interface *oi)
1096{
1097 struct ospf_lsa *new;
1098
1099 /* Create new network-LSA instance. */
1100 new = ospf_network_lsa_new (oi);
1101 if (new == NULL)
1102 return NULL;
1103
1104 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001105 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001106
1107 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001108 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001109
1110 /* Flooding new LSA through area. */
1111 ospf_flood_through_area (oi->area, NULL, new);
1112
1113 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1114 {
ajse588f212004-12-08 18:12:06 +00001115 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001116 new->data->type, inet_ntoa (new->data->id), new);
1117 ospf_lsa_header_dump (new->data);
1118 }
1119
1120 return new;
1121}
1122
1123int
1124ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1125{
1126 struct ospf_area *area = lsa->area;
1127 struct ospf_lsa *new;
1128
1129 assert (lsa->data);
1130
1131 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001132 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001133
1134 /* Create new network-LSA instance. */
1135 new = ospf_network_lsa_new (oi);
1136 if (new == NULL)
1137 return -1;
1138 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1139
paul68980082003-03-25 05:07:42 +00001140 ospf_lsa_install (area->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001141
1142 /* Flood LSA through aera. */
1143 ospf_flood_through_area (area, NULL, new);
1144
1145 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1146 {
ajse588f212004-12-08 18:12:06 +00001147 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001148 new->data->type, inet_ntoa (new->data->id));
1149 ospf_lsa_header_dump (new->data);
1150 }
1151
1152 return 0;
1153}
1154
paul4dadc292005-05-06 21:37:42 +00001155static int
paul718e3742002-12-13 20:15:29 +00001156ospf_network_lsa_refresh_timer (struct thread *t)
1157{
1158 struct ospf_interface *oi;
1159
1160 oi = THREAD_ARG (t);
1161 oi->t_network_lsa_self = NULL;
1162
1163 if (oi->network_lsa_self)
1164 /* Now refresh network-LSA. */
1165 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1166 else
1167 /* Newly create network-LSA. */
1168 ospf_network_lsa_originate (oi);
1169
1170 return 0;
1171}
1172
1173void
1174ospf_network_lsa_timer_add (struct ospf_interface *oi)
1175{
1176 /* Keep interface's self-originated network-LSA. */
1177 struct ospf_lsa *lsa = oi->network_lsa_self;
1178
1179 /* Cancel previously schedules network-LSA timer. */
1180 if (oi->t_network_lsa_self)
1181 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001182 zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
paul718e3742002-12-13 20:15:29 +00001183 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1184
1185 /* If network-LSA is originated previously, check the interval time. */
1186 if (lsa)
1187 {
1188 int delay;
1189 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1190 {
1191 oi->t_network_lsa_self =
1192 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1193 oi, delay);
1194 return;
1195 }
1196 }
1197
1198 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001199 zlog_debug ("Scheduling network-LSA origination right away");
paul718e3742002-12-13 20:15:29 +00001200
1201 /* Immediately refresh network-LSA. */
1202 oi->t_network_lsa_self =
1203 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1204}
1205
1206
paul4dadc292005-05-06 21:37:42 +00001207static void
paul718e3742002-12-13 20:15:29 +00001208stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1209{
1210 u_int32_t metric;
1211 char *mp;
1212
1213 /* Put 0 metric. TOS metric is not supported. */
1214 metric = htonl (metric_value);
1215 mp = (char *) &metric;
1216 mp++;
1217 stream_put (s, mp, 3);
1218}
1219
1220/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001221static void
paul718e3742002-12-13 20:15:29 +00001222ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1223 u_int32_t metric)
1224{
1225 struct in_addr mask;
1226
1227 masklen2ip (p->prefixlen, &mask);
1228
1229 /* Put Network Mask. */
1230 stream_put_ipv4 (s, mask.s_addr);
1231
1232 /* Set # TOS. */
1233 stream_putc (s, (u_char) 0);
1234
1235 /* Set metric. */
1236 stream_put_ospf_metric (s, metric);
1237}
1238
paul4dadc292005-05-06 21:37:42 +00001239static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001240ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1241 u_int32_t metric, struct in_addr id)
1242{
1243 struct stream *s;
1244 struct ospf_lsa *new;
1245 struct lsa_header *lsah;
1246 int length;
1247
paulc24d6022005-11-20 14:54:12 +00001248 if (id.s_addr == 0xffffffff)
1249 {
1250 /* Maybe Link State ID not available. */
1251 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1252 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1253 OSPF_SUMMARY_LSA);
1254 return NULL;
1255 }
1256
paul718e3742002-12-13 20:15:29 +00001257 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001258 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001259
1260 /* Create new stream for LSA. */
1261 s = stream_new (OSPF_MAX_LSA_SIZE);
1262 lsah = (struct lsa_header *) STREAM_DATA (s);
1263
paul68980082003-03-25 05:07:42 +00001264 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1265 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001266
1267 /* Set summary-LSA body fields. */
1268 ospf_summary_lsa_body_set (s, p, metric);
1269
1270 /* Set length. */
1271 length = stream_get_endp (s);
1272 lsah->length = htons (length);
1273
1274 /* Create OSPF LSA instance. */
1275 new = ospf_lsa_new ();
1276 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001277 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001278
1279 /* Copy LSA to store. */
1280 new->data = ospf_lsa_data_new (length);
1281 memcpy (new->data, lsah, length);
1282 stream_free (s);
1283
1284 return new;
1285}
1286
1287/* Originate Summary-LSA. */
1288struct ospf_lsa *
1289ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1290 struct ospf_area *area)
1291{
1292 struct ospf_lsa *new;
1293 struct in_addr id;
1294
paul68980082003-03-25 05:07:42 +00001295 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001296
paulc24d6022005-11-20 14:54:12 +00001297 if (id.s_addr == 0xffffffff)
1298 {
1299 /* Maybe Link State ID not available. */
1300 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1301 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1302 OSPF_SUMMARY_LSA);
1303 return NULL;
1304 }
1305
paul718e3742002-12-13 20:15:29 +00001306 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001307 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1308 return NULL;
paul718e3742002-12-13 20:15:29 +00001309
1310 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001311 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001312
1313 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001314 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001315
1316 /* Flooding new LSA through area. */
1317 ospf_flood_through_area (area, NULL, new);
1318
1319 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1320 {
ajse588f212004-12-08 18:12:06 +00001321 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001322 new->data->type, inet_ntoa (new->data->id), new);
1323 ospf_lsa_header_dump (new->data);
1324 }
1325
1326 return new;
1327}
1328
1329struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001330ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001331{
1332 struct ospf_lsa *new;
1333 struct summary_lsa *sl;
1334 struct prefix p;
1335
1336 /* Sanity check. */
1337 assert (lsa->data);
1338
1339 sl = (struct summary_lsa *)lsa->data;
1340 p.prefixlen = ip_masklen (sl->mask);
1341 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1342 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001343
1344 if (!new)
1345 return NULL;
1346
paul718e3742002-12-13 20:15:29 +00001347 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001348
paul68980082003-03-25 05:07:42 +00001349 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001350
1351 /* Flood LSA through AS. */
1352 ospf_flood_through_area (new->area, NULL, new);
1353
1354 /* Debug logging. */
1355 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1356 {
ajse588f212004-12-08 18:12:06 +00001357 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001358 new->data->type, inet_ntoa (new->data->id));
1359 ospf_lsa_header_dump (new->data);
1360 }
1361
1362 return new;
1363}
1364
1365
1366/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001367static void
paul718e3742002-12-13 20:15:29 +00001368ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1369 u_int32_t metric)
1370{
1371 struct in_addr mask;
1372
1373 masklen2ip (p->prefixlen, &mask);
1374
1375 /* Put Network Mask. */
1376 stream_put_ipv4 (s, mask.s_addr);
1377
1378 /* Set # TOS. */
1379 stream_putc (s, (u_char) 0);
1380
1381 /* Set metric. */
1382 stream_put_ospf_metric (s, metric);
1383}
1384
paul4dadc292005-05-06 21:37:42 +00001385static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001386ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1387 u_int32_t metric, struct in_addr id)
1388{
1389 struct stream *s;
1390 struct ospf_lsa *new;
1391 struct lsa_header *lsah;
1392 int length;
1393
paulc24d6022005-11-20 14:54:12 +00001394 if (id.s_addr == 0xffffffff)
1395 {
1396 /* Maybe Link State ID not available. */
1397 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1398 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1399 OSPF_ASBR_SUMMARY_LSA);
1400 return NULL;
1401 }
1402
paul718e3742002-12-13 20:15:29 +00001403 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001404 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001405
1406 /* Create new stream for LSA. */
1407 s = stream_new (OSPF_MAX_LSA_SIZE);
1408 lsah = (struct lsa_header *) STREAM_DATA (s);
1409
paul68980082003-03-25 05:07:42 +00001410 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1411 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001412
1413 /* Set summary-LSA body fields. */
1414 ospf_summary_asbr_lsa_body_set (s, p, metric);
1415
1416 /* Set length. */
1417 length = stream_get_endp (s);
1418 lsah->length = htons (length);
1419
1420 /* Create OSPF LSA instance. */
1421 new = ospf_lsa_new ();
1422 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001423 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001424
1425 /* Copy LSA to store. */
1426 new->data = ospf_lsa_data_new (length);
1427 memcpy (new->data, lsah, length);
1428 stream_free (s);
1429
1430 return new;
1431}
1432
1433/* Originate summary-ASBR-LSA. */
1434struct ospf_lsa *
1435ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1436 struct ospf_area *area)
1437{
1438 struct ospf_lsa *new;
1439 struct in_addr id;
1440
paul68980082003-03-25 05:07:42 +00001441 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001442
paulc24d6022005-11-20 14:54:12 +00001443 if (id.s_addr == 0xffffffff)
1444 {
1445 /* Maybe Link State ID not available. */
1446 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1447 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1448 OSPF_ASBR_SUMMARY_LSA);
1449 return NULL;
1450 }
1451
paul718e3742002-12-13 20:15:29 +00001452 /* Create new summary-LSA instance. */
1453 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001454 if (!new)
1455 return NULL;
paul718e3742002-12-13 20:15:29 +00001456
1457 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001458 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001459
1460 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001461 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001462
1463 /* Flooding new LSA through area. */
1464 ospf_flood_through_area (area, NULL, new);
1465
1466 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1467 {
ajse588f212004-12-08 18:12:06 +00001468 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001469 new->data->type, inet_ntoa (new->data->id), new);
1470 ospf_lsa_header_dump (new->data);
1471 }
1472
1473 return new;
1474}
1475
1476struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001477ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001478{
1479 struct ospf_lsa *new;
1480 struct summary_lsa *sl;
1481 struct prefix p;
1482
1483 /* Sanity check. */
1484 assert (lsa->data);
1485
1486 sl = (struct summary_lsa *)lsa->data;
1487 p.prefixlen = ip_masklen (sl->mask);
1488 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1489 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001490 if (!new)
1491 return NULL;
paul718e3742002-12-13 20:15:29 +00001492
1493 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001494
paul68980082003-03-25 05:07:42 +00001495 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001496
1497 /* Flood LSA through area. */
1498 ospf_flood_through_area (new->area, NULL, new);
1499
1500 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1501 {
ajse588f212004-12-08 18:12:06 +00001502 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001503 new->data->type, inet_ntoa (new->data->id));
1504 ospf_lsa_header_dump (new->data);
1505 }
1506
1507 return new;
1508}
1509
1510/* AS-external-LSA related functions. */
1511
1512/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1513 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001514static struct in_addr
paul68980082003-03-25 05:07:42 +00001515ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001516{
1517 struct in_addr fwd;
1518 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001519 struct listnode *node;
1520 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001521
1522 fwd.s_addr = 0;
1523
1524 if (!nexthop.s_addr)
1525 return fwd;
1526
1527 /* Check whether nexthop is covered by OSPF network. */
1528 nh.family = AF_INET;
1529 nh.u.prefix4 = nexthop;
1530 nh.prefixlen = IPV4_MAX_BITLEN;
1531
paul1eb8ef22005-04-07 07:30:20 +00001532 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1533 if (if_is_operative (oi->ifp))
1534 if (oi->address->family == AF_INET)
1535 if (prefix_match (oi->address, &nh))
1536 return nexthop;
paul718e3742002-12-13 20:15:29 +00001537
1538 return fwd;
1539}
1540
paul718e3742002-12-13 20:15:29 +00001541/* NSSA-external-LSA related functions. */
1542
1543/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001544
paul718e3742002-12-13 20:15:29 +00001545struct in_addr
1546ospf_get_ip_from_ifp (struct ospf_interface *oi)
1547{
1548 struct in_addr fwd;
1549
1550 fwd.s_addr = 0;
1551
paul2e3b2e42002-12-13 21:03:13 +00001552 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001553 return oi->address->u.prefix4;
1554
1555 return fwd;
1556}
1557
1558/* Get 1st IP connection for Forward Addr */
1559struct in_addr
paulf2c80652002-12-13 21:44:27 +00001560ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001561{
1562 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001563 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001564 struct listnode *node;
1565 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001566
1567 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001568 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001569
paul1eb8ef22005-04-07 07:30:20 +00001570 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001571 {
paul2e3b2e42002-12-13 21:03:13 +00001572 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001573 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001574 if (oi->address && oi->address->family == AF_INET)
1575 {
1576 if (best_default.s_addr == 0)
1577 best_default = oi->address->u.prefix4;
1578 if (oi->area == area)
1579 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001580 }
paul718e3742002-12-13 20:15:29 +00001581 }
paulf2c80652002-12-13 21:44:27 +00001582 if (best_default.s_addr != 0)
1583 return best_default;
paul718e3742002-12-13 20:15:29 +00001584
paul68980082003-03-25 05:07:42 +00001585 if (best_default.s_addr != 0)
1586 return best_default;
1587
paul718e3742002-12-13 20:15:29 +00001588 return fwd;
1589}
hassobeebba72004-06-20 21:00:27 +00001590
paul718e3742002-12-13 20:15:29 +00001591#define DEFAULT_DEFAULT_METRIC 20
1592#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1593#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1594
1595#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1596
1597int
paul68980082003-03-25 05:07:42 +00001598metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001599{
paul68980082003-03-25 05:07:42 +00001600 return (ospf->dmetric[src].type < 0 ?
1601 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001602}
1603
1604int
paul68980082003-03-25 05:07:42 +00001605metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001606{
paul68980082003-03-25 05:07:42 +00001607 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001608 {
1609 if (src == DEFAULT_ROUTE)
1610 {
paul68980082003-03-25 05:07:42 +00001611 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001612 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1613 else
1614 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1615 }
paul68980082003-03-25 05:07:42 +00001616 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001617 return DEFAULT_DEFAULT_METRIC;
1618 else
paul68980082003-03-25 05:07:42 +00001619 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001620 }
1621
paul68980082003-03-25 05:07:42 +00001622 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001623}
1624
1625/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001626static void
paul68980082003-03-25 05:07:42 +00001627ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1628 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001629{
1630 struct prefix_ipv4 *p = &ei->p;
1631 struct in_addr mask, fwd_addr;
1632 u_int32_t mvalue;
1633 int mtype;
1634 int type;
1635
1636 /* Put Network Mask. */
1637 masklen2ip (p->prefixlen, &mask);
1638 stream_put_ipv4 (s, mask.s_addr);
1639
1640 /* If prefix is default, specify DEFAULT_ROUTE. */
1641 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1642
1643 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001644 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001645
1646 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001647 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001648
1649 /* Put type of external metric. */
1650 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1651
1652 /* Put 0 metric. TOS metric is not supported. */
1653 stream_put_ospf_metric (s, mvalue);
1654
1655 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001656 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001657
1658 /* Put forwarding address. */
1659 stream_put_ipv4 (s, fwd_addr.s_addr);
1660
1661 /* Put route tag -- This value should be introduced from configuration. */
1662 stream_putl (s, 0);
1663}
1664
1665/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001666static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001667ospf_external_lsa_new (struct ospf *ospf,
1668 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001669{
1670 struct stream *s;
1671 struct lsa_header *lsah;
1672 struct ospf_lsa *new;
1673 struct in_addr id;
1674 int length;
1675
1676 if (ei == NULL)
1677 {
1678 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001679 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
paul718e3742002-12-13 20:15:29 +00001680 return NULL;
1681 }
1682
1683 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001684 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001685
1686 /* If old Link State ID is specified, refresh LSA with same ID. */
1687 if (old_id)
1688 id = *old_id;
1689 /* Get Link State with unique ID. */
1690 else
1691 {
paul68980082003-03-25 05:07:42 +00001692 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001693 if (id.s_addr == 0xffffffff)
1694 {
1695 /* Maybe Link State ID not available. */
1696 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001697 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001698 return NULL;
1699 }
1700 }
1701
1702 /* Create new stream for LSA. */
1703 s = stream_new (OSPF_MAX_LSA_SIZE);
1704 lsah = (struct lsa_header *) STREAM_DATA (s);
1705
1706 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001707 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1708 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001709
1710 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001711 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001712
1713 /* Set length. */
1714 length = stream_get_endp (s);
1715 lsah->length = htons (length);
1716
1717 /* Now, create OSPF LSA instance. */
1718 new = ospf_lsa_new ();
1719 new->area = NULL;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001720 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001721
1722 /* Copy LSA data to store, discard stream. */
1723 new->data = ospf_lsa_data_new (length);
1724 memcpy (new->data, lsah, length);
1725 stream_free (s);
1726
1727 return new;
1728}
1729
paul718e3742002-12-13 20:15:29 +00001730/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001731static void
paul68980082003-03-25 05:07:42 +00001732ospf_install_flood_nssa (struct ospf *ospf,
1733 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001734{
pauld4a53d52003-07-12 21:30:57 +00001735 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001736 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001737 struct ospf_area *area;
1738 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001739
pauld4a53d52003-07-12 21:30:57 +00001740 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1741 * which originated from an NSSA area. In which case it should not be
1742 * flooded back to NSSA areas.
1743 */
1744 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1745 return;
1746
paul718e3742002-12-13 20:15:29 +00001747 /* NSSA Originate or Refresh (If anyNSSA)
1748
1749 LSA is self-originated. And just installed as Type-5.
1750 Additionally, install as Type-7 LSDB for every attached NSSA.
1751
1752 P-Bit controls which ABR performs translation to outside world; If
1753 we are an ABR....do not set the P-bit, because we send the Type-5,
1754 not as the ABR Translator, but as the ASBR owner within the AS!
1755
1756 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1757 elected ABR Translator will see the P-bit, Translate, and re-flood.
1758
1759 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1760 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1761
paul1eb8ef22005-04-07 07:30:20 +00001762 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001763 {
hasso0c14ad82003-07-03 08:36:02 +00001764 /* Don't install Type-7 LSA's into nonNSSA area */
1765 if (area->external_routing != OSPF_AREA_NSSA)
1766 continue;
paul718e3742002-12-13 20:15:29 +00001767
paul68980082003-03-25 05:07:42 +00001768 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001769 new = ospf_lsa_dup (lsa);
1770 new->area = area;
1771 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001772
paul68980082003-03-25 05:07:42 +00001773 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001774 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001775 {
pauld4a53d52003-07-12 21:30:57 +00001776 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001777
1778 /* set non-zero FWD ADDR
1779
1780 draft-ietf-ospf-nssa-update-09.txt
1781
1782 if the network between the NSSA AS boundary router and the
1783 adjacent AS is advertised into OSPF as an internal OSPF route,
1784 the forwarding address should be the next op address as is cu
1785 currently done with type-5 LSAs. If the intervening network is
1786 not adversited into OSPF as an internal OSPF route and the
1787 type-7 LSA's P-bit is set a forwarding address should be
1788 selected from one of the router's active OSPF inteface addresses
1789 which belong to the NSSA. If no such addresses exist, then
1790 no type-7 LSA's with the P-bit set should originate from this
1791 router. */
1792
pauld4a53d52003-07-12 21:30:57 +00001793 /* kevinm: not updating lsa anymore, just new */
1794 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001795
1796 if (extlsa->e[0].fwd_addr.s_addr == 0)
1797 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001798
pauld7480322003-05-16 17:31:51 +00001799 if (extlsa->e[0].fwd_addr.s_addr == 0)
1800 {
1801 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001802 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001803 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001804 return;
1805 }
paulf2c80652002-12-13 21:44:27 +00001806 }
paul718e3742002-12-13 20:15:29 +00001807
paul68980082003-03-25 05:07:42 +00001808 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001809 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001810
1811 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001812 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001813 }
paul718e3742002-12-13 20:15:29 +00001814}
pauld4a53d52003-07-12 21:30:57 +00001815
paul4dadc292005-05-06 21:37:42 +00001816static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001817ospf_lsa_translated_nssa_new (struct ospf *ospf,
1818 struct ospf_lsa *type7)
1819{
1820
1821 struct ospf_lsa *new;
1822 struct as_external_lsa *ext, *extnew;
1823 struct external_info ei;
1824
1825 ext = (struct as_external_lsa *)(type7->data);
1826
1827 /* need external_info struct, fill in bare minimum */
1828 ei.p.family = AF_INET;
1829 ei.p.prefix = type7->data->id;
1830 ei.p.prefixlen = ip_masklen (ext->mask);
1831 ei.type = ZEBRA_ROUTE_OSPF;
1832 ei.nexthop = ext->header.adv_router;
1833 ei.route_map_set.metric = -1;
1834 ei.route_map_set.metric_type = -1;
1835 ei.tag = 0;
1836
1837 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1838 {
1839 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001840 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001841 "Translated Type-5 for %s",
1842 inet_ntoa (ei.p.prefix));
1843 return NULL;
1844 }
1845
1846 extnew = (struct as_external_lsa *)(new->data);
1847
1848 /* copy over Type-7 data to new */
1849 extnew->e[0].tos = ext->e[0].tos;
1850 extnew->e[0].route_tag = ext->e[0].route_tag;
1851 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1852 new->data->ls_seqnum = type7->data->ls_seqnum;
1853
1854 /* add translated flag, checksum and lock new lsa */
1855 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
pauld4a53d52003-07-12 21:30:57 +00001856 new = ospf_lsa_lock (new);
1857
1858 return new;
1859}
1860
1861/* compare type-5 to type-7
1862 * -1: err, 0: same, 1: different
1863 */
paul4dadc292005-05-06 21:37:42 +00001864static int
pauld4a53d52003-07-12 21:30:57 +00001865ospf_lsa_translated_nssa_compare (struct ospf_lsa *t7, struct ospf_lsa *t5)
1866{
1867
1868 struct as_external_lsa *e5 = (struct as_external_lsa *)t5,
1869 *e7 = (struct as_external_lsa *)t7;
1870
1871
1872 /* sanity checks */
1873 if (! ((t5->data->type == OSPF_AS_EXTERNAL_LSA)
1874 && (t7->data->type == OSPF_AS_NSSA_LSA)))
1875 return -1;
1876
1877 if (t5->data->id.s_addr != t7->data->id.s_addr)
1878 return -1;
1879
1880 if (t5->data->ls_seqnum != t7->data->ls_seqnum)
1881 return LSA_REFRESH_FORCE;
1882
1883 if (e5->mask.s_addr != e7->mask.s_addr)
1884 return LSA_REFRESH_FORCE;
1885
1886 if (e5->e[0].fwd_addr.s_addr != e7->e[0].fwd_addr.s_addr)
1887 return LSA_REFRESH_FORCE;
1888
1889 if (e5->e[0].route_tag != e7->e[0].route_tag)
1890 return LSA_REFRESH_FORCE;
1891
1892 if (GET_METRIC (e5->e[0].metric) != GET_METRIC (e7->e[0].metric))
1893 return LSA_REFRESH_FORCE;
1894
1895 return LSA_REFRESH_IF_CHANGED;
1896}
1897
1898/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1899struct ospf_lsa *
1900ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1901{
1902 struct ospf_lsa *new;
1903 struct as_external_lsa *extnew;
1904
1905 /* we cant use ospf_external_lsa_originate() as we need to set
1906 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1907 */
1908
1909 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1910 {
1911 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001912 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001913 "Type-7, Id %s, to Type-5",
1914 inet_ntoa (type7->data->id));
1915 return NULL;
1916 }
1917
1918 extnew = (struct as_external_lsa *)new;
1919
1920 if (IS_DEBUG_OSPF_NSSA)
1921 {
ajse588f212004-12-08 18:12:06 +00001922 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001923 "translated Type 7, installed:");
1924 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001925 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1926 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001927 }
1928
1929 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1930 {
1931 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001932 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001933 "Could not install LSA "
1934 "id %s", inet_ntoa (type7->data->id));
1935 return NULL;
1936 }
1937
1938 ospf->lsa_originate_count++;
1939 ospf_flood_through_as (ospf, NULL, new);
1940
1941 return new;
1942}
1943
1944/* Refresh Translated from NSSA AS-external-LSA. */
1945struct ospf_lsa *
1946ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1947 struct ospf_lsa *type5)
1948{
1949 struct ospf_lsa *new = NULL;
1950
1951 /* Sanity checks. */
1952 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00001953 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00001954 return NULL;
pauld4a53d52003-07-12 21:30:57 +00001955 if (type7)
1956 assert (type7->data);
1957 if (type5)
1958 assert (type5->data);
1959 assert (ospf->anyNSSA);
1960
1961 /* get required data according to what has been given */
1962 if (type7 && type5 == NULL)
1963 {
1964 /* find the translated Type-5 for this Type-7 */
1965 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1966 struct prefix_ipv4 p =
1967 {
1968 .prefix = type7->data->id,
1969 .prefixlen = ip_masklen (ext->mask),
1970 .family = AF_INET,
1971 };
1972
1973 type5 = ospf_external_info_find_lsa (ospf, &p);
1974 }
1975 else if (type5 && type7 == NULL)
1976 {
1977 /* find the type-7 from which supplied type-5 was translated,
1978 * ie find first type-7 with same LSA Id.
1979 */
paul1eb8ef22005-04-07 07:30:20 +00001980 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00001981 struct route_node *rn;
1982 struct ospf_lsa *lsa;
1983 struct ospf_area *area;
1984
paul1eb8ef22005-04-07 07:30:20 +00001985 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00001986 {
1987 if (area->external_routing != OSPF_AREA_NSSA
1988 && !type7)
1989 continue;
1990
1991 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
1992 {
1993 if (lsa->data->id.s_addr == type5->data->id.s_addr)
1994 {
1995 type7 = lsa;
1996 break;
1997 }
1998 }
1999 }
2000 }
2001
2002 /* do we have type7? */
2003 if (!type7)
2004 {
2005 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002006 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00002007 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00002008 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00002009 return NULL;
2010 }
2011
2012 /* do we have valid translated type5? */
2013 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
2014 {
2015 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002016 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00002017 "found for Type-7 with Id %s",
2018 inet_ntoa (type7->data->id));
2019 return NULL;
2020 }
2021
2022 /* Delete LSA from neighbor retransmit-list. */
2023 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
2024
2025 /* create new translated LSA */
2026 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
2027 {
2028 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002029 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00002030 "Type-7 for %s to Type-5",
2031 inet_ntoa (type7->data->id));
2032 return NULL;
2033 }
2034
2035 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
2036 {
2037 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002038 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00002039 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00002040 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00002041 return NULL;
2042 }
2043
2044 /* Flood LSA through area. */
2045 ospf_flood_through_as (ospf, NULL, new);
2046
2047 return new;
2048}
paul718e3742002-12-13 20:15:29 +00002049
2050int
2051is_prefix_default (struct prefix_ipv4 *p)
2052{
2053 struct prefix_ipv4 q;
2054
2055 q.family = AF_INET;
2056 q.prefix.s_addr = 0;
2057 q.prefixlen = 0;
2058
2059 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
2060}
2061
2062/* Originate an AS-external-LSA, install and flood. */
2063struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002064ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00002065{
2066 struct ospf_lsa *new;
2067
2068 /* Added for NSSA project....
2069
2070 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2071 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2072 every area. The Type-7's are flooded to every IR and every ABR; We
2073 install the Type-5 LSDB so that the normal "refresh" code operates
2074 as usual, and flag them as not used during ASE calculations. The
2075 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2076 Address of non-zero.
2077
2078 If an ABR is the elected NSSA translator, following SPF and during
2079 the ABR task it will translate all the scanned Type-7's, with P-bit
2080 ON and not-self generated, and translate to Type-5's throughout the
2081 non-NSSA/STUB AS.
2082
2083 A difference in operation depends whether this ASBR is an ABR
2084 or not. If not an ABR, the P-bit is ON, to indicate that any
2085 elected NSSA-ABR can perform its translation.
2086
2087 If an ABR, the P-bit is OFF; No ABR will perform translation and
2088 this ASBR will flood the Type-5 LSA as usual.
2089
2090 For the case where this ASBR is not an ABR, the ASE calculations
2091 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2092 demonstrate to the user that there are LSA's that belong to any
2093 attached NSSA.
2094
2095 Finally, it just so happens that when the ABR is translating every
2096 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2097 approved Type-5 (translated from Type-7); at the end of translation
2098 if any Translated Type-5's remain unapproved, then they must be
2099 flushed from the AS.
2100
2101 */
2102
2103 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002104 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002105 return NULL;
2106
2107 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002108 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002109 {
2110 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002111 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002112 inet_ntoa (ei->p.prefix));
2113 return NULL;
2114 }
2115
2116 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002117 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002118
2119 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002120 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002121
2122 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002123 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002124
paul718e3742002-12-13 20:15:29 +00002125 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002126 if (ospf->anyNSSA &&
2127 /* stay away from translated LSAs! */
2128 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002129 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002130
2131 /* Debug logging. */
2132 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2133 {
ajse588f212004-12-08 18:12:06 +00002134 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002135 new->data->type, inet_ntoa (new->data->id), new);
2136 ospf_lsa_header_dump (new->data);
2137 }
2138
2139 return new;
2140}
2141
2142/* Originate AS-external-LSA from external info with initial flag. */
2143int
paul68980082003-03-25 05:07:42 +00002144ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002145{
paul68980082003-03-25 05:07:42 +00002146 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002147 struct route_node *rn;
2148 struct external_info *ei;
2149 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002150 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002151
paul68980082003-03-25 05:07:42 +00002152 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002153
2154 /* Originate As-external-LSA from all type of distribute source. */
2155 if ((rt = EXTERNAL_INFO (type)))
2156 for (rn = route_top (rt); rn; rn = route_next (rn))
2157 if ((ei = rn->info) != NULL)
2158 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002159 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002160 zlog_warn ("LSA: AS-external-LSA was not originated.");
2161
2162 return 0;
2163}
2164
paul4dadc292005-05-06 21:37:42 +00002165static struct external_info *
paul020709f2003-04-04 02:44:16 +00002166ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002167{
2168 int type;
2169 struct route_node *rn;
2170 struct prefix_ipv4 p;
2171
2172 p.family = AF_INET;
2173 p.prefix.s_addr = 0;
2174 p.prefixlen = 0;
2175
2176 /* First, lookup redistributed default route. */
2177 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2178 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2179 {
2180 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2181 if (rn != NULL)
2182 {
2183 route_unlock_node (rn);
2184 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002185 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002186 return rn->info;
2187 }
2188 }
2189
2190 return NULL;
2191}
2192
2193int
paul68980082003-03-25 05:07:42 +00002194ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002195{
paul718e3742002-12-13 20:15:29 +00002196 struct prefix_ipv4 p;
2197 struct in_addr nexthop;
2198 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002199 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002200
Paul Jakma4021b602006-05-12 22:55:41 +00002201 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002202
2203 p.family = AF_INET;
2204 p.prefix.s_addr = 0;
2205 p.prefixlen = 0;
2206
Paul Jakma4021b602006-05-12 22:55:41 +00002207 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002208 {
2209 /* If there is no default route via redistribute,
2210 then originate AS-external-LSA with nexthop 0 (self). */
2211 nexthop.s_addr = 0;
2212 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2213 }
2214
paul020709f2003-04-04 02:44:16 +00002215 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002216 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002217
2218 return 0;
2219}
2220
paul645878f2003-04-13 21:42:11 +00002221/* Flush any NSSA LSAs for given prefix */
2222void
2223ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2224{
paul1eb8ef22005-04-07 07:30:20 +00002225 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002226 struct ospf_lsa *lsa;
2227 struct ospf_area *area;
2228
paul1eb8ef22005-04-07 07:30:20 +00002229 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002230 {
paul1eb8ef22005-04-07 07:30:20 +00002231 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002232 {
2233 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2234 ospf->router_id)))
2235 {
2236 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002237 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002238 inet_ntoa (p->prefix), p->prefixlen);
2239 continue;
2240 }
2241 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2242 if (!IS_LSA_MAXAGE (lsa))
2243 {
2244 ospf_refresher_unregister_lsa (ospf, lsa);
2245 ospf_lsa_flush_area (lsa, area);
2246 }
2247 }
paul645878f2003-04-13 21:42:11 +00002248 }
2249}
paul645878f2003-04-13 21:42:11 +00002250
paul718e3742002-12-13 20:15:29 +00002251/* Flush an AS-external-LSA from LSDB and routing domain. */
2252void
paul68980082003-03-25 05:07:42 +00002253ospf_external_lsa_flush (struct ospf *ospf,
2254 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002255 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002256{
2257 struct ospf_lsa *lsa;
2258
2259 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002260 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002261 inet_ntoa (p->prefix), p->prefixlen);
2262
2263 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002264 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002265 {
2266 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002267 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002268 inet_ntoa (p->prefix), p->prefixlen);
2269 return;
2270 }
hassobeebba72004-06-20 21:00:27 +00002271
pauld4a53d52003-07-12 21:30:57 +00002272 /* If LSA is selforiginated, not a translated LSA, and there is
2273 * NSSA area, flush Type-7 LSA's at first.
2274 */
2275 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2276 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002277 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002278
2279 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002280 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002281
2282 /* There must be no self-originated LSA in rtrs_external. */
2283#if 0
2284 /* Remove External route from Zebra. */
2285 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2286#endif
2287
2288 if (!IS_LSA_MAXAGE (lsa))
2289 {
2290 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002291 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002292
2293 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002294 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002295 }
2296
2297 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002298 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002299}
2300
2301void
paul68980082003-03-25 05:07:42 +00002302ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002303{
2304 struct prefix_ipv4 p;
2305 struct external_info *ei;
2306 struct ospf_lsa *lsa;
2307
2308 p.family = AF_INET;
2309 p.prefixlen = 0;
2310 p.prefix.s_addr = 0;
2311
paul020709f2003-04-04 02:44:16 +00002312 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002313 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002314
2315 if (ei)
2316 {
2317 if (lsa)
2318 {
2319 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002320 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002321 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002322 }
2323 else
2324 {
2325 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002326 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002327 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002328 }
2329 }
2330 else
2331 {
2332 if (lsa)
2333 {
2334 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002335 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002336 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002337 }
2338 }
2339}
2340
2341void
paul68980082003-03-25 05:07:42 +00002342ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002343{
2344 struct route_node *rn;
2345 struct external_info *ei;
2346
2347 if (type != DEFAULT_ROUTE)
2348 if (EXTERNAL_INFO(type))
2349 /* Refresh each redistributed AS-external-LSAs. */
2350 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2351 if ((ei = rn->info))
2352 if (!is_prefix_default (&ei->p))
2353 {
2354 struct ospf_lsa *lsa;
2355
paul68980082003-03-25 05:07:42 +00002356 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2357 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002358 else
paul68980082003-03-25 05:07:42 +00002359 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002360 }
2361}
2362
2363/* Refresh AS-external-LSA. */
2364void
paul68980082003-03-25 05:07:42 +00002365ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002366 struct external_info *ei, int force)
2367{
2368 struct ospf_lsa *new;
2369 int changed;
2370
2371 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002372 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002373 {
pauld4a53d52003-07-12 21:30:57 +00002374 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002375 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002376 "redist check fail",
2377 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002378 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002379 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +00002380 return;
2381 }
2382
2383 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002384 {
2385 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002386 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002387 lsa->data->type, inet_ntoa (lsa->data->id));
2388 return;
2389 }
paul718e3742002-12-13 20:15:29 +00002390
2391 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002392 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002393
2394 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002395 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002396
paul68980082003-03-25 05:07:42 +00002397 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002398
2399 if (new == NULL)
2400 {
2401 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002402 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002403 inet_ntoa (lsa->data->id));
2404 return;
2405 }
2406
2407 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2408
paul68980082003-03-25 05:07:42 +00002409 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002410
2411 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002412 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002413
paul718e3742002-12-13 20:15:29 +00002414 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002415 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002416 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002417
pauld4a53d52003-07-12 21:30:57 +00002418 /* Register self-originated LSA to refresh queue.
2419 * Translated LSAs should not be registered, but refreshed upon
2420 * refresh of the Type-7
2421 */
2422 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2423 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002424
2425 /* Debug logging. */
2426 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2427 {
ajse588f212004-12-08 18:12:06 +00002428 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002429 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002430 ospf_lsa_header_dump (new->data);
2431 }
2432
2433 return;
2434}
2435
2436
2437/* LSA installation functions. */
2438
2439/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002440static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002441ospf_router_lsa_install (struct ospf *ospf,
2442 struct ospf_lsa *new, int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002443{
2444 struct ospf_area *area = new->area;
2445
2446 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2447 The entire routing table must be recalculated, starting with
2448 the shortest path calculations for each area (not just the
2449 area whose link-state database has changed).
2450 */
2451 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002452 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002453
Joakim Tjernlundbd246242009-01-05 17:44:46 +01002454 /* Only install LSA if it is originated/refreshed by us.
2455 * If LSA was received by flooding, the RECEIVED flag is set so do
2456 * not link the LSA */
2457 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
paul718e3742002-12-13 20:15:29 +00002458 {
2459 /* Set router-LSA refresh timer. */
2460 OSPF_TIMER_OFF (area->t_router_lsa_self);
2461 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
pauld4a53d52003-07-12 21:30:57 +00002462 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
paul718e3742002-12-13 20:15:29 +00002463
2464 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002465 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002466 area->router_lsa_self = ospf_lsa_lock (new);
2467
2468 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002469 zlog_debug("LSA[Type%d]: ID %s seq 0x%x is self-originated",
paul0c2be262004-05-31 14:16:54 +00002470 new->data->type, inet_ntoa (new->data->id),
2471 ntohl(new->data->ls_seqnum));
paul718e3742002-12-13 20:15:29 +00002472 }
2473
2474 return new;
2475}
2476
2477#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2478 if (!(T)) \
2479 (T) = thread_add_timer (master, (F), oi, (V))
2480
2481/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002482static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002483ospf_network_lsa_install (struct ospf *ospf,
2484 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002485 struct ospf_lsa *new,
2486 int rt_recalc)
2487{
2488
2489 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2490 The entire routing table must be recalculated, starting with
2491 the shortest path calculations for each area (not just the
2492 area whose link-state database has changed).
2493 */
2494 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002495 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002496
2497 /* We supposed that when LSA is originated by us, we pass the int
2498 for which it was originated. If LSA was received by flooding,
2499 the RECEIVED flag is set, so we do not link the LSA to the int. */
2500 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2501 {
2502 /* Set LSRefresh timer. */
2503 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2504
2505 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2506 ospf_network_lsa_refresh_timer,
2507 OSPF_LS_REFRESH_TIME);
2508
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002509 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002510 oi->network_lsa_self = ospf_lsa_lock (new);
2511 }
2512
2513 return new;
2514}
2515
2516/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002517static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002518ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2519 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002520{
paul718e3742002-12-13 20:15:29 +00002521 if (rt_recalc && !IS_LSA_SELF (new))
2522 {
2523 /* RFC 2328 Section 13.2 Summary-LSAs
2524 The best route to the destination described by the summary-
2525 LSA must be recalculated (see Section 16.5). If this
2526 destination is an AS boundary router, it may also be
2527 necessary to re-examine all the AS-external-LSAs.
2528 */
2529
2530#if 0
2531 /* This doesn't exist yet... */
2532 ospf_summary_incremental_update(new); */
2533#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002534 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002535#endif /* #if 0 */
2536
2537 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002538 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002539 }
2540
2541 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002542 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002543
2544 return new;
2545}
2546
2547/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002548static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002549ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2550 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002551{
2552 if (rt_recalc && !IS_LSA_SELF (new))
2553 {
2554 /* RFC 2328 Section 13.2 Summary-LSAs
2555 The best route to the destination described by the summary-
2556 LSA must be recalculated (see Section 16.5). If this
2557 destination is an AS boundary router, it may also be
2558 necessary to re-examine all the AS-external-LSAs.
2559 */
2560#if 0
2561 /* These don't exist yet... */
2562 ospf_summary_incremental_update(new);
2563 /* Isn't this done by the above call?
2564 - RFC 2328 Section 16.5 implies it should be */
2565 /* ospf_ase_calculate_schedule(); */
2566#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002567 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002568#endif /* #if 0 */
2569 }
2570
2571 /* register LSA to refresh-list. */
2572 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002573 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002574
2575 return new;
2576}
2577
2578/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002579static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002580ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2581 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002582{
paul68980082003-03-25 05:07:42 +00002583 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002584 /* If LSA is not self-originated, calculate an external route. */
2585 if (rt_recalc)
2586 {
2587 /* RFC 2328 Section 13.2 AS-external-LSAs
2588 The best route to the destination described by the AS-
2589 external-LSA must be recalculated (see Section 16.6).
2590 */
2591
2592 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002593 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002594 }
2595
pauld4a53d52003-07-12 21:30:57 +00002596 if (new->data->type == OSPF_AS_NSSA_LSA)
2597 {
2598 /* There is no point to register selforiginate Type-7 LSA for
2599 * refreshing. We rely on refreshing Type-5 LSA's
2600 */
2601 if (IS_LSA_SELF (new))
2602 return new;
2603 else
2604 {
2605 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2606 * New translations will be taken care of by the abr_task.
2607 */
2608 ospf_translated_nssa_refresh (ospf, new, NULL);
2609 }
2610 }
pauld7480322003-05-16 17:31:51 +00002611
pauld4a53d52003-07-12 21:30:57 +00002612 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002613 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002614 */
hassobeebba72004-06-20 21:00:27 +00002615 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002616 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002617
2618 return new;
2619}
2620
2621void
paul68980082003-03-25 05:07:42 +00002622ospf_discard_from_db (struct ospf *ospf,
2623 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002624{
2625 struct ospf_lsa *old;
2626
Paul Jakmaac904de2006-06-15 12:04:57 +00002627 if (!lsdb)
2628 {
2629 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2630 if (!lsa)
2631 zlog_warn ("%s: and NULL LSA!", __func__);
2632 else
2633 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2634 lsa->data->type, inet_ntoa (lsa->data->id));
2635 return;
2636 }
2637
paul718e3742002-12-13 20:15:29 +00002638 old = ospf_lsdb_lookup (lsdb, lsa);
2639
2640 if (!old)
2641 return;
2642
2643 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002644 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002645
2646 switch (old->data->type)
2647 {
2648 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002649 ospf_ase_unregister_external_lsa (old, ospf);
2650 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2651 break;
paul718e3742002-12-13 20:15:29 +00002652#ifdef HAVE_OPAQUE_LSA
2653 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002654 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002655 break;
paul69310a62005-05-11 18:09:59 +00002656#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002657 case OSPF_AS_NSSA_LSA:
2658 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2659 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002660 break;
paul718e3742002-12-13 20:15:29 +00002661 default:
paul68980082003-03-25 05:07:42 +00002662 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002663 break;
2664 }
2665
paul68980082003-03-25 05:07:42 +00002666 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002667 ospf_lsa_discard (old);
2668}
2669
paul718e3742002-12-13 20:15:29 +00002670struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002671ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2672 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002673{
2674 struct ospf_lsa *new = NULL;
2675 struct ospf_lsa *old = NULL;
2676 struct ospf_lsdb *lsdb = NULL;
2677 int rt_recalc;
2678
2679 /* Set LSDB. */
2680 switch (lsa->data->type)
2681 {
paulf2c80652002-12-13 21:44:27 +00002682 /* kevinm */
2683 case OSPF_AS_NSSA_LSA:
2684 if (lsa->area)
2685 lsdb = lsa->area->lsdb;
2686 else
paul68980082003-03-25 05:07:42 +00002687 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002688 break;
paul718e3742002-12-13 20:15:29 +00002689 case OSPF_AS_EXTERNAL_LSA:
2690#ifdef HAVE_OPAQUE_LSA
2691 case OSPF_OPAQUE_AS_LSA:
2692#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002693 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002694 break;
2695 default:
2696 lsdb = lsa->area->lsdb;
2697 break;
2698 }
2699
paul718e3742002-12-13 20:15:29 +00002700 assert (lsdb);
2701
2702 /* RFC 2328 13.2. Installing LSAs in the database
2703
2704 Installing a new LSA in the database, either as the result of
2705 flooding or a newly self-originated LSA, may cause the OSPF
2706 routing table structure to be recalculated. The contents of the
2707 new LSA should be compared to the old instance, if present. If
2708 there is no difference, there is no need to recalculate the
2709 routing table. When comparing an LSA to its previous instance,
2710 the following are all considered to be differences in contents:
2711
2712 o The LSA's Options field has changed.
2713
2714 o One of the LSA instances has LS age set to MaxAge, and
2715 the other does not.
2716
2717 o The length field in the LSA header has changed.
2718
2719 o The body of the LSA (i.e., anything outside the 20-byte
2720 LSA header) has changed. Note that this excludes changes
2721 in LS Sequence Number and LS Checksum.
2722
2723 */
2724 /* Look up old LSA and determine if any SPF calculation or incremental
2725 update is needed */
2726 old = ospf_lsdb_lookup (lsdb, lsa);
2727
2728 /* Do comparision and record if recalc needed. */
2729 rt_recalc = 0;
2730 if ( old == NULL || ospf_lsa_different(old, lsa))
2731 rt_recalc = 1;
2732
paul7ddf1d62003-10-13 09:06:46 +00002733 /*
2734 Sequence number check (Section 14.1 of rfc 2328)
2735 "Premature aging is used when it is time for a self-originated
2736 LSA's sequence number field to wrap. At this point, the current
2737 LSA instance (having LS sequence number MaxSequenceNumber) must
2738 be prematurely aged and flushed from the routing domain before a
2739 new instance with sequence number equal to InitialSequenceNumber
2740 can be originated. "
2741 */
2742
Paul Jakmac2b478d2006-03-30 14:16:11 +00002743 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002744 {
2745 if (ospf_lsa_is_self_originated(ospf, lsa))
2746 {
paul0c2be262004-05-31 14:16:54 +00002747 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2748
2749 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002750 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2751 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2752
2753 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2754 {
ajse588f212004-12-08 18:12:06 +00002755 zlog_debug ("ospf_lsa_install() Premature Aging "
paul7ddf1d62003-10-13 09:06:46 +00002756 "lsa 0x%lx", (u_long)lsa);
2757 ospf_lsa_header_dump (lsa->data);
2758 }
2759 }
2760 else
2761 {
2762 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2763 {
ajse588f212004-12-08 18:12:06 +00002764 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002765 "that was not self originated. Ignoring\n");
2766 ospf_lsa_header_dump (lsa->data);
2767 }
2768 return old;
2769 }
2770 }
2771
paul718e3742002-12-13 20:15:29 +00002772 /* discard old LSA from LSDB */
2773 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002774 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002775
paul718e3742002-12-13 20:15:29 +00002776 /* Calculate Checksum if self-originated?. */
2777 if (IS_LSA_SELF (lsa))
2778 ospf_lsa_checksum (lsa->data);
2779
hassofe71a972004-12-22 16:16:02 +00002780 /* Insert LSA to LSDB. */
2781 ospf_lsdb_add (lsdb, lsa);
2782 lsa->lsdb = lsdb;
2783
paul718e3742002-12-13 20:15:29 +00002784 /* Do LSA specific installation process. */
2785 switch (lsa->data->type)
2786 {
2787 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002788 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002789 break;
2790 case OSPF_NETWORK_LSA:
2791 assert (oi);
paul68980082003-03-25 05:07:42 +00002792 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002793 break;
2794 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002795 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002796 break;
2797 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002798 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002799 break;
2800 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002801 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002802 break;
2803#ifdef HAVE_OPAQUE_LSA
2804 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002805 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002806 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002807 else
paul68980082003-03-25 05:07:42 +00002808 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002809 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002810 case OSPF_OPAQUE_AREA_LSA:
2811 case OSPF_OPAQUE_AS_LSA:
2812 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2813 break;
2814#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002815 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002816 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002817 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002818 break;
2819 }
2820
2821 if (new == NULL)
2822 return new; /* Installation failed, cannot proceed further -- endo. */
2823
2824 /* Debug logs. */
2825 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2826 {
2827 char area_str[INET_ADDRSTRLEN];
2828
2829 switch (lsa->data->type)
2830 {
2831 case OSPF_AS_EXTERNAL_LSA:
2832#ifdef HAVE_OPAQUE_LSA
2833 case OSPF_OPAQUE_AS_LSA:
2834#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002835 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002836 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002837 dump_lsa_key (new),
2838 LOOKUP (ospf_lsa_type_msg, new->data->type));
2839 break;
2840 default:
2841 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002842 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002843 dump_lsa_key (new),
2844 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2845 break;
2846 }
2847 }
2848
paul7ddf1d62003-10-13 09:06:46 +00002849 /*
2850 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2851 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2852 */
2853 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2854 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002855 {
paul7ddf1d62003-10-13 09:06:46 +00002856 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002857 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002858 new->data->type,
2859 inet_ntoa (new->data->id),
2860 lsa);
paul68980082003-03-25 05:07:42 +00002861 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002862 }
2863
2864 return new;
2865}
2866
2867
paul4dadc292005-05-06 21:37:42 +00002868static int
paul68980082003-03-25 05:07:42 +00002869ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002870{
paul1eb8ef22005-04-07 07:30:20 +00002871 struct listnode *node, *nnode;
2872 struct ospf_interface *oi;
2873
2874 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002875 {
paul718e3742002-12-13 20:15:29 +00002876 struct route_node *rn;
2877 struct ospf_neighbor *nbr;
2878
2879 if (ospf_if_is_enable (oi))
2880 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2881 if ((nbr = rn->info) != NULL)
2882 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2883 {
2884 route_unlock_node (rn);
2885 return 0;
2886 }
2887 }
2888
2889 return 1;
2890}
2891
2892
2893#ifdef ORIGINAL_CODING
2894/* This function flood the maxaged LSA to DR. */
2895void
2896ospf_maxage_flood (struct ospf_lsa *lsa)
2897{
2898 switch (lsa->data->type)
2899 {
2900 case OSPF_ROUTER_LSA:
2901 case OSPF_NETWORK_LSA:
2902 case OSPF_SUMMARY_LSA:
2903 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00002904 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00002905#ifdef HAVE_OPAQUE_LSA
2906 case OSPF_OPAQUE_LINK_LSA:
2907 case OSPF_OPAQUE_AREA_LSA:
2908#endif /* HAVE_OPAQUE_LSA */
2909 ospf_flood_through_area (lsa->area, NULL, lsa);
2910 break;
2911 case OSPF_AS_EXTERNAL_LSA:
2912#ifdef HAVE_OPAQUE_LSA
2913 case OSPF_OPAQUE_AS_LSA:
2914#endif /* HAVE_OPAQUE_LSA */
2915 ospf_flood_through_as (NULL, lsa);
2916 break;
2917 default:
2918 break;
2919 }
2920}
2921#endif /* ORIGINAL_CODING */
2922
paul4dadc292005-05-06 21:37:42 +00002923static int
paul718e3742002-12-13 20:15:29 +00002924ospf_maxage_lsa_remover (struct thread *thread)
2925{
paul68980082003-03-25 05:07:42 +00002926 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002927 struct ospf_lsa *lsa;
2928 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002929 int reschedule = 0;
2930
paul68980082003-03-25 05:07:42 +00002931 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002932
2933 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002934 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002935
paul68980082003-03-25 05:07:42 +00002936 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002937
2938 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002939 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002940 {
paul718e3742002-12-13 20:15:29 +00002941 if (lsa->retransmit_counter > 0)
2942 {
2943 reschedule = 1;
2944 continue;
2945 }
2946
2947 /* Remove LSA from the LSDB */
2948 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2949 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002950 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
paul7ddf1d62003-10-13 09:06:46 +00002951 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002952
2953 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002954 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002955 lsa->data->type, inet_ntoa (lsa->data->id));
2956
2957 /* Flood max age LSA. */
2958#ifdef ORIGINAL_CODING
2959 ospf_maxage_flood (lsa);
2960#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00002961 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00002962#endif /* ORIGINAL_CODING */
2963
paul7ddf1d62003-10-13 09:06:46 +00002964 if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
2965 {
2966 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002967 zlog_debug ("originating new router lsa for lsa 0x%lx \n",
paul7ddf1d62003-10-13 09:06:46 +00002968 (u_long)lsa);
2969 ospf_router_lsa_originate(lsa->area);
2970 }
2971
paul718e3742002-12-13 20:15:29 +00002972 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002973 if (lsa->lsdb)
2974 {
2975 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2976 ospf_lsdb_delete (lsa->lsdb, lsa);
2977 }
2978 else
2979 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2980 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002981 }
2982
2983 /* A MaxAge LSA must be removed immediately from the router's link
2984 state database as soon as both a) it is no longer contained on any
2985 neighbor Link state retransmission lists and b) none of the router's
2986 neighbors are in states Exchange or Loading. */
2987 if (reschedule)
paul68980082003-03-25 05:07:42 +00002988 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00002989
2990 return 0;
2991}
2992
paul4dadc292005-05-06 21:37:42 +00002993static int
paul68980082003-03-25 05:07:42 +00002994ospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new)
paul718e3742002-12-13 20:15:29 +00002995{
hasso52dc7ee2004-09-23 19:18:23 +00002996 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00002997 struct ospf_lsa *lsa;
2998
2999 for (ALL_LIST_ELEMENTS_RO (ospf->maxage_lsa, node, lsa))
3000 if (lsa == new)
paul718e3742002-12-13 20:15:29 +00003001 return 1;
3002
3003 return 0;
3004}
3005
3006void
paul68980082003-03-25 05:07:42 +00003007ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003008{
hasso52dc7ee2004-09-23 19:18:23 +00003009 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003010
paul68980082003-03-25 05:07:42 +00003011 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00003012 {
paul68980082003-03-25 05:07:42 +00003013 list_delete_node (ospf->maxage_lsa, n);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003014 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +00003015 }
3016}
3017
3018void
paul68980082003-03-25 05:07:42 +00003019ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003020{
3021 /* When we saw a MaxAge LSA flooded to us, we put it on the list
3022 and schedule the MaxAge LSA remover. */
paul68980082003-03-25 05:07:42 +00003023 if (ospf_lsa_maxage_exist (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003024 {
3025 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003026 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00003027 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
3028 return;
3029 }
3030
paul68980082003-03-25 05:07:42 +00003031 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00003032
3033 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003034 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003035
paul68980082003-03-25 05:07:42 +00003036 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003037}
3038
paul4dadc292005-05-06 21:37:42 +00003039static int
paul68980082003-03-25 05:07:42 +00003040ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003041{
paul718e3742002-12-13 20:15:29 +00003042 /* Stay away from any Local Translated Type-7 LSAs */
3043 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3044 return 0;
paul718e3742002-12-13 20:15:29 +00003045
3046 if (IS_LSA_MAXAGE (lsa))
3047 /* Self-originated LSAs should NOT time-out instead,
3048 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00003049 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003050 {
3051 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003052 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003053
3054 switch (lsa->data->type)
3055 {
paul718e3742002-12-13 20:15:29 +00003056#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00003057 case OSPF_OPAQUE_LINK_LSA:
3058 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003059 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003060 /*
3061 * As a general rule, whenever network topology has changed
3062 * (due to an LSA removal in this case), routing recalculation
3063 * should be triggered. However, this is not true for opaque
3064 * LSAs. Even if an opaque LSA instance is going to be removed
3065 * from the routing domain, it does not mean a change in network
3066 * topology, and thus, routing recalculation is not needed here.
3067 */
3068 break;
paul718e3742002-12-13 20:15:29 +00003069#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00003070 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003071 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003072 ospf_ase_incremental_update (ospf, lsa);
3073 break;
paul718e3742002-12-13 20:15:29 +00003074 default:
paul68980082003-03-25 05:07:42 +00003075 ospf_spf_calculate_schedule (ospf);
3076 break;
paul718e3742002-12-13 20:15:29 +00003077 }
paul68980082003-03-25 05:07:42 +00003078 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003079 }
3080
3081 return 0;
3082}
3083
3084/* Periodical check of MaxAge LSA. */
3085int
paul68980082003-03-25 05:07:42 +00003086ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003087{
paul68980082003-03-25 05:07:42 +00003088 struct ospf *ospf = THREAD_ARG (thread);
3089 struct route_node *rn;
3090 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003091 struct ospf_area *area;
3092 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003093
paul68980082003-03-25 05:07:42 +00003094 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003095
paul1eb8ef22005-04-07 07:30:20 +00003096 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003097 {
paul68980082003-03-25 05:07:42 +00003098 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3099 ospf_lsa_maxage_walker_remover (ospf, lsa);
3100 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3101 ospf_lsa_maxage_walker_remover (ospf, lsa);
3102 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3103 ospf_lsa_maxage_walker_remover (ospf, lsa);
3104 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3105 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003106#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003107 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3108 ospf_lsa_maxage_walker_remover (ospf, lsa);
3109 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3110 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003111#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003112 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3113 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003114 }
3115
paul4fb949e2003-05-10 20:06:51 +00003116 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003117 if (ospf->lsdb)
3118 {
3119 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3120 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003121#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003122 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3123 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003124#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003125 }
paul718e3742002-12-13 20:15:29 +00003126
paul68980082003-03-25 05:07:42 +00003127 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3128 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003129 return 0;
3130}
3131
paul68980082003-03-25 05:07:42 +00003132struct ospf_lsa *
3133ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3134 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003135{
paul68980082003-03-25 05:07:42 +00003136 struct ospf_lsa *lsa;
3137 struct in_addr mask, id;
3138 struct lsa_header_mask
3139 {
3140 struct lsa_header header;
3141 struct in_addr mask;
3142 } *hmask;
paul718e3742002-12-13 20:15:29 +00003143
paul68980082003-03-25 05:07:42 +00003144 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3145 if (lsa == NULL)
3146 return NULL;
paul718e3742002-12-13 20:15:29 +00003147
paul68980082003-03-25 05:07:42 +00003148 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003149
paul68980082003-03-25 05:07:42 +00003150 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003151
paul68980082003-03-25 05:07:42 +00003152 if (mask.s_addr != hmask->mask.s_addr)
3153 {
3154 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3155 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3156 if (!lsa)
3157 return NULL;
3158 }
paul718e3742002-12-13 20:15:29 +00003159
paul68980082003-03-25 05:07:42 +00003160 return lsa;
paul718e3742002-12-13 20:15:29 +00003161}
3162
3163struct ospf_lsa *
3164ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3165 struct in_addr id, struct in_addr adv_router)
3166{
paule05fba42003-04-13 20:20:53 +00003167 struct ospf *ospf = ospf_lookup();
3168 assert(ospf);
3169
paul718e3742002-12-13 20:15:29 +00003170 switch (type)
3171 {
3172 case OSPF_ROUTER_LSA:
3173 case OSPF_NETWORK_LSA:
3174 case OSPF_SUMMARY_LSA:
3175 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003176 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003177#ifdef HAVE_OPAQUE_LSA
3178 case OSPF_OPAQUE_LINK_LSA:
3179 case OSPF_OPAQUE_AREA_LSA:
3180#endif /* HAVE_OPAQUE_LSA */
3181 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003182 case OSPF_AS_EXTERNAL_LSA:
3183#ifdef HAVE_OPAQUE_LSA
3184 case OSPF_OPAQUE_AS_LSA:
3185#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003186 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003187 default:
3188 break;
3189 }
3190
3191 return NULL;
3192}
3193
3194struct ospf_lsa *
3195ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3196 struct in_addr id)
3197{
3198 struct ospf_lsa *lsa;
3199 struct route_node *rn;
3200
3201 switch (type)
3202 {
3203 case OSPF_ROUTER_LSA:
3204 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003205 case OSPF_NETWORK_LSA:
3206 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3207 if ((lsa = rn->info))
3208 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3209 {
3210 route_unlock_node (rn);
3211 return lsa;
3212 }
3213 break;
3214 case OSPF_SUMMARY_LSA:
3215 case OSPF_ASBR_SUMMARY_LSA:
3216 /* Currently not used. */
3217 assert (1);
3218 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003219 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003220 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003221#ifdef HAVE_OPAQUE_LSA
3222 case OSPF_OPAQUE_LINK_LSA:
3223 case OSPF_OPAQUE_AREA_LSA:
3224 case OSPF_OPAQUE_AS_LSA:
3225 /* Currently not used. */
3226 break;
3227#endif /* HAVE_OPAQUE_LSA */
3228 default:
3229 break;
3230 }
3231
3232 return NULL;
3233}
3234
3235struct ospf_lsa *
3236ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3237{
3238 struct ospf_lsa *match;
3239
3240#ifdef HAVE_OPAQUE_LSA
3241 /*
3242 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3243 * is redefined to have two subfields; opaque-type and opaque-id.
3244 * However, it is harmless to treat the two sub fields together, as if
3245 * they two were forming a unique LSA-ID.
3246 */
3247#endif /* HAVE_OPAQUE_LSA */
3248
3249 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3250
3251 if (match == NULL)
3252 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003253 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003254 lsah->type, inet_ntoa (lsah->id));
3255
3256 return match;
3257}
3258
3259/* return +n, l1 is more recent.
3260 return -n, l2 is more recent.
3261 return 0, l1 and l2 is identical. */
3262int
3263ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3264{
3265 int r;
3266 int x, y;
3267
3268 if (l1 == NULL && l2 == NULL)
3269 return 0;
3270 if (l1 == NULL)
3271 return -1;
3272 if (l2 == NULL)
3273 return 1;
3274
3275 /* compare LS sequence number. */
3276 x = (int) ntohl (l1->data->ls_seqnum);
3277 y = (int) ntohl (l2->data->ls_seqnum);
3278 if (x > y)
3279 return 1;
3280 if (x < y)
3281 return -1;
3282
3283 /* compare LS checksum. */
3284 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3285 if (r)
3286 return r;
3287
3288 /* compare LS age. */
3289 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3290 return 1;
3291 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3292 return -1;
3293
3294 /* compare LS age with MaxAgeDiff. */
3295 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3296 return -1;
3297 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3298 return 1;
3299
3300 /* LSAs are identical. */
3301 return 0;
3302}
3303
3304/* If two LSAs are different, return 1, otherwise return 0. */
3305int
3306ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3307{
3308 char *p1, *p2;
3309 assert (l1);
3310 assert (l2);
3311 assert (l1->data);
3312 assert (l2->data);
3313
3314 if (l1->data->options != l2->data->options)
3315 return 1;
3316
3317 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3318 return 1;
3319
3320 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3321 return 1;
3322
3323 if (l1->data->length != l2->data->length)
3324 return 1;
3325
3326 if (l1->data->length == 0)
3327 return 1;
3328
pauld1825832003-04-03 01:27:01 +00003329 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003330
3331 p1 = (char *) l1->data;
3332 p2 = (char *) l2->data;
3333
3334 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3335 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3336 return 1;
3337
3338 return 0;
3339}
3340
3341#ifdef ORIGINAL_CODING
3342void
3343ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3344 struct ospf_lsa *self,
3345 struct ospf_lsa *new)
3346{
3347 u_int32_t seqnum;
3348
3349 /* Adjust LS Sequence Number. */
3350 seqnum = ntohl (new->data->ls_seqnum) + 1;
3351 self->data->ls_seqnum = htonl (seqnum);
3352
3353 /* Recalculate LSA checksum. */
3354 ospf_lsa_checksum (self->data);
3355
3356 /* Reflooding LSA. */
3357 /* RFC2328 Section 13.3
3358 On non-broadcast networks, separate Link State Update
3359 packets must be sent, as unicasts, to each adjacent neighbor
3360 (i.e., those in state Exchange or greater). The destination
3361 IP addresses for these packets are the neighbors' IP
3362 addresses. */
3363 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3364 {
3365 struct route_node *rn;
3366 struct ospf_neighbor *onbr;
3367
3368 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3369 if ((onbr = rn->info) != NULL)
3370 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3371 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3372 }
3373 else
3374 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3375
3376 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003377 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003378 self->data->type, inet_ntoa (self->data->id));
3379}
3380#else /* ORIGINAL_CODING */
3381static int
paul68980082003-03-25 05:07:42 +00003382ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003383{
3384 if (lsa == NULL || !IS_LSA_SELF (lsa))
3385 return 0;
3386
3387 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003388 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 +00003389
3390 /* Force given lsa's age to MaxAge. */
3391 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3392
3393 switch (lsa->data->type)
3394 {
3395#ifdef HAVE_OPAQUE_LSA
3396 case OSPF_OPAQUE_LINK_LSA:
3397 case OSPF_OPAQUE_AREA_LSA:
3398 case OSPF_OPAQUE_AS_LSA:
3399 ospf_opaque_lsa_refresh (lsa);
3400 break;
3401#endif /* HAVE_OPAQUE_LSA */
3402 default:
paul68980082003-03-25 05:07:42 +00003403 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003404 break;
3405 }
3406
3407 return 0;
3408}
3409
3410void
paul68980082003-03-25 05:07:42 +00003411ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003412{
paul1eb8ef22005-04-07 07:30:20 +00003413 struct listnode *node, *nnode;
3414 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003415 struct ospf_area *area;
3416 struct ospf_interface *oi;
3417 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003418 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003419 int need_to_flush_ase = 0;
3420
paul1eb8ef22005-04-07 07:30:20 +00003421 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003422 {
paul718e3742002-12-13 20:15:29 +00003423 if ((lsa = area->router_lsa_self) != NULL)
3424 {
3425 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003426 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 +00003427
3428 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003429 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003430 area->router_lsa_self = NULL;
3431 OSPF_TIMER_OFF (area->t_router_lsa_self);
3432 }
3433
paul1eb8ef22005-04-07 07:30:20 +00003434 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003435 {
paul718e3742002-12-13 20:15:29 +00003436 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003437 && oi->state == ISM_DR
3438 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003439 {
3440 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003441 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00003442
3443 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003444 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003445 oi->network_lsa_self = NULL;
3446 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3447 }
3448
3449 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3450 && area->external_routing == OSPF_AREA_DEFAULT)
3451 need_to_flush_ase = 1;
3452 }
3453
paul68980082003-03-25 05:07:42 +00003454 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3455 ospf_lsa_flush_schedule (ospf, lsa);
3456 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3457 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003458#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003459 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3460 ospf_lsa_flush_schedule (ospf, lsa);
3461 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3462 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003463#endif /* HAVE_OPAQUE_LSA */
3464 }
3465
3466 if (need_to_flush_ase)
3467 {
paul68980082003-03-25 05:07:42 +00003468 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3469 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003470#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003471 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3472 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003473#endif /* HAVE_OPAQUE_LSA */
3474 }
3475
3476 /*
3477 * Make sure that the MaxAge LSA remover is executed immediately,
3478 * without conflicting to other threads.
3479 */
paul68980082003-03-25 05:07:42 +00003480 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003481 {
paul68980082003-03-25 05:07:42 +00003482 OSPF_TIMER_OFF (ospf->t_maxage);
3483 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003484 }
3485
3486 return;
3487}
3488#endif /* ORIGINAL_CODING */
3489
3490/* If there is self-originated LSA, then return 1, otherwise return 0. */
3491/* An interface-independent version of ospf_lsa_is_self_originated */
3492int
paul68980082003-03-25 05:07:42 +00003493ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003494{
hasso52dc7ee2004-09-23 19:18:23 +00003495 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003496 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003497
3498 /* This LSA is already checked. */
3499 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3500 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3501
3502 /* Make sure LSA is self-checked. */
3503 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3504
3505 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003506 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003507 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3508
3509 /* LSA is router-LSA. */
3510 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003511 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003512 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3513
3514 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3515 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003516 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003517 {
paul718e3742002-12-13 20:15:29 +00003518 /* Ignore virtual link. */
3519 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3520 if (oi->address->family == AF_INET)
3521 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3522 {
3523 /* to make it easier later */
3524 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3525 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3526 }
3527 }
3528
3529 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3530}
3531
3532/* Get unique Link State ID. */
3533struct in_addr
paul68980082003-03-25 05:07:42 +00003534ospf_lsa_unique_id (struct ospf *ospf,
3535 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003536{
3537 struct ospf_lsa *lsa;
3538 struct in_addr mask, id;
3539
3540 id = p->prefix;
3541
3542 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003543 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003544 if (lsa)
3545 {
3546 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3547 if (ip_masklen (al->mask) == p->prefixlen)
3548 {
3549 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003550 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003551 "Can't get Link State ID for %s/%d",
3552 inet_ntoa (p->prefix), p->prefixlen);
3553 /* id.s_addr = 0; */
3554 id.s_addr = 0xffffffff;
3555 return id;
3556 }
3557 /* Masklen differs, then apply wildcard mask to Link State ID. */
3558 else
3559 {
3560 masklen2ip (p->prefixlen, &mask);
3561
3562 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003563 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3564 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003565 if (lsa)
3566 {
3567 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003568 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003569 "Can't get Link State ID for %s/%d",
3570 inet_ntoa (p->prefix), p->prefixlen);
3571 /* id.s_addr = 0; */
3572 id.s_addr = 0xffffffff;
3573 return id;
3574 }
3575 }
3576 }
3577
3578 return id;
3579}
3580
3581
Paul Jakma70461d72006-05-12 22:57:57 +00003582#define LSA_ACTION_FLOOD_AREA 1
3583#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003584
3585struct lsa_action
3586{
3587 u_char action;
3588 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003589 struct ospf_lsa *lsa;
3590};
3591
paul4dadc292005-05-06 21:37:42 +00003592static int
paul718e3742002-12-13 20:15:29 +00003593ospf_lsa_action (struct thread *t)
3594{
3595 struct lsa_action *data;
3596
3597 data = THREAD_ARG (t);
3598
3599 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003600 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003601 data->action);
3602
3603 switch (data->action)
3604 {
paul718e3742002-12-13 20:15:29 +00003605 case LSA_ACTION_FLOOD_AREA:
3606 ospf_flood_through_area (data->area, NULL, data->lsa);
3607 break;
paul718e3742002-12-13 20:15:29 +00003608 case LSA_ACTION_FLUSH_AREA:
3609 ospf_lsa_flush_area (data->lsa, data->area);
3610 break;
paul718e3742002-12-13 20:15:29 +00003611 }
3612
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003613 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003614 XFREE (MTYPE_OSPF_MESSAGE, data);
3615 return 0;
3616}
3617
3618void
3619ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3620{
3621 struct lsa_action *data;
3622
Stephen Hemminger393deb92008-08-18 14:13:29 -07003623 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003624 data->action = LSA_ACTION_FLOOD_AREA;
3625 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003626 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003627
3628 thread_add_event (master, ospf_lsa_action, data, 0);
3629}
3630
3631void
3632ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3633{
3634 struct lsa_action *data;
3635
Stephen Hemminger393deb92008-08-18 14:13:29 -07003636 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003637 data->action = LSA_ACTION_FLUSH_AREA;
3638 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003639 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003640
3641 thread_add_event (master, ospf_lsa_action, data, 0);
3642}
3643
3644
3645/* LSA Refreshment functions. */
paul4dadc292005-05-06 21:37:42 +00003646static void
paul68980082003-03-25 05:07:42 +00003647ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003648{
3649 struct external_info *ei;
3650 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3651
3652 switch (lsa->data->type)
3653 {
3654 /* Router and Network LSAs are processed differently. */
3655 case OSPF_ROUTER_LSA:
3656 case OSPF_NETWORK_LSA:
3657 break;
3658 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003659 ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003660 break;
3661 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003662 ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003663 break;
3664 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003665 /* Translated from NSSA Type-5s are refreshed when
3666 * from refresh of Type-7 - do not refresh these directly.
3667 */
3668 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3669 break;
paul718e3742002-12-13 20:15:29 +00003670 ei = ospf_external_info_check (lsa);
3671 if (ei)
pauld4a53d52003-07-12 21:30:57 +00003672 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003673 else
pauld4a53d52003-07-12 21:30:57 +00003674 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003675 break;
3676#ifdef HAVE_OPAQUE_LSA
3677 case OSPF_OPAQUE_LINK_LSA:
3678 case OSPF_OPAQUE_AREA_LSA:
3679 case OSPF_OPAQUE_AS_LSA:
3680 ospf_opaque_lsa_refresh (lsa);
3681 break;
pauld7480322003-05-16 17:31:51 +00003682#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003683 default:
3684 break;
paul718e3742002-12-13 20:15:29 +00003685 }
3686}
3687
3688void
paul68980082003-03-25 05:07:42 +00003689ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003690{
3691 u_int16_t index, current_index;
3692
3693 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3694
3695 if (lsa->refresh_list < 0)
3696 {
3697 int delay;
3698
3699 if (LS_AGE (lsa) == 0 &&
3700 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3701 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3702 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3703 else
3704 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3705 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3706 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3707
3708 if (delay < 0)
3709 delay = 0;
3710
paul68980082003-03-25 05:07:42 +00003711 current_index = ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003712 (quagga_time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003713
3714 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3715 % (OSPF_LSA_REFRESHER_SLOTS);
3716
3717 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003718 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003719 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003720 if (!ospf->lsa_refresh_queue.qs[index])
3721 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003722 listnode_add (ospf->lsa_refresh_queue.qs[index],
3723 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003724 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003725 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003726 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003727 "setting refresh_list on lsa %p (slod %d)",
3728 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003729 }
3730}
3731
3732void
paul68980082003-03-25 05:07:42 +00003733ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003734{
3735 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3736 if (lsa->refresh_list >= 0)
3737 {
hasso52dc7ee2004-09-23 19:18:23 +00003738 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003739 listnode_delete (refresh_list, lsa);
3740 if (!listcount (refresh_list))
3741 {
3742 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003743 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003744 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003745 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003746 lsa->refresh_list = -1;
3747 }
3748}
3749
3750int
3751ospf_lsa_refresh_walker (struct thread *t)
3752{
hasso52dc7ee2004-09-23 19:18:23 +00003753 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003754 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003755 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003756 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003757 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003758 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003759
3760 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003761 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003762
3763
paul68980082003-03-25 05:07:42 +00003764 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003765
ajs9dbc7972005-03-13 19:27:22 +00003766 /* Note: if clock has jumped backwards, then time change could be negative,
3767 so we are careful to cast the expression to unsigned before taking
3768 modulus. */
paul68980082003-03-25 05:07:42 +00003769 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003770 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003771 (quagga_time (NULL) - ospf->lsa_refresher_started) /
ajs9dbc7972005-03-13 19:27:22 +00003772 OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003773
3774 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003775 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003776 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003777
paul68980082003-03-25 05:07:42 +00003778 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003779 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3780 {
3781 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003782 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003783 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003784
paul68980082003-03-25 05:07:42 +00003785 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003786
paul68980082003-03-25 05:07:42 +00003787 ospf->lsa_refresh_queue.qs [i] = NULL;
3788
paul718e3742002-12-13 20:15:29 +00003789 if (refresh_list)
3790 {
paul1eb8ef22005-04-07 07:30:20 +00003791 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003792 {
paul718e3742002-12-13 20:15:29 +00003793 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003794 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003795 "refresh lsa %p (slot %d)",
3796 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003797
3798 list_delete_node (refresh_list, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003799 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003800 lsa->refresh_list = -1;
3801 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003802 }
3803 list_free (refresh_list);
3804 }
3805 }
3806
paul68980082003-03-25 05:07:42 +00003807 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3808 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003809 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003810
paul1eb8ef22005-04-07 07:30:20 +00003811 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
3812 ospf_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003813
3814 list_delete (lsa_to_refresh);
3815
3816 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003817 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003818
3819 return 0;
3820}
3821