blob: 132a281c7fdb0b8ffda99fd4d651fa8b95e0bf22 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
2 * OSPF Link State Advertisement
3 * Copyright (C) 1999, 2000 Toshiaki Takada
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "linklist.h"
26#include "prefix.h"
27#include "if.h"
28#include "table.h"
29#include "memory.h"
30#include "stream.h"
31#include "log.h"
32#include "thread.h"
33#include "hash.h"
34#include "sockunion.h" /* for inet_aton() */
Jingjing Duan6a270cd2008-08-13 19:09:10 +010035#include "checksum.h"
paul718e3742002-12-13 20:15:29 +000036
37#include "ospfd/ospfd.h"
38#include "ospfd/ospf_interface.h"
39#include "ospfd/ospf_ism.h"
40#include "ospfd/ospf_asbr.h"
41#include "ospfd/ospf_lsa.h"
42#include "ospfd/ospf_lsdb.h"
43#include "ospfd/ospf_neighbor.h"
44#include "ospfd/ospf_nsm.h"
45#include "ospfd/ospf_flood.h"
46#include "ospfd/ospf_packet.h"
47#include "ospfd/ospf_spf.h"
48#include "ospfd/ospf_dump.h"
49#include "ospfd/ospf_route.h"
50#include "ospfd/ospf_ase.h"
51#include "ospfd/ospf_zebra.h"
52
53
54u_int32_t
55get_metric (u_char *metric)
56{
57 u_int32_t m;
58 m = metric[0];
59 m = (m << 8) + metric[1];
60 m = (m << 8) + metric[2];
61 return m;
62}
63
64
65struct timeval
66tv_adjust (struct timeval a)
67{
68 while (a.tv_usec >= 1000000)
69 {
70 a.tv_usec -= 1000000;
71 a.tv_sec++;
72 }
73
74 while (a.tv_usec < 0)
75 {
76 a.tv_usec += 1000000;
77 a.tv_sec--;
78 }
79
80 return a;
81}
82
83int
84tv_ceil (struct timeval a)
85{
86 a = tv_adjust (a);
87
88 return (a.tv_usec ? a.tv_sec + 1 : a.tv_sec);
89}
90
91int
92tv_floor (struct timeval a)
93{
94 a = tv_adjust (a);
95
96 return a.tv_sec;
97}
98
99struct timeval
100int2tv (int a)
101{
102 struct timeval ret;
103
104 ret.tv_sec = a;
105 ret.tv_usec = 0;
106
107 return ret;
108}
109
110struct timeval
111tv_add (struct timeval a, struct timeval b)
112{
113 struct timeval ret;
114
115 ret.tv_sec = a.tv_sec + b.tv_sec;
116 ret.tv_usec = a.tv_usec + b.tv_usec;
117
118 return tv_adjust (ret);
119}
120
121struct timeval
122tv_sub (struct timeval a, struct timeval b)
123{
124 struct timeval ret;
125
126 ret.tv_sec = a.tv_sec - b.tv_sec;
127 ret.tv_usec = a.tv_usec - b.tv_usec;
128
129 return tv_adjust (ret);
130}
131
132int
133tv_cmp (struct timeval a, struct timeval b)
134{
135 return (a.tv_sec == b.tv_sec ?
136 a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
137}
138
139int
140ospf_lsa_refresh_delay (struct ospf_lsa *lsa)
141{
142 struct timeval delta, now;
143 int delay = 0;
144
Paul Jakma2518efd2006-08-27 06:49:29 +0000145 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +0000146 delta = tv_sub (now, lsa->tv_orig);
147
148 if (tv_cmp (delta, int2tv (OSPF_MIN_LS_INTERVAL)) < 0)
149 {
150 delay = tv_ceil (tv_sub (int2tv (OSPF_MIN_LS_INTERVAL), delta));
151
152 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000153 zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
paul718e3742002-12-13 20:15:29 +0000154 lsa->data->type, inet_ntoa (lsa->data->id), delay);
155
156 assert (delay > 0);
157 }
158
159 return delay;
160}
161
162
163int
164get_age (struct ospf_lsa *lsa)
165{
166 int age;
paul718e3742002-12-13 20:15:29 +0000167
Paul Jakma2518efd2006-08-27 06:49:29 +0000168 age = ntohs (lsa->data->ls_age)
169 + tv_floor (tv_sub (recent_relative_time (), lsa->tv_recv));
paul718e3742002-12-13 20:15:29 +0000170
171 return age;
172}
173
174
175/* Fletcher Checksum -- Refer to RFC1008. */
paul718e3742002-12-13 20:15:29 +0000176
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100177/* All the offsets are zero-based. The offsets in the RFC1008 are
178 one-based. */
paul718e3742002-12-13 20:15:29 +0000179u_int16_t
180ospf_lsa_checksum (struct lsa_header *lsa)
181{
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100182 u_char *buffer = (u_char *) &lsa->options;
183 int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */
paul718e3742002-12-13 20:15:29 +0000184
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100185 /* Skip the AGE field */
186 u_int16_t len = ntohs(lsa->length) - options_offset;
paul718e3742002-12-13 20:15:29 +0000187
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100188 /* Checksum offset starts from "options" field, not the beginning of the
189 lsa_header struct. The offset is 14, rather than 16. */
190 int checksum_offset = (u_char *) &lsa->checksum - buffer;
paul718e3742002-12-13 20:15:29 +0000191
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100192 return fletcher_checksum(buffer, len, checksum_offset);
paul718e3742002-12-13 20:15:29 +0000193}
194
195
196
197/* Create OSPF LSA. */
198struct ospf_lsa *
199ospf_lsa_new ()
200{
201 struct ospf_lsa *new;
202
203 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
paul718e3742002-12-13 20:15:29 +0000204
205 new->flags = 0;
206 new->lock = 1;
207 new->retransmit_counter = 0;
Paul Jakma2518efd2006-08-27 06:49:29 +0000208 new->tv_recv = recent_relative_time ();
paul718e3742002-12-13 20:15:29 +0000209 new->tv_orig = new->tv_recv;
210 new->refresh_list = -1;
211
212 return new;
213}
214
215/* Duplicate OSPF LSA. */
216struct ospf_lsa *
217ospf_lsa_dup (struct ospf_lsa *lsa)
218{
219 struct ospf_lsa *new;
220
221 if (lsa == NULL)
222 return NULL;
223
224 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
225
226 memcpy (new, lsa, sizeof (struct ospf_lsa));
227 UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
228 new->lock = 1;
229 new->retransmit_counter = 0;
230 new->data = ospf_lsa_data_dup (lsa->data);
231
paulf2c80652002-12-13 21:44:27 +0000232 /* kevinm: Clear the refresh_list, otherwise there are going
233 to be problems when we try to remove the LSA from the
234 queue (which it's not a member of.)
235 XXX: Should we add the LSA to the refresh_list queue? */
236 new->refresh_list = -1;
237
238 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000239 zlog_debug ("LSA: duplicated %p (new: %p)", lsa, new);
paulf2c80652002-12-13 21:44:27 +0000240
paul718e3742002-12-13 20:15:29 +0000241 return new;
242}
243
244/* Free OSPF LSA. */
245void
246ospf_lsa_free (struct ospf_lsa *lsa)
247{
248 assert (lsa->lock == 0);
249
250 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000251 zlog_debug ("LSA: freed %p", lsa);
paul718e3742002-12-13 20:15:29 +0000252
253 /* Delete LSA data. */
254 if (lsa->data != NULL)
255 ospf_lsa_data_free (lsa->data);
256
257 assert (lsa->refresh_list < 0);
258
259 memset (lsa, 0, sizeof (struct ospf_lsa));
260 XFREE (MTYPE_OSPF_LSA, lsa);
261}
262
263/* Lock LSA. */
264struct ospf_lsa *
265ospf_lsa_lock (struct ospf_lsa *lsa)
266{
267 lsa->lock++;
268 return lsa;
269}
270
271/* Unlock LSA. */
272void
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000273ospf_lsa_unlock (struct ospf_lsa **lsa)
paul718e3742002-12-13 20:15:29 +0000274{
275 /* This is sanity check. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000276 if (!lsa || !*lsa)
paul718e3742002-12-13 20:15:29 +0000277 return;
278
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000279 (*lsa)->lock--;
paul718e3742002-12-13 20:15:29 +0000280
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000281 assert ((*lsa)->lock >= 0);
paul718e3742002-12-13 20:15:29 +0000282
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000283 if ((*lsa)->lock == 0)
paul718e3742002-12-13 20:15:29 +0000284 {
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000285 assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
286 ospf_lsa_free (*lsa);
287 *lsa = NULL;
paul718e3742002-12-13 20:15:29 +0000288 }
289}
290
291/* Check discard flag. */
292void
293ospf_lsa_discard (struct ospf_lsa *lsa)
294{
295 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
296 {
297 SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000298 ospf_lsa_unlock (&lsa);
paul718e3742002-12-13 20:15:29 +0000299 }
300}
301
302/* Create LSA data. */
303struct lsa_header *
304ospf_lsa_data_new (size_t size)
305{
Stephen Hemminger393deb92008-08-18 14:13:29 -0700306 return XCALLOC (MTYPE_OSPF_LSA_DATA, size);
paul718e3742002-12-13 20:15:29 +0000307}
308
309/* Duplicate LSA data. */
310struct lsa_header *
311ospf_lsa_data_dup (struct lsa_header *lsah)
312{
313 struct lsa_header *new;
314
315 new = ospf_lsa_data_new (ntohs (lsah->length));
316 memcpy (new, lsah, ntohs (lsah->length));
317
318 return new;
319}
320
321/* Free LSA data. */
322void
323ospf_lsa_data_free (struct lsa_header *lsah)
324{
325 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000326 zlog_debug ("LSA[Type%d:%s]: data freed %p",
paul718e3742002-12-13 20:15:29 +0000327 lsah->type, inet_ntoa (lsah->id), lsah);
328
329 XFREE (MTYPE_OSPF_LSA_DATA, lsah);
330}
331
332
333/* LSA general functions. */
334
335const char *
336dump_lsa_key (struct ospf_lsa *lsa)
337{
338 static char buf[] = {
hasso52dc7ee2004-09-23 19:18:23 +0000339 "Type255,id(255.255.255.255),ar(255.255.255.255)"
paul718e3742002-12-13 20:15:29 +0000340 };
341 struct lsa_header *lsah;
342
343 if (lsa != NULL && (lsah = lsa->data) != NULL)
344 {
345 char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
346 strcpy (id, inet_ntoa (lsah->id));
347 strcpy (ar, inet_ntoa (lsah->adv_router));
348
349 sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
350 }
351 else
352 strcpy (buf, "NULL");
353
354 return buf;
355}
356
357u_int32_t
358lsa_seqnum_increment (struct ospf_lsa *lsa)
359{
360 u_int32_t seqnum;
361
362 seqnum = ntohl (lsa->data->ls_seqnum) + 1;
363
364 return htonl (seqnum);
365}
366
367void
368lsa_header_set (struct stream *s, u_char options,
paul68980082003-03-25 05:07:42 +0000369 u_char type, struct in_addr id, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +0000370{
371 struct lsa_header *lsah;
372
373 lsah = (struct lsa_header *) STREAM_DATA (s);
374
375 lsah->ls_age = htons (0);
376 lsah->options = options;
377 lsah->type = type;
378 lsah->id = id;
paul68980082003-03-25 05:07:42 +0000379 lsah->adv_router = router_id;
paul718e3742002-12-13 20:15:29 +0000380 lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
381
paul9985f832005-02-09 15:51:56 +0000382 stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000383}
384
paul68980082003-03-25 05:07:42 +0000385
paul718e3742002-12-13 20:15:29 +0000386/* router-LSA related functions. */
387/* Get router-LSA flags. */
paul4dadc292005-05-06 21:37:42 +0000388static u_char
paul718e3742002-12-13 20:15:29 +0000389router_lsa_flags (struct ospf_area *area)
390{
391 u_char flags;
392
paul68980082003-03-25 05:07:42 +0000393 flags = area->ospf->flags;
paul718e3742002-12-13 20:15:29 +0000394
395 /* Set virtual link flag. */
396 if (ospf_full_virtual_nbrs (area))
397 SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
398 else
399 /* Just sanity check */
400 UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);
401
402 /* Set Shortcut ABR behabiour flag. */
403 UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
paul68980082003-03-25 05:07:42 +0000404 if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
paul718e3742002-12-13 20:15:29 +0000405 if (!OSPF_IS_AREA_BACKBONE (area))
406 if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
paul68980082003-03-25 05:07:42 +0000407 area->ospf->backbone == NULL) ||
paul718e3742002-12-13 20:15:29 +0000408 area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
409 SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
410
411 /* ASBR can't exit in stub area. */
Greg Troxelfc787e82007-08-06 15:50:20 +0000412 if (area->external_routing == OSPF_AREA_STUB)
paul942b6c12003-06-22 08:22:18 +0000413 UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
414 /* If ASBR set External flag */
415 else if (IS_OSPF_ASBR (area->ospf))
416 SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
417
418 /* Set ABR dependent flags */
419 if (IS_OSPF_ABR (area->ospf))
420 {
421 SET_FLAG (flags, ROUTER_LSA_BORDER);
paul942b6c12003-06-22 08:22:18 +0000422 /* If Area is NSSA and we are both ABR and unconditional translator,
pauld4a53d52003-07-12 21:30:57 +0000423 * set Nt bit to inform other routers.
paul942b6c12003-06-22 08:22:18 +0000424 */
pauld4a53d52003-07-12 21:30:57 +0000425 if ( (area->external_routing == OSPF_AREA_NSSA)
426 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
427 SET_FLAG (flags, ROUTER_LSA_NT);
paul942b6c12003-06-22 08:22:18 +0000428 }
paul718e3742002-12-13 20:15:29 +0000429 return flags;
430}
431
432/* Lookup neighbor other than myself.
433 And check neighbor count,
434 Point-to-Point link must have only 1 neighbor. */
435struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +0000436ospf_nbr_lookup_ptop (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +0000437{
paul718e3742002-12-13 20:15:29 +0000438 struct ospf_neighbor *nbr = NULL;
paul68980082003-03-25 05:07:42 +0000439 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000440
441 /* Search neighbor, there must be one of two nbrs. */
paul68980082003-03-25 05:07:42 +0000442 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
443 if ((nbr = rn->info))
444 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000445 if (nbr->state == NSM_Full)
paul68980082003-03-25 05:07:42 +0000446 {
447 route_unlock_node (rn);
448 break;
449 }
paul718e3742002-12-13 20:15:29 +0000450
451 /* PtoP link must have only 1 neighbor. */
paul68980082003-03-25 05:07:42 +0000452 if (ospf_nbr_count (oi, 0) > 1)
paul718e3742002-12-13 20:15:29 +0000453 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
454
455 return nbr;
456}
457
paul88d6cf32005-10-29 12:50:09 +0000458/* Determine cost of link, taking RFC3137 stub-router support into
459 * consideration
460 */
461static u_int16_t
462ospf_link_cost (struct ospf_interface *oi)
463{
464 /* RFC3137 stub router support */
465 if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
466 return oi->output_cost;
467 else
468 return OSPF_OUTPUT_COST_INFINITE;
469}
470
paul718e3742002-12-13 20:15:29 +0000471/* Set a link information. */
paul779adb02006-01-18 15:07:38 +0000472static char
paul718e3742002-12-13 20:15:29 +0000473link_info_set (struct stream *s, struct in_addr id,
474 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
475{
paul779adb02006-01-18 15:07:38 +0000476 /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
477 * vast majority of cases. Some rare routers with lots of links need more.
478 * we try accomodate those here.
479 */
480 if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
481 {
482 size_t ret = OSPF_MAX_LSA_SIZE;
483
484 /* Can we enlarge the stream still? */
485 if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
486 {
487 /* we futz the size here for simplicity, really we need to account
488 * for just:
489 * IP Header - (sizeof (struct ip))
490 * OSPF Header - OSPF_HEADER_SIZE
491 * LSA Header - OSPF_LSA_HEADER_SIZE
492 * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
493 *
494 * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
495 */
496 ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
497 }
498
499 if (ret == OSPF_MAX_LSA_SIZE)
500 {
Paul Jakma53725102009-08-03 16:34:16 +0100501 zlog_warn ("%s: Out of space in LSA stream, left %zd, size %zd",
paul779adb02006-01-18 15:07:38 +0000502 __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
503 return 0;
504 }
505 }
506
paul718e3742002-12-13 20:15:29 +0000507 /* TOS based routing is not supported. */
508 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
509 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
510 stream_putc (s, type); /* Link Type. */
511 stream_putc (s, tos); /* TOS = 0. */
512 stream_putw (s, cost); /* Link Cost. */
paul779adb02006-01-18 15:07:38 +0000513
514 return 1;
paul718e3742002-12-13 20:15:29 +0000515}
516
Andrew J. Schorre4529632006-12-12 19:18:21 +0000517/* Describe Point-to-Point link (Section 12.4.1.1). */
paul4dadc292005-05-06 21:37:42 +0000518static int
paul718e3742002-12-13 20:15:29 +0000519lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
520{
521 int links = 0;
522 struct ospf_neighbor *nbr;
523 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000524 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000525
526 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000527 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
paul718e3742002-12-13 20:15:29 +0000528
paul68980082003-03-25 05:07:42 +0000529 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000530 if (nbr->state == NSM_Full)
531 {
532 /* For unnumbered point-to-point networks, the Link Data field
533 should specify the interface's MIB-II ifIndex value. */
paul779adb02006-01-18 15:07:38 +0000534 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
535 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000536 }
537
Andrew J. Schorre4529632006-12-12 19:18:21 +0000538 /* Regardless of the state of the neighboring router, we must
539 add a Type 3 link (stub network).
540 N.B. Options 1 & 2 share basically the same logic. */
541 masklen2ip (oi->address->prefixlen, &mask);
542 id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
543 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
544 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000545 return links;
546}
547
548/* Describe Broadcast Link. */
paul4dadc292005-05-06 21:37:42 +0000549static int
paul718e3742002-12-13 20:15:29 +0000550lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
551{
552 struct ospf_neighbor *dr;
553 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000554 u_int16_t cost = ospf_link_cost (oi);
555
paul718e3742002-12-13 20:15:29 +0000556 /* Describe Type 3 Link. */
557 if (oi->state == ISM_Waiting)
558 {
559 masklen2ip (oi->address->prefixlen, &mask);
560 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000561 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
562 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000563 }
564
565 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
566 /* Describe Type 2 link. */
567 if (dr && (dr->state == NSM_Full ||
568 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000569 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000570 {
paul779adb02006-01-18 15:07:38 +0000571 return link_info_set (s, DR (oi), oi->address->u.prefix4,
572 LSA_LINK_TYPE_TRANSIT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000573 }
574 /* Describe type 3 link. */
575 else
576 {
577 masklen2ip (oi->address->prefixlen, &mask);
578 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000579 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
580 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000581 }
paul718e3742002-12-13 20:15:29 +0000582}
583
paul4dadc292005-05-06 21:37:42 +0000584static int
paul718e3742002-12-13 20:15:29 +0000585lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
586{
587 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000588
paul718e3742002-12-13 20:15:29 +0000589 /* Describe Type 3 Link. */
590 if (oi->state != ISM_Loopback)
591 return 0;
592
593 mask.s_addr = 0xffffffff;
594 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000595 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000596}
597
598/* Describe Virtual Link. */
paul4dadc292005-05-06 21:37:42 +0000599static int
paul718e3742002-12-13 20:15:29 +0000600lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
601{
602 struct ospf_neighbor *nbr;
paul88d6cf32005-10-29 12:50:09 +0000603 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000604
paul718e3742002-12-13 20:15:29 +0000605 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000606 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000607 if (nbr->state == NSM_Full)
608 {
paul779adb02006-01-18 15:07:38 +0000609 return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
610 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
paul718e3742002-12-13 20:15:29 +0000611 }
612
613 return 0;
614}
615
616#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
617
paul7afa08d2002-12-13 20:59:45 +0000618/* this function add for support point-to-multipoint ,see rfc2328
61912.4.1.4.*/
620/* from "edward rrr" <edward_rrr@hotmail.com>
621 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul4dadc292005-05-06 21:37:42 +0000622static int
paul68980082003-03-25 05:07:42 +0000623lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000624{
625 int links = 0;
626 struct route_node *rn;
627 struct ospf_neighbor *nbr = NULL;
628 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000629 u_int16_t cost = ospf_link_cost (oi);
paul7afa08d2002-12-13 20:59:45 +0000630
631 mask.s_addr = 0xffffffff;
632 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000633 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
paul7afa08d2002-12-13 20:59:45 +0000634
paul1cc8f762003-04-05 19:34:32 +0000635 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000636 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000637
638 /* Search neighbor, */
639 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
640 if ((nbr = rn->info) != NULL)
641 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000642 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000643 if (nbr->state == NSM_Full)
644
645 {
paul779adb02006-01-18 15:07:38 +0000646 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
647 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul1cc8f762003-04-05 19:34:32 +0000648 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000649 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000650 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000651 }
652
653 return links;
paul7afa08d2002-12-13 20:59:45 +0000654}
655
paul718e3742002-12-13 20:15:29 +0000656/* Set router-LSA link information. */
paul4dadc292005-05-06 21:37:42 +0000657static int
paul718e3742002-12-13 20:15:29 +0000658router_lsa_link_set (struct stream *s, struct ospf_area *area)
659{
hasso52dc7ee2004-09-23 19:18:23 +0000660 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000661 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000662 int links = 0;
663
paul1eb8ef22005-04-07 07:30:20 +0000664 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +0000665 {
paul718e3742002-12-13 20:15:29 +0000666 struct interface *ifp = oi->ifp;
667
668 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000669 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000670 {
671 if (oi->state != ISM_Down)
672 {
673 /* Describe each link. */
674 switch (oi->type)
675 {
676 case OSPF_IFTYPE_POINTOPOINT:
677 links += lsa_link_ptop_set (s, oi);
678 break;
679 case OSPF_IFTYPE_BROADCAST:
680 links += lsa_link_broadcast_set (s, oi);
681 break;
682 case OSPF_IFTYPE_NBMA:
683 links += lsa_link_nbma_set (s, oi);
684 break;
685 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000686 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000687 break;
688 case OSPF_IFTYPE_VIRTUALLINK:
689 links += lsa_link_virtuallink_set (s, oi);
690 break;
691 case OSPF_IFTYPE_LOOPBACK:
692 links += lsa_link_loopback_set (s, oi);
693 }
694 }
695 }
696 }
697
698 return links;
699}
700
701/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000702static void
paul718e3742002-12-13 20:15:29 +0000703ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
704{
705 unsigned long putp;
706 u_int16_t cnt;
707
708 /* Set flags. */
709 stream_putc (s, router_lsa_flags (area));
710
711 /* Set Zero fields. */
712 stream_putc (s, 0);
713
714 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000715 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000716
717 /* Forward word */
718 stream_putw(s, 0);
719
720 /* Set all link information. */
721 cnt = router_lsa_link_set (s, area);
722
723 /* Set # of links here. */
724 stream_putw_at (s, putp, cnt);
725}
paul88d6cf32005-10-29 12:50:09 +0000726
727static int
728ospf_stub_router_timer (struct thread *t)
729{
730 struct ospf_area *area = THREAD_ARG (t);
731
732 area->t_stub_router = NULL;
733
734 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
735
736 /* clear stub route state and generate router-lsa refresh, don't
737 * clobber an administratively set stub-router state though.
738 */
739 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
740 return 0;
741
742 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
743
744 ospf_router_lsa_timer_add (area);
745
746 return 0;
747}
paul718e3742002-12-13 20:15:29 +0000748
paul88d6cf32005-10-29 12:50:09 +0000749inline static void
750ospf_stub_router_check (struct ospf_area *area)
751{
752 /* area must either be administratively configured to be stub
753 * or startup-time stub-router must be configured and we must in a pre-stub
754 * state.
755 */
756 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
757 {
758 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
759 return;
760 }
761
762 /* not admin-stubbed, check whether startup stubbing is configured and
763 * whether it's not been done yet
764 */
765 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
766 return;
767
768 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
769 {
770 /* stub-router is hence done forever for this area, even if someone
771 * tries configure it (take effect next restart).
772 */
773 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
774 return;
775 }
776
777 /* startup stub-router configured and not yet done */
778 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
779
780 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
781 area->ospf->stub_router_startup_time);
782}
783
paul718e3742002-12-13 20:15:29 +0000784/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000785static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000786ospf_router_lsa_new (struct ospf_area *area)
787{
paul68980082003-03-25 05:07:42 +0000788 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000789 struct stream *s;
790 struct lsa_header *lsah;
791 struct ospf_lsa *new;
792 int length;
793
794 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000795 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000796
paul88d6cf32005-10-29 12:50:09 +0000797 /* check whether stub-router is desired, and if this is the first
798 * router LSA.
799 */
800 ospf_stub_router_check (area);
801
paul718e3742002-12-13 20:15:29 +0000802 /* Create a stream for LSA. */
803 s = stream_new (OSPF_MAX_LSA_SIZE);
paul718e3742002-12-13 20:15:29 +0000804 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000805 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000806 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000807
808 /* Set router-LSA body fields. */
809 ospf_router_lsa_body_set (s, area);
810
811 /* Set length. */
812 length = stream_get_endp (s);
paul779adb02006-01-18 15:07:38 +0000813 lsah = (struct lsa_header *) STREAM_DATA (s);
paul718e3742002-12-13 20:15:29 +0000814 lsah->length = htons (length);
815
816 /* Now, create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000817 if ( (new = ospf_lsa_new ()) == NULL)
818 {
819 zlog_err ("%s: Unable to create new lsa", __func__);
820 return NULL;
821 }
822
paul718e3742002-12-13 20:15:29 +0000823 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +0000824 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +0000825
826 /* Copy LSA data to store, discard stream. */
827 new->data = ospf_lsa_data_new (length);
828 memcpy (new->data, lsah, length);
829 stream_free (s);
830
831 return new;
832}
833
834/* Originate Router-LSA. */
paul88d6cf32005-10-29 12:50:09 +0000835static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000836ospf_router_lsa_originate (struct ospf_area *area)
837{
838 struct ospf_lsa *new;
paul88d6cf32005-10-29 12:50:09 +0000839
paul718e3742002-12-13 20:15:29 +0000840 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000841 if ( (new = ospf_router_lsa_new (area)) == NULL)
842 {
843 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
844 return NULL;
845 }
paul718e3742002-12-13 20:15:29 +0000846
847 /* Sanity check. */
848 if (new->data->adv_router.s_addr == 0)
849 {
850 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000851 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000852 ospf_lsa_discard (new);
853 return NULL;
854 }
855
856 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000857 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000858
859 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000860 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000861
862 /* Flooding new LSA through area. */
863 ospf_flood_through_area (area, NULL, new);
864
865 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
866 {
ajse588f212004-12-08 18:12:06 +0000867 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
paul718e3742002-12-13 20:15:29 +0000868 new->data->type, inet_ntoa (new->data->id), new);
869 ospf_lsa_header_dump (new->data);
870 }
871
872 return new;
873}
874
875/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000876static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000877ospf_router_lsa_refresh (struct ospf_lsa *lsa)
878{
879 struct ospf_area *area = lsa->area;
880 struct ospf_lsa *new;
881
882 /* Sanity check. */
883 assert (lsa->data);
884
885 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000886 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000887
888 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000889 if ( (new = ospf_router_lsa_new (area)) == NULL)
890 {
891 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
892 return NULL;
893 }
894
paul718e3742002-12-13 20:15:29 +0000895 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
896
paul68980082003-03-25 05:07:42 +0000897 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000898
899 /* Flood LSA through area. */
900 ospf_flood_through_area (area, NULL, new);
901
902 /* Debug logging. */
903 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
904 {
ajse588f212004-12-08 18:12:06 +0000905 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000906 new->data->type, inet_ntoa (new->data->id));
907 ospf_lsa_header_dump (new->data);
908 }
909
910 return NULL;
911}
912
paul4dadc292005-05-06 21:37:42 +0000913static int
paul718e3742002-12-13 20:15:29 +0000914ospf_router_lsa_timer (struct thread *t)
915{
916 struct ospf_area *area;
917
918 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000919 zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
paul718e3742002-12-13 20:15:29 +0000920
921 area = THREAD_ARG (t);
922 area->t_router_lsa_self = NULL;
923
924 /* Now refresh router-LSA. */
925 if (area->router_lsa_self)
926 ospf_router_lsa_refresh (area->router_lsa_self);
927 /* Newly originate router-LSA. */
928 else
929 ospf_router_lsa_originate (area);
930
931 return 0;
932}
933
934void
935ospf_router_lsa_timer_add (struct ospf_area *area)
936{
937 /* Keep area's self-originated router-LSA. */
938 struct ospf_lsa *lsa = area->router_lsa_self;
939
940 /* Cancel previously scheduled router-LSA timer. */
941 if (area->t_router_lsa_self)
942 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000943 zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
paul718e3742002-12-13 20:15:29 +0000944
945 OSPF_TIMER_OFF (area->t_router_lsa_self);
946
947 /* If router-LSA is originated previously, check the interval time. */
948 if (lsa)
949 {
950 int delay;
951 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
952 {
953 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
954 ospf_router_lsa_timer, delay);
955 return;
956 }
957 }
958
959 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000960 zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
paul718e3742002-12-13 20:15:29 +0000961
962 /* Immediately refresh router-LSA. */
963 OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
964}
965
966int
paul68980082003-03-25 05:07:42 +0000967ospf_router_lsa_update_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000968{
paul68980082003-03-25 05:07:42 +0000969 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +0000970 struct listnode *node, *nnode;
971 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +0000972
973 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000974 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +0000975
paul68980082003-03-25 05:07:42 +0000976 ospf->t_router_lsa_update = NULL;
paul718e3742002-12-13 20:15:29 +0000977
paul1eb8ef22005-04-07 07:30:20 +0000978 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000979 {
paul718e3742002-12-13 20:15:29 +0000980 struct ospf_lsa *lsa = area->router_lsa_self;
981 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +0000982 const char *area_str;
paul718e3742002-12-13 20:15:29 +0000983
984 /* Keep Area ID string. */
985 area_str = AREA_NAME (area);
986
987 /* If LSA not exist in this Area, originate new. */
988 if (lsa == NULL)
989 {
990 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000991 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +0000992
993 ospf_router_lsa_originate (area);
994 }
995 /* If router-ID is changed, Link ID must change.
996 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +0000997 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000998 {
999 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001000 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +00001001 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
1002 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001003 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00001004 area->router_lsa_self = NULL;
1005
1006 /* Refresh router-LSA, (not install) and flood through area. */
1007 ospf_router_lsa_timer_add (area);
1008 }
1009 else
1010 {
1011 rl = (struct router_lsa *) lsa->data;
1012 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +00001013 if (rl->flags != ospf->flags)
paul718e3742002-12-13 20:15:29 +00001014 ospf_router_lsa_timer_add (area);
1015 }
1016 }
1017
1018 return 0;
1019}
1020
1021
1022/* network-LSA related functions. */
1023/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001024static void
paul718e3742002-12-13 20:15:29 +00001025ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1026{
1027 struct in_addr mask;
1028 struct route_node *rn;
1029 struct ospf_neighbor *nbr;
1030
1031 masklen2ip (oi->address->prefixlen, &mask);
1032 stream_put_ipv4 (s, mask.s_addr);
1033
1034 /* The network-LSA lists those routers that are fully adjacent to
1035 the Designated Router; each fully adjacent router is identified by
1036 its OSPF Router ID. The Designated Router includes itself in this
1037 list. RFC2328, Section 12.4.2 */
1038
1039 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1040 if ((nbr = rn->info) != NULL)
1041 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1042 stream_put_ipv4 (s, nbr->router_id.s_addr);
1043}
1044
paul4dadc292005-05-06 21:37:42 +00001045static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001046ospf_network_lsa_new (struct ospf_interface *oi)
1047{
1048 struct stream *s;
1049 struct ospf_lsa *new;
1050 struct lsa_header *lsah;
1051 int length;
1052
1053 /* If there are no neighbours on this network (the net is stub),
1054 the router does not originate network-LSA (see RFC 12.4.2) */
1055 if (oi->full_nbrs == 0)
1056 return NULL;
1057
1058 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001059 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001060
1061 /* Create new stream for LSA. */
1062 s = stream_new (OSPF_MAX_LSA_SIZE);
1063 lsah = (struct lsa_header *) STREAM_DATA (s);
1064
1065 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001066 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001067
1068 /* Set network-LSA body fields. */
1069 ospf_network_lsa_body_set (s, oi);
1070
1071 /* Set length. */
1072 length = stream_get_endp (s);
1073 lsah->length = htons (length);
1074
1075 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001076 if ( (new = ospf_lsa_new ()) == NULL)
1077 {
1078 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1079 return NULL;
1080 }
1081
paul718e3742002-12-13 20:15:29 +00001082 new->area = oi->area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001083 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001084
1085 /* Copy LSA to store. */
1086 new->data = ospf_lsa_data_new (length);
1087 memcpy (new->data, lsah, length);
1088 stream_free (s);
1089
1090 return new;
1091}
1092
1093/* Originate network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001094static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001095ospf_network_lsa_originate (struct ospf_interface *oi)
1096{
1097 struct ospf_lsa *new;
1098
1099 /* Create new network-LSA instance. */
1100 new = ospf_network_lsa_new (oi);
1101 if (new == NULL)
1102 return NULL;
1103
1104 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001105 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001106
1107 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001108 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001109
1110 /* Flooding new LSA through area. */
1111 ospf_flood_through_area (oi->area, NULL, new);
1112
1113 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1114 {
ajse588f212004-12-08 18:12:06 +00001115 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001116 new->data->type, inet_ntoa (new->data->id), new);
1117 ospf_lsa_header_dump (new->data);
1118 }
1119
1120 return new;
1121}
1122
1123int
1124ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1125{
1126 struct ospf_area *area = lsa->area;
1127 struct ospf_lsa *new;
1128
1129 assert (lsa->data);
1130
1131 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001132 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001133
1134 /* Create new network-LSA instance. */
1135 new = ospf_network_lsa_new (oi);
1136 if (new == NULL)
1137 return -1;
1138 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1139
paul68980082003-03-25 05:07:42 +00001140 ospf_lsa_install (area->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001141
1142 /* Flood LSA through aera. */
1143 ospf_flood_through_area (area, NULL, new);
1144
1145 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1146 {
ajse588f212004-12-08 18:12:06 +00001147 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001148 new->data->type, inet_ntoa (new->data->id));
1149 ospf_lsa_header_dump (new->data);
1150 }
1151
1152 return 0;
1153}
1154
paul4dadc292005-05-06 21:37:42 +00001155static int
paul718e3742002-12-13 20:15:29 +00001156ospf_network_lsa_refresh_timer (struct thread *t)
1157{
1158 struct ospf_interface *oi;
1159
1160 oi = THREAD_ARG (t);
1161 oi->t_network_lsa_self = NULL;
1162
1163 if (oi->network_lsa_self)
1164 /* Now refresh network-LSA. */
1165 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1166 else
1167 /* Newly create network-LSA. */
1168 ospf_network_lsa_originate (oi);
1169
1170 return 0;
1171}
1172
1173void
1174ospf_network_lsa_timer_add (struct ospf_interface *oi)
1175{
1176 /* Keep interface's self-originated network-LSA. */
1177 struct ospf_lsa *lsa = oi->network_lsa_self;
1178
1179 /* Cancel previously schedules network-LSA timer. */
1180 if (oi->t_network_lsa_self)
1181 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001182 zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
paul718e3742002-12-13 20:15:29 +00001183 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1184
1185 /* If network-LSA is originated previously, check the interval time. */
1186 if (lsa)
1187 {
1188 int delay;
1189 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1190 {
1191 oi->t_network_lsa_self =
1192 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1193 oi, delay);
1194 return;
1195 }
1196 }
1197
1198 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001199 zlog_debug ("Scheduling network-LSA origination right away");
paul718e3742002-12-13 20:15:29 +00001200
1201 /* Immediately refresh network-LSA. */
1202 oi->t_network_lsa_self =
1203 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1204}
1205
1206
paul4dadc292005-05-06 21:37:42 +00001207static void
paul718e3742002-12-13 20:15:29 +00001208stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1209{
1210 u_int32_t metric;
1211 char *mp;
1212
1213 /* Put 0 metric. TOS metric is not supported. */
1214 metric = htonl (metric_value);
1215 mp = (char *) &metric;
1216 mp++;
1217 stream_put (s, mp, 3);
1218}
1219
1220/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001221static void
paul718e3742002-12-13 20:15:29 +00001222ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1223 u_int32_t metric)
1224{
1225 struct in_addr mask;
1226
1227 masklen2ip (p->prefixlen, &mask);
1228
1229 /* Put Network Mask. */
1230 stream_put_ipv4 (s, mask.s_addr);
1231
1232 /* Set # TOS. */
1233 stream_putc (s, (u_char) 0);
1234
1235 /* Set metric. */
1236 stream_put_ospf_metric (s, metric);
1237}
1238
paul4dadc292005-05-06 21:37:42 +00001239static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001240ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1241 u_int32_t metric, struct in_addr id)
1242{
1243 struct stream *s;
1244 struct ospf_lsa *new;
1245 struct lsa_header *lsah;
1246 int length;
1247
paulc24d6022005-11-20 14:54:12 +00001248 if (id.s_addr == 0xffffffff)
1249 {
1250 /* Maybe Link State ID not available. */
1251 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1252 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1253 OSPF_SUMMARY_LSA);
1254 return NULL;
1255 }
1256
paul718e3742002-12-13 20:15:29 +00001257 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001258 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001259
1260 /* Create new stream for LSA. */
1261 s = stream_new (OSPF_MAX_LSA_SIZE);
1262 lsah = (struct lsa_header *) STREAM_DATA (s);
1263
paul68980082003-03-25 05:07:42 +00001264 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1265 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001266
1267 /* Set summary-LSA body fields. */
1268 ospf_summary_lsa_body_set (s, p, metric);
1269
1270 /* Set length. */
1271 length = stream_get_endp (s);
1272 lsah->length = htons (length);
1273
1274 /* Create OSPF LSA instance. */
1275 new = ospf_lsa_new ();
1276 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001277 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001278
1279 /* Copy LSA to store. */
1280 new->data = ospf_lsa_data_new (length);
1281 memcpy (new->data, lsah, length);
1282 stream_free (s);
1283
1284 return new;
1285}
1286
1287/* Originate Summary-LSA. */
1288struct ospf_lsa *
1289ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1290 struct ospf_area *area)
1291{
1292 struct ospf_lsa *new;
1293 struct in_addr id;
1294
paul68980082003-03-25 05:07:42 +00001295 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001296
paulc24d6022005-11-20 14:54:12 +00001297 if (id.s_addr == 0xffffffff)
1298 {
1299 /* Maybe Link State ID not available. */
1300 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1301 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1302 OSPF_SUMMARY_LSA);
1303 return NULL;
1304 }
1305
paul718e3742002-12-13 20:15:29 +00001306 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001307 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1308 return NULL;
paul718e3742002-12-13 20:15:29 +00001309
1310 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001311 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001312
1313 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001314 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001315
1316 /* Flooding new LSA through area. */
1317 ospf_flood_through_area (area, NULL, new);
1318
1319 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1320 {
ajse588f212004-12-08 18:12:06 +00001321 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001322 new->data->type, inet_ntoa (new->data->id), new);
1323 ospf_lsa_header_dump (new->data);
1324 }
1325
1326 return new;
1327}
1328
1329struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001330ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001331{
1332 struct ospf_lsa *new;
1333 struct summary_lsa *sl;
1334 struct prefix p;
1335
1336 /* Sanity check. */
1337 assert (lsa->data);
1338
1339 sl = (struct summary_lsa *)lsa->data;
1340 p.prefixlen = ip_masklen (sl->mask);
1341 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1342 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001343
1344 if (!new)
1345 return NULL;
1346
paul718e3742002-12-13 20:15:29 +00001347 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001348
paul68980082003-03-25 05:07:42 +00001349 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001350
1351 /* Flood LSA through AS. */
1352 ospf_flood_through_area (new->area, NULL, new);
1353
1354 /* Debug logging. */
1355 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1356 {
ajse588f212004-12-08 18:12:06 +00001357 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001358 new->data->type, inet_ntoa (new->data->id));
1359 ospf_lsa_header_dump (new->data);
1360 }
1361
1362 return new;
1363}
1364
1365
1366/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001367static void
paul718e3742002-12-13 20:15:29 +00001368ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1369 u_int32_t metric)
1370{
1371 struct in_addr mask;
1372
1373 masklen2ip (p->prefixlen, &mask);
1374
1375 /* Put Network Mask. */
1376 stream_put_ipv4 (s, mask.s_addr);
1377
1378 /* Set # TOS. */
1379 stream_putc (s, (u_char) 0);
1380
1381 /* Set metric. */
1382 stream_put_ospf_metric (s, metric);
1383}
1384
paul4dadc292005-05-06 21:37:42 +00001385static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001386ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1387 u_int32_t metric, struct in_addr id)
1388{
1389 struct stream *s;
1390 struct ospf_lsa *new;
1391 struct lsa_header *lsah;
1392 int length;
1393
paulc24d6022005-11-20 14:54:12 +00001394 if (id.s_addr == 0xffffffff)
1395 {
1396 /* Maybe Link State ID not available. */
1397 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1398 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1399 OSPF_ASBR_SUMMARY_LSA);
1400 return NULL;
1401 }
1402
paul718e3742002-12-13 20:15:29 +00001403 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001404 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001405
1406 /* Create new stream for LSA. */
1407 s = stream_new (OSPF_MAX_LSA_SIZE);
1408 lsah = (struct lsa_header *) STREAM_DATA (s);
1409
paul68980082003-03-25 05:07:42 +00001410 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1411 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001412
1413 /* Set summary-LSA body fields. */
1414 ospf_summary_asbr_lsa_body_set (s, p, metric);
1415
1416 /* Set length. */
1417 length = stream_get_endp (s);
1418 lsah->length = htons (length);
1419
1420 /* Create OSPF LSA instance. */
1421 new = ospf_lsa_new ();
1422 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001423 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001424
1425 /* Copy LSA to store. */
1426 new->data = ospf_lsa_data_new (length);
1427 memcpy (new->data, lsah, length);
1428 stream_free (s);
1429
1430 return new;
1431}
1432
1433/* Originate summary-ASBR-LSA. */
1434struct ospf_lsa *
1435ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1436 struct ospf_area *area)
1437{
1438 struct ospf_lsa *new;
1439 struct in_addr id;
1440
paul68980082003-03-25 05:07:42 +00001441 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001442
paulc24d6022005-11-20 14:54:12 +00001443 if (id.s_addr == 0xffffffff)
1444 {
1445 /* Maybe Link State ID not available. */
1446 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1447 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1448 OSPF_ASBR_SUMMARY_LSA);
1449 return NULL;
1450 }
1451
paul718e3742002-12-13 20:15:29 +00001452 /* Create new summary-LSA instance. */
1453 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001454 if (!new)
1455 return NULL;
paul718e3742002-12-13 20:15:29 +00001456
1457 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001458 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001459
1460 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001461 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001462
1463 /* Flooding new LSA through area. */
1464 ospf_flood_through_area (area, NULL, new);
1465
1466 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1467 {
ajse588f212004-12-08 18:12:06 +00001468 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001469 new->data->type, inet_ntoa (new->data->id), new);
1470 ospf_lsa_header_dump (new->data);
1471 }
1472
1473 return new;
1474}
1475
1476struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001477ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001478{
1479 struct ospf_lsa *new;
1480 struct summary_lsa *sl;
1481 struct prefix p;
1482
1483 /* Sanity check. */
1484 assert (lsa->data);
1485
1486 sl = (struct summary_lsa *)lsa->data;
1487 p.prefixlen = ip_masklen (sl->mask);
1488 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1489 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001490 if (!new)
1491 return NULL;
paul718e3742002-12-13 20:15:29 +00001492
1493 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001494
paul68980082003-03-25 05:07:42 +00001495 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001496
1497 /* Flood LSA through area. */
1498 ospf_flood_through_area (new->area, NULL, new);
1499
1500 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1501 {
ajse588f212004-12-08 18:12:06 +00001502 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001503 new->data->type, inet_ntoa (new->data->id));
1504 ospf_lsa_header_dump (new->data);
1505 }
1506
1507 return new;
1508}
1509
1510/* AS-external-LSA related functions. */
1511
1512/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1513 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001514static struct in_addr
paul68980082003-03-25 05:07:42 +00001515ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001516{
1517 struct in_addr fwd;
1518 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001519 struct listnode *node;
1520 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001521
1522 fwd.s_addr = 0;
1523
1524 if (!nexthop.s_addr)
1525 return fwd;
1526
1527 /* Check whether nexthop is covered by OSPF network. */
1528 nh.family = AF_INET;
1529 nh.u.prefix4 = nexthop;
1530 nh.prefixlen = IPV4_MAX_BITLEN;
Paul Jakma4ca15d42009-08-03 15:16:41 +01001531
1532 /* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be
1533 * better to make use of the per-ifp table of ois.
1534 */
paul1eb8ef22005-04-07 07:30:20 +00001535 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1536 if (if_is_operative (oi->ifp))
1537 if (oi->address->family == AF_INET)
1538 if (prefix_match (oi->address, &nh))
1539 return nexthop;
paul718e3742002-12-13 20:15:29 +00001540
1541 return fwd;
1542}
1543
paul718e3742002-12-13 20:15:29 +00001544/* NSSA-external-LSA related functions. */
1545
1546/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001547
paul718e3742002-12-13 20:15:29 +00001548struct in_addr
1549ospf_get_ip_from_ifp (struct ospf_interface *oi)
1550{
1551 struct in_addr fwd;
1552
1553 fwd.s_addr = 0;
1554
paul2e3b2e42002-12-13 21:03:13 +00001555 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001556 return oi->address->u.prefix4;
1557
1558 return fwd;
1559}
1560
1561/* Get 1st IP connection for Forward Addr */
1562struct in_addr
paulf2c80652002-12-13 21:44:27 +00001563ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001564{
1565 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001566 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001567 struct listnode *node;
1568 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001569
1570 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001571 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001572
paul1eb8ef22005-04-07 07:30:20 +00001573 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001574 {
paul2e3b2e42002-12-13 21:03:13 +00001575 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001576 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001577 if (oi->address && oi->address->family == AF_INET)
1578 {
1579 if (best_default.s_addr == 0)
1580 best_default = oi->address->u.prefix4;
1581 if (oi->area == area)
1582 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001583 }
paul718e3742002-12-13 20:15:29 +00001584 }
paulf2c80652002-12-13 21:44:27 +00001585 if (best_default.s_addr != 0)
1586 return best_default;
paul718e3742002-12-13 20:15:29 +00001587
paul68980082003-03-25 05:07:42 +00001588 if (best_default.s_addr != 0)
1589 return best_default;
1590
paul718e3742002-12-13 20:15:29 +00001591 return fwd;
1592}
hassobeebba72004-06-20 21:00:27 +00001593
paul718e3742002-12-13 20:15:29 +00001594#define DEFAULT_DEFAULT_METRIC 20
1595#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1596#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1597
1598#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1599
1600int
paul68980082003-03-25 05:07:42 +00001601metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001602{
paul68980082003-03-25 05:07:42 +00001603 return (ospf->dmetric[src].type < 0 ?
1604 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001605}
1606
1607int
paul68980082003-03-25 05:07:42 +00001608metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001609{
paul68980082003-03-25 05:07:42 +00001610 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001611 {
1612 if (src == DEFAULT_ROUTE)
1613 {
paul68980082003-03-25 05:07:42 +00001614 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001615 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1616 else
1617 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1618 }
paul68980082003-03-25 05:07:42 +00001619 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001620 return DEFAULT_DEFAULT_METRIC;
1621 else
paul68980082003-03-25 05:07:42 +00001622 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001623 }
1624
paul68980082003-03-25 05:07:42 +00001625 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001626}
1627
1628/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001629static void
paul68980082003-03-25 05:07:42 +00001630ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1631 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001632{
1633 struct prefix_ipv4 *p = &ei->p;
1634 struct in_addr mask, fwd_addr;
1635 u_int32_t mvalue;
1636 int mtype;
1637 int type;
1638
1639 /* Put Network Mask. */
1640 masklen2ip (p->prefixlen, &mask);
1641 stream_put_ipv4 (s, mask.s_addr);
1642
1643 /* If prefix is default, specify DEFAULT_ROUTE. */
1644 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1645
1646 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001647 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001648
1649 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001650 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001651
1652 /* Put type of external metric. */
1653 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1654
1655 /* Put 0 metric. TOS metric is not supported. */
1656 stream_put_ospf_metric (s, mvalue);
1657
1658 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001659 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001660
1661 /* Put forwarding address. */
1662 stream_put_ipv4 (s, fwd_addr.s_addr);
1663
1664 /* Put route tag -- This value should be introduced from configuration. */
1665 stream_putl (s, 0);
1666}
1667
1668/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001669static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001670ospf_external_lsa_new (struct ospf *ospf,
1671 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001672{
1673 struct stream *s;
1674 struct lsa_header *lsah;
1675 struct ospf_lsa *new;
1676 struct in_addr id;
1677 int length;
1678
1679 if (ei == NULL)
1680 {
1681 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001682 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
paul718e3742002-12-13 20:15:29 +00001683 return NULL;
1684 }
1685
1686 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001687 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001688
1689 /* If old Link State ID is specified, refresh LSA with same ID. */
1690 if (old_id)
1691 id = *old_id;
1692 /* Get Link State with unique ID. */
1693 else
1694 {
paul68980082003-03-25 05:07:42 +00001695 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001696 if (id.s_addr == 0xffffffff)
1697 {
1698 /* Maybe Link State ID not available. */
1699 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001700 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001701 return NULL;
1702 }
1703 }
1704
1705 /* Create new stream for LSA. */
1706 s = stream_new (OSPF_MAX_LSA_SIZE);
1707 lsah = (struct lsa_header *) STREAM_DATA (s);
1708
1709 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001710 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1711 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001712
1713 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001714 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001715
1716 /* Set length. */
1717 length = stream_get_endp (s);
1718 lsah->length = htons (length);
1719
1720 /* Now, create OSPF LSA instance. */
1721 new = ospf_lsa_new ();
1722 new->area = NULL;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001723 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001724
1725 /* Copy LSA data to store, discard stream. */
1726 new->data = ospf_lsa_data_new (length);
1727 memcpy (new->data, lsah, length);
1728 stream_free (s);
1729
1730 return new;
1731}
1732
paul718e3742002-12-13 20:15:29 +00001733/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001734static void
paul68980082003-03-25 05:07:42 +00001735ospf_install_flood_nssa (struct ospf *ospf,
1736 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001737{
pauld4a53d52003-07-12 21:30:57 +00001738 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001739 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001740 struct ospf_area *area;
1741 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001742
pauld4a53d52003-07-12 21:30:57 +00001743 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1744 * which originated from an NSSA area. In which case it should not be
1745 * flooded back to NSSA areas.
1746 */
1747 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1748 return;
1749
paul718e3742002-12-13 20:15:29 +00001750 /* NSSA Originate or Refresh (If anyNSSA)
1751
1752 LSA is self-originated. And just installed as Type-5.
1753 Additionally, install as Type-7 LSDB for every attached NSSA.
1754
1755 P-Bit controls which ABR performs translation to outside world; If
1756 we are an ABR....do not set the P-bit, because we send the Type-5,
1757 not as the ABR Translator, but as the ASBR owner within the AS!
1758
1759 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1760 elected ABR Translator will see the P-bit, Translate, and re-flood.
1761
1762 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1763 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1764
paul1eb8ef22005-04-07 07:30:20 +00001765 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001766 {
hasso0c14ad82003-07-03 08:36:02 +00001767 /* Don't install Type-7 LSA's into nonNSSA area */
1768 if (area->external_routing != OSPF_AREA_NSSA)
1769 continue;
paul718e3742002-12-13 20:15:29 +00001770
paul68980082003-03-25 05:07:42 +00001771 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001772 new = ospf_lsa_dup (lsa);
1773 new->area = area;
1774 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001775
paul68980082003-03-25 05:07:42 +00001776 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001777 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001778 {
pauld4a53d52003-07-12 21:30:57 +00001779 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001780
1781 /* set non-zero FWD ADDR
1782
1783 draft-ietf-ospf-nssa-update-09.txt
1784
1785 if the network between the NSSA AS boundary router and the
1786 adjacent AS is advertised into OSPF as an internal OSPF route,
1787 the forwarding address should be the next op address as is cu
1788 currently done with type-5 LSAs. If the intervening network is
1789 not adversited into OSPF as an internal OSPF route and the
1790 type-7 LSA's P-bit is set a forwarding address should be
1791 selected from one of the router's active OSPF inteface addresses
1792 which belong to the NSSA. If no such addresses exist, then
1793 no type-7 LSA's with the P-bit set should originate from this
1794 router. */
1795
pauld4a53d52003-07-12 21:30:57 +00001796 /* kevinm: not updating lsa anymore, just new */
1797 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001798
1799 if (extlsa->e[0].fwd_addr.s_addr == 0)
1800 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001801
pauld7480322003-05-16 17:31:51 +00001802 if (extlsa->e[0].fwd_addr.s_addr == 0)
1803 {
1804 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001805 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001806 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001807 return;
1808 }
paulf2c80652002-12-13 21:44:27 +00001809 }
paul718e3742002-12-13 20:15:29 +00001810
paul68980082003-03-25 05:07:42 +00001811 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001812 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001813
1814 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001815 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001816 }
paul718e3742002-12-13 20:15:29 +00001817}
pauld4a53d52003-07-12 21:30:57 +00001818
paul4dadc292005-05-06 21:37:42 +00001819static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001820ospf_lsa_translated_nssa_new (struct ospf *ospf,
1821 struct ospf_lsa *type7)
1822{
1823
1824 struct ospf_lsa *new;
1825 struct as_external_lsa *ext, *extnew;
1826 struct external_info ei;
1827
1828 ext = (struct as_external_lsa *)(type7->data);
1829
1830 /* need external_info struct, fill in bare minimum */
1831 ei.p.family = AF_INET;
1832 ei.p.prefix = type7->data->id;
1833 ei.p.prefixlen = ip_masklen (ext->mask);
1834 ei.type = ZEBRA_ROUTE_OSPF;
1835 ei.nexthop = ext->header.adv_router;
1836 ei.route_map_set.metric = -1;
1837 ei.route_map_set.metric_type = -1;
1838 ei.tag = 0;
1839
1840 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1841 {
1842 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001843 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001844 "Translated Type-5 for %s",
1845 inet_ntoa (ei.p.prefix));
1846 return NULL;
1847 }
1848
1849 extnew = (struct as_external_lsa *)(new->data);
1850
1851 /* copy over Type-7 data to new */
1852 extnew->e[0].tos = ext->e[0].tos;
1853 extnew->e[0].route_tag = ext->e[0].route_tag;
1854 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1855 new->data->ls_seqnum = type7->data->ls_seqnum;
1856
1857 /* add translated flag, checksum and lock new lsa */
1858 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
pauld4a53d52003-07-12 21:30:57 +00001859 new = ospf_lsa_lock (new);
1860
1861 return new;
1862}
1863
pauld4a53d52003-07-12 21:30:57 +00001864/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1865struct ospf_lsa *
1866ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1867{
1868 struct ospf_lsa *new;
1869 struct as_external_lsa *extnew;
1870
1871 /* we cant use ospf_external_lsa_originate() as we need to set
1872 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1873 */
1874
1875 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1876 {
1877 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001878 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001879 "Type-7, Id %s, to Type-5",
1880 inet_ntoa (type7->data->id));
1881 return NULL;
1882 }
1883
1884 extnew = (struct as_external_lsa *)new;
1885
1886 if (IS_DEBUG_OSPF_NSSA)
1887 {
ajse588f212004-12-08 18:12:06 +00001888 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001889 "translated Type 7, installed:");
1890 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001891 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1892 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001893 }
1894
1895 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1896 {
1897 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001898 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001899 "Could not install LSA "
1900 "id %s", inet_ntoa (type7->data->id));
1901 return NULL;
1902 }
1903
1904 ospf->lsa_originate_count++;
1905 ospf_flood_through_as (ospf, NULL, new);
1906
1907 return new;
1908}
1909
1910/* Refresh Translated from NSSA AS-external-LSA. */
1911struct ospf_lsa *
1912ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1913 struct ospf_lsa *type5)
1914{
1915 struct ospf_lsa *new = NULL;
1916
1917 /* Sanity checks. */
1918 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00001919 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00001920 return NULL;
pauld4a53d52003-07-12 21:30:57 +00001921 if (type7)
1922 assert (type7->data);
1923 if (type5)
1924 assert (type5->data);
1925 assert (ospf->anyNSSA);
1926
1927 /* get required data according to what has been given */
1928 if (type7 && type5 == NULL)
1929 {
1930 /* find the translated Type-5 for this Type-7 */
1931 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1932 struct prefix_ipv4 p =
1933 {
1934 .prefix = type7->data->id,
1935 .prefixlen = ip_masklen (ext->mask),
1936 .family = AF_INET,
1937 };
1938
1939 type5 = ospf_external_info_find_lsa (ospf, &p);
1940 }
1941 else if (type5 && type7 == NULL)
1942 {
1943 /* find the type-7 from which supplied type-5 was translated,
1944 * ie find first type-7 with same LSA Id.
1945 */
paul1eb8ef22005-04-07 07:30:20 +00001946 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00001947 struct route_node *rn;
1948 struct ospf_lsa *lsa;
1949 struct ospf_area *area;
1950
paul1eb8ef22005-04-07 07:30:20 +00001951 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00001952 {
1953 if (area->external_routing != OSPF_AREA_NSSA
1954 && !type7)
1955 continue;
1956
1957 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
1958 {
1959 if (lsa->data->id.s_addr == type5->data->id.s_addr)
1960 {
1961 type7 = lsa;
1962 break;
1963 }
1964 }
1965 }
1966 }
1967
1968 /* do we have type7? */
1969 if (!type7)
1970 {
1971 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001972 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00001973 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00001974 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00001975 return NULL;
1976 }
1977
1978 /* do we have valid translated type5? */
1979 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
1980 {
1981 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001982 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00001983 "found for Type-7 with Id %s",
1984 inet_ntoa (type7->data->id));
1985 return NULL;
1986 }
1987
1988 /* Delete LSA from neighbor retransmit-list. */
1989 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
1990
1991 /* create new translated LSA */
1992 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1993 {
1994 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001995 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001996 "Type-7 for %s to Type-5",
1997 inet_ntoa (type7->data->id));
1998 return NULL;
1999 }
2000
2001 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
2002 {
2003 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002004 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00002005 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00002006 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00002007 return NULL;
2008 }
2009
2010 /* Flood LSA through area. */
2011 ospf_flood_through_as (ospf, NULL, new);
2012
2013 return new;
2014}
paul718e3742002-12-13 20:15:29 +00002015
2016int
2017is_prefix_default (struct prefix_ipv4 *p)
2018{
2019 struct prefix_ipv4 q;
2020
2021 q.family = AF_INET;
2022 q.prefix.s_addr = 0;
2023 q.prefixlen = 0;
2024
2025 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
2026}
2027
2028/* Originate an AS-external-LSA, install and flood. */
2029struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002030ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00002031{
2032 struct ospf_lsa *new;
2033
2034 /* Added for NSSA project....
2035
2036 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2037 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2038 every area. The Type-7's are flooded to every IR and every ABR; We
2039 install the Type-5 LSDB so that the normal "refresh" code operates
2040 as usual, and flag them as not used during ASE calculations. The
2041 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2042 Address of non-zero.
2043
2044 If an ABR is the elected NSSA translator, following SPF and during
2045 the ABR task it will translate all the scanned Type-7's, with P-bit
2046 ON and not-self generated, and translate to Type-5's throughout the
2047 non-NSSA/STUB AS.
2048
2049 A difference in operation depends whether this ASBR is an ABR
2050 or not. If not an ABR, the P-bit is ON, to indicate that any
2051 elected NSSA-ABR can perform its translation.
2052
2053 If an ABR, the P-bit is OFF; No ABR will perform translation and
2054 this ASBR will flood the Type-5 LSA as usual.
2055
2056 For the case where this ASBR is not an ABR, the ASE calculations
2057 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2058 demonstrate to the user that there are LSA's that belong to any
2059 attached NSSA.
2060
2061 Finally, it just so happens that when the ABR is translating every
2062 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2063 approved Type-5 (translated from Type-7); at the end of translation
2064 if any Translated Type-5's remain unapproved, then they must be
2065 flushed from the AS.
2066
2067 */
2068
2069 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002070 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002071 return NULL;
2072
2073 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002074 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002075 {
2076 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002077 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002078 inet_ntoa (ei->p.prefix));
2079 return NULL;
2080 }
2081
2082 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002083 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002084
2085 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002086 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002087
2088 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002089 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002090
paul718e3742002-12-13 20:15:29 +00002091 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002092 if (ospf->anyNSSA &&
2093 /* stay away from translated LSAs! */
2094 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002095 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002096
2097 /* Debug logging. */
2098 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2099 {
ajse588f212004-12-08 18:12:06 +00002100 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002101 new->data->type, inet_ntoa (new->data->id), new);
2102 ospf_lsa_header_dump (new->data);
2103 }
2104
2105 return new;
2106}
2107
2108/* Originate AS-external-LSA from external info with initial flag. */
2109int
paul68980082003-03-25 05:07:42 +00002110ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002111{
paul68980082003-03-25 05:07:42 +00002112 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002113 struct route_node *rn;
2114 struct external_info *ei;
2115 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002116 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002117
paul68980082003-03-25 05:07:42 +00002118 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002119
2120 /* Originate As-external-LSA from all type of distribute source. */
2121 if ((rt = EXTERNAL_INFO (type)))
2122 for (rn = route_top (rt); rn; rn = route_next (rn))
2123 if ((ei = rn->info) != NULL)
2124 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002125 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002126 zlog_warn ("LSA: AS-external-LSA was not originated.");
2127
2128 return 0;
2129}
2130
paul4dadc292005-05-06 21:37:42 +00002131static struct external_info *
paul020709f2003-04-04 02:44:16 +00002132ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002133{
2134 int type;
2135 struct route_node *rn;
2136 struct prefix_ipv4 p;
2137
2138 p.family = AF_INET;
2139 p.prefix.s_addr = 0;
2140 p.prefixlen = 0;
2141
2142 /* First, lookup redistributed default route. */
2143 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2144 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2145 {
2146 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2147 if (rn != NULL)
2148 {
2149 route_unlock_node (rn);
2150 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002151 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002152 return rn->info;
2153 }
2154 }
2155
2156 return NULL;
2157}
2158
2159int
paul68980082003-03-25 05:07:42 +00002160ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002161{
paul718e3742002-12-13 20:15:29 +00002162 struct prefix_ipv4 p;
2163 struct in_addr nexthop;
2164 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002165 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002166
Paul Jakma4021b602006-05-12 22:55:41 +00002167 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002168
2169 p.family = AF_INET;
2170 p.prefix.s_addr = 0;
2171 p.prefixlen = 0;
2172
Paul Jakma4021b602006-05-12 22:55:41 +00002173 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002174 {
2175 /* If there is no default route via redistribute,
2176 then originate AS-external-LSA with nexthop 0 (self). */
2177 nexthop.s_addr = 0;
2178 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2179 }
2180
paul020709f2003-04-04 02:44:16 +00002181 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002182 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002183
2184 return 0;
2185}
2186
paul645878f2003-04-13 21:42:11 +00002187/* Flush any NSSA LSAs for given prefix */
2188void
2189ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2190{
paul1eb8ef22005-04-07 07:30:20 +00002191 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002192 struct ospf_lsa *lsa;
2193 struct ospf_area *area;
2194
paul1eb8ef22005-04-07 07:30:20 +00002195 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002196 {
paul1eb8ef22005-04-07 07:30:20 +00002197 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002198 {
2199 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2200 ospf->router_id)))
2201 {
2202 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002203 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002204 inet_ntoa (p->prefix), p->prefixlen);
2205 continue;
2206 }
2207 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2208 if (!IS_LSA_MAXAGE (lsa))
2209 {
2210 ospf_refresher_unregister_lsa (ospf, lsa);
2211 ospf_lsa_flush_area (lsa, area);
2212 }
2213 }
paul645878f2003-04-13 21:42:11 +00002214 }
2215}
paul645878f2003-04-13 21:42:11 +00002216
paul718e3742002-12-13 20:15:29 +00002217/* Flush an AS-external-LSA from LSDB and routing domain. */
2218void
paul68980082003-03-25 05:07:42 +00002219ospf_external_lsa_flush (struct ospf *ospf,
2220 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002221 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002222{
2223 struct ospf_lsa *lsa;
2224
2225 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002226 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002227 inet_ntoa (p->prefix), p->prefixlen);
2228
2229 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002230 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002231 {
2232 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002233 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002234 inet_ntoa (p->prefix), p->prefixlen);
2235 return;
2236 }
hassobeebba72004-06-20 21:00:27 +00002237
pauld4a53d52003-07-12 21:30:57 +00002238 /* If LSA is selforiginated, not a translated LSA, and there is
2239 * NSSA area, flush Type-7 LSA's at first.
2240 */
2241 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2242 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002243 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002244
2245 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002246 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002247
2248 /* There must be no self-originated LSA in rtrs_external. */
2249#if 0
2250 /* Remove External route from Zebra. */
2251 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2252#endif
2253
2254 if (!IS_LSA_MAXAGE (lsa))
2255 {
2256 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002257 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002258
2259 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002260 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002261 }
2262
2263 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002264 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002265}
2266
2267void
paul68980082003-03-25 05:07:42 +00002268ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002269{
2270 struct prefix_ipv4 p;
2271 struct external_info *ei;
2272 struct ospf_lsa *lsa;
2273
2274 p.family = AF_INET;
2275 p.prefixlen = 0;
2276 p.prefix.s_addr = 0;
2277
paul020709f2003-04-04 02:44:16 +00002278 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002279 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002280
2281 if (ei)
2282 {
2283 if (lsa)
2284 {
2285 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002286 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002287 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002288 }
2289 else
2290 {
2291 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002292 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002293 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002294 }
2295 }
2296 else
2297 {
2298 if (lsa)
2299 {
2300 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002301 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002302 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002303 }
2304 }
2305}
2306
2307void
paul68980082003-03-25 05:07:42 +00002308ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002309{
2310 struct route_node *rn;
2311 struct external_info *ei;
2312
2313 if (type != DEFAULT_ROUTE)
2314 if (EXTERNAL_INFO(type))
2315 /* Refresh each redistributed AS-external-LSAs. */
2316 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2317 if ((ei = rn->info))
2318 if (!is_prefix_default (&ei->p))
2319 {
2320 struct ospf_lsa *lsa;
2321
paul68980082003-03-25 05:07:42 +00002322 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2323 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002324 else
paul68980082003-03-25 05:07:42 +00002325 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002326 }
2327}
2328
2329/* Refresh AS-external-LSA. */
2330void
paul68980082003-03-25 05:07:42 +00002331ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002332 struct external_info *ei, int force)
2333{
2334 struct ospf_lsa *new;
2335 int changed;
2336
2337 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002338 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002339 {
pauld4a53d52003-07-12 21:30:57 +00002340 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002341 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002342 "redist check fail",
2343 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002344 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002345 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +00002346 return;
2347 }
2348
2349 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002350 {
2351 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002352 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002353 lsa->data->type, inet_ntoa (lsa->data->id));
2354 return;
2355 }
paul718e3742002-12-13 20:15:29 +00002356
2357 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002358 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002359
2360 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002361 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002362
paul68980082003-03-25 05:07:42 +00002363 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002364
2365 if (new == NULL)
2366 {
2367 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002368 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002369 inet_ntoa (lsa->data->id));
2370 return;
2371 }
2372
2373 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2374
paul68980082003-03-25 05:07:42 +00002375 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002376
2377 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002378 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002379
paul718e3742002-12-13 20:15:29 +00002380 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002381 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002382 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002383
pauld4a53d52003-07-12 21:30:57 +00002384 /* Register self-originated LSA to refresh queue.
2385 * Translated LSAs should not be registered, but refreshed upon
2386 * refresh of the Type-7
2387 */
2388 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2389 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002390
2391 /* Debug logging. */
2392 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2393 {
ajse588f212004-12-08 18:12:06 +00002394 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002395 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002396 ospf_lsa_header_dump (new->data);
2397 }
2398
2399 return;
2400}
2401
2402
2403/* LSA installation functions. */
2404
2405/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002406static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002407ospf_router_lsa_install (struct ospf *ospf,
2408 struct ospf_lsa *new, int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002409{
2410 struct ospf_area *area = new->area;
2411
2412 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2413 The entire routing table must be recalculated, starting with
2414 the shortest path calculations for each area (not just the
2415 area whose link-state database has changed).
2416 */
paul718e3742002-12-13 20:15:29 +00002417
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002418 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002419 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002420
2421 /* Only install LSA if it is originated/refreshed by us.
2422 * If LSA was received by flooding, the RECEIVED flag is set so do
2423 * not link the LSA */
2424 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2425 return new; /* ignore stale LSA */
2426
paul718e3742002-12-13 20:15:29 +00002427 /* Set router-LSA refresh timer. */
2428 OSPF_TIMER_OFF (area->t_router_lsa_self);
2429 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
pauld4a53d52003-07-12 21:30:57 +00002430 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002431
paul718e3742002-12-13 20:15:29 +00002432 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002433 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002434 area->router_lsa_self = ospf_lsa_lock (new);
2435
paul718e3742002-12-13 20:15:29 +00002436 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002437 if (rt_recalc)
2438 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002439
2440 return new;
2441}
2442
2443#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2444 if (!(T)) \
2445 (T) = thread_add_timer (master, (F), oi, (V))
2446
2447/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002448static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002449ospf_network_lsa_install (struct ospf *ospf,
2450 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002451 struct ospf_lsa *new,
2452 int rt_recalc)
2453{
2454
2455 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2456 The entire routing table must be recalculated, starting with
2457 the shortest path calculations for each area (not just the
2458 area whose link-state database has changed).
2459 */
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002460 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002461 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002462 /* We supposed that when LSA is originated by us, we pass the int
2463 for which it was originated. If LSA was received by flooding,
2464 the RECEIVED flag is set, so we do not link the LSA to the int. */
2465 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2466 return new; /* ignore stale LSA */
2467
paul718e3742002-12-13 20:15:29 +00002468 /* Set LSRefresh timer. */
2469 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2470
2471 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2472 ospf_network_lsa_refresh_timer,
2473 OSPF_LS_REFRESH_TIME);
2474
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002475 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002476 oi->network_lsa_self = ospf_lsa_lock (new);
2477 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002478 if (rt_recalc)
2479 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002480
2481 return new;
2482}
2483
2484/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002485static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002486ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2487 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002488{
paul718e3742002-12-13 20:15:29 +00002489 if (rt_recalc && !IS_LSA_SELF (new))
2490 {
2491 /* RFC 2328 Section 13.2 Summary-LSAs
2492 The best route to the destination described by the summary-
2493 LSA must be recalculated (see Section 16.5). If this
2494 destination is an AS boundary router, it may also be
2495 necessary to re-examine all the AS-external-LSAs.
2496 */
2497
2498#if 0
2499 /* This doesn't exist yet... */
2500 ospf_summary_incremental_update(new); */
2501#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002502 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002503#endif /* #if 0 */
2504
2505 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002506 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002507 }
2508
2509 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002510 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002511
2512 return new;
2513}
2514
2515/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002516static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002517ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2518 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002519{
2520 if (rt_recalc && !IS_LSA_SELF (new))
2521 {
2522 /* RFC 2328 Section 13.2 Summary-LSAs
2523 The best route to the destination described by the summary-
2524 LSA must be recalculated (see Section 16.5). If this
2525 destination is an AS boundary router, it may also be
2526 necessary to re-examine all the AS-external-LSAs.
2527 */
2528#if 0
2529 /* These don't exist yet... */
2530 ospf_summary_incremental_update(new);
2531 /* Isn't this done by the above call?
2532 - RFC 2328 Section 16.5 implies it should be */
2533 /* ospf_ase_calculate_schedule(); */
2534#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002535 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002536#endif /* #if 0 */
2537 }
2538
2539 /* register LSA to refresh-list. */
2540 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002541 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002542
2543 return new;
2544}
2545
2546/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002547static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002548ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2549 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002550{
paul68980082003-03-25 05:07:42 +00002551 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002552 /* If LSA is not self-originated, calculate an external route. */
2553 if (rt_recalc)
2554 {
2555 /* RFC 2328 Section 13.2 AS-external-LSAs
2556 The best route to the destination described by the AS-
2557 external-LSA must be recalculated (see Section 16.6).
2558 */
2559
2560 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002561 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002562 }
2563
pauld4a53d52003-07-12 21:30:57 +00002564 if (new->data->type == OSPF_AS_NSSA_LSA)
2565 {
2566 /* There is no point to register selforiginate Type-7 LSA for
2567 * refreshing. We rely on refreshing Type-5 LSA's
2568 */
2569 if (IS_LSA_SELF (new))
2570 return new;
2571 else
2572 {
2573 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2574 * New translations will be taken care of by the abr_task.
2575 */
2576 ospf_translated_nssa_refresh (ospf, new, NULL);
2577 }
2578 }
pauld7480322003-05-16 17:31:51 +00002579
pauld4a53d52003-07-12 21:30:57 +00002580 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002581 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002582 */
hassobeebba72004-06-20 21:00:27 +00002583 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002584 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002585
2586 return new;
2587}
2588
2589void
paul68980082003-03-25 05:07:42 +00002590ospf_discard_from_db (struct ospf *ospf,
2591 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002592{
2593 struct ospf_lsa *old;
2594
Paul Jakmaac904de2006-06-15 12:04:57 +00002595 if (!lsdb)
2596 {
2597 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2598 if (!lsa)
2599 zlog_warn ("%s: and NULL LSA!", __func__);
2600 else
2601 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2602 lsa->data->type, inet_ntoa (lsa->data->id));
2603 return;
2604 }
2605
paul718e3742002-12-13 20:15:29 +00002606 old = ospf_lsdb_lookup (lsdb, lsa);
2607
2608 if (!old)
2609 return;
2610
2611 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002612 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002613
2614 switch (old->data->type)
2615 {
2616 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002617 ospf_ase_unregister_external_lsa (old, ospf);
2618 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2619 break;
paul718e3742002-12-13 20:15:29 +00002620#ifdef HAVE_OPAQUE_LSA
2621 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002622 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002623 break;
paul69310a62005-05-11 18:09:59 +00002624#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002625 case OSPF_AS_NSSA_LSA:
2626 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2627 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002628 break;
paul718e3742002-12-13 20:15:29 +00002629 default:
paul68980082003-03-25 05:07:42 +00002630 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002631 break;
2632 }
2633
paul68980082003-03-25 05:07:42 +00002634 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002635 ospf_lsa_discard (old);
2636}
2637
paul718e3742002-12-13 20:15:29 +00002638struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002639ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2640 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002641{
2642 struct ospf_lsa *new = NULL;
2643 struct ospf_lsa *old = NULL;
2644 struct ospf_lsdb *lsdb = NULL;
2645 int rt_recalc;
2646
2647 /* Set LSDB. */
2648 switch (lsa->data->type)
2649 {
paulf2c80652002-12-13 21:44:27 +00002650 /* kevinm */
2651 case OSPF_AS_NSSA_LSA:
2652 if (lsa->area)
2653 lsdb = lsa->area->lsdb;
2654 else
paul68980082003-03-25 05:07:42 +00002655 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002656 break;
paul718e3742002-12-13 20:15:29 +00002657 case OSPF_AS_EXTERNAL_LSA:
2658#ifdef HAVE_OPAQUE_LSA
2659 case OSPF_OPAQUE_AS_LSA:
2660#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002661 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002662 break;
2663 default:
2664 lsdb = lsa->area->lsdb;
2665 break;
2666 }
2667
paul718e3742002-12-13 20:15:29 +00002668 assert (lsdb);
2669
2670 /* RFC 2328 13.2. Installing LSAs in the database
2671
2672 Installing a new LSA in the database, either as the result of
2673 flooding or a newly self-originated LSA, may cause the OSPF
2674 routing table structure to be recalculated. The contents of the
2675 new LSA should be compared to the old instance, if present. If
2676 there is no difference, there is no need to recalculate the
2677 routing table. When comparing an LSA to its previous instance,
2678 the following are all considered to be differences in contents:
2679
2680 o The LSA's Options field has changed.
2681
2682 o One of the LSA instances has LS age set to MaxAge, and
2683 the other does not.
2684
2685 o The length field in the LSA header has changed.
2686
2687 o The body of the LSA (i.e., anything outside the 20-byte
2688 LSA header) has changed. Note that this excludes changes
2689 in LS Sequence Number and LS Checksum.
2690
2691 */
2692 /* Look up old LSA and determine if any SPF calculation or incremental
2693 update is needed */
2694 old = ospf_lsdb_lookup (lsdb, lsa);
2695
2696 /* Do comparision and record if recalc needed. */
2697 rt_recalc = 0;
2698 if ( old == NULL || ospf_lsa_different(old, lsa))
2699 rt_recalc = 1;
2700
paul7ddf1d62003-10-13 09:06:46 +00002701 /*
2702 Sequence number check (Section 14.1 of rfc 2328)
2703 "Premature aging is used when it is time for a self-originated
2704 LSA's sequence number field to wrap. At this point, the current
2705 LSA instance (having LS sequence number MaxSequenceNumber) must
2706 be prematurely aged and flushed from the routing domain before a
2707 new instance with sequence number equal to InitialSequenceNumber
2708 can be originated. "
2709 */
2710
Paul Jakmac2b478d2006-03-30 14:16:11 +00002711 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002712 {
2713 if (ospf_lsa_is_self_originated(ospf, lsa))
2714 {
paul0c2be262004-05-31 14:16:54 +00002715 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2716
2717 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002718 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2719 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2720
2721 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2722 {
ajse588f212004-12-08 18:12:06 +00002723 zlog_debug ("ospf_lsa_install() Premature Aging "
paul7ddf1d62003-10-13 09:06:46 +00002724 "lsa 0x%lx", (u_long)lsa);
2725 ospf_lsa_header_dump (lsa->data);
2726 }
2727 }
2728 else
2729 {
2730 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2731 {
ajse588f212004-12-08 18:12:06 +00002732 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002733 "that was not self originated. Ignoring\n");
2734 ospf_lsa_header_dump (lsa->data);
2735 }
2736 return old;
2737 }
2738 }
2739
paul718e3742002-12-13 20:15:29 +00002740 /* discard old LSA from LSDB */
2741 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002742 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002743
paul718e3742002-12-13 20:15:29 +00002744 /* Calculate Checksum if self-originated?. */
2745 if (IS_LSA_SELF (lsa))
2746 ospf_lsa_checksum (lsa->data);
2747
hassofe71a972004-12-22 16:16:02 +00002748 /* Insert LSA to LSDB. */
2749 ospf_lsdb_add (lsdb, lsa);
2750 lsa->lsdb = lsdb;
2751
paul718e3742002-12-13 20:15:29 +00002752 /* Do LSA specific installation process. */
2753 switch (lsa->data->type)
2754 {
2755 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002756 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002757 break;
2758 case OSPF_NETWORK_LSA:
2759 assert (oi);
paul68980082003-03-25 05:07:42 +00002760 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002761 break;
2762 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002763 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002764 break;
2765 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002766 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002767 break;
2768 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002769 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002770 break;
2771#ifdef HAVE_OPAQUE_LSA
2772 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002773 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002774 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002775 else
paul68980082003-03-25 05:07:42 +00002776 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002777 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002778 case OSPF_OPAQUE_AREA_LSA:
2779 case OSPF_OPAQUE_AS_LSA:
2780 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2781 break;
2782#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002783 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002784 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002785 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002786 break;
2787 }
2788
2789 if (new == NULL)
2790 return new; /* Installation failed, cannot proceed further -- endo. */
2791
2792 /* Debug logs. */
2793 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2794 {
2795 char area_str[INET_ADDRSTRLEN];
2796
2797 switch (lsa->data->type)
2798 {
2799 case OSPF_AS_EXTERNAL_LSA:
2800#ifdef HAVE_OPAQUE_LSA
2801 case OSPF_OPAQUE_AS_LSA:
2802#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002803 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002804 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002805 dump_lsa_key (new),
2806 LOOKUP (ospf_lsa_type_msg, new->data->type));
2807 break;
2808 default:
2809 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002810 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002811 dump_lsa_key (new),
2812 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2813 break;
2814 }
2815 }
2816
paul7ddf1d62003-10-13 09:06:46 +00002817 /*
2818 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2819 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2820 */
2821 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2822 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002823 {
paul7ddf1d62003-10-13 09:06:46 +00002824 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002825 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002826 new->data->type,
2827 inet_ntoa (new->data->id),
2828 lsa);
paul68980082003-03-25 05:07:42 +00002829 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002830 }
2831
2832 return new;
2833}
2834
2835
paul4dadc292005-05-06 21:37:42 +00002836static int
paul68980082003-03-25 05:07:42 +00002837ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002838{
paul1eb8ef22005-04-07 07:30:20 +00002839 struct listnode *node, *nnode;
2840 struct ospf_interface *oi;
2841
2842 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002843 {
paul718e3742002-12-13 20:15:29 +00002844 struct route_node *rn;
2845 struct ospf_neighbor *nbr;
2846
2847 if (ospf_if_is_enable (oi))
2848 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2849 if ((nbr = rn->info) != NULL)
2850 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2851 {
2852 route_unlock_node (rn);
2853 return 0;
2854 }
2855 }
2856
2857 return 1;
2858}
2859
2860
2861#ifdef ORIGINAL_CODING
2862/* This function flood the maxaged LSA to DR. */
2863void
2864ospf_maxage_flood (struct ospf_lsa *lsa)
2865{
2866 switch (lsa->data->type)
2867 {
2868 case OSPF_ROUTER_LSA:
2869 case OSPF_NETWORK_LSA:
2870 case OSPF_SUMMARY_LSA:
2871 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00002872 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00002873#ifdef HAVE_OPAQUE_LSA
2874 case OSPF_OPAQUE_LINK_LSA:
2875 case OSPF_OPAQUE_AREA_LSA:
2876#endif /* HAVE_OPAQUE_LSA */
2877 ospf_flood_through_area (lsa->area, NULL, lsa);
2878 break;
2879 case OSPF_AS_EXTERNAL_LSA:
2880#ifdef HAVE_OPAQUE_LSA
2881 case OSPF_OPAQUE_AS_LSA:
2882#endif /* HAVE_OPAQUE_LSA */
2883 ospf_flood_through_as (NULL, lsa);
2884 break;
2885 default:
2886 break;
2887 }
2888}
2889#endif /* ORIGINAL_CODING */
2890
paul4dadc292005-05-06 21:37:42 +00002891static int
paul718e3742002-12-13 20:15:29 +00002892ospf_maxage_lsa_remover (struct thread *thread)
2893{
paul68980082003-03-25 05:07:42 +00002894 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002895 struct ospf_lsa *lsa;
2896 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002897 int reschedule = 0;
2898
paul68980082003-03-25 05:07:42 +00002899 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002900
2901 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002902 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002903
paul68980082003-03-25 05:07:42 +00002904 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002905
2906 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002907 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002908 {
paul718e3742002-12-13 20:15:29 +00002909 if (lsa->retransmit_counter > 0)
2910 {
2911 reschedule = 1;
2912 continue;
2913 }
2914
2915 /* Remove LSA from the LSDB */
Denis Ovsienkof6247bf2011-10-24 18:17:09 +04002916 if (IS_LSA_SELF (lsa))
paul718e3742002-12-13 20:15:29 +00002917 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002918 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
paul7ddf1d62003-10-13 09:06:46 +00002919 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002920
2921 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002922 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002923 lsa->data->type, inet_ntoa (lsa->data->id));
2924
2925 /* Flood max age LSA. */
2926#ifdef ORIGINAL_CODING
2927 ospf_maxage_flood (lsa);
2928#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00002929 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00002930#endif /* ORIGINAL_CODING */
2931
paul7ddf1d62003-10-13 09:06:46 +00002932 if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
2933 {
2934 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002935 zlog_debug ("originating new router lsa for lsa 0x%lx \n",
paul7ddf1d62003-10-13 09:06:46 +00002936 (u_long)lsa);
2937 ospf_router_lsa_originate(lsa->area);
2938 }
2939
paul718e3742002-12-13 20:15:29 +00002940 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002941 if (lsa->lsdb)
2942 {
2943 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2944 ospf_lsdb_delete (lsa->lsdb, lsa);
2945 }
2946 else
2947 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2948 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002949 }
2950
2951 /* A MaxAge LSA must be removed immediately from the router's link
2952 state database as soon as both a) it is no longer contained on any
2953 neighbor Link state retransmission lists and b) none of the router's
2954 neighbors are in states Exchange or Loading. */
2955 if (reschedule)
paul68980082003-03-25 05:07:42 +00002956 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00002957
2958 return 0;
2959}
2960
paul718e3742002-12-13 20:15:29 +00002961void
paul68980082003-03-25 05:07:42 +00002962ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002963{
hasso52dc7ee2004-09-23 19:18:23 +00002964 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00002965
paul68980082003-03-25 05:07:42 +00002966 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00002967 {
paul68980082003-03-25 05:07:42 +00002968 list_delete_node (ospf->maxage_lsa, n);
Stephen Hemminger3106a032009-08-06 12:58:05 -07002969 UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002970 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +00002971 }
2972}
2973
2974void
paul68980082003-03-25 05:07:42 +00002975ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002976{
2977 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2978 and schedule the MaxAge LSA remover. */
Stephen Hemminger3106a032009-08-06 12:58:05 -07002979 if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
paul718e3742002-12-13 20:15:29 +00002980 {
2981 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002982 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00002983 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2984 return;
2985 }
2986
paul68980082003-03-25 05:07:42 +00002987 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
Stephen Hemminger3106a032009-08-06 12:58:05 -07002988 SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
paul718e3742002-12-13 20:15:29 +00002989
2990 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002991 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002992
paul68980082003-03-25 05:07:42 +00002993 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00002994}
2995
paul4dadc292005-05-06 21:37:42 +00002996static int
paul68980082003-03-25 05:07:42 +00002997ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002998{
paul718e3742002-12-13 20:15:29 +00002999 /* Stay away from any Local Translated Type-7 LSAs */
3000 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3001 return 0;
paul718e3742002-12-13 20:15:29 +00003002
3003 if (IS_LSA_MAXAGE (lsa))
3004 /* Self-originated LSAs should NOT time-out instead,
3005 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00003006 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003007 {
3008 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003009 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003010
3011 switch (lsa->data->type)
3012 {
paul718e3742002-12-13 20:15:29 +00003013#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00003014 case OSPF_OPAQUE_LINK_LSA:
3015 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003016 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003017 /*
3018 * As a general rule, whenever network topology has changed
3019 * (due to an LSA removal in this case), routing recalculation
3020 * should be triggered. However, this is not true for opaque
3021 * LSAs. Even if an opaque LSA instance is going to be removed
3022 * from the routing domain, it does not mean a change in network
3023 * topology, and thus, routing recalculation is not needed here.
3024 */
3025 break;
paul718e3742002-12-13 20:15:29 +00003026#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00003027 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003028 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003029 ospf_ase_incremental_update (ospf, lsa);
3030 break;
paul718e3742002-12-13 20:15:29 +00003031 default:
paul68980082003-03-25 05:07:42 +00003032 ospf_spf_calculate_schedule (ospf);
3033 break;
paul718e3742002-12-13 20:15:29 +00003034 }
paul68980082003-03-25 05:07:42 +00003035 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003036 }
3037
3038 return 0;
3039}
3040
3041/* Periodical check of MaxAge LSA. */
3042int
paul68980082003-03-25 05:07:42 +00003043ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003044{
paul68980082003-03-25 05:07:42 +00003045 struct ospf *ospf = THREAD_ARG (thread);
3046 struct route_node *rn;
3047 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003048 struct ospf_area *area;
3049 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003050
paul68980082003-03-25 05:07:42 +00003051 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003052
paul1eb8ef22005-04-07 07:30:20 +00003053 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003054 {
paul68980082003-03-25 05:07:42 +00003055 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3056 ospf_lsa_maxage_walker_remover (ospf, lsa);
3057 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3058 ospf_lsa_maxage_walker_remover (ospf, lsa);
3059 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3060 ospf_lsa_maxage_walker_remover (ospf, lsa);
3061 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3062 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003063#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003064 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3065 ospf_lsa_maxage_walker_remover (ospf, lsa);
3066 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3067 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003068#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003069 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3070 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003071 }
3072
paul4fb949e2003-05-10 20:06:51 +00003073 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003074 if (ospf->lsdb)
3075 {
3076 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3077 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003078#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003079 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3080 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003081#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003082 }
paul718e3742002-12-13 20:15:29 +00003083
paul68980082003-03-25 05:07:42 +00003084 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3085 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003086 return 0;
3087}
3088
paul68980082003-03-25 05:07:42 +00003089struct ospf_lsa *
3090ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3091 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003092{
paul68980082003-03-25 05:07:42 +00003093 struct ospf_lsa *lsa;
3094 struct in_addr mask, id;
3095 struct lsa_header_mask
3096 {
3097 struct lsa_header header;
3098 struct in_addr mask;
3099 } *hmask;
paul718e3742002-12-13 20:15:29 +00003100
paul68980082003-03-25 05:07:42 +00003101 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3102 if (lsa == NULL)
3103 return NULL;
paul718e3742002-12-13 20:15:29 +00003104
paul68980082003-03-25 05:07:42 +00003105 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003106
paul68980082003-03-25 05:07:42 +00003107 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003108
paul68980082003-03-25 05:07:42 +00003109 if (mask.s_addr != hmask->mask.s_addr)
3110 {
3111 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3112 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3113 if (!lsa)
3114 return NULL;
3115 }
paul718e3742002-12-13 20:15:29 +00003116
paul68980082003-03-25 05:07:42 +00003117 return lsa;
paul718e3742002-12-13 20:15:29 +00003118}
3119
3120struct ospf_lsa *
3121ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3122 struct in_addr id, struct in_addr adv_router)
3123{
paule05fba42003-04-13 20:20:53 +00003124 struct ospf *ospf = ospf_lookup();
3125 assert(ospf);
3126
paul718e3742002-12-13 20:15:29 +00003127 switch (type)
3128 {
3129 case OSPF_ROUTER_LSA:
3130 case OSPF_NETWORK_LSA:
3131 case OSPF_SUMMARY_LSA:
3132 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003133 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003134#ifdef HAVE_OPAQUE_LSA
3135 case OSPF_OPAQUE_LINK_LSA:
3136 case OSPF_OPAQUE_AREA_LSA:
3137#endif /* HAVE_OPAQUE_LSA */
3138 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003139 case OSPF_AS_EXTERNAL_LSA:
3140#ifdef HAVE_OPAQUE_LSA
3141 case OSPF_OPAQUE_AS_LSA:
3142#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003143 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003144 default:
3145 break;
3146 }
3147
3148 return NULL;
3149}
3150
3151struct ospf_lsa *
3152ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3153 struct in_addr id)
3154{
3155 struct ospf_lsa *lsa;
3156 struct route_node *rn;
3157
3158 switch (type)
3159 {
3160 case OSPF_ROUTER_LSA:
3161 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003162 case OSPF_NETWORK_LSA:
3163 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3164 if ((lsa = rn->info))
3165 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3166 {
3167 route_unlock_node (rn);
3168 return lsa;
3169 }
3170 break;
3171 case OSPF_SUMMARY_LSA:
3172 case OSPF_ASBR_SUMMARY_LSA:
3173 /* Currently not used. */
3174 assert (1);
3175 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003176 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003177 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003178#ifdef HAVE_OPAQUE_LSA
3179 case OSPF_OPAQUE_LINK_LSA:
3180 case OSPF_OPAQUE_AREA_LSA:
3181 case OSPF_OPAQUE_AS_LSA:
3182 /* Currently not used. */
3183 break;
3184#endif /* HAVE_OPAQUE_LSA */
3185 default:
3186 break;
3187 }
3188
3189 return NULL;
3190}
3191
3192struct ospf_lsa *
3193ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3194{
3195 struct ospf_lsa *match;
3196
3197#ifdef HAVE_OPAQUE_LSA
3198 /*
3199 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3200 * is redefined to have two subfields; opaque-type and opaque-id.
3201 * However, it is harmless to treat the two sub fields together, as if
3202 * they two were forming a unique LSA-ID.
3203 */
3204#endif /* HAVE_OPAQUE_LSA */
3205
3206 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3207
3208 if (match == NULL)
3209 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003210 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003211 lsah->type, inet_ntoa (lsah->id));
3212
3213 return match;
3214}
3215
3216/* return +n, l1 is more recent.
3217 return -n, l2 is more recent.
3218 return 0, l1 and l2 is identical. */
3219int
3220ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3221{
3222 int r;
3223 int x, y;
3224
3225 if (l1 == NULL && l2 == NULL)
3226 return 0;
3227 if (l1 == NULL)
3228 return -1;
3229 if (l2 == NULL)
3230 return 1;
3231
3232 /* compare LS sequence number. */
3233 x = (int) ntohl (l1->data->ls_seqnum);
3234 y = (int) ntohl (l2->data->ls_seqnum);
3235 if (x > y)
3236 return 1;
3237 if (x < y)
3238 return -1;
3239
3240 /* compare LS checksum. */
3241 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3242 if (r)
3243 return r;
3244
3245 /* compare LS age. */
3246 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3247 return 1;
3248 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3249 return -1;
3250
3251 /* compare LS age with MaxAgeDiff. */
3252 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3253 return -1;
3254 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3255 return 1;
3256
3257 /* LSAs are identical. */
3258 return 0;
3259}
3260
3261/* If two LSAs are different, return 1, otherwise return 0. */
3262int
3263ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3264{
3265 char *p1, *p2;
3266 assert (l1);
3267 assert (l2);
3268 assert (l1->data);
3269 assert (l2->data);
3270
3271 if (l1->data->options != l2->data->options)
3272 return 1;
3273
3274 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3275 return 1;
3276
3277 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3278 return 1;
3279
3280 if (l1->data->length != l2->data->length)
3281 return 1;
3282
3283 if (l1->data->length == 0)
3284 return 1;
3285
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02003286 if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
3287 return 1; /* May be a stale LSA in the LSBD */
3288
pauld1825832003-04-03 01:27:01 +00003289 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003290
3291 p1 = (char *) l1->data;
3292 p2 = (char *) l2->data;
3293
3294 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3295 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3296 return 1;
3297
3298 return 0;
3299}
3300
3301#ifdef ORIGINAL_CODING
3302void
3303ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3304 struct ospf_lsa *self,
3305 struct ospf_lsa *new)
3306{
3307 u_int32_t seqnum;
3308
3309 /* Adjust LS Sequence Number. */
3310 seqnum = ntohl (new->data->ls_seqnum) + 1;
3311 self->data->ls_seqnum = htonl (seqnum);
3312
3313 /* Recalculate LSA checksum. */
3314 ospf_lsa_checksum (self->data);
3315
3316 /* Reflooding LSA. */
3317 /* RFC2328 Section 13.3
3318 On non-broadcast networks, separate Link State Update
3319 packets must be sent, as unicasts, to each adjacent neighbor
3320 (i.e., those in state Exchange or greater). The destination
3321 IP addresses for these packets are the neighbors' IP
3322 addresses. */
3323 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3324 {
3325 struct route_node *rn;
3326 struct ospf_neighbor *onbr;
3327
3328 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3329 if ((onbr = rn->info) != NULL)
3330 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3331 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3332 }
3333 else
3334 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3335
3336 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003337 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003338 self->data->type, inet_ntoa (self->data->id));
3339}
3340#else /* ORIGINAL_CODING */
3341static int
paul68980082003-03-25 05:07:42 +00003342ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003343{
3344 if (lsa == NULL || !IS_LSA_SELF (lsa))
3345 return 0;
3346
3347 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003348 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 +00003349
3350 /* Force given lsa's age to MaxAge. */
3351 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3352
3353 switch (lsa->data->type)
3354 {
3355#ifdef HAVE_OPAQUE_LSA
3356 case OSPF_OPAQUE_LINK_LSA:
3357 case OSPF_OPAQUE_AREA_LSA:
3358 case OSPF_OPAQUE_AS_LSA:
3359 ospf_opaque_lsa_refresh (lsa);
3360 break;
3361#endif /* HAVE_OPAQUE_LSA */
3362 default:
paul68980082003-03-25 05:07:42 +00003363 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003364 break;
3365 }
3366
3367 return 0;
3368}
3369
3370void
paul68980082003-03-25 05:07:42 +00003371ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003372{
paul1eb8ef22005-04-07 07:30:20 +00003373 struct listnode *node, *nnode;
3374 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003375 struct ospf_area *area;
3376 struct ospf_interface *oi;
3377 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003378 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003379 int need_to_flush_ase = 0;
3380
paul1eb8ef22005-04-07 07:30:20 +00003381 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003382 {
paul718e3742002-12-13 20:15:29 +00003383 if ((lsa = area->router_lsa_self) != NULL)
3384 {
3385 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003386 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 +00003387
3388 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003389 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003390 area->router_lsa_self = NULL;
3391 OSPF_TIMER_OFF (area->t_router_lsa_self);
3392 }
3393
paul1eb8ef22005-04-07 07:30:20 +00003394 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003395 {
paul718e3742002-12-13 20:15:29 +00003396 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003397 && oi->state == ISM_DR
3398 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003399 {
3400 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003401 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 +00003402
3403 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003404 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003405 oi->network_lsa_self = NULL;
3406 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3407 }
3408
3409 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3410 && area->external_routing == OSPF_AREA_DEFAULT)
3411 need_to_flush_ase = 1;
3412 }
3413
paul68980082003-03-25 05:07:42 +00003414 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3415 ospf_lsa_flush_schedule (ospf, lsa);
3416 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3417 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003418#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003419 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3420 ospf_lsa_flush_schedule (ospf, lsa);
3421 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3422 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003423#endif /* HAVE_OPAQUE_LSA */
3424 }
3425
3426 if (need_to_flush_ase)
3427 {
paul68980082003-03-25 05:07:42 +00003428 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3429 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003430#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003431 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3432 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003433#endif /* HAVE_OPAQUE_LSA */
3434 }
3435
3436 /*
3437 * Make sure that the MaxAge LSA remover is executed immediately,
3438 * without conflicting to other threads.
3439 */
paul68980082003-03-25 05:07:42 +00003440 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003441 {
paul68980082003-03-25 05:07:42 +00003442 OSPF_TIMER_OFF (ospf->t_maxage);
3443 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003444 }
3445
3446 return;
3447}
3448#endif /* ORIGINAL_CODING */
3449
3450/* If there is self-originated LSA, then return 1, otherwise return 0. */
3451/* An interface-independent version of ospf_lsa_is_self_originated */
3452int
paul68980082003-03-25 05:07:42 +00003453ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003454{
hasso52dc7ee2004-09-23 19:18:23 +00003455 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003456 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003457
3458 /* This LSA is already checked. */
3459 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
Denis Ovsienkof6247bf2011-10-24 18:17:09 +04003460 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003461
3462 /* Make sure LSA is self-checked. */
3463 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3464
3465 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003466 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003467 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3468
3469 /* LSA is router-LSA. */
3470 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003471 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003472 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3473
3474 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3475 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003476 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003477 {
paul718e3742002-12-13 20:15:29 +00003478 /* Ignore virtual link. */
3479 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3480 if (oi->address->family == AF_INET)
3481 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3482 {
3483 /* to make it easier later */
3484 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
Denis Ovsienkof6247bf2011-10-24 18:17:09 +04003485 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003486 }
3487 }
3488
Denis Ovsienkof6247bf2011-10-24 18:17:09 +04003489 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003490}
3491
3492/* Get unique Link State ID. */
3493struct in_addr
paul68980082003-03-25 05:07:42 +00003494ospf_lsa_unique_id (struct ospf *ospf,
3495 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003496{
3497 struct ospf_lsa *lsa;
3498 struct in_addr mask, id;
3499
3500 id = p->prefix;
3501
3502 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003503 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003504 if (lsa)
3505 {
3506 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3507 if (ip_masklen (al->mask) == p->prefixlen)
3508 {
3509 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003510 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003511 "Can't get Link State ID for %s/%d",
3512 inet_ntoa (p->prefix), p->prefixlen);
3513 /* id.s_addr = 0; */
3514 id.s_addr = 0xffffffff;
3515 return id;
3516 }
3517 /* Masklen differs, then apply wildcard mask to Link State ID. */
3518 else
3519 {
3520 masklen2ip (p->prefixlen, &mask);
3521
3522 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003523 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3524 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003525 if (lsa)
3526 {
3527 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003528 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003529 "Can't get Link State ID for %s/%d",
3530 inet_ntoa (p->prefix), p->prefixlen);
3531 /* id.s_addr = 0; */
3532 id.s_addr = 0xffffffff;
3533 return id;
3534 }
3535 }
3536 }
3537
3538 return id;
3539}
3540
3541
Paul Jakma70461d72006-05-12 22:57:57 +00003542#define LSA_ACTION_FLOOD_AREA 1
3543#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003544
3545struct lsa_action
3546{
3547 u_char action;
3548 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003549 struct ospf_lsa *lsa;
3550};
3551
paul4dadc292005-05-06 21:37:42 +00003552static int
paul718e3742002-12-13 20:15:29 +00003553ospf_lsa_action (struct thread *t)
3554{
3555 struct lsa_action *data;
3556
3557 data = THREAD_ARG (t);
3558
3559 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003560 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003561 data->action);
3562
3563 switch (data->action)
3564 {
paul718e3742002-12-13 20:15:29 +00003565 case LSA_ACTION_FLOOD_AREA:
3566 ospf_flood_through_area (data->area, NULL, data->lsa);
3567 break;
paul718e3742002-12-13 20:15:29 +00003568 case LSA_ACTION_FLUSH_AREA:
3569 ospf_lsa_flush_area (data->lsa, data->area);
3570 break;
paul718e3742002-12-13 20:15:29 +00003571 }
3572
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003573 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003574 XFREE (MTYPE_OSPF_MESSAGE, data);
3575 return 0;
3576}
3577
3578void
3579ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3580{
3581 struct lsa_action *data;
3582
Stephen Hemminger393deb92008-08-18 14:13:29 -07003583 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003584 data->action = LSA_ACTION_FLOOD_AREA;
3585 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003586 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003587
3588 thread_add_event (master, ospf_lsa_action, data, 0);
3589}
3590
3591void
3592ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3593{
3594 struct lsa_action *data;
3595
Stephen Hemminger393deb92008-08-18 14:13:29 -07003596 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003597 data->action = LSA_ACTION_FLUSH_AREA;
3598 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003599 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003600
3601 thread_add_event (master, ospf_lsa_action, data, 0);
3602}
3603
3604
3605/* LSA Refreshment functions. */
paul4dadc292005-05-06 21:37:42 +00003606static void
paul68980082003-03-25 05:07:42 +00003607ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003608{
3609 struct external_info *ei;
Denis Ovsienkof6247bf2011-10-24 18:17:09 +04003610 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003611
3612 switch (lsa->data->type)
3613 {
3614 /* Router and Network LSAs are processed differently. */
3615 case OSPF_ROUTER_LSA:
3616 case OSPF_NETWORK_LSA:
3617 break;
3618 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003619 ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003620 break;
3621 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003622 ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003623 break;
3624 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003625 /* Translated from NSSA Type-5s are refreshed when
3626 * from refresh of Type-7 - do not refresh these directly.
3627 */
3628 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3629 break;
paul718e3742002-12-13 20:15:29 +00003630 ei = ospf_external_info_check (lsa);
3631 if (ei)
pauld4a53d52003-07-12 21:30:57 +00003632 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003633 else
pauld4a53d52003-07-12 21:30:57 +00003634 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003635 break;
3636#ifdef HAVE_OPAQUE_LSA
3637 case OSPF_OPAQUE_LINK_LSA:
3638 case OSPF_OPAQUE_AREA_LSA:
3639 case OSPF_OPAQUE_AS_LSA:
3640 ospf_opaque_lsa_refresh (lsa);
3641 break;
pauld7480322003-05-16 17:31:51 +00003642#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003643 default:
3644 break;
paul718e3742002-12-13 20:15:29 +00003645 }
3646}
3647
3648void
paul68980082003-03-25 05:07:42 +00003649ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003650{
3651 u_int16_t index, current_index;
3652
Denis Ovsienkof6247bf2011-10-24 18:17:09 +04003653 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003654
3655 if (lsa->refresh_list < 0)
3656 {
3657 int delay;
3658
3659 if (LS_AGE (lsa) == 0 &&
3660 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3661 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3662 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3663 else
3664 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3665 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3666 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3667
3668 if (delay < 0)
3669 delay = 0;
3670
paul68980082003-03-25 05:07:42 +00003671 current_index = ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003672 (quagga_time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003673
3674 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3675 % (OSPF_LSA_REFRESHER_SLOTS);
3676
3677 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003678 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003679 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003680 if (!ospf->lsa_refresh_queue.qs[index])
3681 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003682 listnode_add (ospf->lsa_refresh_queue.qs[index],
3683 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003684 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003685 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003686 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
Denis Ovsienko5c8d16f2011-10-22 22:18:55 +04003687 "setting refresh_list on lsa %p (index %u)",
pauld4a53d52003-07-12 21:30:57 +00003688 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003689 }
3690}
3691
3692void
paul68980082003-03-25 05:07:42 +00003693ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003694{
Denis Ovsienkof6247bf2011-10-24 18:17:09 +04003695 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003696 if (lsa->refresh_list >= 0)
3697 {
hasso52dc7ee2004-09-23 19:18:23 +00003698 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003699 listnode_delete (refresh_list, lsa);
3700 if (!listcount (refresh_list))
3701 {
3702 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003703 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003704 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003705 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003706 lsa->refresh_list = -1;
3707 }
3708}
3709
3710int
3711ospf_lsa_refresh_walker (struct thread *t)
3712{
hasso52dc7ee2004-09-23 19:18:23 +00003713 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003714 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003715 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003716 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003717 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003718 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003719
3720 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003721 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003722
3723
paul68980082003-03-25 05:07:42 +00003724 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003725
ajs9dbc7972005-03-13 19:27:22 +00003726 /* Note: if clock has jumped backwards, then time change could be negative,
3727 so we are careful to cast the expression to unsigned before taking
3728 modulus. */
paul68980082003-03-25 05:07:42 +00003729 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003730 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003731 (quagga_time (NULL) - ospf->lsa_refresher_started) /
ajs9dbc7972005-03-13 19:27:22 +00003732 OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003733
3734 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003735 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003736 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003737
paul68980082003-03-25 05:07:42 +00003738 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003739 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3740 {
3741 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003742 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003743 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003744
paul68980082003-03-25 05:07:42 +00003745 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003746
paul68980082003-03-25 05:07:42 +00003747 ospf->lsa_refresh_queue.qs [i] = NULL;
3748
paul718e3742002-12-13 20:15:29 +00003749 if (refresh_list)
3750 {
paul1eb8ef22005-04-07 07:30:20 +00003751 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003752 {
paul718e3742002-12-13 20:15:29 +00003753 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003754 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003755 "refresh lsa %p (slot %d)",
3756 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003757
3758 list_delete_node (refresh_list, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003759 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003760 lsa->refresh_list = -1;
3761 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003762 }
3763 list_free (refresh_list);
3764 }
3765 }
3766
paul68980082003-03-25 05:07:42 +00003767 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3768 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003769 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003770
paul1eb8ef22005-04-07 07:30:20 +00003771 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
3772 ospf_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003773
3774 list_delete (lsa_to_refresh);
3775
3776 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003777 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003778
3779 return 0;
3780}
3781