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