blob: acc9c3f497e6906f351550c969a88635a51716c6 [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;
Paul Jakma4ca15d42009-08-03 15:16:41 +01001531
1532 /* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be
1533 * better to make use of the per-ifp table of ois.
1534 */
paul1eb8ef22005-04-07 07:30:20 +00001535 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1536 if (if_is_operative (oi->ifp))
1537 if (oi->address->family == AF_INET)
1538 if (prefix_match (oi->address, &nh))
1539 return nexthop;
paul718e3742002-12-13 20:15:29 +00001540
1541 return fwd;
1542}
1543
paul718e3742002-12-13 20:15:29 +00001544/* NSSA-external-LSA related functions. */
1545
1546/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001547
paul718e3742002-12-13 20:15:29 +00001548struct in_addr
1549ospf_get_ip_from_ifp (struct ospf_interface *oi)
1550{
1551 struct in_addr fwd;
1552
1553 fwd.s_addr = 0;
1554
paul2e3b2e42002-12-13 21:03:13 +00001555 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001556 return oi->address->u.prefix4;
1557
1558 return fwd;
1559}
1560
1561/* Get 1st IP connection for Forward Addr */
1562struct in_addr
paulf2c80652002-12-13 21:44:27 +00001563ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001564{
1565 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001566 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001567 struct listnode *node;
1568 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001569
1570 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001571 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001572
paul1eb8ef22005-04-07 07:30:20 +00001573 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001574 {
paul2e3b2e42002-12-13 21:03:13 +00001575 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001576 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001577 if (oi->address && oi->address->family == AF_INET)
1578 {
1579 if (best_default.s_addr == 0)
1580 best_default = oi->address->u.prefix4;
1581 if (oi->area == area)
1582 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001583 }
paul718e3742002-12-13 20:15:29 +00001584 }
paulf2c80652002-12-13 21:44:27 +00001585 if (best_default.s_addr != 0)
1586 return best_default;
paul718e3742002-12-13 20:15:29 +00001587
paul68980082003-03-25 05:07:42 +00001588 if (best_default.s_addr != 0)
1589 return best_default;
1590
paul718e3742002-12-13 20:15:29 +00001591 return fwd;
1592}
hassobeebba72004-06-20 21:00:27 +00001593
paul718e3742002-12-13 20:15:29 +00001594#define DEFAULT_DEFAULT_METRIC 20
1595#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1596#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1597
1598#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1599
1600int
paul68980082003-03-25 05:07:42 +00001601metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001602{
paul68980082003-03-25 05:07:42 +00001603 return (ospf->dmetric[src].type < 0 ?
1604 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001605}
1606
1607int
paul68980082003-03-25 05:07:42 +00001608metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001609{
paul68980082003-03-25 05:07:42 +00001610 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001611 {
1612 if (src == DEFAULT_ROUTE)
1613 {
paul68980082003-03-25 05:07:42 +00001614 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001615 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1616 else
1617 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1618 }
paul68980082003-03-25 05:07:42 +00001619 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001620 return DEFAULT_DEFAULT_METRIC;
1621 else
paul68980082003-03-25 05:07:42 +00001622 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001623 }
1624
paul68980082003-03-25 05:07:42 +00001625 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001626}
1627
1628/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001629static void
paul68980082003-03-25 05:07:42 +00001630ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1631 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001632{
1633 struct prefix_ipv4 *p = &ei->p;
1634 struct in_addr mask, fwd_addr;
1635 u_int32_t mvalue;
1636 int mtype;
1637 int type;
1638
1639 /* Put Network Mask. */
1640 masklen2ip (p->prefixlen, &mask);
1641 stream_put_ipv4 (s, mask.s_addr);
1642
1643 /* If prefix is default, specify DEFAULT_ROUTE. */
1644 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1645
1646 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001647 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001648
1649 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001650 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001651
1652 /* Put type of external metric. */
1653 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1654
1655 /* Put 0 metric. TOS metric is not supported. */
1656 stream_put_ospf_metric (s, mvalue);
1657
1658 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001659 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001660
1661 /* Put forwarding address. */
1662 stream_put_ipv4 (s, fwd_addr.s_addr);
1663
1664 /* Put route tag -- This value should be introduced from configuration. */
1665 stream_putl (s, 0);
1666}
1667
1668/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001669static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001670ospf_external_lsa_new (struct ospf *ospf,
1671 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001672{
1673 struct stream *s;
1674 struct lsa_header *lsah;
1675 struct ospf_lsa *new;
1676 struct in_addr id;
1677 int length;
1678
1679 if (ei == NULL)
1680 {
1681 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001682 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
paul718e3742002-12-13 20:15:29 +00001683 return NULL;
1684 }
1685
1686 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001687 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001688
1689 /* If old Link State ID is specified, refresh LSA with same ID. */
1690 if (old_id)
1691 id = *old_id;
1692 /* Get Link State with unique ID. */
1693 else
1694 {
paul68980082003-03-25 05:07:42 +00001695 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001696 if (id.s_addr == 0xffffffff)
1697 {
1698 /* Maybe Link State ID not available. */
1699 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001700 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001701 return NULL;
1702 }
1703 }
1704
1705 /* Create new stream for LSA. */
1706 s = stream_new (OSPF_MAX_LSA_SIZE);
1707 lsah = (struct lsa_header *) STREAM_DATA (s);
1708
1709 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001710 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1711 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001712
1713 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001714 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001715
1716 /* Set length. */
1717 length = stream_get_endp (s);
1718 lsah->length = htons (length);
1719
1720 /* Now, create OSPF LSA instance. */
1721 new = ospf_lsa_new ();
1722 new->area = NULL;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001723 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001724
1725 /* Copy LSA data to store, discard stream. */
1726 new->data = ospf_lsa_data_new (length);
1727 memcpy (new->data, lsah, length);
1728 stream_free (s);
1729
1730 return new;
1731}
1732
paul718e3742002-12-13 20:15:29 +00001733/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001734static void
paul68980082003-03-25 05:07:42 +00001735ospf_install_flood_nssa (struct ospf *ospf,
1736 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001737{
pauld4a53d52003-07-12 21:30:57 +00001738 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001739 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001740 struct ospf_area *area;
1741 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001742
pauld4a53d52003-07-12 21:30:57 +00001743 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1744 * which originated from an NSSA area. In which case it should not be
1745 * flooded back to NSSA areas.
1746 */
1747 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1748 return;
1749
paul718e3742002-12-13 20:15:29 +00001750 /* NSSA Originate or Refresh (If anyNSSA)
1751
1752 LSA is self-originated. And just installed as Type-5.
1753 Additionally, install as Type-7 LSDB for every attached NSSA.
1754
1755 P-Bit controls which ABR performs translation to outside world; If
1756 we are an ABR....do not set the P-bit, because we send the Type-5,
1757 not as the ABR Translator, but as the ASBR owner within the AS!
1758
1759 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1760 elected ABR Translator will see the P-bit, Translate, and re-flood.
1761
1762 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1763 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1764
paul1eb8ef22005-04-07 07:30:20 +00001765 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001766 {
hasso0c14ad82003-07-03 08:36:02 +00001767 /* Don't install Type-7 LSA's into nonNSSA area */
1768 if (area->external_routing != OSPF_AREA_NSSA)
1769 continue;
paul718e3742002-12-13 20:15:29 +00001770
paul68980082003-03-25 05:07:42 +00001771 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001772 new = ospf_lsa_dup (lsa);
1773 new->area = area;
1774 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001775
paul68980082003-03-25 05:07:42 +00001776 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001777 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001778 {
pauld4a53d52003-07-12 21:30:57 +00001779 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001780
1781 /* set non-zero FWD ADDR
1782
1783 draft-ietf-ospf-nssa-update-09.txt
1784
1785 if the network between the NSSA AS boundary router and the
1786 adjacent AS is advertised into OSPF as an internal OSPF route,
1787 the forwarding address should be the next op address as is cu
1788 currently done with type-5 LSAs. If the intervening network is
1789 not adversited into OSPF as an internal OSPF route and the
1790 type-7 LSA's P-bit is set a forwarding address should be
1791 selected from one of the router's active OSPF inteface addresses
1792 which belong to the NSSA. If no such addresses exist, then
1793 no type-7 LSA's with the P-bit set should originate from this
1794 router. */
1795
pauld4a53d52003-07-12 21:30:57 +00001796 /* kevinm: not updating lsa anymore, just new */
1797 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001798
1799 if (extlsa->e[0].fwd_addr.s_addr == 0)
1800 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001801
pauld7480322003-05-16 17:31:51 +00001802 if (extlsa->e[0].fwd_addr.s_addr == 0)
1803 {
1804 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001805 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001806 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001807 return;
1808 }
paulf2c80652002-12-13 21:44:27 +00001809 }
paul718e3742002-12-13 20:15:29 +00001810
paul68980082003-03-25 05:07:42 +00001811 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001812 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001813
1814 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001815 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001816 }
paul718e3742002-12-13 20:15:29 +00001817}
pauld4a53d52003-07-12 21:30:57 +00001818
paul4dadc292005-05-06 21:37:42 +00001819static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001820ospf_lsa_translated_nssa_new (struct ospf *ospf,
1821 struct ospf_lsa *type7)
1822{
1823
1824 struct ospf_lsa *new;
1825 struct as_external_lsa *ext, *extnew;
1826 struct external_info ei;
1827
1828 ext = (struct as_external_lsa *)(type7->data);
1829
1830 /* need external_info struct, fill in bare minimum */
1831 ei.p.family = AF_INET;
1832 ei.p.prefix = type7->data->id;
1833 ei.p.prefixlen = ip_masklen (ext->mask);
1834 ei.type = ZEBRA_ROUTE_OSPF;
1835 ei.nexthop = ext->header.adv_router;
1836 ei.route_map_set.metric = -1;
1837 ei.route_map_set.metric_type = -1;
1838 ei.tag = 0;
1839
1840 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1841 {
1842 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001843 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001844 "Translated Type-5 for %s",
1845 inet_ntoa (ei.p.prefix));
1846 return NULL;
1847 }
1848
1849 extnew = (struct as_external_lsa *)(new->data);
1850
1851 /* copy over Type-7 data to new */
1852 extnew->e[0].tos = ext->e[0].tos;
1853 extnew->e[0].route_tag = ext->e[0].route_tag;
1854 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1855 new->data->ls_seqnum = type7->data->ls_seqnum;
1856
1857 /* add translated flag, checksum and lock new lsa */
1858 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
pauld4a53d52003-07-12 21:30:57 +00001859 new = ospf_lsa_lock (new);
1860
1861 return new;
1862}
1863
1864/* compare type-5 to type-7
1865 * -1: err, 0: same, 1: different
1866 */
paul4dadc292005-05-06 21:37:42 +00001867static int
pauld4a53d52003-07-12 21:30:57 +00001868ospf_lsa_translated_nssa_compare (struct ospf_lsa *t7, struct ospf_lsa *t5)
1869{
1870
1871 struct as_external_lsa *e5 = (struct as_external_lsa *)t5,
1872 *e7 = (struct as_external_lsa *)t7;
1873
1874
1875 /* sanity checks */
1876 if (! ((t5->data->type == OSPF_AS_EXTERNAL_LSA)
1877 && (t7->data->type == OSPF_AS_NSSA_LSA)))
1878 return -1;
1879
1880 if (t5->data->id.s_addr != t7->data->id.s_addr)
1881 return -1;
1882
1883 if (t5->data->ls_seqnum != t7->data->ls_seqnum)
1884 return LSA_REFRESH_FORCE;
1885
1886 if (e5->mask.s_addr != e7->mask.s_addr)
1887 return LSA_REFRESH_FORCE;
1888
1889 if (e5->e[0].fwd_addr.s_addr != e7->e[0].fwd_addr.s_addr)
1890 return LSA_REFRESH_FORCE;
1891
1892 if (e5->e[0].route_tag != e7->e[0].route_tag)
1893 return LSA_REFRESH_FORCE;
1894
1895 if (GET_METRIC (e5->e[0].metric) != GET_METRIC (e7->e[0].metric))
1896 return LSA_REFRESH_FORCE;
1897
1898 return LSA_REFRESH_IF_CHANGED;
1899}
1900
1901/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1902struct ospf_lsa *
1903ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1904{
1905 struct ospf_lsa *new;
1906 struct as_external_lsa *extnew;
1907
1908 /* we cant use ospf_external_lsa_originate() as we need to set
1909 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1910 */
1911
1912 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1913 {
1914 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001915 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001916 "Type-7, Id %s, to Type-5",
1917 inet_ntoa (type7->data->id));
1918 return NULL;
1919 }
1920
1921 extnew = (struct as_external_lsa *)new;
1922
1923 if (IS_DEBUG_OSPF_NSSA)
1924 {
ajse588f212004-12-08 18:12:06 +00001925 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001926 "translated Type 7, installed:");
1927 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001928 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1929 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001930 }
1931
1932 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1933 {
1934 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001935 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001936 "Could not install LSA "
1937 "id %s", inet_ntoa (type7->data->id));
1938 return NULL;
1939 }
1940
1941 ospf->lsa_originate_count++;
1942 ospf_flood_through_as (ospf, NULL, new);
1943
1944 return new;
1945}
1946
1947/* Refresh Translated from NSSA AS-external-LSA. */
1948struct ospf_lsa *
1949ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1950 struct ospf_lsa *type5)
1951{
1952 struct ospf_lsa *new = NULL;
1953
1954 /* Sanity checks. */
1955 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00001956 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00001957 return NULL;
pauld4a53d52003-07-12 21:30:57 +00001958 if (type7)
1959 assert (type7->data);
1960 if (type5)
1961 assert (type5->data);
1962 assert (ospf->anyNSSA);
1963
1964 /* get required data according to what has been given */
1965 if (type7 && type5 == NULL)
1966 {
1967 /* find the translated Type-5 for this Type-7 */
1968 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1969 struct prefix_ipv4 p =
1970 {
1971 .prefix = type7->data->id,
1972 .prefixlen = ip_masklen (ext->mask),
1973 .family = AF_INET,
1974 };
1975
1976 type5 = ospf_external_info_find_lsa (ospf, &p);
1977 }
1978 else if (type5 && type7 == NULL)
1979 {
1980 /* find the type-7 from which supplied type-5 was translated,
1981 * ie find first type-7 with same LSA Id.
1982 */
paul1eb8ef22005-04-07 07:30:20 +00001983 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00001984 struct route_node *rn;
1985 struct ospf_lsa *lsa;
1986 struct ospf_area *area;
1987
paul1eb8ef22005-04-07 07:30:20 +00001988 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00001989 {
1990 if (area->external_routing != OSPF_AREA_NSSA
1991 && !type7)
1992 continue;
1993
1994 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
1995 {
1996 if (lsa->data->id.s_addr == type5->data->id.s_addr)
1997 {
1998 type7 = lsa;
1999 break;
2000 }
2001 }
2002 }
2003 }
2004
2005 /* do we have type7? */
2006 if (!type7)
2007 {
2008 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002009 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00002010 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00002011 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00002012 return NULL;
2013 }
2014
2015 /* do we have valid translated type5? */
2016 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
2017 {
2018 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002019 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00002020 "found for Type-7 with Id %s",
2021 inet_ntoa (type7->data->id));
2022 return NULL;
2023 }
2024
2025 /* Delete LSA from neighbor retransmit-list. */
2026 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
2027
2028 /* create new translated LSA */
2029 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
2030 {
2031 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002032 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00002033 "Type-7 for %s to Type-5",
2034 inet_ntoa (type7->data->id));
2035 return NULL;
2036 }
2037
2038 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
2039 {
2040 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002041 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00002042 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00002043 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00002044 return NULL;
2045 }
2046
2047 /* Flood LSA through area. */
2048 ospf_flood_through_as (ospf, NULL, new);
2049
2050 return new;
2051}
paul718e3742002-12-13 20:15:29 +00002052
2053int
2054is_prefix_default (struct prefix_ipv4 *p)
2055{
2056 struct prefix_ipv4 q;
2057
2058 q.family = AF_INET;
2059 q.prefix.s_addr = 0;
2060 q.prefixlen = 0;
2061
2062 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
2063}
2064
2065/* Originate an AS-external-LSA, install and flood. */
2066struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002067ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00002068{
2069 struct ospf_lsa *new;
2070
2071 /* Added for NSSA project....
2072
2073 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2074 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2075 every area. The Type-7's are flooded to every IR and every ABR; We
2076 install the Type-5 LSDB so that the normal "refresh" code operates
2077 as usual, and flag them as not used during ASE calculations. The
2078 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2079 Address of non-zero.
2080
2081 If an ABR is the elected NSSA translator, following SPF and during
2082 the ABR task it will translate all the scanned Type-7's, with P-bit
2083 ON and not-self generated, and translate to Type-5's throughout the
2084 non-NSSA/STUB AS.
2085
2086 A difference in operation depends whether this ASBR is an ABR
2087 or not. If not an ABR, the P-bit is ON, to indicate that any
2088 elected NSSA-ABR can perform its translation.
2089
2090 If an ABR, the P-bit is OFF; No ABR will perform translation and
2091 this ASBR will flood the Type-5 LSA as usual.
2092
2093 For the case where this ASBR is not an ABR, the ASE calculations
2094 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2095 demonstrate to the user that there are LSA's that belong to any
2096 attached NSSA.
2097
2098 Finally, it just so happens that when the ABR is translating every
2099 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2100 approved Type-5 (translated from Type-7); at the end of translation
2101 if any Translated Type-5's remain unapproved, then they must be
2102 flushed from the AS.
2103
2104 */
2105
2106 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002107 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002108 return NULL;
2109
2110 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002111 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002112 {
2113 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002114 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002115 inet_ntoa (ei->p.prefix));
2116 return NULL;
2117 }
2118
2119 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002120 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002121
2122 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002123 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002124
2125 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002126 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002127
paul718e3742002-12-13 20:15:29 +00002128 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002129 if (ospf->anyNSSA &&
2130 /* stay away from translated LSAs! */
2131 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002132 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002133
2134 /* Debug logging. */
2135 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2136 {
ajse588f212004-12-08 18:12:06 +00002137 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002138 new->data->type, inet_ntoa (new->data->id), new);
2139 ospf_lsa_header_dump (new->data);
2140 }
2141
2142 return new;
2143}
2144
2145/* Originate AS-external-LSA from external info with initial flag. */
2146int
paul68980082003-03-25 05:07:42 +00002147ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002148{
paul68980082003-03-25 05:07:42 +00002149 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002150 struct route_node *rn;
2151 struct external_info *ei;
2152 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002153 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002154
paul68980082003-03-25 05:07:42 +00002155 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002156
2157 /* Originate As-external-LSA from all type of distribute source. */
2158 if ((rt = EXTERNAL_INFO (type)))
2159 for (rn = route_top (rt); rn; rn = route_next (rn))
2160 if ((ei = rn->info) != NULL)
2161 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002162 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002163 zlog_warn ("LSA: AS-external-LSA was not originated.");
2164
2165 return 0;
2166}
2167
paul4dadc292005-05-06 21:37:42 +00002168static struct external_info *
paul020709f2003-04-04 02:44:16 +00002169ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002170{
2171 int type;
2172 struct route_node *rn;
2173 struct prefix_ipv4 p;
2174
2175 p.family = AF_INET;
2176 p.prefix.s_addr = 0;
2177 p.prefixlen = 0;
2178
2179 /* First, lookup redistributed default route. */
2180 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2181 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2182 {
2183 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2184 if (rn != NULL)
2185 {
2186 route_unlock_node (rn);
2187 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002188 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002189 return rn->info;
2190 }
2191 }
2192
2193 return NULL;
2194}
2195
2196int
paul68980082003-03-25 05:07:42 +00002197ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002198{
paul718e3742002-12-13 20:15:29 +00002199 struct prefix_ipv4 p;
2200 struct in_addr nexthop;
2201 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002202 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002203
Paul Jakma4021b602006-05-12 22:55:41 +00002204 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002205
2206 p.family = AF_INET;
2207 p.prefix.s_addr = 0;
2208 p.prefixlen = 0;
2209
Paul Jakma4021b602006-05-12 22:55:41 +00002210 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002211 {
2212 /* If there is no default route via redistribute,
2213 then originate AS-external-LSA with nexthop 0 (self). */
2214 nexthop.s_addr = 0;
2215 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2216 }
2217
paul020709f2003-04-04 02:44:16 +00002218 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002219 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002220
2221 return 0;
2222}
2223
paul645878f2003-04-13 21:42:11 +00002224/* Flush any NSSA LSAs for given prefix */
2225void
2226ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2227{
paul1eb8ef22005-04-07 07:30:20 +00002228 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002229 struct ospf_lsa *lsa;
2230 struct ospf_area *area;
2231
paul1eb8ef22005-04-07 07:30:20 +00002232 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002233 {
paul1eb8ef22005-04-07 07:30:20 +00002234 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002235 {
2236 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2237 ospf->router_id)))
2238 {
2239 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002240 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002241 inet_ntoa (p->prefix), p->prefixlen);
2242 continue;
2243 }
2244 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2245 if (!IS_LSA_MAXAGE (lsa))
2246 {
2247 ospf_refresher_unregister_lsa (ospf, lsa);
2248 ospf_lsa_flush_area (lsa, area);
2249 }
2250 }
paul645878f2003-04-13 21:42:11 +00002251 }
2252}
paul645878f2003-04-13 21:42:11 +00002253
paul718e3742002-12-13 20:15:29 +00002254/* Flush an AS-external-LSA from LSDB and routing domain. */
2255void
paul68980082003-03-25 05:07:42 +00002256ospf_external_lsa_flush (struct ospf *ospf,
2257 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002258 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002259{
2260 struct ospf_lsa *lsa;
2261
2262 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002263 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002264 inet_ntoa (p->prefix), p->prefixlen);
2265
2266 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002267 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002268 {
2269 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002270 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002271 inet_ntoa (p->prefix), p->prefixlen);
2272 return;
2273 }
hassobeebba72004-06-20 21:00:27 +00002274
pauld4a53d52003-07-12 21:30:57 +00002275 /* If LSA is selforiginated, not a translated LSA, and there is
2276 * NSSA area, flush Type-7 LSA's at first.
2277 */
2278 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2279 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002280 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002281
2282 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002283 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002284
2285 /* There must be no self-originated LSA in rtrs_external. */
2286#if 0
2287 /* Remove External route from Zebra. */
2288 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2289#endif
2290
2291 if (!IS_LSA_MAXAGE (lsa))
2292 {
2293 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002294 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002295
2296 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002297 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002298 }
2299
2300 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002301 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002302}
2303
2304void
paul68980082003-03-25 05:07:42 +00002305ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002306{
2307 struct prefix_ipv4 p;
2308 struct external_info *ei;
2309 struct ospf_lsa *lsa;
2310
2311 p.family = AF_INET;
2312 p.prefixlen = 0;
2313 p.prefix.s_addr = 0;
2314
paul020709f2003-04-04 02:44:16 +00002315 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002316 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002317
2318 if (ei)
2319 {
2320 if (lsa)
2321 {
2322 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002323 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002324 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002325 }
2326 else
2327 {
2328 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002329 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002330 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002331 }
2332 }
2333 else
2334 {
2335 if (lsa)
2336 {
2337 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002338 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002339 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002340 }
2341 }
2342}
2343
2344void
paul68980082003-03-25 05:07:42 +00002345ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002346{
2347 struct route_node *rn;
2348 struct external_info *ei;
2349
2350 if (type != DEFAULT_ROUTE)
2351 if (EXTERNAL_INFO(type))
2352 /* Refresh each redistributed AS-external-LSAs. */
2353 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2354 if ((ei = rn->info))
2355 if (!is_prefix_default (&ei->p))
2356 {
2357 struct ospf_lsa *lsa;
2358
paul68980082003-03-25 05:07:42 +00002359 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2360 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002361 else
paul68980082003-03-25 05:07:42 +00002362 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002363 }
2364}
2365
2366/* Refresh AS-external-LSA. */
2367void
paul68980082003-03-25 05:07:42 +00002368ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002369 struct external_info *ei, int force)
2370{
2371 struct ospf_lsa *new;
2372 int changed;
2373
2374 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002375 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002376 {
pauld4a53d52003-07-12 21:30:57 +00002377 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002378 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002379 "redist check fail",
2380 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002381 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002382 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +00002383 return;
2384 }
2385
2386 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002387 {
2388 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002389 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002390 lsa->data->type, inet_ntoa (lsa->data->id));
2391 return;
2392 }
paul718e3742002-12-13 20:15:29 +00002393
2394 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002395 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002396
2397 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002398 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002399
paul68980082003-03-25 05:07:42 +00002400 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002401
2402 if (new == NULL)
2403 {
2404 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002405 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002406 inet_ntoa (lsa->data->id));
2407 return;
2408 }
2409
2410 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2411
paul68980082003-03-25 05:07:42 +00002412 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002413
2414 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002415 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002416
paul718e3742002-12-13 20:15:29 +00002417 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002418 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002419 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002420
pauld4a53d52003-07-12 21:30:57 +00002421 /* Register self-originated LSA to refresh queue.
2422 * Translated LSAs should not be registered, but refreshed upon
2423 * refresh of the Type-7
2424 */
2425 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2426 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002427
2428 /* Debug logging. */
2429 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2430 {
ajse588f212004-12-08 18:12:06 +00002431 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002432 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002433 ospf_lsa_header_dump (new->data);
2434 }
2435
2436 return;
2437}
2438
2439
2440/* LSA installation functions. */
2441
2442/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002443static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002444ospf_router_lsa_install (struct ospf *ospf,
2445 struct ospf_lsa *new, int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002446{
2447 struct ospf_area *area = new->area;
2448
2449 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2450 The entire routing table must be recalculated, starting with
2451 the shortest path calculations for each area (not just the
2452 area whose link-state database has changed).
2453 */
2454 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002455 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002456
Joakim Tjernlundbd246242009-01-05 17:44:46 +01002457 /* Only install LSA if it is originated/refreshed by us.
2458 * If LSA was received by flooding, the RECEIVED flag is set so do
2459 * not link the LSA */
2460 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
paul718e3742002-12-13 20:15:29 +00002461 {
2462 /* Set router-LSA refresh timer. */
2463 OSPF_TIMER_OFF (area->t_router_lsa_self);
2464 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
pauld4a53d52003-07-12 21:30:57 +00002465 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
paul718e3742002-12-13 20:15:29 +00002466
2467 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002468 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002469 area->router_lsa_self = ospf_lsa_lock (new);
2470
2471 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002472 zlog_debug("LSA[Type%d]: ID %s seq 0x%x is self-originated",
paul0c2be262004-05-31 14:16:54 +00002473 new->data->type, inet_ntoa (new->data->id),
2474 ntohl(new->data->ls_seqnum));
paul718e3742002-12-13 20:15:29 +00002475 }
2476
2477 return new;
2478}
2479
2480#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2481 if (!(T)) \
2482 (T) = thread_add_timer (master, (F), oi, (V))
2483
2484/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002485static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002486ospf_network_lsa_install (struct ospf *ospf,
2487 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002488 struct ospf_lsa *new,
2489 int rt_recalc)
2490{
2491
2492 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2493 The entire routing table must be recalculated, starting with
2494 the shortest path calculations for each area (not just the
2495 area whose link-state database has changed).
2496 */
2497 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002498 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002499
2500 /* We supposed that when LSA is originated by us, we pass the int
2501 for which it was originated. If LSA was received by flooding,
2502 the RECEIVED flag is set, so we do not link the LSA to the int. */
2503 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2504 {
2505 /* Set LSRefresh timer. */
2506 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2507
2508 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2509 ospf_network_lsa_refresh_timer,
2510 OSPF_LS_REFRESH_TIME);
2511
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002512 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002513 oi->network_lsa_self = ospf_lsa_lock (new);
2514 }
2515
2516 return new;
2517}
2518
2519/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002520static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002521ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2522 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002523{
paul718e3742002-12-13 20:15:29 +00002524 if (rt_recalc && !IS_LSA_SELF (new))
2525 {
2526 /* RFC 2328 Section 13.2 Summary-LSAs
2527 The best route to the destination described by the summary-
2528 LSA must be recalculated (see Section 16.5). If this
2529 destination is an AS boundary router, it may also be
2530 necessary to re-examine all the AS-external-LSAs.
2531 */
2532
2533#if 0
2534 /* This doesn't exist yet... */
2535 ospf_summary_incremental_update(new); */
2536#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002537 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002538#endif /* #if 0 */
2539
2540 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002541 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002542 }
2543
2544 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002545 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002546
2547 return new;
2548}
2549
2550/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002551static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002552ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2553 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002554{
2555 if (rt_recalc && !IS_LSA_SELF (new))
2556 {
2557 /* RFC 2328 Section 13.2 Summary-LSAs
2558 The best route to the destination described by the summary-
2559 LSA must be recalculated (see Section 16.5). If this
2560 destination is an AS boundary router, it may also be
2561 necessary to re-examine all the AS-external-LSAs.
2562 */
2563#if 0
2564 /* These don't exist yet... */
2565 ospf_summary_incremental_update(new);
2566 /* Isn't this done by the above call?
2567 - RFC 2328 Section 16.5 implies it should be */
2568 /* ospf_ase_calculate_schedule(); */
2569#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002570 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002571#endif /* #if 0 */
2572 }
2573
2574 /* register LSA to refresh-list. */
2575 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002576 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002577
2578 return new;
2579}
2580
2581/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002582static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002583ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2584 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002585{
paul68980082003-03-25 05:07:42 +00002586 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002587 /* If LSA is not self-originated, calculate an external route. */
2588 if (rt_recalc)
2589 {
2590 /* RFC 2328 Section 13.2 AS-external-LSAs
2591 The best route to the destination described by the AS-
2592 external-LSA must be recalculated (see Section 16.6).
2593 */
2594
2595 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002596 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002597 }
2598
pauld4a53d52003-07-12 21:30:57 +00002599 if (new->data->type == OSPF_AS_NSSA_LSA)
2600 {
2601 /* There is no point to register selforiginate Type-7 LSA for
2602 * refreshing. We rely on refreshing Type-5 LSA's
2603 */
2604 if (IS_LSA_SELF (new))
2605 return new;
2606 else
2607 {
2608 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2609 * New translations will be taken care of by the abr_task.
2610 */
2611 ospf_translated_nssa_refresh (ospf, new, NULL);
2612 }
2613 }
pauld7480322003-05-16 17:31:51 +00002614
pauld4a53d52003-07-12 21:30:57 +00002615 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002616 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002617 */
hassobeebba72004-06-20 21:00:27 +00002618 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002619 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002620
2621 return new;
2622}
2623
2624void
paul68980082003-03-25 05:07:42 +00002625ospf_discard_from_db (struct ospf *ospf,
2626 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002627{
2628 struct ospf_lsa *old;
2629
Paul Jakmaac904de2006-06-15 12:04:57 +00002630 if (!lsdb)
2631 {
2632 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2633 if (!lsa)
2634 zlog_warn ("%s: and NULL LSA!", __func__);
2635 else
2636 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2637 lsa->data->type, inet_ntoa (lsa->data->id));
2638 return;
2639 }
2640
paul718e3742002-12-13 20:15:29 +00002641 old = ospf_lsdb_lookup (lsdb, lsa);
2642
2643 if (!old)
2644 return;
2645
2646 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002647 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002648
2649 switch (old->data->type)
2650 {
2651 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002652 ospf_ase_unregister_external_lsa (old, ospf);
2653 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2654 break;
paul718e3742002-12-13 20:15:29 +00002655#ifdef HAVE_OPAQUE_LSA
2656 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002657 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002658 break;
paul69310a62005-05-11 18:09:59 +00002659#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002660 case OSPF_AS_NSSA_LSA:
2661 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2662 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002663 break;
paul718e3742002-12-13 20:15:29 +00002664 default:
paul68980082003-03-25 05:07:42 +00002665 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002666 break;
2667 }
2668
paul68980082003-03-25 05:07:42 +00002669 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002670 ospf_lsa_discard (old);
2671}
2672
paul718e3742002-12-13 20:15:29 +00002673struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002674ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2675 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002676{
2677 struct ospf_lsa *new = NULL;
2678 struct ospf_lsa *old = NULL;
2679 struct ospf_lsdb *lsdb = NULL;
2680 int rt_recalc;
2681
2682 /* Set LSDB. */
2683 switch (lsa->data->type)
2684 {
paulf2c80652002-12-13 21:44:27 +00002685 /* kevinm */
2686 case OSPF_AS_NSSA_LSA:
2687 if (lsa->area)
2688 lsdb = lsa->area->lsdb;
2689 else
paul68980082003-03-25 05:07:42 +00002690 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002691 break;
paul718e3742002-12-13 20:15:29 +00002692 case OSPF_AS_EXTERNAL_LSA:
2693#ifdef HAVE_OPAQUE_LSA
2694 case OSPF_OPAQUE_AS_LSA:
2695#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002696 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002697 break;
2698 default:
2699 lsdb = lsa->area->lsdb;
2700 break;
2701 }
2702
paul718e3742002-12-13 20:15:29 +00002703 assert (lsdb);
2704
2705 /* RFC 2328 13.2. Installing LSAs in the database
2706
2707 Installing a new LSA in the database, either as the result of
2708 flooding or a newly self-originated LSA, may cause the OSPF
2709 routing table structure to be recalculated. The contents of the
2710 new LSA should be compared to the old instance, if present. If
2711 there is no difference, there is no need to recalculate the
2712 routing table. When comparing an LSA to its previous instance,
2713 the following are all considered to be differences in contents:
2714
2715 o The LSA's Options field has changed.
2716
2717 o One of the LSA instances has LS age set to MaxAge, and
2718 the other does not.
2719
2720 o The length field in the LSA header has changed.
2721
2722 o The body of the LSA (i.e., anything outside the 20-byte
2723 LSA header) has changed. Note that this excludes changes
2724 in LS Sequence Number and LS Checksum.
2725
2726 */
2727 /* Look up old LSA and determine if any SPF calculation or incremental
2728 update is needed */
2729 old = ospf_lsdb_lookup (lsdb, lsa);
2730
2731 /* Do comparision and record if recalc needed. */
2732 rt_recalc = 0;
2733 if ( old == NULL || ospf_lsa_different(old, lsa))
2734 rt_recalc = 1;
2735
paul7ddf1d62003-10-13 09:06:46 +00002736 /*
2737 Sequence number check (Section 14.1 of rfc 2328)
2738 "Premature aging is used when it is time for a self-originated
2739 LSA's sequence number field to wrap. At this point, the current
2740 LSA instance (having LS sequence number MaxSequenceNumber) must
2741 be prematurely aged and flushed from the routing domain before a
2742 new instance with sequence number equal to InitialSequenceNumber
2743 can be originated. "
2744 */
2745
Paul Jakmac2b478d2006-03-30 14:16:11 +00002746 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002747 {
2748 if (ospf_lsa_is_self_originated(ospf, lsa))
2749 {
paul0c2be262004-05-31 14:16:54 +00002750 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2751
2752 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002753 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2754 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2755
2756 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2757 {
ajse588f212004-12-08 18:12:06 +00002758 zlog_debug ("ospf_lsa_install() Premature Aging "
paul7ddf1d62003-10-13 09:06:46 +00002759 "lsa 0x%lx", (u_long)lsa);
2760 ospf_lsa_header_dump (lsa->data);
2761 }
2762 }
2763 else
2764 {
2765 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2766 {
ajse588f212004-12-08 18:12:06 +00002767 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002768 "that was not self originated. Ignoring\n");
2769 ospf_lsa_header_dump (lsa->data);
2770 }
2771 return old;
2772 }
2773 }
2774
paul718e3742002-12-13 20:15:29 +00002775 /* discard old LSA from LSDB */
2776 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002777 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002778
paul718e3742002-12-13 20:15:29 +00002779 /* Calculate Checksum if self-originated?. */
2780 if (IS_LSA_SELF (lsa))
2781 ospf_lsa_checksum (lsa->data);
2782
hassofe71a972004-12-22 16:16:02 +00002783 /* Insert LSA to LSDB. */
2784 ospf_lsdb_add (lsdb, lsa);
2785 lsa->lsdb = lsdb;
2786
paul718e3742002-12-13 20:15:29 +00002787 /* Do LSA specific installation process. */
2788 switch (lsa->data->type)
2789 {
2790 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002791 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002792 break;
2793 case OSPF_NETWORK_LSA:
2794 assert (oi);
paul68980082003-03-25 05:07:42 +00002795 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002796 break;
2797 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002798 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002799 break;
2800 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002801 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002802 break;
2803 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002804 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002805 break;
2806#ifdef HAVE_OPAQUE_LSA
2807 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002808 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002809 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002810 else
paul68980082003-03-25 05:07:42 +00002811 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002812 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002813 case OSPF_OPAQUE_AREA_LSA:
2814 case OSPF_OPAQUE_AS_LSA:
2815 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2816 break;
2817#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002818 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002819 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002820 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002821 break;
2822 }
2823
2824 if (new == NULL)
2825 return new; /* Installation failed, cannot proceed further -- endo. */
2826
2827 /* Debug logs. */
2828 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2829 {
2830 char area_str[INET_ADDRSTRLEN];
2831
2832 switch (lsa->data->type)
2833 {
2834 case OSPF_AS_EXTERNAL_LSA:
2835#ifdef HAVE_OPAQUE_LSA
2836 case OSPF_OPAQUE_AS_LSA:
2837#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002838 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002839 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002840 dump_lsa_key (new),
2841 LOOKUP (ospf_lsa_type_msg, new->data->type));
2842 break;
2843 default:
2844 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002845 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002846 dump_lsa_key (new),
2847 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2848 break;
2849 }
2850 }
2851
paul7ddf1d62003-10-13 09:06:46 +00002852 /*
2853 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2854 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2855 */
2856 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2857 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002858 {
paul7ddf1d62003-10-13 09:06:46 +00002859 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002860 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002861 new->data->type,
2862 inet_ntoa (new->data->id),
2863 lsa);
paul68980082003-03-25 05:07:42 +00002864 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002865 }
2866
2867 return new;
2868}
2869
2870
paul4dadc292005-05-06 21:37:42 +00002871static int
paul68980082003-03-25 05:07:42 +00002872ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002873{
paul1eb8ef22005-04-07 07:30:20 +00002874 struct listnode *node, *nnode;
2875 struct ospf_interface *oi;
2876
2877 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002878 {
paul718e3742002-12-13 20:15:29 +00002879 struct route_node *rn;
2880 struct ospf_neighbor *nbr;
2881
2882 if (ospf_if_is_enable (oi))
2883 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2884 if ((nbr = rn->info) != NULL)
2885 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2886 {
2887 route_unlock_node (rn);
2888 return 0;
2889 }
2890 }
2891
2892 return 1;
2893}
2894
2895
2896#ifdef ORIGINAL_CODING
2897/* This function flood the maxaged LSA to DR. */
2898void
2899ospf_maxage_flood (struct ospf_lsa *lsa)
2900{
2901 switch (lsa->data->type)
2902 {
2903 case OSPF_ROUTER_LSA:
2904 case OSPF_NETWORK_LSA:
2905 case OSPF_SUMMARY_LSA:
2906 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00002907 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00002908#ifdef HAVE_OPAQUE_LSA
2909 case OSPF_OPAQUE_LINK_LSA:
2910 case OSPF_OPAQUE_AREA_LSA:
2911#endif /* HAVE_OPAQUE_LSA */
2912 ospf_flood_through_area (lsa->area, NULL, lsa);
2913 break;
2914 case OSPF_AS_EXTERNAL_LSA:
2915#ifdef HAVE_OPAQUE_LSA
2916 case OSPF_OPAQUE_AS_LSA:
2917#endif /* HAVE_OPAQUE_LSA */
2918 ospf_flood_through_as (NULL, lsa);
2919 break;
2920 default:
2921 break;
2922 }
2923}
2924#endif /* ORIGINAL_CODING */
2925
paul4dadc292005-05-06 21:37:42 +00002926static int
paul718e3742002-12-13 20:15:29 +00002927ospf_maxage_lsa_remover (struct thread *thread)
2928{
paul68980082003-03-25 05:07:42 +00002929 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002930 struct ospf_lsa *lsa;
2931 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002932 int reschedule = 0;
2933
paul68980082003-03-25 05:07:42 +00002934 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002935
2936 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002937 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002938
paul68980082003-03-25 05:07:42 +00002939 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002940
2941 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002942 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002943 {
paul718e3742002-12-13 20:15:29 +00002944 if (lsa->retransmit_counter > 0)
2945 {
2946 reschedule = 1;
2947 continue;
2948 }
2949
2950 /* Remove LSA from the LSDB */
2951 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2952 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002953 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
paul7ddf1d62003-10-13 09:06:46 +00002954 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002955
2956 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002957 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002958 lsa->data->type, inet_ntoa (lsa->data->id));
2959
2960 /* Flood max age LSA. */
2961#ifdef ORIGINAL_CODING
2962 ospf_maxage_flood (lsa);
2963#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00002964 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00002965#endif /* ORIGINAL_CODING */
2966
paul7ddf1d62003-10-13 09:06:46 +00002967 if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
2968 {
2969 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002970 zlog_debug ("originating new router lsa for lsa 0x%lx \n",
paul7ddf1d62003-10-13 09:06:46 +00002971 (u_long)lsa);
2972 ospf_router_lsa_originate(lsa->area);
2973 }
2974
paul718e3742002-12-13 20:15:29 +00002975 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002976 if (lsa->lsdb)
2977 {
2978 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2979 ospf_lsdb_delete (lsa->lsdb, lsa);
2980 }
2981 else
2982 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2983 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002984 }
2985
2986 /* A MaxAge LSA must be removed immediately from the router's link
2987 state database as soon as both a) it is no longer contained on any
2988 neighbor Link state retransmission lists and b) none of the router's
2989 neighbors are in states Exchange or Loading. */
2990 if (reschedule)
paul68980082003-03-25 05:07:42 +00002991 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00002992
2993 return 0;
2994}
2995
paul4dadc292005-05-06 21:37:42 +00002996static int
paul68980082003-03-25 05:07:42 +00002997ospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new)
paul718e3742002-12-13 20:15:29 +00002998{
hasso52dc7ee2004-09-23 19:18:23 +00002999 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003000 struct ospf_lsa *lsa;
3001
3002 for (ALL_LIST_ELEMENTS_RO (ospf->maxage_lsa, node, lsa))
3003 if (lsa == new)
paul718e3742002-12-13 20:15:29 +00003004 return 1;
3005
3006 return 0;
3007}
3008
3009void
paul68980082003-03-25 05:07:42 +00003010ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003011{
hasso52dc7ee2004-09-23 19:18:23 +00003012 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003013
paul68980082003-03-25 05:07:42 +00003014 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00003015 {
paul68980082003-03-25 05:07:42 +00003016 list_delete_node (ospf->maxage_lsa, n);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003017 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +00003018 }
3019}
3020
3021void
paul68980082003-03-25 05:07:42 +00003022ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003023{
3024 /* When we saw a MaxAge LSA flooded to us, we put it on the list
3025 and schedule the MaxAge LSA remover. */
paul68980082003-03-25 05:07:42 +00003026 if (ospf_lsa_maxage_exist (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003027 {
3028 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003029 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00003030 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
3031 return;
3032 }
3033
paul68980082003-03-25 05:07:42 +00003034 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00003035
3036 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003037 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003038
paul68980082003-03-25 05:07:42 +00003039 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003040}
3041
paul4dadc292005-05-06 21:37:42 +00003042static int
paul68980082003-03-25 05:07:42 +00003043ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003044{
paul718e3742002-12-13 20:15:29 +00003045 /* Stay away from any Local Translated Type-7 LSAs */
3046 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3047 return 0;
paul718e3742002-12-13 20:15:29 +00003048
3049 if (IS_LSA_MAXAGE (lsa))
3050 /* Self-originated LSAs should NOT time-out instead,
3051 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00003052 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003053 {
3054 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003055 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003056
3057 switch (lsa->data->type)
3058 {
paul718e3742002-12-13 20:15:29 +00003059#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00003060 case OSPF_OPAQUE_LINK_LSA:
3061 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003062 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003063 /*
3064 * As a general rule, whenever network topology has changed
3065 * (due to an LSA removal in this case), routing recalculation
3066 * should be triggered. However, this is not true for opaque
3067 * LSAs. Even if an opaque LSA instance is going to be removed
3068 * from the routing domain, it does not mean a change in network
3069 * topology, and thus, routing recalculation is not needed here.
3070 */
3071 break;
paul718e3742002-12-13 20:15:29 +00003072#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00003073 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003074 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003075 ospf_ase_incremental_update (ospf, lsa);
3076 break;
paul718e3742002-12-13 20:15:29 +00003077 default:
paul68980082003-03-25 05:07:42 +00003078 ospf_spf_calculate_schedule (ospf);
3079 break;
paul718e3742002-12-13 20:15:29 +00003080 }
paul68980082003-03-25 05:07:42 +00003081 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003082 }
3083
3084 return 0;
3085}
3086
3087/* Periodical check of MaxAge LSA. */
3088int
paul68980082003-03-25 05:07:42 +00003089ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003090{
paul68980082003-03-25 05:07:42 +00003091 struct ospf *ospf = THREAD_ARG (thread);
3092 struct route_node *rn;
3093 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003094 struct ospf_area *area;
3095 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003096
paul68980082003-03-25 05:07:42 +00003097 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003098
paul1eb8ef22005-04-07 07:30:20 +00003099 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003100 {
paul68980082003-03-25 05:07:42 +00003101 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3102 ospf_lsa_maxage_walker_remover (ospf, lsa);
3103 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3104 ospf_lsa_maxage_walker_remover (ospf, lsa);
3105 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3106 ospf_lsa_maxage_walker_remover (ospf, lsa);
3107 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3108 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003109#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003110 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3111 ospf_lsa_maxage_walker_remover (ospf, lsa);
3112 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3113 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003114#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003115 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3116 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003117 }
3118
paul4fb949e2003-05-10 20:06:51 +00003119 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003120 if (ospf->lsdb)
3121 {
3122 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3123 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003124#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003125 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3126 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003127#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003128 }
paul718e3742002-12-13 20:15:29 +00003129
paul68980082003-03-25 05:07:42 +00003130 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3131 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003132 return 0;
3133}
3134
paul68980082003-03-25 05:07:42 +00003135struct ospf_lsa *
3136ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3137 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003138{
paul68980082003-03-25 05:07:42 +00003139 struct ospf_lsa *lsa;
3140 struct in_addr mask, id;
3141 struct lsa_header_mask
3142 {
3143 struct lsa_header header;
3144 struct in_addr mask;
3145 } *hmask;
paul718e3742002-12-13 20:15:29 +00003146
paul68980082003-03-25 05:07:42 +00003147 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3148 if (lsa == NULL)
3149 return NULL;
paul718e3742002-12-13 20:15:29 +00003150
paul68980082003-03-25 05:07:42 +00003151 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003152
paul68980082003-03-25 05:07:42 +00003153 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003154
paul68980082003-03-25 05:07:42 +00003155 if (mask.s_addr != hmask->mask.s_addr)
3156 {
3157 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3158 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3159 if (!lsa)
3160 return NULL;
3161 }
paul718e3742002-12-13 20:15:29 +00003162
paul68980082003-03-25 05:07:42 +00003163 return lsa;
paul718e3742002-12-13 20:15:29 +00003164}
3165
3166struct ospf_lsa *
3167ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3168 struct in_addr id, struct in_addr adv_router)
3169{
paule05fba42003-04-13 20:20:53 +00003170 struct ospf *ospf = ospf_lookup();
3171 assert(ospf);
3172
paul718e3742002-12-13 20:15:29 +00003173 switch (type)
3174 {
3175 case OSPF_ROUTER_LSA:
3176 case OSPF_NETWORK_LSA:
3177 case OSPF_SUMMARY_LSA:
3178 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003179 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003180#ifdef HAVE_OPAQUE_LSA
3181 case OSPF_OPAQUE_LINK_LSA:
3182 case OSPF_OPAQUE_AREA_LSA:
3183#endif /* HAVE_OPAQUE_LSA */
3184 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003185 case OSPF_AS_EXTERNAL_LSA:
3186#ifdef HAVE_OPAQUE_LSA
3187 case OSPF_OPAQUE_AS_LSA:
3188#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003189 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003190 default:
3191 break;
3192 }
3193
3194 return NULL;
3195}
3196
3197struct ospf_lsa *
3198ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3199 struct in_addr id)
3200{
3201 struct ospf_lsa *lsa;
3202 struct route_node *rn;
3203
3204 switch (type)
3205 {
3206 case OSPF_ROUTER_LSA:
3207 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003208 case OSPF_NETWORK_LSA:
3209 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3210 if ((lsa = rn->info))
3211 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3212 {
3213 route_unlock_node (rn);
3214 return lsa;
3215 }
3216 break;
3217 case OSPF_SUMMARY_LSA:
3218 case OSPF_ASBR_SUMMARY_LSA:
3219 /* Currently not used. */
3220 assert (1);
3221 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003222 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003223 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003224#ifdef HAVE_OPAQUE_LSA
3225 case OSPF_OPAQUE_LINK_LSA:
3226 case OSPF_OPAQUE_AREA_LSA:
3227 case OSPF_OPAQUE_AS_LSA:
3228 /* Currently not used. */
3229 break;
3230#endif /* HAVE_OPAQUE_LSA */
3231 default:
3232 break;
3233 }
3234
3235 return NULL;
3236}
3237
3238struct ospf_lsa *
3239ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3240{
3241 struct ospf_lsa *match;
3242
3243#ifdef HAVE_OPAQUE_LSA
3244 /*
3245 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3246 * is redefined to have two subfields; opaque-type and opaque-id.
3247 * However, it is harmless to treat the two sub fields together, as if
3248 * they two were forming a unique LSA-ID.
3249 */
3250#endif /* HAVE_OPAQUE_LSA */
3251
3252 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3253
3254 if (match == NULL)
3255 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003256 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003257 lsah->type, inet_ntoa (lsah->id));
3258
3259 return match;
3260}
3261
3262/* return +n, l1 is more recent.
3263 return -n, l2 is more recent.
3264 return 0, l1 and l2 is identical. */
3265int
3266ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3267{
3268 int r;
3269 int x, y;
3270
3271 if (l1 == NULL && l2 == NULL)
3272 return 0;
3273 if (l1 == NULL)
3274 return -1;
3275 if (l2 == NULL)
3276 return 1;
3277
3278 /* compare LS sequence number. */
3279 x = (int) ntohl (l1->data->ls_seqnum);
3280 y = (int) ntohl (l2->data->ls_seqnum);
3281 if (x > y)
3282 return 1;
3283 if (x < y)
3284 return -1;
3285
3286 /* compare LS checksum. */
3287 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3288 if (r)
3289 return r;
3290
3291 /* compare LS age. */
3292 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3293 return 1;
3294 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3295 return -1;
3296
3297 /* compare LS age with MaxAgeDiff. */
3298 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3299 return -1;
3300 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3301 return 1;
3302
3303 /* LSAs are identical. */
3304 return 0;
3305}
3306
3307/* If two LSAs are different, return 1, otherwise return 0. */
3308int
3309ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3310{
3311 char *p1, *p2;
3312 assert (l1);
3313 assert (l2);
3314 assert (l1->data);
3315 assert (l2->data);
3316
3317 if (l1->data->options != l2->data->options)
3318 return 1;
3319
3320 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3321 return 1;
3322
3323 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3324 return 1;
3325
3326 if (l1->data->length != l2->data->length)
3327 return 1;
3328
3329 if (l1->data->length == 0)
3330 return 1;
3331
pauld1825832003-04-03 01:27:01 +00003332 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003333
3334 p1 = (char *) l1->data;
3335 p2 = (char *) l2->data;
3336
3337 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3338 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3339 return 1;
3340
3341 return 0;
3342}
3343
3344#ifdef ORIGINAL_CODING
3345void
3346ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3347 struct ospf_lsa *self,
3348 struct ospf_lsa *new)
3349{
3350 u_int32_t seqnum;
3351
3352 /* Adjust LS Sequence Number. */
3353 seqnum = ntohl (new->data->ls_seqnum) + 1;
3354 self->data->ls_seqnum = htonl (seqnum);
3355
3356 /* Recalculate LSA checksum. */
3357 ospf_lsa_checksum (self->data);
3358
3359 /* Reflooding LSA. */
3360 /* RFC2328 Section 13.3
3361 On non-broadcast networks, separate Link State Update
3362 packets must be sent, as unicasts, to each adjacent neighbor
3363 (i.e., those in state Exchange or greater). The destination
3364 IP addresses for these packets are the neighbors' IP
3365 addresses. */
3366 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3367 {
3368 struct route_node *rn;
3369 struct ospf_neighbor *onbr;
3370
3371 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3372 if ((onbr = rn->info) != NULL)
3373 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3374 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3375 }
3376 else
3377 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3378
3379 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003380 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003381 self->data->type, inet_ntoa (self->data->id));
3382}
3383#else /* ORIGINAL_CODING */
3384static int
paul68980082003-03-25 05:07:42 +00003385ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003386{
3387 if (lsa == NULL || !IS_LSA_SELF (lsa))
3388 return 0;
3389
3390 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003391 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 +00003392
3393 /* Force given lsa's age to MaxAge. */
3394 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3395
3396 switch (lsa->data->type)
3397 {
3398#ifdef HAVE_OPAQUE_LSA
3399 case OSPF_OPAQUE_LINK_LSA:
3400 case OSPF_OPAQUE_AREA_LSA:
3401 case OSPF_OPAQUE_AS_LSA:
3402 ospf_opaque_lsa_refresh (lsa);
3403 break;
3404#endif /* HAVE_OPAQUE_LSA */
3405 default:
paul68980082003-03-25 05:07:42 +00003406 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003407 break;
3408 }
3409
3410 return 0;
3411}
3412
3413void
paul68980082003-03-25 05:07:42 +00003414ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003415{
paul1eb8ef22005-04-07 07:30:20 +00003416 struct listnode *node, *nnode;
3417 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003418 struct ospf_area *area;
3419 struct ospf_interface *oi;
3420 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003421 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003422 int need_to_flush_ase = 0;
3423
paul1eb8ef22005-04-07 07:30:20 +00003424 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003425 {
paul718e3742002-12-13 20:15:29 +00003426 if ((lsa = area->router_lsa_self) != NULL)
3427 {
3428 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003429 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 +00003430
3431 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003432 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003433 area->router_lsa_self = NULL;
3434 OSPF_TIMER_OFF (area->t_router_lsa_self);
3435 }
3436
paul1eb8ef22005-04-07 07:30:20 +00003437 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003438 {
paul718e3742002-12-13 20:15:29 +00003439 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003440 && oi->state == ISM_DR
3441 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003442 {
3443 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003444 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 +00003445
3446 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003447 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003448 oi->network_lsa_self = NULL;
3449 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3450 }
3451
3452 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3453 && area->external_routing == OSPF_AREA_DEFAULT)
3454 need_to_flush_ase = 1;
3455 }
3456
paul68980082003-03-25 05:07:42 +00003457 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3458 ospf_lsa_flush_schedule (ospf, lsa);
3459 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3460 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003461#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003462 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3463 ospf_lsa_flush_schedule (ospf, lsa);
3464 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3465 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003466#endif /* HAVE_OPAQUE_LSA */
3467 }
3468
3469 if (need_to_flush_ase)
3470 {
paul68980082003-03-25 05:07:42 +00003471 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3472 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003473#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003474 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3475 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003476#endif /* HAVE_OPAQUE_LSA */
3477 }
3478
3479 /*
3480 * Make sure that the MaxAge LSA remover is executed immediately,
3481 * without conflicting to other threads.
3482 */
paul68980082003-03-25 05:07:42 +00003483 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003484 {
paul68980082003-03-25 05:07:42 +00003485 OSPF_TIMER_OFF (ospf->t_maxage);
3486 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003487 }
3488
3489 return;
3490}
3491#endif /* ORIGINAL_CODING */
3492
3493/* If there is self-originated LSA, then return 1, otherwise return 0. */
3494/* An interface-independent version of ospf_lsa_is_self_originated */
3495int
paul68980082003-03-25 05:07:42 +00003496ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003497{
hasso52dc7ee2004-09-23 19:18:23 +00003498 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003499 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003500
3501 /* This LSA is already checked. */
3502 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3503 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3504
3505 /* Make sure LSA is self-checked. */
3506 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3507
3508 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003509 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003510 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3511
3512 /* LSA is router-LSA. */
3513 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003514 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003515 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3516
3517 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3518 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003519 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003520 {
paul718e3742002-12-13 20:15:29 +00003521 /* Ignore virtual link. */
3522 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3523 if (oi->address->family == AF_INET)
3524 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3525 {
3526 /* to make it easier later */
3527 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3528 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3529 }
3530 }
3531
3532 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3533}
3534
3535/* Get unique Link State ID. */
3536struct in_addr
paul68980082003-03-25 05:07:42 +00003537ospf_lsa_unique_id (struct ospf *ospf,
3538 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003539{
3540 struct ospf_lsa *lsa;
3541 struct in_addr mask, id;
3542
3543 id = p->prefix;
3544
3545 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003546 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003547 if (lsa)
3548 {
3549 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3550 if (ip_masklen (al->mask) == p->prefixlen)
3551 {
3552 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003553 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003554 "Can't get Link State ID for %s/%d",
3555 inet_ntoa (p->prefix), p->prefixlen);
3556 /* id.s_addr = 0; */
3557 id.s_addr = 0xffffffff;
3558 return id;
3559 }
3560 /* Masklen differs, then apply wildcard mask to Link State ID. */
3561 else
3562 {
3563 masklen2ip (p->prefixlen, &mask);
3564
3565 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003566 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3567 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003568 if (lsa)
3569 {
3570 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003571 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003572 "Can't get Link State ID for %s/%d",
3573 inet_ntoa (p->prefix), p->prefixlen);
3574 /* id.s_addr = 0; */
3575 id.s_addr = 0xffffffff;
3576 return id;
3577 }
3578 }
3579 }
3580
3581 return id;
3582}
3583
3584
Paul Jakma70461d72006-05-12 22:57:57 +00003585#define LSA_ACTION_FLOOD_AREA 1
3586#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003587
3588struct lsa_action
3589{
3590 u_char action;
3591 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003592 struct ospf_lsa *lsa;
3593};
3594
paul4dadc292005-05-06 21:37:42 +00003595static int
paul718e3742002-12-13 20:15:29 +00003596ospf_lsa_action (struct thread *t)
3597{
3598 struct lsa_action *data;
3599
3600 data = THREAD_ARG (t);
3601
3602 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003603 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003604 data->action);
3605
3606 switch (data->action)
3607 {
paul718e3742002-12-13 20:15:29 +00003608 case LSA_ACTION_FLOOD_AREA:
3609 ospf_flood_through_area (data->area, NULL, data->lsa);
3610 break;
paul718e3742002-12-13 20:15:29 +00003611 case LSA_ACTION_FLUSH_AREA:
3612 ospf_lsa_flush_area (data->lsa, data->area);
3613 break;
paul718e3742002-12-13 20:15:29 +00003614 }
3615
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003616 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003617 XFREE (MTYPE_OSPF_MESSAGE, data);
3618 return 0;
3619}
3620
3621void
3622ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3623{
3624 struct lsa_action *data;
3625
Stephen Hemminger393deb92008-08-18 14:13:29 -07003626 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003627 data->action = LSA_ACTION_FLOOD_AREA;
3628 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003629 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003630
3631 thread_add_event (master, ospf_lsa_action, data, 0);
3632}
3633
3634void
3635ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3636{
3637 struct lsa_action *data;
3638
Stephen Hemminger393deb92008-08-18 14:13:29 -07003639 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003640 data->action = LSA_ACTION_FLUSH_AREA;
3641 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003642 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003643
3644 thread_add_event (master, ospf_lsa_action, data, 0);
3645}
3646
3647
3648/* LSA Refreshment functions. */
paul4dadc292005-05-06 21:37:42 +00003649static void
paul68980082003-03-25 05:07:42 +00003650ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003651{
3652 struct external_info *ei;
3653 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3654
3655 switch (lsa->data->type)
3656 {
3657 /* Router and Network LSAs are processed differently. */
3658 case OSPF_ROUTER_LSA:
3659 case OSPF_NETWORK_LSA:
3660 break;
3661 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003662 ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003663 break;
3664 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003665 ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003666 break;
3667 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003668 /* Translated from NSSA Type-5s are refreshed when
3669 * from refresh of Type-7 - do not refresh these directly.
3670 */
3671 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3672 break;
paul718e3742002-12-13 20:15:29 +00003673 ei = ospf_external_info_check (lsa);
3674 if (ei)
pauld4a53d52003-07-12 21:30:57 +00003675 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003676 else
pauld4a53d52003-07-12 21:30:57 +00003677 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003678 break;
3679#ifdef HAVE_OPAQUE_LSA
3680 case OSPF_OPAQUE_LINK_LSA:
3681 case OSPF_OPAQUE_AREA_LSA:
3682 case OSPF_OPAQUE_AS_LSA:
3683 ospf_opaque_lsa_refresh (lsa);
3684 break;
pauld7480322003-05-16 17:31:51 +00003685#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003686 default:
3687 break;
paul718e3742002-12-13 20:15:29 +00003688 }
3689}
3690
3691void
paul68980082003-03-25 05:07:42 +00003692ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003693{
3694 u_int16_t index, current_index;
3695
3696 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3697
3698 if (lsa->refresh_list < 0)
3699 {
3700 int delay;
3701
3702 if (LS_AGE (lsa) == 0 &&
3703 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3704 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3705 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3706 else
3707 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3708 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3709 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3710
3711 if (delay < 0)
3712 delay = 0;
3713
paul68980082003-03-25 05:07:42 +00003714 current_index = ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003715 (quagga_time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003716
3717 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3718 % (OSPF_LSA_REFRESHER_SLOTS);
3719
3720 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003721 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003722 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003723 if (!ospf->lsa_refresh_queue.qs[index])
3724 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003725 listnode_add (ospf->lsa_refresh_queue.qs[index],
3726 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003727 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003728 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003729 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003730 "setting refresh_list on lsa %p (slod %d)",
3731 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003732 }
3733}
3734
3735void
paul68980082003-03-25 05:07:42 +00003736ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003737{
3738 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3739 if (lsa->refresh_list >= 0)
3740 {
hasso52dc7ee2004-09-23 19:18:23 +00003741 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003742 listnode_delete (refresh_list, lsa);
3743 if (!listcount (refresh_list))
3744 {
3745 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003746 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003747 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003748 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003749 lsa->refresh_list = -1;
3750 }
3751}
3752
3753int
3754ospf_lsa_refresh_walker (struct thread *t)
3755{
hasso52dc7ee2004-09-23 19:18:23 +00003756 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003757 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003758 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003759 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003760 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003761 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003762
3763 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003764 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003765
3766
paul68980082003-03-25 05:07:42 +00003767 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003768
ajs9dbc7972005-03-13 19:27:22 +00003769 /* Note: if clock has jumped backwards, then time change could be negative,
3770 so we are careful to cast the expression to unsigned before taking
3771 modulus. */
paul68980082003-03-25 05:07:42 +00003772 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003773 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003774 (quagga_time (NULL) - ospf->lsa_refresher_started) /
ajs9dbc7972005-03-13 19:27:22 +00003775 OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003776
3777 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003778 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003779 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003780
paul68980082003-03-25 05:07:42 +00003781 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003782 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3783 {
3784 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003785 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003786 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003787
paul68980082003-03-25 05:07:42 +00003788 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003789
paul68980082003-03-25 05:07:42 +00003790 ospf->lsa_refresh_queue.qs [i] = NULL;
3791
paul718e3742002-12-13 20:15:29 +00003792 if (refresh_list)
3793 {
paul1eb8ef22005-04-07 07:30:20 +00003794 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003795 {
paul718e3742002-12-13 20:15:29 +00003796 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003797 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003798 "refresh lsa %p (slot %d)",
3799 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003800
3801 list_delete_node (refresh_list, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003802 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003803 lsa->refresh_list = -1;
3804 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003805 }
3806 list_free (refresh_list);
3807 }
3808 }
3809
paul68980082003-03-25 05:07:42 +00003810 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3811 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003812 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003813
paul1eb8ef22005-04-07 07:30:20 +00003814 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
3815 ospf_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003816
3817 list_delete (lsa_to_refresh);
3818
3819 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003820 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003821
3822 return 0;
3823}
3824