blob: ec736fc166e1fdd9431445a0903395dd668ed04b [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
2 * OSPF Link State Advertisement
3 * Copyright (C) 1999, 2000 Toshiaki Takada
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "linklist.h"
26#include "prefix.h"
27#include "if.h"
28#include "table.h"
29#include "memory.h"
30#include "stream.h"
31#include "log.h"
32#include "thread.h"
33#include "hash.h"
34#include "sockunion.h" /* for inet_aton() */
Jingjing Duan6a270cd2008-08-13 19:09:10 +010035#include "checksum.h"
paul718e3742002-12-13 20:15:29 +000036
37#include "ospfd/ospfd.h"
38#include "ospfd/ospf_interface.h"
39#include "ospfd/ospf_ism.h"
40#include "ospfd/ospf_asbr.h"
41#include "ospfd/ospf_lsa.h"
42#include "ospfd/ospf_lsdb.h"
43#include "ospfd/ospf_neighbor.h"
44#include "ospfd/ospf_nsm.h"
45#include "ospfd/ospf_flood.h"
46#include "ospfd/ospf_packet.h"
47#include "ospfd/ospf_spf.h"
48#include "ospfd/ospf_dump.h"
49#include "ospfd/ospf_route.h"
50#include "ospfd/ospf_ase.h"
51#include "ospfd/ospf_zebra.h"
52
53
54u_int32_t
55get_metric (u_char *metric)
56{
57 u_int32_t m;
58 m = metric[0];
59 m = (m << 8) + metric[1];
60 m = (m << 8) + metric[2];
61 return m;
62}
63
64
65struct timeval
66tv_adjust (struct timeval a)
67{
68 while (a.tv_usec >= 1000000)
69 {
70 a.tv_usec -= 1000000;
71 a.tv_sec++;
72 }
73
74 while (a.tv_usec < 0)
75 {
76 a.tv_usec += 1000000;
77 a.tv_sec--;
78 }
79
80 return a;
81}
82
83int
84tv_ceil (struct timeval a)
85{
86 a = tv_adjust (a);
87
88 return (a.tv_usec ? a.tv_sec + 1 : a.tv_sec);
89}
90
91int
92tv_floor (struct timeval a)
93{
94 a = tv_adjust (a);
95
96 return a.tv_sec;
97}
98
99struct timeval
100int2tv (int a)
101{
102 struct timeval ret;
103
104 ret.tv_sec = a;
105 ret.tv_usec = 0;
106
107 return ret;
108}
109
110struct timeval
111tv_add (struct timeval a, struct timeval b)
112{
113 struct timeval ret;
114
115 ret.tv_sec = a.tv_sec + b.tv_sec;
116 ret.tv_usec = a.tv_usec + b.tv_usec;
117
118 return tv_adjust (ret);
119}
120
121struct timeval
122tv_sub (struct timeval a, struct timeval b)
123{
124 struct timeval ret;
125
126 ret.tv_sec = a.tv_sec - b.tv_sec;
127 ret.tv_usec = a.tv_usec - b.tv_usec;
128
129 return tv_adjust (ret);
130}
131
132int
133tv_cmp (struct timeval a, struct timeval b)
134{
135 return (a.tv_sec == b.tv_sec ?
136 a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
137}
138
139int
140ospf_lsa_refresh_delay (struct ospf_lsa *lsa)
141{
142 struct timeval delta, now;
143 int delay = 0;
144
Paul Jakma2518efd2006-08-27 06:49:29 +0000145 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +0000146 delta = tv_sub (now, lsa->tv_orig);
147
148 if (tv_cmp (delta, int2tv (OSPF_MIN_LS_INTERVAL)) < 0)
149 {
150 delay = tv_ceil (tv_sub (int2tv (OSPF_MIN_LS_INTERVAL), delta));
151
152 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000153 zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
paul718e3742002-12-13 20:15:29 +0000154 lsa->data->type, inet_ntoa (lsa->data->id), delay);
155
156 assert (delay > 0);
157 }
158
159 return delay;
160}
161
162
163int
164get_age (struct ospf_lsa *lsa)
165{
166 int age;
paul718e3742002-12-13 20:15:29 +0000167
Paul Jakma2518efd2006-08-27 06:49:29 +0000168 age = ntohs (lsa->data->ls_age)
169 + tv_floor (tv_sub (recent_relative_time (), lsa->tv_recv));
paul718e3742002-12-13 20:15:29 +0000170
171 return age;
172}
173
174
175/* Fletcher Checksum -- Refer to RFC1008. */
paul718e3742002-12-13 20:15:29 +0000176
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100177/* All the offsets are zero-based. The offsets in the RFC1008 are
178 one-based. */
paul718e3742002-12-13 20:15:29 +0000179u_int16_t
180ospf_lsa_checksum (struct lsa_header *lsa)
181{
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100182 u_char *buffer = (u_char *) &lsa->options;
183 int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */
paul718e3742002-12-13 20:15:29 +0000184
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100185 /* Skip the AGE field */
186 u_int16_t len = ntohs(lsa->length) - options_offset;
paul718e3742002-12-13 20:15:29 +0000187
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100188 /* Checksum offset starts from "options" field, not the beginning of the
189 lsa_header struct. The offset is 14, rather than 16. */
190 int checksum_offset = (u_char *) &lsa->checksum - buffer;
paul718e3742002-12-13 20:15:29 +0000191
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100192 return fletcher_checksum(buffer, len, checksum_offset);
paul718e3742002-12-13 20:15:29 +0000193}
194
195
196
197/* Create OSPF LSA. */
198struct ospf_lsa *
199ospf_lsa_new ()
200{
201 struct ospf_lsa *new;
202
203 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
paul718e3742002-12-13 20:15:29 +0000204
205 new->flags = 0;
206 new->lock = 1;
207 new->retransmit_counter = 0;
Paul Jakma2518efd2006-08-27 06:49:29 +0000208 new->tv_recv = recent_relative_time ();
paul718e3742002-12-13 20:15:29 +0000209 new->tv_orig = new->tv_recv;
210 new->refresh_list = -1;
211
212 return new;
213}
214
215/* Duplicate OSPF LSA. */
216struct ospf_lsa *
217ospf_lsa_dup (struct ospf_lsa *lsa)
218{
219 struct ospf_lsa *new;
220
221 if (lsa == NULL)
222 return NULL;
223
224 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
225
226 memcpy (new, lsa, sizeof (struct ospf_lsa));
227 UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
228 new->lock = 1;
229 new->retransmit_counter = 0;
230 new->data = ospf_lsa_data_dup (lsa->data);
231
paulf2c80652002-12-13 21:44:27 +0000232 /* kevinm: Clear the refresh_list, otherwise there are going
233 to be problems when we try to remove the LSA from the
234 queue (which it's not a member of.)
235 XXX: Should we add the LSA to the refresh_list queue? */
236 new->refresh_list = -1;
237
238 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000239 zlog_debug ("LSA: duplicated %p (new: %p)", lsa, new);
paulf2c80652002-12-13 21:44:27 +0000240
paul718e3742002-12-13 20:15:29 +0000241 return new;
242}
243
244/* Free OSPF LSA. */
245void
246ospf_lsa_free (struct ospf_lsa *lsa)
247{
248 assert (lsa->lock == 0);
249
250 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000251 zlog_debug ("LSA: freed %p", lsa);
paul718e3742002-12-13 20:15:29 +0000252
253 /* Delete LSA data. */
254 if (lsa->data != NULL)
255 ospf_lsa_data_free (lsa->data);
256
257 assert (lsa->refresh_list < 0);
258
259 memset (lsa, 0, sizeof (struct ospf_lsa));
260 XFREE (MTYPE_OSPF_LSA, lsa);
261}
262
263/* Lock LSA. */
264struct ospf_lsa *
265ospf_lsa_lock (struct ospf_lsa *lsa)
266{
267 lsa->lock++;
268 return lsa;
269}
270
271/* Unlock LSA. */
272void
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000273ospf_lsa_unlock (struct ospf_lsa **lsa)
paul718e3742002-12-13 20:15:29 +0000274{
275 /* This is sanity check. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000276 if (!lsa || !*lsa)
paul718e3742002-12-13 20:15:29 +0000277 return;
278
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000279 (*lsa)->lock--;
paul718e3742002-12-13 20:15:29 +0000280
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000281 assert ((*lsa)->lock >= 0);
paul718e3742002-12-13 20:15:29 +0000282
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000283 if ((*lsa)->lock == 0)
paul718e3742002-12-13 20:15:29 +0000284 {
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000285 assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
286 ospf_lsa_free (*lsa);
287 *lsa = NULL;
paul718e3742002-12-13 20:15:29 +0000288 }
289}
290
291/* Check discard flag. */
292void
293ospf_lsa_discard (struct ospf_lsa *lsa)
294{
295 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
296 {
297 SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000298 ospf_lsa_unlock (&lsa);
paul718e3742002-12-13 20:15:29 +0000299 }
300}
301
302/* Create LSA data. */
303struct lsa_header *
304ospf_lsa_data_new (size_t size)
305{
Stephen Hemminger393deb92008-08-18 14:13:29 -0700306 return XCALLOC (MTYPE_OSPF_LSA_DATA, size);
paul718e3742002-12-13 20:15:29 +0000307}
308
309/* Duplicate LSA data. */
310struct lsa_header *
311ospf_lsa_data_dup (struct lsa_header *lsah)
312{
313 struct lsa_header *new;
314
315 new = ospf_lsa_data_new (ntohs (lsah->length));
316 memcpy (new, lsah, ntohs (lsah->length));
317
318 return new;
319}
320
321/* Free LSA data. */
322void
323ospf_lsa_data_free (struct lsa_header *lsah)
324{
325 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000326 zlog_debug ("LSA[Type%d:%s]: data freed %p",
paul718e3742002-12-13 20:15:29 +0000327 lsah->type, inet_ntoa (lsah->id), lsah);
328
329 XFREE (MTYPE_OSPF_LSA_DATA, lsah);
330}
331
332
333/* LSA general functions. */
334
335const char *
336dump_lsa_key (struct ospf_lsa *lsa)
337{
338 static char buf[] = {
hasso52dc7ee2004-09-23 19:18:23 +0000339 "Type255,id(255.255.255.255),ar(255.255.255.255)"
paul718e3742002-12-13 20:15:29 +0000340 };
341 struct lsa_header *lsah;
342
343 if (lsa != NULL && (lsah = lsa->data) != NULL)
344 {
345 char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
346 strcpy (id, inet_ntoa (lsah->id));
347 strcpy (ar, inet_ntoa (lsah->adv_router));
348
349 sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
350 }
351 else
352 strcpy (buf, "NULL");
353
354 return buf;
355}
356
357u_int32_t
358lsa_seqnum_increment (struct ospf_lsa *lsa)
359{
360 u_int32_t seqnum;
361
362 seqnum = ntohl (lsa->data->ls_seqnum) + 1;
363
364 return htonl (seqnum);
365}
366
367void
368lsa_header_set (struct stream *s, u_char options,
paul68980082003-03-25 05:07:42 +0000369 u_char type, struct in_addr id, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +0000370{
371 struct lsa_header *lsah;
372
373 lsah = (struct lsa_header *) STREAM_DATA (s);
374
375 lsah->ls_age = htons (0);
376 lsah->options = options;
377 lsah->type = type;
378 lsah->id = id;
paul68980082003-03-25 05:07:42 +0000379 lsah->adv_router = router_id;
paul718e3742002-12-13 20:15:29 +0000380 lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
381
paul9985f832005-02-09 15:51:56 +0000382 stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000383}
384
paul68980082003-03-25 05:07:42 +0000385
paul718e3742002-12-13 20:15:29 +0000386/* router-LSA related functions. */
387/* Get router-LSA flags. */
paul4dadc292005-05-06 21:37:42 +0000388static u_char
paul718e3742002-12-13 20:15:29 +0000389router_lsa_flags (struct ospf_area *area)
390{
391 u_char flags;
392
paul68980082003-03-25 05:07:42 +0000393 flags = area->ospf->flags;
paul718e3742002-12-13 20:15:29 +0000394
395 /* Set virtual link flag. */
396 if (ospf_full_virtual_nbrs (area))
397 SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
398 else
399 /* Just sanity check */
400 UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);
401
402 /* Set Shortcut ABR behabiour flag. */
403 UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
paul68980082003-03-25 05:07:42 +0000404 if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
paul718e3742002-12-13 20:15:29 +0000405 if (!OSPF_IS_AREA_BACKBONE (area))
406 if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
paul68980082003-03-25 05:07:42 +0000407 area->ospf->backbone == NULL) ||
paul718e3742002-12-13 20:15:29 +0000408 area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
409 SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
410
411 /* ASBR can't exit in stub area. */
Greg Troxelfc787e82007-08-06 15:50:20 +0000412 if (area->external_routing == OSPF_AREA_STUB)
paul942b6c12003-06-22 08:22:18 +0000413 UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
414 /* If ASBR set External flag */
415 else if (IS_OSPF_ASBR (area->ospf))
416 SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
417
418 /* Set ABR dependent flags */
419 if (IS_OSPF_ABR (area->ospf))
420 {
421 SET_FLAG (flags, ROUTER_LSA_BORDER);
paul942b6c12003-06-22 08:22:18 +0000422 /* If Area is NSSA and we are both ABR and unconditional translator,
pauld4a53d52003-07-12 21:30:57 +0000423 * set Nt bit to inform other routers.
paul942b6c12003-06-22 08:22:18 +0000424 */
pauld4a53d52003-07-12 21:30:57 +0000425 if ( (area->external_routing == OSPF_AREA_NSSA)
426 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
427 SET_FLAG (flags, ROUTER_LSA_NT);
paul942b6c12003-06-22 08:22:18 +0000428 }
paul718e3742002-12-13 20:15:29 +0000429 return flags;
430}
431
432/* Lookup neighbor other than myself.
433 And check neighbor count,
434 Point-to-Point link must have only 1 neighbor. */
435struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +0000436ospf_nbr_lookup_ptop (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +0000437{
paul718e3742002-12-13 20:15:29 +0000438 struct ospf_neighbor *nbr = NULL;
paul68980082003-03-25 05:07:42 +0000439 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000440
441 /* Search neighbor, there must be one of two nbrs. */
paul68980082003-03-25 05:07:42 +0000442 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
443 if ((nbr = rn->info))
444 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000445 if (nbr->state == NSM_Full)
paul68980082003-03-25 05:07:42 +0000446 {
447 route_unlock_node (rn);
448 break;
449 }
paul718e3742002-12-13 20:15:29 +0000450
451 /* PtoP link must have only 1 neighbor. */
paul68980082003-03-25 05:07:42 +0000452 if (ospf_nbr_count (oi, 0) > 1)
paul718e3742002-12-13 20:15:29 +0000453 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
454
455 return nbr;
456}
457
paul88d6cf32005-10-29 12:50:09 +0000458/* Determine cost of link, taking RFC3137 stub-router support into
459 * consideration
460 */
461static u_int16_t
462ospf_link_cost (struct ospf_interface *oi)
463{
464 /* RFC3137 stub router support */
465 if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
466 return oi->output_cost;
467 else
468 return OSPF_OUTPUT_COST_INFINITE;
469}
470
paul718e3742002-12-13 20:15:29 +0000471/* Set a link information. */
paul779adb02006-01-18 15:07:38 +0000472static char
paul718e3742002-12-13 20:15:29 +0000473link_info_set (struct stream *s, struct in_addr id,
474 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
475{
paul779adb02006-01-18 15:07:38 +0000476 /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
477 * vast majority of cases. Some rare routers with lots of links need more.
478 * we try accomodate those here.
479 */
480 if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
481 {
482 size_t ret = OSPF_MAX_LSA_SIZE;
483
484 /* Can we enlarge the stream still? */
485 if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
486 {
487 /* we futz the size here for simplicity, really we need to account
488 * for just:
489 * IP Header - (sizeof (struct ip))
490 * OSPF Header - OSPF_HEADER_SIZE
491 * LSA Header - OSPF_LSA_HEADER_SIZE
492 * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
493 *
494 * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
495 */
496 ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
497 }
498
499 if (ret == OSPF_MAX_LSA_SIZE)
500 {
Paul Jakma53725102009-08-03 16:34:16 +0100501 zlog_warn ("%s: Out of space in LSA stream, left %zd, size %zd",
paul779adb02006-01-18 15:07:38 +0000502 __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
503 return 0;
504 }
505 }
506
paul718e3742002-12-13 20:15:29 +0000507 /* TOS based routing is not supported. */
508 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
509 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
510 stream_putc (s, type); /* Link Type. */
511 stream_putc (s, tos); /* TOS = 0. */
512 stream_putw (s, cost); /* Link Cost. */
paul779adb02006-01-18 15:07:38 +0000513
514 return 1;
paul718e3742002-12-13 20:15:29 +0000515}
516
Andrew J. Schorre4529632006-12-12 19:18:21 +0000517/* Describe Point-to-Point link (Section 12.4.1.1). */
paul4dadc292005-05-06 21:37:42 +0000518static int
paul718e3742002-12-13 20:15:29 +0000519lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
520{
521 int links = 0;
522 struct ospf_neighbor *nbr;
523 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000524 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000525
526 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000527 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
paul718e3742002-12-13 20:15:29 +0000528
paul68980082003-03-25 05:07:42 +0000529 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000530 if (nbr->state == NSM_Full)
531 {
532 /* For unnumbered point-to-point networks, the Link Data field
533 should specify the interface's MIB-II ifIndex value. */
paul779adb02006-01-18 15:07:38 +0000534 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
535 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000536 }
537
Andrew J. Schorre4529632006-12-12 19:18:21 +0000538 /* Regardless of the state of the neighboring router, we must
539 add a Type 3 link (stub network).
540 N.B. Options 1 & 2 share basically the same logic. */
541 masklen2ip (oi->address->prefixlen, &mask);
542 id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
543 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
544 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000545 return links;
546}
547
548/* Describe Broadcast Link. */
paul4dadc292005-05-06 21:37:42 +0000549static int
paul718e3742002-12-13 20:15:29 +0000550lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
551{
552 struct ospf_neighbor *dr;
553 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000554 u_int16_t cost = ospf_link_cost (oi);
555
paul718e3742002-12-13 20:15:29 +0000556 /* Describe Type 3 Link. */
557 if (oi->state == ISM_Waiting)
558 {
559 masklen2ip (oi->address->prefixlen, &mask);
560 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000561 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
562 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000563 }
564
565 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
566 /* Describe Type 2 link. */
567 if (dr && (dr->state == NSM_Full ||
568 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000569 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000570 {
paul779adb02006-01-18 15:07:38 +0000571 return link_info_set (s, DR (oi), oi->address->u.prefix4,
572 LSA_LINK_TYPE_TRANSIT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000573 }
574 /* Describe type 3 link. */
575 else
576 {
577 masklen2ip (oi->address->prefixlen, &mask);
578 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000579 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
580 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000581 }
paul718e3742002-12-13 20:15:29 +0000582}
583
paul4dadc292005-05-06 21:37:42 +0000584static int
paul718e3742002-12-13 20:15:29 +0000585lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
586{
587 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000588
paul718e3742002-12-13 20:15:29 +0000589 /* Describe Type 3 Link. */
590 if (oi->state != ISM_Loopback)
591 return 0;
592
593 mask.s_addr = 0xffffffff;
594 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000595 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000596}
597
598/* Describe Virtual Link. */
paul4dadc292005-05-06 21:37:42 +0000599static int
paul718e3742002-12-13 20:15:29 +0000600lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
601{
602 struct ospf_neighbor *nbr;
paul88d6cf32005-10-29 12:50:09 +0000603 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000604
paul718e3742002-12-13 20:15:29 +0000605 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000606 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000607 if (nbr->state == NSM_Full)
608 {
paul779adb02006-01-18 15:07:38 +0000609 return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
610 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
paul718e3742002-12-13 20:15:29 +0000611 }
612
613 return 0;
614}
615
616#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
617
paul7afa08d2002-12-13 20:59:45 +0000618/* this function add for support point-to-multipoint ,see rfc2328
61912.4.1.4.*/
620/* from "edward rrr" <edward_rrr@hotmail.com>
621 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul4dadc292005-05-06 21:37:42 +0000622static int
paul68980082003-03-25 05:07:42 +0000623lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000624{
625 int links = 0;
626 struct route_node *rn;
627 struct ospf_neighbor *nbr = NULL;
628 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000629 u_int16_t cost = ospf_link_cost (oi);
paul7afa08d2002-12-13 20:59:45 +0000630
631 mask.s_addr = 0xffffffff;
632 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000633 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
paul7afa08d2002-12-13 20:59:45 +0000634
paul1cc8f762003-04-05 19:34:32 +0000635 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000636 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000637
638 /* Search neighbor, */
639 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
640 if ((nbr = rn->info) != NULL)
641 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000642 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000643 if (nbr->state == NSM_Full)
644
645 {
paul779adb02006-01-18 15:07:38 +0000646 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
647 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul1cc8f762003-04-05 19:34:32 +0000648 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000649 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000650 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000651 }
652
653 return links;
paul7afa08d2002-12-13 20:59:45 +0000654}
655
paul718e3742002-12-13 20:15:29 +0000656/* Set router-LSA link information. */
paul4dadc292005-05-06 21:37:42 +0000657static int
paul718e3742002-12-13 20:15:29 +0000658router_lsa_link_set (struct stream *s, struct ospf_area *area)
659{
hasso52dc7ee2004-09-23 19:18:23 +0000660 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000661 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000662 int links = 0;
663
paul1eb8ef22005-04-07 07:30:20 +0000664 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +0000665 {
paul718e3742002-12-13 20:15:29 +0000666 struct interface *ifp = oi->ifp;
667
668 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000669 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000670 {
671 if (oi->state != ISM_Down)
672 {
673 /* Describe each link. */
674 switch (oi->type)
675 {
676 case OSPF_IFTYPE_POINTOPOINT:
677 links += lsa_link_ptop_set (s, oi);
678 break;
679 case OSPF_IFTYPE_BROADCAST:
680 links += lsa_link_broadcast_set (s, oi);
681 break;
682 case OSPF_IFTYPE_NBMA:
683 links += lsa_link_nbma_set (s, oi);
684 break;
685 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000686 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000687 break;
688 case OSPF_IFTYPE_VIRTUALLINK:
689 links += lsa_link_virtuallink_set (s, oi);
690 break;
691 case OSPF_IFTYPE_LOOPBACK:
692 links += lsa_link_loopback_set (s, oi);
693 }
694 }
695 }
696 }
697
698 return links;
699}
700
701/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000702static void
paul718e3742002-12-13 20:15:29 +0000703ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
704{
705 unsigned long putp;
706 u_int16_t cnt;
707
708 /* Set flags. */
709 stream_putc (s, router_lsa_flags (area));
710
711 /* Set Zero fields. */
712 stream_putc (s, 0);
713
714 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000715 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000716
717 /* Forward word */
718 stream_putw(s, 0);
719
720 /* Set all link information. */
721 cnt = router_lsa_link_set (s, area);
722
723 /* Set # of links here. */
724 stream_putw_at (s, putp, cnt);
725}
paul88d6cf32005-10-29 12:50:09 +0000726
727static int
728ospf_stub_router_timer (struct thread *t)
729{
730 struct ospf_area *area = THREAD_ARG (t);
731
732 area->t_stub_router = NULL;
733
734 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
735
736 /* clear stub route state and generate router-lsa refresh, don't
737 * clobber an administratively set stub-router state though.
738 */
739 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
740 return 0;
741
742 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
743
744 ospf_router_lsa_timer_add (area);
745
746 return 0;
747}
paul718e3742002-12-13 20:15:29 +0000748
paul88d6cf32005-10-29 12:50:09 +0000749inline static void
750ospf_stub_router_check (struct ospf_area *area)
751{
752 /* area must either be administratively configured to be stub
753 * or startup-time stub-router must be configured and we must in a pre-stub
754 * state.
755 */
756 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
757 {
758 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
759 return;
760 }
761
762 /* not admin-stubbed, check whether startup stubbing is configured and
763 * whether it's not been done yet
764 */
765 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
766 return;
767
768 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
769 {
770 /* stub-router is hence done forever for this area, even if someone
771 * tries configure it (take effect next restart).
772 */
773 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
774 return;
775 }
776
777 /* startup stub-router configured and not yet done */
778 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
779
780 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
781 area->ospf->stub_router_startup_time);
782}
783
paul718e3742002-12-13 20:15:29 +0000784/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000785static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000786ospf_router_lsa_new (struct ospf_area *area)
787{
paul68980082003-03-25 05:07:42 +0000788 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000789 struct stream *s;
790 struct lsa_header *lsah;
791 struct ospf_lsa *new;
792 int length;
793
794 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000795 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000796
paul88d6cf32005-10-29 12:50:09 +0000797 /* check whether stub-router is desired, and if this is the first
798 * router LSA.
799 */
800 ospf_stub_router_check (area);
801
paul718e3742002-12-13 20:15:29 +0000802 /* Create a stream for LSA. */
803 s = stream_new (OSPF_MAX_LSA_SIZE);
paul718e3742002-12-13 20:15:29 +0000804 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000805 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000806 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000807
808 /* Set router-LSA body fields. */
809 ospf_router_lsa_body_set (s, area);
810
811 /* Set length. */
812 length = stream_get_endp (s);
paul779adb02006-01-18 15:07:38 +0000813 lsah = (struct lsa_header *) STREAM_DATA (s);
paul718e3742002-12-13 20:15:29 +0000814 lsah->length = htons (length);
815
816 /* Now, create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000817 if ( (new = ospf_lsa_new ()) == NULL)
818 {
819 zlog_err ("%s: Unable to create new lsa", __func__);
820 return NULL;
821 }
822
paul718e3742002-12-13 20:15:29 +0000823 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +0000824 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +0000825
826 /* Copy LSA data to store, discard stream. */
827 new->data = ospf_lsa_data_new (length);
828 memcpy (new->data, lsah, length);
829 stream_free (s);
830
831 return new;
832}
833
834/* Originate Router-LSA. */
paul88d6cf32005-10-29 12:50:09 +0000835static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000836ospf_router_lsa_originate (struct ospf_area *area)
837{
838 struct ospf_lsa *new;
paul88d6cf32005-10-29 12:50:09 +0000839
paul718e3742002-12-13 20:15:29 +0000840 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000841 if ( (new = ospf_router_lsa_new (area)) == NULL)
842 {
843 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
844 return NULL;
845 }
paul718e3742002-12-13 20:15:29 +0000846
847 /* Sanity check. */
848 if (new->data->adv_router.s_addr == 0)
849 {
850 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000851 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000852 ospf_lsa_discard (new);
853 return NULL;
854 }
855
856 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000857 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000858
859 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000860 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000861
862 /* Flooding new LSA through area. */
863 ospf_flood_through_area (area, NULL, new);
864
865 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
866 {
ajse588f212004-12-08 18:12:06 +0000867 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
paul718e3742002-12-13 20:15:29 +0000868 new->data->type, inet_ntoa (new->data->id), new);
869 ospf_lsa_header_dump (new->data);
870 }
871
872 return new;
873}
874
875/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000876static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000877ospf_router_lsa_refresh (struct ospf_lsa *lsa)
878{
879 struct ospf_area *area = lsa->area;
880 struct ospf_lsa *new;
881
882 /* Sanity check. */
883 assert (lsa->data);
884
885 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000886 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000887
888 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000889 if ( (new = ospf_router_lsa_new (area)) == NULL)
890 {
891 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
892 return NULL;
893 }
894
paul718e3742002-12-13 20:15:29 +0000895 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
896
paul68980082003-03-25 05:07:42 +0000897 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000898
899 /* Flood LSA through area. */
900 ospf_flood_through_area (area, NULL, new);
901
902 /* Debug logging. */
903 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
904 {
ajse588f212004-12-08 18:12:06 +0000905 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000906 new->data->type, inet_ntoa (new->data->id));
907 ospf_lsa_header_dump (new->data);
908 }
909
910 return NULL;
911}
912
paul4dadc292005-05-06 21:37:42 +0000913static int
paul718e3742002-12-13 20:15:29 +0000914ospf_router_lsa_timer (struct thread *t)
915{
916 struct ospf_area *area;
917
918 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000919 zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
paul718e3742002-12-13 20:15:29 +0000920
921 area = THREAD_ARG (t);
922 area->t_router_lsa_self = NULL;
923
924 /* Now refresh router-LSA. */
925 if (area->router_lsa_self)
926 ospf_router_lsa_refresh (area->router_lsa_self);
927 /* Newly originate router-LSA. */
928 else
929 ospf_router_lsa_originate (area);
930
931 return 0;
932}
933
934void
935ospf_router_lsa_timer_add (struct ospf_area *area)
936{
937 /* Keep area's self-originated router-LSA. */
938 struct ospf_lsa *lsa = area->router_lsa_self;
939
940 /* Cancel previously scheduled router-LSA timer. */
941 if (area->t_router_lsa_self)
942 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000943 zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
paul718e3742002-12-13 20:15:29 +0000944
945 OSPF_TIMER_OFF (area->t_router_lsa_self);
946
947 /* If router-LSA is originated previously, check the interval time. */
948 if (lsa)
949 {
950 int delay;
951 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
952 {
953 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
954 ospf_router_lsa_timer, delay);
955 return;
956 }
957 }
958
959 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000960 zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
paul718e3742002-12-13 20:15:29 +0000961
962 /* Immediately refresh router-LSA. */
963 OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
964}
965
966int
paul68980082003-03-25 05:07:42 +0000967ospf_router_lsa_update_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000968{
paul68980082003-03-25 05:07:42 +0000969 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +0000970 struct listnode *node, *nnode;
971 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +0000972
973 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000974 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +0000975
paul68980082003-03-25 05:07:42 +0000976 ospf->t_router_lsa_update = NULL;
paul718e3742002-12-13 20:15:29 +0000977
paul1eb8ef22005-04-07 07:30:20 +0000978 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000979 {
paul718e3742002-12-13 20:15:29 +0000980 struct ospf_lsa *lsa = area->router_lsa_self;
981 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +0000982 const char *area_str;
paul718e3742002-12-13 20:15:29 +0000983
984 /* Keep Area ID string. */
985 area_str = AREA_NAME (area);
986
987 /* If LSA not exist in this Area, originate new. */
988 if (lsa == NULL)
989 {
990 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000991 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +0000992
993 ospf_router_lsa_originate (area);
994 }
995 /* If router-ID is changed, Link ID must change.
996 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +0000997 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000998 {
999 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001000 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +00001001 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
1002 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001003 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00001004 area->router_lsa_self = NULL;
1005
1006 /* Refresh router-LSA, (not install) and flood through area. */
1007 ospf_router_lsa_timer_add (area);
1008 }
1009 else
1010 {
1011 rl = (struct router_lsa *) lsa->data;
1012 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +00001013 if (rl->flags != ospf->flags)
paul718e3742002-12-13 20:15:29 +00001014 ospf_router_lsa_timer_add (area);
1015 }
1016 }
1017
1018 return 0;
1019}
1020
1021
1022/* network-LSA related functions. */
1023/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001024static void
paul718e3742002-12-13 20:15:29 +00001025ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1026{
1027 struct in_addr mask;
1028 struct route_node *rn;
1029 struct ospf_neighbor *nbr;
1030
1031 masklen2ip (oi->address->prefixlen, &mask);
1032 stream_put_ipv4 (s, mask.s_addr);
1033
1034 /* The network-LSA lists those routers that are fully adjacent to
1035 the Designated Router; each fully adjacent router is identified by
1036 its OSPF Router ID. The Designated Router includes itself in this
1037 list. RFC2328, Section 12.4.2 */
1038
1039 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1040 if ((nbr = rn->info) != NULL)
1041 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1042 stream_put_ipv4 (s, nbr->router_id.s_addr);
1043}
1044
paul4dadc292005-05-06 21:37:42 +00001045static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001046ospf_network_lsa_new (struct ospf_interface *oi)
1047{
1048 struct stream *s;
1049 struct ospf_lsa *new;
1050 struct lsa_header *lsah;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001051 struct ospf_if_params *oip;
paul718e3742002-12-13 20:15:29 +00001052 int length;
1053
1054 /* If there are no neighbours on this network (the net is stub),
1055 the router does not originate network-LSA (see RFC 12.4.2) */
1056 if (oi->full_nbrs == 0)
1057 return NULL;
1058
1059 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001060 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001061
1062 /* Create new stream for LSA. */
1063 s = stream_new (OSPF_MAX_LSA_SIZE);
1064 lsah = (struct lsa_header *) STREAM_DATA (s);
1065
1066 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001067 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001068
1069 /* Set network-LSA body fields. */
1070 ospf_network_lsa_body_set (s, oi);
1071
1072 /* Set length. */
1073 length = stream_get_endp (s);
1074 lsah->length = htons (length);
1075
1076 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001077 if ( (new = ospf_lsa_new ()) == NULL)
1078 {
1079 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1080 return NULL;
1081 }
1082
paul718e3742002-12-13 20:15:29 +00001083 new->area = oi->area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001084 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001085
1086 /* Copy LSA to store. */
1087 new->data = ospf_lsa_data_new (length);
1088 memcpy (new->data, lsah, length);
1089 stream_free (s);
Paul Jakma7eb5b472009-10-13 16:13:13 +01001090
1091 /* Remember prior network LSA sequence numbers, even if we stop
1092 * originating one for this oi, to try avoid re-originating LSAs with a
1093 * prior sequence number, and thus speed up adjency forming & convergence.
1094 */
1095 if ((oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4)))
1096 {
1097 new->data->ls_seqnum = oip->network_lsa_seqnum;
1098 new->data->ls_seqnum = lsa_seqnum_increment (new);
1099 }
1100 else
1101 {
1102 oip = ospf_get_if_params (oi->ifp, oi->address->u.prefix4);
1103 ospf_if_update_params (oi->ifp, oi->address->u.prefix4);
1104 }
1105 oip->network_lsa_seqnum = new->data->ls_seqnum;
1106
paul718e3742002-12-13 20:15:29 +00001107 return new;
1108}
1109
1110/* Originate network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001111static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001112ospf_network_lsa_originate (struct ospf_interface *oi)
1113{
1114 struct ospf_lsa *new;
1115
1116 /* Create new network-LSA instance. */
1117 new = ospf_network_lsa_new (oi);
1118 if (new == NULL)
1119 return NULL;
1120
1121 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001122 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001123
1124 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001125 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001126
1127 /* Flooding new LSA through area. */
1128 ospf_flood_through_area (oi->area, NULL, new);
1129
1130 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1131 {
ajse588f212004-12-08 18:12:06 +00001132 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001133 new->data->type, inet_ntoa (new->data->id), new);
1134 ospf_lsa_header_dump (new->data);
1135 }
1136
1137 return new;
1138}
1139
1140int
1141ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1142{
1143 struct ospf_area *area = lsa->area;
1144 struct ospf_lsa *new;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001145 struct ospf_if_params *oip;
paul718e3742002-12-13 20:15:29 +00001146
1147 assert (lsa->data);
1148
1149 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001150 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001151
1152 /* Create new network-LSA instance. */
1153 new = ospf_network_lsa_new (oi);
1154 if (new == NULL)
1155 return -1;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001156
1157 oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4);
1158 assert (oip != NULL);
1159 oip->network_lsa_seqnum = new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001160
paul68980082003-03-25 05:07:42 +00001161 ospf_lsa_install (area->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001162
1163 /* Flood LSA through aera. */
1164 ospf_flood_through_area (area, NULL, new);
1165
1166 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1167 {
ajse588f212004-12-08 18:12:06 +00001168 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001169 new->data->type, inet_ntoa (new->data->id));
1170 ospf_lsa_header_dump (new->data);
1171 }
1172
1173 return 0;
1174}
1175
paul4dadc292005-05-06 21:37:42 +00001176static int
paul718e3742002-12-13 20:15:29 +00001177ospf_network_lsa_refresh_timer (struct thread *t)
1178{
1179 struct ospf_interface *oi;
1180
1181 oi = THREAD_ARG (t);
1182 oi->t_network_lsa_self = NULL;
1183
1184 if (oi->network_lsa_self)
1185 /* Now refresh network-LSA. */
1186 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1187 else
1188 /* Newly create network-LSA. */
1189 ospf_network_lsa_originate (oi);
1190
1191 return 0;
1192}
1193
1194void
1195ospf_network_lsa_timer_add (struct ospf_interface *oi)
1196{
1197 /* Keep interface's self-originated network-LSA. */
1198 struct ospf_lsa *lsa = oi->network_lsa_self;
1199
1200 /* Cancel previously schedules network-LSA timer. */
1201 if (oi->t_network_lsa_self)
1202 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001203 zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
paul718e3742002-12-13 20:15:29 +00001204 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1205
1206 /* If network-LSA is originated previously, check the interval time. */
1207 if (lsa)
1208 {
1209 int delay;
1210 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1211 {
1212 oi->t_network_lsa_self =
1213 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1214 oi, delay);
1215 return;
1216 }
1217 }
1218
1219 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001220 zlog_debug ("Scheduling network-LSA origination right away");
paul718e3742002-12-13 20:15:29 +00001221
1222 /* Immediately refresh network-LSA. */
1223 oi->t_network_lsa_self =
1224 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1225}
1226
1227
paul4dadc292005-05-06 21:37:42 +00001228static void
paul718e3742002-12-13 20:15:29 +00001229stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1230{
1231 u_int32_t metric;
1232 char *mp;
1233
1234 /* Put 0 metric. TOS metric is not supported. */
1235 metric = htonl (metric_value);
1236 mp = (char *) &metric;
1237 mp++;
1238 stream_put (s, mp, 3);
1239}
1240
1241/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001242static void
paul718e3742002-12-13 20:15:29 +00001243ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1244 u_int32_t metric)
1245{
1246 struct in_addr mask;
1247
1248 masklen2ip (p->prefixlen, &mask);
1249
1250 /* Put Network Mask. */
1251 stream_put_ipv4 (s, mask.s_addr);
1252
1253 /* Set # TOS. */
1254 stream_putc (s, (u_char) 0);
1255
1256 /* Set metric. */
1257 stream_put_ospf_metric (s, metric);
1258}
1259
paul4dadc292005-05-06 21:37:42 +00001260static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001261ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1262 u_int32_t metric, struct in_addr id)
1263{
1264 struct stream *s;
1265 struct ospf_lsa *new;
1266 struct lsa_header *lsah;
1267 int length;
1268
paulc24d6022005-11-20 14:54:12 +00001269 if (id.s_addr == 0xffffffff)
1270 {
1271 /* Maybe Link State ID not available. */
1272 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1273 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1274 OSPF_SUMMARY_LSA);
1275 return NULL;
1276 }
1277
paul718e3742002-12-13 20:15:29 +00001278 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001279 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001280
1281 /* Create new stream for LSA. */
1282 s = stream_new (OSPF_MAX_LSA_SIZE);
1283 lsah = (struct lsa_header *) STREAM_DATA (s);
1284
paul68980082003-03-25 05:07:42 +00001285 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1286 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001287
1288 /* Set summary-LSA body fields. */
1289 ospf_summary_lsa_body_set (s, p, metric);
1290
1291 /* Set length. */
1292 length = stream_get_endp (s);
1293 lsah->length = htons (length);
1294
1295 /* Create OSPF LSA instance. */
1296 new = ospf_lsa_new ();
1297 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001298 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001299
1300 /* Copy LSA to store. */
1301 new->data = ospf_lsa_data_new (length);
1302 memcpy (new->data, lsah, length);
1303 stream_free (s);
1304
1305 return new;
1306}
1307
1308/* Originate Summary-LSA. */
1309struct ospf_lsa *
1310ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1311 struct ospf_area *area)
1312{
1313 struct ospf_lsa *new;
1314 struct in_addr id;
1315
paul68980082003-03-25 05:07:42 +00001316 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001317
paulc24d6022005-11-20 14:54:12 +00001318 if (id.s_addr == 0xffffffff)
1319 {
1320 /* Maybe Link State ID not available. */
1321 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1322 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1323 OSPF_SUMMARY_LSA);
1324 return NULL;
1325 }
1326
paul718e3742002-12-13 20:15:29 +00001327 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001328 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1329 return NULL;
paul718e3742002-12-13 20:15:29 +00001330
1331 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001332 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001333
1334 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001335 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001336
1337 /* Flooding new LSA through area. */
1338 ospf_flood_through_area (area, NULL, new);
1339
1340 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1341 {
ajse588f212004-12-08 18:12:06 +00001342 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001343 new->data->type, inet_ntoa (new->data->id), new);
1344 ospf_lsa_header_dump (new->data);
1345 }
1346
1347 return new;
1348}
1349
1350struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001351ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001352{
1353 struct ospf_lsa *new;
1354 struct summary_lsa *sl;
1355 struct prefix p;
1356
1357 /* Sanity check. */
1358 assert (lsa->data);
1359
1360 sl = (struct summary_lsa *)lsa->data;
1361 p.prefixlen = ip_masklen (sl->mask);
1362 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1363 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001364
1365 if (!new)
1366 return NULL;
1367
paul718e3742002-12-13 20:15:29 +00001368 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001369
paul68980082003-03-25 05:07:42 +00001370 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001371
1372 /* Flood LSA through AS. */
1373 ospf_flood_through_area (new->area, NULL, new);
1374
1375 /* Debug logging. */
1376 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1377 {
ajse588f212004-12-08 18:12:06 +00001378 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001379 new->data->type, inet_ntoa (new->data->id));
1380 ospf_lsa_header_dump (new->data);
1381 }
1382
1383 return new;
1384}
1385
1386
1387/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001388static void
paul718e3742002-12-13 20:15:29 +00001389ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1390 u_int32_t metric)
1391{
1392 struct in_addr mask;
1393
1394 masklen2ip (p->prefixlen, &mask);
1395
1396 /* Put Network Mask. */
1397 stream_put_ipv4 (s, mask.s_addr);
1398
1399 /* Set # TOS. */
1400 stream_putc (s, (u_char) 0);
1401
1402 /* Set metric. */
1403 stream_put_ospf_metric (s, metric);
1404}
1405
paul4dadc292005-05-06 21:37:42 +00001406static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001407ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1408 u_int32_t metric, struct in_addr id)
1409{
1410 struct stream *s;
1411 struct ospf_lsa *new;
1412 struct lsa_header *lsah;
1413 int length;
1414
paulc24d6022005-11-20 14:54:12 +00001415 if (id.s_addr == 0xffffffff)
1416 {
1417 /* Maybe Link State ID not available. */
1418 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1419 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1420 OSPF_ASBR_SUMMARY_LSA);
1421 return NULL;
1422 }
1423
paul718e3742002-12-13 20:15:29 +00001424 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001425 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001426
1427 /* Create new stream for LSA. */
1428 s = stream_new (OSPF_MAX_LSA_SIZE);
1429 lsah = (struct lsa_header *) STREAM_DATA (s);
1430
paul68980082003-03-25 05:07:42 +00001431 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1432 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001433
1434 /* Set summary-LSA body fields. */
1435 ospf_summary_asbr_lsa_body_set (s, p, metric);
1436
1437 /* Set length. */
1438 length = stream_get_endp (s);
1439 lsah->length = htons (length);
1440
1441 /* Create OSPF LSA instance. */
1442 new = ospf_lsa_new ();
1443 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001444 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001445
1446 /* Copy LSA to store. */
1447 new->data = ospf_lsa_data_new (length);
1448 memcpy (new->data, lsah, length);
1449 stream_free (s);
1450
1451 return new;
1452}
1453
1454/* Originate summary-ASBR-LSA. */
1455struct ospf_lsa *
1456ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1457 struct ospf_area *area)
1458{
1459 struct ospf_lsa *new;
1460 struct in_addr id;
1461
paul68980082003-03-25 05:07:42 +00001462 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001463
paulc24d6022005-11-20 14:54:12 +00001464 if (id.s_addr == 0xffffffff)
1465 {
1466 /* Maybe Link State ID not available. */
1467 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1468 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1469 OSPF_ASBR_SUMMARY_LSA);
1470 return NULL;
1471 }
1472
paul718e3742002-12-13 20:15:29 +00001473 /* Create new summary-LSA instance. */
1474 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001475 if (!new)
1476 return NULL;
paul718e3742002-12-13 20:15:29 +00001477
1478 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001479 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001480
1481 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001482 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001483
1484 /* Flooding new LSA through area. */
1485 ospf_flood_through_area (area, NULL, new);
1486
1487 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1488 {
ajse588f212004-12-08 18:12:06 +00001489 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001490 new->data->type, inet_ntoa (new->data->id), new);
1491 ospf_lsa_header_dump (new->data);
1492 }
1493
1494 return new;
1495}
1496
1497struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001498ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001499{
1500 struct ospf_lsa *new;
1501 struct summary_lsa *sl;
1502 struct prefix p;
1503
1504 /* Sanity check. */
1505 assert (lsa->data);
1506
1507 sl = (struct summary_lsa *)lsa->data;
1508 p.prefixlen = ip_masklen (sl->mask);
1509 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1510 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001511 if (!new)
1512 return NULL;
paul718e3742002-12-13 20:15:29 +00001513
1514 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001515
paul68980082003-03-25 05:07:42 +00001516 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001517
1518 /* Flood LSA through area. */
1519 ospf_flood_through_area (new->area, NULL, new);
1520
1521 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1522 {
ajse588f212004-12-08 18:12:06 +00001523 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001524 new->data->type, inet_ntoa (new->data->id));
1525 ospf_lsa_header_dump (new->data);
1526 }
1527
1528 return new;
1529}
1530
1531/* AS-external-LSA related functions. */
1532
1533/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1534 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001535static struct in_addr
paul68980082003-03-25 05:07:42 +00001536ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001537{
1538 struct in_addr fwd;
1539 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001540 struct listnode *node;
1541 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001542
1543 fwd.s_addr = 0;
1544
1545 if (!nexthop.s_addr)
1546 return fwd;
1547
1548 /* Check whether nexthop is covered by OSPF network. */
1549 nh.family = AF_INET;
1550 nh.u.prefix4 = nexthop;
1551 nh.prefixlen = IPV4_MAX_BITLEN;
Paul Jakma4ca15d42009-08-03 15:16:41 +01001552
1553 /* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be
1554 * better to make use of the per-ifp table of ois.
1555 */
paul1eb8ef22005-04-07 07:30:20 +00001556 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1557 if (if_is_operative (oi->ifp))
1558 if (oi->address->family == AF_INET)
1559 if (prefix_match (oi->address, &nh))
1560 return nexthop;
paul718e3742002-12-13 20:15:29 +00001561
1562 return fwd;
1563}
1564
paul718e3742002-12-13 20:15:29 +00001565/* NSSA-external-LSA related functions. */
1566
1567/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001568
paul718e3742002-12-13 20:15:29 +00001569struct in_addr
1570ospf_get_ip_from_ifp (struct ospf_interface *oi)
1571{
1572 struct in_addr fwd;
1573
1574 fwd.s_addr = 0;
1575
paul2e3b2e42002-12-13 21:03:13 +00001576 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001577 return oi->address->u.prefix4;
1578
1579 return fwd;
1580}
1581
1582/* Get 1st IP connection for Forward Addr */
1583struct in_addr
paulf2c80652002-12-13 21:44:27 +00001584ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001585{
1586 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001587 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001588 struct listnode *node;
1589 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001590
1591 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001592 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001593
paul1eb8ef22005-04-07 07:30:20 +00001594 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001595 {
paul2e3b2e42002-12-13 21:03:13 +00001596 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001597 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001598 if (oi->address && oi->address->family == AF_INET)
1599 {
1600 if (best_default.s_addr == 0)
1601 best_default = oi->address->u.prefix4;
1602 if (oi->area == area)
1603 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001604 }
paul718e3742002-12-13 20:15:29 +00001605 }
paulf2c80652002-12-13 21:44:27 +00001606 if (best_default.s_addr != 0)
1607 return best_default;
paul718e3742002-12-13 20:15:29 +00001608
paul68980082003-03-25 05:07:42 +00001609 if (best_default.s_addr != 0)
1610 return best_default;
1611
paul718e3742002-12-13 20:15:29 +00001612 return fwd;
1613}
hassobeebba72004-06-20 21:00:27 +00001614
paul718e3742002-12-13 20:15:29 +00001615#define DEFAULT_DEFAULT_METRIC 20
1616#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1617#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1618
1619#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1620
1621int
paul68980082003-03-25 05:07:42 +00001622metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001623{
paul68980082003-03-25 05:07:42 +00001624 return (ospf->dmetric[src].type < 0 ?
1625 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001626}
1627
1628int
paul68980082003-03-25 05:07:42 +00001629metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001630{
paul68980082003-03-25 05:07:42 +00001631 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001632 {
1633 if (src == DEFAULT_ROUTE)
1634 {
paul68980082003-03-25 05:07:42 +00001635 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001636 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1637 else
1638 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1639 }
paul68980082003-03-25 05:07:42 +00001640 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001641 return DEFAULT_DEFAULT_METRIC;
1642 else
paul68980082003-03-25 05:07:42 +00001643 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001644 }
1645
paul68980082003-03-25 05:07:42 +00001646 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001647}
1648
1649/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001650static void
paul68980082003-03-25 05:07:42 +00001651ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1652 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001653{
1654 struct prefix_ipv4 *p = &ei->p;
1655 struct in_addr mask, fwd_addr;
1656 u_int32_t mvalue;
1657 int mtype;
1658 int type;
1659
1660 /* Put Network Mask. */
1661 masklen2ip (p->prefixlen, &mask);
1662 stream_put_ipv4 (s, mask.s_addr);
1663
1664 /* If prefix is default, specify DEFAULT_ROUTE. */
1665 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1666
1667 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001668 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001669
1670 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001671 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001672
1673 /* Put type of external metric. */
1674 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1675
1676 /* Put 0 metric. TOS metric is not supported. */
1677 stream_put_ospf_metric (s, mvalue);
1678
1679 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001680 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001681
1682 /* Put forwarding address. */
1683 stream_put_ipv4 (s, fwd_addr.s_addr);
1684
1685 /* Put route tag -- This value should be introduced from configuration. */
1686 stream_putl (s, 0);
1687}
1688
1689/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001690static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001691ospf_external_lsa_new (struct ospf *ospf,
1692 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001693{
1694 struct stream *s;
1695 struct lsa_header *lsah;
1696 struct ospf_lsa *new;
1697 struct in_addr id;
1698 int length;
1699
1700 if (ei == NULL)
1701 {
1702 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001703 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
paul718e3742002-12-13 20:15:29 +00001704 return NULL;
1705 }
1706
1707 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001708 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001709
1710 /* If old Link State ID is specified, refresh LSA with same ID. */
1711 if (old_id)
1712 id = *old_id;
1713 /* Get Link State with unique ID. */
1714 else
1715 {
paul68980082003-03-25 05:07:42 +00001716 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001717 if (id.s_addr == 0xffffffff)
1718 {
1719 /* Maybe Link State ID not available. */
1720 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001721 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001722 return NULL;
1723 }
1724 }
1725
1726 /* Create new stream for LSA. */
1727 s = stream_new (OSPF_MAX_LSA_SIZE);
1728 lsah = (struct lsa_header *) STREAM_DATA (s);
1729
1730 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001731 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1732 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001733
1734 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001735 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001736
1737 /* Set length. */
1738 length = stream_get_endp (s);
1739 lsah->length = htons (length);
1740
1741 /* Now, create OSPF LSA instance. */
1742 new = ospf_lsa_new ();
1743 new->area = NULL;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001744 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001745
1746 /* Copy LSA data to store, discard stream. */
1747 new->data = ospf_lsa_data_new (length);
1748 memcpy (new->data, lsah, length);
1749 stream_free (s);
1750
1751 return new;
1752}
1753
paul718e3742002-12-13 20:15:29 +00001754/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001755static void
paul68980082003-03-25 05:07:42 +00001756ospf_install_flood_nssa (struct ospf *ospf,
1757 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001758{
pauld4a53d52003-07-12 21:30:57 +00001759 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001760 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001761 struct ospf_area *area;
1762 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001763
pauld4a53d52003-07-12 21:30:57 +00001764 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1765 * which originated from an NSSA area. In which case it should not be
1766 * flooded back to NSSA areas.
1767 */
1768 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1769 return;
1770
paul718e3742002-12-13 20:15:29 +00001771 /* NSSA Originate or Refresh (If anyNSSA)
1772
1773 LSA is self-originated. And just installed as Type-5.
1774 Additionally, install as Type-7 LSDB for every attached NSSA.
1775
1776 P-Bit controls which ABR performs translation to outside world; If
1777 we are an ABR....do not set the P-bit, because we send the Type-5,
1778 not as the ABR Translator, but as the ASBR owner within the AS!
1779
1780 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1781 elected ABR Translator will see the P-bit, Translate, and re-flood.
1782
1783 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1784 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1785
paul1eb8ef22005-04-07 07:30:20 +00001786 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001787 {
hasso0c14ad82003-07-03 08:36:02 +00001788 /* Don't install Type-7 LSA's into nonNSSA area */
1789 if (area->external_routing != OSPF_AREA_NSSA)
1790 continue;
paul718e3742002-12-13 20:15:29 +00001791
paul68980082003-03-25 05:07:42 +00001792 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001793 new = ospf_lsa_dup (lsa);
1794 new->area = area;
1795 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001796
paul68980082003-03-25 05:07:42 +00001797 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001798 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001799 {
pauld4a53d52003-07-12 21:30:57 +00001800 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001801
1802 /* set non-zero FWD ADDR
1803
1804 draft-ietf-ospf-nssa-update-09.txt
1805
1806 if the network between the NSSA AS boundary router and the
1807 adjacent AS is advertised into OSPF as an internal OSPF route,
1808 the forwarding address should be the next op address as is cu
1809 currently done with type-5 LSAs. If the intervening network is
1810 not adversited into OSPF as an internal OSPF route and the
1811 type-7 LSA's P-bit is set a forwarding address should be
1812 selected from one of the router's active OSPF inteface addresses
1813 which belong to the NSSA. If no such addresses exist, then
1814 no type-7 LSA's with the P-bit set should originate from this
1815 router. */
1816
pauld4a53d52003-07-12 21:30:57 +00001817 /* kevinm: not updating lsa anymore, just new */
1818 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001819
1820 if (extlsa->e[0].fwd_addr.s_addr == 0)
1821 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001822
pauld7480322003-05-16 17:31:51 +00001823 if (extlsa->e[0].fwd_addr.s_addr == 0)
1824 {
1825 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001826 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001827 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001828 return;
1829 }
paulf2c80652002-12-13 21:44:27 +00001830 }
paul718e3742002-12-13 20:15:29 +00001831
paul68980082003-03-25 05:07:42 +00001832 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001833 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001834
1835 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001836 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001837 }
paul718e3742002-12-13 20:15:29 +00001838}
pauld4a53d52003-07-12 21:30:57 +00001839
paul4dadc292005-05-06 21:37:42 +00001840static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001841ospf_lsa_translated_nssa_new (struct ospf *ospf,
1842 struct ospf_lsa *type7)
1843{
1844
1845 struct ospf_lsa *new;
1846 struct as_external_lsa *ext, *extnew;
1847 struct external_info ei;
1848
1849 ext = (struct as_external_lsa *)(type7->data);
1850
1851 /* need external_info struct, fill in bare minimum */
1852 ei.p.family = AF_INET;
1853 ei.p.prefix = type7->data->id;
1854 ei.p.prefixlen = ip_masklen (ext->mask);
1855 ei.type = ZEBRA_ROUTE_OSPF;
1856 ei.nexthop = ext->header.adv_router;
1857 ei.route_map_set.metric = -1;
1858 ei.route_map_set.metric_type = -1;
1859 ei.tag = 0;
1860
1861 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1862 {
1863 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001864 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001865 "Translated Type-5 for %s",
1866 inet_ntoa (ei.p.prefix));
1867 return NULL;
1868 }
1869
1870 extnew = (struct as_external_lsa *)(new->data);
1871
1872 /* copy over Type-7 data to new */
1873 extnew->e[0].tos = ext->e[0].tos;
1874 extnew->e[0].route_tag = ext->e[0].route_tag;
1875 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1876 new->data->ls_seqnum = type7->data->ls_seqnum;
1877
1878 /* add translated flag, checksum and lock new lsa */
1879 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
pauld4a53d52003-07-12 21:30:57 +00001880 new = ospf_lsa_lock (new);
1881
1882 return new;
1883}
1884
pauld4a53d52003-07-12 21:30:57 +00001885/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1886struct ospf_lsa *
1887ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1888{
1889 struct ospf_lsa *new;
1890 struct as_external_lsa *extnew;
1891
1892 /* we cant use ospf_external_lsa_originate() as we need to set
1893 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1894 */
1895
1896 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1897 {
1898 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001899 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001900 "Type-7, Id %s, to Type-5",
1901 inet_ntoa (type7->data->id));
1902 return NULL;
1903 }
1904
1905 extnew = (struct as_external_lsa *)new;
1906
1907 if (IS_DEBUG_OSPF_NSSA)
1908 {
ajse588f212004-12-08 18:12:06 +00001909 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001910 "translated Type 7, installed:");
1911 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001912 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1913 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001914 }
1915
1916 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1917 {
1918 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001919 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001920 "Could not install LSA "
1921 "id %s", inet_ntoa (type7->data->id));
1922 return NULL;
1923 }
1924
1925 ospf->lsa_originate_count++;
1926 ospf_flood_through_as (ospf, NULL, new);
1927
1928 return new;
1929}
1930
1931/* Refresh Translated from NSSA AS-external-LSA. */
1932struct ospf_lsa *
1933ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1934 struct ospf_lsa *type5)
1935{
1936 struct ospf_lsa *new = NULL;
1937
1938 /* Sanity checks. */
1939 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00001940 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00001941 return NULL;
pauld4a53d52003-07-12 21:30:57 +00001942 if (type7)
1943 assert (type7->data);
1944 if (type5)
1945 assert (type5->data);
1946 assert (ospf->anyNSSA);
1947
1948 /* get required data according to what has been given */
1949 if (type7 && type5 == NULL)
1950 {
1951 /* find the translated Type-5 for this Type-7 */
1952 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1953 struct prefix_ipv4 p =
1954 {
1955 .prefix = type7->data->id,
1956 .prefixlen = ip_masklen (ext->mask),
1957 .family = AF_INET,
1958 };
1959
1960 type5 = ospf_external_info_find_lsa (ospf, &p);
1961 }
1962 else if (type5 && type7 == NULL)
1963 {
1964 /* find the type-7 from which supplied type-5 was translated,
1965 * ie find first type-7 with same LSA Id.
1966 */
paul1eb8ef22005-04-07 07:30:20 +00001967 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00001968 struct route_node *rn;
1969 struct ospf_lsa *lsa;
1970 struct ospf_area *area;
1971
paul1eb8ef22005-04-07 07:30:20 +00001972 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00001973 {
1974 if (area->external_routing != OSPF_AREA_NSSA
1975 && !type7)
1976 continue;
1977
1978 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
1979 {
1980 if (lsa->data->id.s_addr == type5->data->id.s_addr)
1981 {
1982 type7 = lsa;
1983 break;
1984 }
1985 }
1986 }
1987 }
1988
1989 /* do we have type7? */
1990 if (!type7)
1991 {
1992 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001993 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00001994 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00001995 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00001996 return NULL;
1997 }
1998
1999 /* do we have valid translated type5? */
2000 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
2001 {
2002 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002003 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00002004 "found for Type-7 with Id %s",
2005 inet_ntoa (type7->data->id));
2006 return NULL;
2007 }
2008
2009 /* Delete LSA from neighbor retransmit-list. */
2010 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
2011
2012 /* create new translated LSA */
2013 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
2014 {
2015 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002016 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00002017 "Type-7 for %s to Type-5",
2018 inet_ntoa (type7->data->id));
2019 return NULL;
2020 }
2021
2022 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
2023 {
2024 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002025 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00002026 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00002027 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00002028 return NULL;
2029 }
2030
2031 /* Flood LSA through area. */
2032 ospf_flood_through_as (ospf, NULL, new);
2033
2034 return new;
2035}
paul718e3742002-12-13 20:15:29 +00002036
2037int
2038is_prefix_default (struct prefix_ipv4 *p)
2039{
2040 struct prefix_ipv4 q;
2041
2042 q.family = AF_INET;
2043 q.prefix.s_addr = 0;
2044 q.prefixlen = 0;
2045
2046 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
2047}
2048
2049/* Originate an AS-external-LSA, install and flood. */
2050struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002051ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00002052{
2053 struct ospf_lsa *new;
2054
2055 /* Added for NSSA project....
2056
2057 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2058 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2059 every area. The Type-7's are flooded to every IR and every ABR; We
2060 install the Type-5 LSDB so that the normal "refresh" code operates
2061 as usual, and flag them as not used during ASE calculations. The
2062 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2063 Address of non-zero.
2064
2065 If an ABR is the elected NSSA translator, following SPF and during
2066 the ABR task it will translate all the scanned Type-7's, with P-bit
2067 ON and not-self generated, and translate to Type-5's throughout the
2068 non-NSSA/STUB AS.
2069
2070 A difference in operation depends whether this ASBR is an ABR
2071 or not. If not an ABR, the P-bit is ON, to indicate that any
2072 elected NSSA-ABR can perform its translation.
2073
2074 If an ABR, the P-bit is OFF; No ABR will perform translation and
2075 this ASBR will flood the Type-5 LSA as usual.
2076
2077 For the case where this ASBR is not an ABR, the ASE calculations
2078 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2079 demonstrate to the user that there are LSA's that belong to any
2080 attached NSSA.
2081
2082 Finally, it just so happens that when the ABR is translating every
2083 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2084 approved Type-5 (translated from Type-7); at the end of translation
2085 if any Translated Type-5's remain unapproved, then they must be
2086 flushed from the AS.
2087
2088 */
2089
2090 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002091 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002092 return NULL;
2093
2094 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002095 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002096 {
2097 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002098 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002099 inet_ntoa (ei->p.prefix));
2100 return NULL;
2101 }
2102
2103 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002104 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002105
2106 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002107 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002108
2109 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002110 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002111
paul718e3742002-12-13 20:15:29 +00002112 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002113 if (ospf->anyNSSA &&
2114 /* stay away from translated LSAs! */
2115 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002116 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002117
2118 /* Debug logging. */
2119 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2120 {
ajse588f212004-12-08 18:12:06 +00002121 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002122 new->data->type, inet_ntoa (new->data->id), new);
2123 ospf_lsa_header_dump (new->data);
2124 }
2125
2126 return new;
2127}
2128
2129/* Originate AS-external-LSA from external info with initial flag. */
2130int
paul68980082003-03-25 05:07:42 +00002131ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002132{
paul68980082003-03-25 05:07:42 +00002133 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002134 struct route_node *rn;
2135 struct external_info *ei;
2136 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002137 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002138
paul68980082003-03-25 05:07:42 +00002139 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002140
2141 /* Originate As-external-LSA from all type of distribute source. */
2142 if ((rt = EXTERNAL_INFO (type)))
2143 for (rn = route_top (rt); rn; rn = route_next (rn))
2144 if ((ei = rn->info) != NULL)
2145 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002146 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002147 zlog_warn ("LSA: AS-external-LSA was not originated.");
2148
2149 return 0;
2150}
2151
paul4dadc292005-05-06 21:37:42 +00002152static struct external_info *
paul020709f2003-04-04 02:44:16 +00002153ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002154{
2155 int type;
2156 struct route_node *rn;
2157 struct prefix_ipv4 p;
2158
2159 p.family = AF_INET;
2160 p.prefix.s_addr = 0;
2161 p.prefixlen = 0;
2162
2163 /* First, lookup redistributed default route. */
2164 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2165 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2166 {
2167 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2168 if (rn != NULL)
2169 {
2170 route_unlock_node (rn);
2171 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002172 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002173 return rn->info;
2174 }
2175 }
2176
2177 return NULL;
2178}
2179
2180int
paul68980082003-03-25 05:07:42 +00002181ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002182{
paul718e3742002-12-13 20:15:29 +00002183 struct prefix_ipv4 p;
2184 struct in_addr nexthop;
2185 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002186 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002187
Paul Jakma4021b602006-05-12 22:55:41 +00002188 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002189
2190 p.family = AF_INET;
2191 p.prefix.s_addr = 0;
2192 p.prefixlen = 0;
2193
Paul Jakma4021b602006-05-12 22:55:41 +00002194 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002195 {
2196 /* If there is no default route via redistribute,
2197 then originate AS-external-LSA with nexthop 0 (self). */
2198 nexthop.s_addr = 0;
2199 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2200 }
2201
paul020709f2003-04-04 02:44:16 +00002202 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002203 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002204
2205 return 0;
2206}
2207
paul645878f2003-04-13 21:42:11 +00002208/* Flush any NSSA LSAs for given prefix */
2209void
2210ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2211{
paul1eb8ef22005-04-07 07:30:20 +00002212 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002213 struct ospf_lsa *lsa;
2214 struct ospf_area *area;
2215
paul1eb8ef22005-04-07 07:30:20 +00002216 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002217 {
paul1eb8ef22005-04-07 07:30:20 +00002218 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002219 {
2220 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2221 ospf->router_id)))
2222 {
2223 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002224 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002225 inet_ntoa (p->prefix), p->prefixlen);
2226 continue;
2227 }
2228 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2229 if (!IS_LSA_MAXAGE (lsa))
2230 {
2231 ospf_refresher_unregister_lsa (ospf, lsa);
2232 ospf_lsa_flush_area (lsa, area);
2233 }
2234 }
paul645878f2003-04-13 21:42:11 +00002235 }
2236}
paul645878f2003-04-13 21:42:11 +00002237
paul718e3742002-12-13 20:15:29 +00002238/* Flush an AS-external-LSA from LSDB and routing domain. */
2239void
paul68980082003-03-25 05:07:42 +00002240ospf_external_lsa_flush (struct ospf *ospf,
2241 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002242 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002243{
2244 struct ospf_lsa *lsa;
2245
2246 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002247 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002248 inet_ntoa (p->prefix), p->prefixlen);
2249
2250 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002251 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002252 {
2253 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002254 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002255 inet_ntoa (p->prefix), p->prefixlen);
2256 return;
2257 }
hassobeebba72004-06-20 21:00:27 +00002258
pauld4a53d52003-07-12 21:30:57 +00002259 /* If LSA is selforiginated, not a translated LSA, and there is
2260 * NSSA area, flush Type-7 LSA's at first.
2261 */
2262 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2263 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002264 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002265
2266 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002267 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002268
2269 /* There must be no self-originated LSA in rtrs_external. */
2270#if 0
2271 /* Remove External route from Zebra. */
2272 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2273#endif
2274
2275 if (!IS_LSA_MAXAGE (lsa))
2276 {
2277 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002278 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002279
2280 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002281 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002282 }
2283
2284 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002285 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002286}
2287
2288void
paul68980082003-03-25 05:07:42 +00002289ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002290{
2291 struct prefix_ipv4 p;
2292 struct external_info *ei;
2293 struct ospf_lsa *lsa;
2294
2295 p.family = AF_INET;
2296 p.prefixlen = 0;
2297 p.prefix.s_addr = 0;
2298
paul020709f2003-04-04 02:44:16 +00002299 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002300 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002301
2302 if (ei)
2303 {
2304 if (lsa)
2305 {
2306 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002307 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002308 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002309 }
2310 else
2311 {
2312 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002313 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002314 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002315 }
2316 }
2317 else
2318 {
2319 if (lsa)
2320 {
2321 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002322 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002323 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002324 }
2325 }
2326}
2327
2328void
paul68980082003-03-25 05:07:42 +00002329ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002330{
2331 struct route_node *rn;
2332 struct external_info *ei;
2333
2334 if (type != DEFAULT_ROUTE)
2335 if (EXTERNAL_INFO(type))
2336 /* Refresh each redistributed AS-external-LSAs. */
2337 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2338 if ((ei = rn->info))
2339 if (!is_prefix_default (&ei->p))
2340 {
2341 struct ospf_lsa *lsa;
2342
paul68980082003-03-25 05:07:42 +00002343 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2344 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002345 else
paul68980082003-03-25 05:07:42 +00002346 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002347 }
2348}
2349
2350/* Refresh AS-external-LSA. */
2351void
paul68980082003-03-25 05:07:42 +00002352ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002353 struct external_info *ei, int force)
2354{
2355 struct ospf_lsa *new;
2356 int changed;
2357
2358 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002359 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002360 {
pauld4a53d52003-07-12 21:30:57 +00002361 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002362 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002363 "redist check fail",
2364 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002365 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002366 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +00002367 return;
2368 }
2369
2370 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002371 {
2372 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002373 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002374 lsa->data->type, inet_ntoa (lsa->data->id));
2375 return;
2376 }
paul718e3742002-12-13 20:15:29 +00002377
2378 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002379 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002380
2381 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002382 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002383
paul68980082003-03-25 05:07:42 +00002384 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002385
2386 if (new == NULL)
2387 {
2388 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002389 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002390 inet_ntoa (lsa->data->id));
2391 return;
2392 }
2393
2394 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2395
paul68980082003-03-25 05:07:42 +00002396 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002397
2398 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002399 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002400
paul718e3742002-12-13 20:15:29 +00002401 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002402 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002403 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002404
pauld4a53d52003-07-12 21:30:57 +00002405 /* Register self-originated LSA to refresh queue.
2406 * Translated LSAs should not be registered, but refreshed upon
2407 * refresh of the Type-7
2408 */
2409 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2410 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002411
2412 /* Debug logging. */
2413 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2414 {
ajse588f212004-12-08 18:12:06 +00002415 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002416 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002417 ospf_lsa_header_dump (new->data);
2418 }
2419
2420 return;
2421}
2422
2423
2424/* LSA installation functions. */
2425
2426/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002427static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002428ospf_router_lsa_install (struct ospf *ospf,
2429 struct ospf_lsa *new, int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002430{
2431 struct ospf_area *area = new->area;
2432
2433 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2434 The entire routing table must be recalculated, starting with
2435 the shortest path calculations for each area (not just the
2436 area whose link-state database has changed).
2437 */
paul718e3742002-12-13 20:15:29 +00002438
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002439 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002440 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002441
2442 /* Only install LSA if it is originated/refreshed by us.
2443 * If LSA was received by flooding, the RECEIVED flag is set so do
2444 * not link the LSA */
2445 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2446 return new; /* ignore stale LSA */
2447
paul718e3742002-12-13 20:15:29 +00002448 /* Set router-LSA refresh timer. */
2449 OSPF_TIMER_OFF (area->t_router_lsa_self);
2450 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
pauld4a53d52003-07-12 21:30:57 +00002451 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002452
paul718e3742002-12-13 20:15:29 +00002453 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002454 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002455 area->router_lsa_self = ospf_lsa_lock (new);
2456
paul718e3742002-12-13 20:15:29 +00002457 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002458 if (rt_recalc)
2459 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002460
2461 return new;
2462}
2463
2464#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2465 if (!(T)) \
2466 (T) = thread_add_timer (master, (F), oi, (V))
2467
2468/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002469static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002470ospf_network_lsa_install (struct ospf *ospf,
2471 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002472 struct ospf_lsa *new,
2473 int rt_recalc)
2474{
2475
2476 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2477 The entire routing table must be recalculated, starting with
2478 the shortest path calculations for each area (not just the
2479 area whose link-state database has changed).
2480 */
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002481 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002482 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002483 /* We supposed that when LSA is originated by us, we pass the int
2484 for which it was originated. If LSA was received by flooding,
2485 the RECEIVED flag is set, so we do not link the LSA to the int. */
2486 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2487 return new; /* ignore stale LSA */
2488
paul718e3742002-12-13 20:15:29 +00002489 /* Set LSRefresh timer. */
2490 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2491
2492 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2493 ospf_network_lsa_refresh_timer,
2494 OSPF_LS_REFRESH_TIME);
2495
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002496 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002497 oi->network_lsa_self = ospf_lsa_lock (new);
2498 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002499 if (rt_recalc)
2500 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002501
2502 return new;
2503}
2504
2505/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002506static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002507ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2508 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002509{
paul718e3742002-12-13 20:15:29 +00002510 if (rt_recalc && !IS_LSA_SELF (new))
2511 {
2512 /* RFC 2328 Section 13.2 Summary-LSAs
2513 The best route to the destination described by the summary-
2514 LSA must be recalculated (see Section 16.5). If this
2515 destination is an AS boundary router, it may also be
2516 necessary to re-examine all the AS-external-LSAs.
2517 */
2518
2519#if 0
2520 /* This doesn't exist yet... */
2521 ospf_summary_incremental_update(new); */
2522#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002523 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002524#endif /* #if 0 */
2525
2526 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002527 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002528 }
2529
2530 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002531 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002532
2533 return new;
2534}
2535
2536/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002537static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002538ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2539 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002540{
2541 if (rt_recalc && !IS_LSA_SELF (new))
2542 {
2543 /* RFC 2328 Section 13.2 Summary-LSAs
2544 The best route to the destination described by the summary-
2545 LSA must be recalculated (see Section 16.5). If this
2546 destination is an AS boundary router, it may also be
2547 necessary to re-examine all the AS-external-LSAs.
2548 */
2549#if 0
2550 /* These don't exist yet... */
2551 ospf_summary_incremental_update(new);
2552 /* Isn't this done by the above call?
2553 - RFC 2328 Section 16.5 implies it should be */
2554 /* ospf_ase_calculate_schedule(); */
2555#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002556 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002557#endif /* #if 0 */
2558 }
2559
2560 /* register LSA to refresh-list. */
2561 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002562 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002563
2564 return new;
2565}
2566
2567/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002568static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002569ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2570 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002571{
paul68980082003-03-25 05:07:42 +00002572 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002573 /* If LSA is not self-originated, calculate an external route. */
2574 if (rt_recalc)
2575 {
2576 /* RFC 2328 Section 13.2 AS-external-LSAs
2577 The best route to the destination described by the AS-
2578 external-LSA must be recalculated (see Section 16.6).
2579 */
2580
2581 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002582 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002583 }
2584
pauld4a53d52003-07-12 21:30:57 +00002585 if (new->data->type == OSPF_AS_NSSA_LSA)
2586 {
2587 /* There is no point to register selforiginate Type-7 LSA for
2588 * refreshing. We rely on refreshing Type-5 LSA's
2589 */
2590 if (IS_LSA_SELF (new))
2591 return new;
2592 else
2593 {
2594 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2595 * New translations will be taken care of by the abr_task.
2596 */
2597 ospf_translated_nssa_refresh (ospf, new, NULL);
2598 }
2599 }
pauld7480322003-05-16 17:31:51 +00002600
pauld4a53d52003-07-12 21:30:57 +00002601 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002602 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002603 */
hassobeebba72004-06-20 21:00:27 +00002604 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002605 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002606
2607 return new;
2608}
2609
2610void
paul68980082003-03-25 05:07:42 +00002611ospf_discard_from_db (struct ospf *ospf,
2612 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002613{
2614 struct ospf_lsa *old;
2615
Paul Jakmaac904de2006-06-15 12:04:57 +00002616 if (!lsdb)
2617 {
2618 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2619 if (!lsa)
2620 zlog_warn ("%s: and NULL LSA!", __func__);
2621 else
2622 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2623 lsa->data->type, inet_ntoa (lsa->data->id));
2624 return;
2625 }
2626
paul718e3742002-12-13 20:15:29 +00002627 old = ospf_lsdb_lookup (lsdb, lsa);
2628
2629 if (!old)
2630 return;
2631
2632 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002633 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002634
2635 switch (old->data->type)
2636 {
2637 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002638 ospf_ase_unregister_external_lsa (old, ospf);
2639 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2640 break;
paul718e3742002-12-13 20:15:29 +00002641#ifdef HAVE_OPAQUE_LSA
2642 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002643 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002644 break;
paul69310a62005-05-11 18:09:59 +00002645#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002646 case OSPF_AS_NSSA_LSA:
2647 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2648 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002649 break;
paul718e3742002-12-13 20:15:29 +00002650 default:
paul68980082003-03-25 05:07:42 +00002651 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002652 break;
2653 }
2654
paul68980082003-03-25 05:07:42 +00002655 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002656 ospf_lsa_discard (old);
2657}
2658
paul718e3742002-12-13 20:15:29 +00002659struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002660ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2661 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002662{
2663 struct ospf_lsa *new = NULL;
2664 struct ospf_lsa *old = NULL;
2665 struct ospf_lsdb *lsdb = NULL;
2666 int rt_recalc;
2667
2668 /* Set LSDB. */
2669 switch (lsa->data->type)
2670 {
paulf2c80652002-12-13 21:44:27 +00002671 /* kevinm */
2672 case OSPF_AS_NSSA_LSA:
2673 if (lsa->area)
2674 lsdb = lsa->area->lsdb;
2675 else
paul68980082003-03-25 05:07:42 +00002676 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002677 break;
paul718e3742002-12-13 20:15:29 +00002678 case OSPF_AS_EXTERNAL_LSA:
2679#ifdef HAVE_OPAQUE_LSA
2680 case OSPF_OPAQUE_AS_LSA:
2681#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002682 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002683 break;
2684 default:
2685 lsdb = lsa->area->lsdb;
2686 break;
2687 }
2688
paul718e3742002-12-13 20:15:29 +00002689 assert (lsdb);
2690
2691 /* RFC 2328 13.2. Installing LSAs in the database
2692
2693 Installing a new LSA in the database, either as the result of
2694 flooding or a newly self-originated LSA, may cause the OSPF
2695 routing table structure to be recalculated. The contents of the
2696 new LSA should be compared to the old instance, if present. If
2697 there is no difference, there is no need to recalculate the
2698 routing table. When comparing an LSA to its previous instance,
2699 the following are all considered to be differences in contents:
2700
2701 o The LSA's Options field has changed.
2702
2703 o One of the LSA instances has LS age set to MaxAge, and
2704 the other does not.
2705
2706 o The length field in the LSA header has changed.
2707
2708 o The body of the LSA (i.e., anything outside the 20-byte
2709 LSA header) has changed. Note that this excludes changes
2710 in LS Sequence Number and LS Checksum.
2711
2712 */
2713 /* Look up old LSA and determine if any SPF calculation or incremental
2714 update is needed */
2715 old = ospf_lsdb_lookup (lsdb, lsa);
2716
2717 /* Do comparision and record if recalc needed. */
2718 rt_recalc = 0;
2719 if ( old == NULL || ospf_lsa_different(old, lsa))
2720 rt_recalc = 1;
2721
paul7ddf1d62003-10-13 09:06:46 +00002722 /*
2723 Sequence number check (Section 14.1 of rfc 2328)
2724 "Premature aging is used when it is time for a self-originated
2725 LSA's sequence number field to wrap. At this point, the current
2726 LSA instance (having LS sequence number MaxSequenceNumber) must
2727 be prematurely aged and flushed from the routing domain before a
2728 new instance with sequence number equal to InitialSequenceNumber
2729 can be originated. "
2730 */
2731
Paul Jakmac2b478d2006-03-30 14:16:11 +00002732 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002733 {
2734 if (ospf_lsa_is_self_originated(ospf, lsa))
2735 {
paul0c2be262004-05-31 14:16:54 +00002736 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2737
2738 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002739 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2740 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2741
2742 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2743 {
ajse588f212004-12-08 18:12:06 +00002744 zlog_debug ("ospf_lsa_install() Premature Aging "
paul7ddf1d62003-10-13 09:06:46 +00002745 "lsa 0x%lx", (u_long)lsa);
2746 ospf_lsa_header_dump (lsa->data);
2747 }
2748 }
2749 else
2750 {
2751 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2752 {
ajse588f212004-12-08 18:12:06 +00002753 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002754 "that was not self originated. Ignoring\n");
2755 ospf_lsa_header_dump (lsa->data);
2756 }
2757 return old;
2758 }
2759 }
2760
paul718e3742002-12-13 20:15:29 +00002761 /* discard old LSA from LSDB */
2762 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002763 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002764
paul718e3742002-12-13 20:15:29 +00002765 /* Calculate Checksum if self-originated?. */
2766 if (IS_LSA_SELF (lsa))
2767 ospf_lsa_checksum (lsa->data);
2768
hassofe71a972004-12-22 16:16:02 +00002769 /* Insert LSA to LSDB. */
2770 ospf_lsdb_add (lsdb, lsa);
2771 lsa->lsdb = lsdb;
2772
paul718e3742002-12-13 20:15:29 +00002773 /* Do LSA specific installation process. */
2774 switch (lsa->data->type)
2775 {
2776 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002777 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002778 break;
2779 case OSPF_NETWORK_LSA:
2780 assert (oi);
paul68980082003-03-25 05:07:42 +00002781 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002782 break;
2783 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002784 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002785 break;
2786 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002787 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002788 break;
2789 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002790 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002791 break;
2792#ifdef HAVE_OPAQUE_LSA
2793 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002794 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002795 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002796 else
paul68980082003-03-25 05:07:42 +00002797 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002798 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002799 case OSPF_OPAQUE_AREA_LSA:
2800 case OSPF_OPAQUE_AS_LSA:
2801 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2802 break;
2803#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002804 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002805 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002806 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002807 break;
2808 }
2809
2810 if (new == NULL)
2811 return new; /* Installation failed, cannot proceed further -- endo. */
2812
2813 /* Debug logs. */
2814 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2815 {
2816 char area_str[INET_ADDRSTRLEN];
2817
2818 switch (lsa->data->type)
2819 {
2820 case OSPF_AS_EXTERNAL_LSA:
2821#ifdef HAVE_OPAQUE_LSA
2822 case OSPF_OPAQUE_AS_LSA:
2823#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002824 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002825 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002826 dump_lsa_key (new),
2827 LOOKUP (ospf_lsa_type_msg, new->data->type));
2828 break;
2829 default:
2830 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002831 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002832 dump_lsa_key (new),
2833 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2834 break;
2835 }
2836 }
2837
paul7ddf1d62003-10-13 09:06:46 +00002838 /*
2839 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2840 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2841 */
2842 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2843 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002844 {
paul7ddf1d62003-10-13 09:06:46 +00002845 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002846 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002847 new->data->type,
2848 inet_ntoa (new->data->id),
2849 lsa);
paul68980082003-03-25 05:07:42 +00002850 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002851 }
2852
2853 return new;
2854}
2855
2856
paul4dadc292005-05-06 21:37:42 +00002857static int
paul68980082003-03-25 05:07:42 +00002858ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002859{
paul1eb8ef22005-04-07 07:30:20 +00002860 struct listnode *node, *nnode;
2861 struct ospf_interface *oi;
2862
2863 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002864 {
paul718e3742002-12-13 20:15:29 +00002865 struct route_node *rn;
2866 struct ospf_neighbor *nbr;
2867
2868 if (ospf_if_is_enable (oi))
2869 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2870 if ((nbr = rn->info) != NULL)
2871 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2872 {
2873 route_unlock_node (rn);
2874 return 0;
2875 }
2876 }
2877
2878 return 1;
2879}
2880
2881
2882#ifdef ORIGINAL_CODING
2883/* This function flood the maxaged LSA to DR. */
2884void
2885ospf_maxage_flood (struct ospf_lsa *lsa)
2886{
2887 switch (lsa->data->type)
2888 {
2889 case OSPF_ROUTER_LSA:
2890 case OSPF_NETWORK_LSA:
2891 case OSPF_SUMMARY_LSA:
2892 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00002893 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00002894#ifdef HAVE_OPAQUE_LSA
2895 case OSPF_OPAQUE_LINK_LSA:
2896 case OSPF_OPAQUE_AREA_LSA:
2897#endif /* HAVE_OPAQUE_LSA */
2898 ospf_flood_through_area (lsa->area, NULL, lsa);
2899 break;
2900 case OSPF_AS_EXTERNAL_LSA:
2901#ifdef HAVE_OPAQUE_LSA
2902 case OSPF_OPAQUE_AS_LSA:
2903#endif /* HAVE_OPAQUE_LSA */
2904 ospf_flood_through_as (NULL, lsa);
2905 break;
2906 default:
2907 break;
2908 }
2909}
2910#endif /* ORIGINAL_CODING */
2911
paul4dadc292005-05-06 21:37:42 +00002912static int
paul718e3742002-12-13 20:15:29 +00002913ospf_maxage_lsa_remover (struct thread *thread)
2914{
paul68980082003-03-25 05:07:42 +00002915 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002916 struct ospf_lsa *lsa;
2917 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002918 int reschedule = 0;
2919
paul68980082003-03-25 05:07:42 +00002920 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002921
2922 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002923 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002924
paul68980082003-03-25 05:07:42 +00002925 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002926
2927 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002928 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002929 {
paul718e3742002-12-13 20:15:29 +00002930 if (lsa->retransmit_counter > 0)
2931 {
2932 reschedule = 1;
2933 continue;
2934 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002935
2936 /* TODO: maybe convert this function to a work-queue */
2937 if (thread_should_yield (thread))
2938 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);
2939
paul718e3742002-12-13 20:15:29 +00002940 /* Remove LSA from the LSDB */
2941 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2942 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002943 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
paul7ddf1d62003-10-13 09:06:46 +00002944 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002945
2946 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002947 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002948 lsa->data->type, inet_ntoa (lsa->data->id));
2949
2950 /* Flood max age LSA. */
2951#ifdef ORIGINAL_CODING
2952 ospf_maxage_flood (lsa);
2953#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00002954 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00002955#endif /* ORIGINAL_CODING */
2956
paul7ddf1d62003-10-13 09:06:46 +00002957 if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
2958 {
2959 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002960 zlog_debug ("originating new router lsa for lsa 0x%lx \n",
paul7ddf1d62003-10-13 09:06:46 +00002961 (u_long)lsa);
2962 ospf_router_lsa_originate(lsa->area);
2963 }
2964
paul718e3742002-12-13 20:15:29 +00002965 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002966 if (lsa->lsdb)
2967 {
2968 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2969 ospf_lsdb_delete (lsa->lsdb, lsa);
2970 }
2971 else
2972 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2973 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002974 }
2975
2976 /* A MaxAge LSA must be removed immediately from the router's link
2977 state database as soon as both a) it is no longer contained on any
2978 neighbor Link state retransmission lists and b) none of the router's
2979 neighbors are in states Exchange or Loading. */
2980 if (reschedule)
paul68980082003-03-25 05:07:42 +00002981 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00002982
2983 return 0;
2984}
2985
paul718e3742002-12-13 20:15:29 +00002986void
paul68980082003-03-25 05:07:42 +00002987ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002988{
hasso52dc7ee2004-09-23 19:18:23 +00002989 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00002990
paul68980082003-03-25 05:07:42 +00002991 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00002992 {
paul68980082003-03-25 05:07:42 +00002993 list_delete_node (ospf->maxage_lsa, n);
Stephen Hemminger3106a032009-08-06 12:58:05 -07002994 UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002995 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +00002996 }
2997}
2998
2999void
paul68980082003-03-25 05:07:42 +00003000ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003001{
3002 /* When we saw a MaxAge LSA flooded to us, we put it on the list
3003 and schedule the MaxAge LSA remover. */
Stephen Hemminger3106a032009-08-06 12:58:05 -07003004 if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
paul718e3742002-12-13 20:15:29 +00003005 {
3006 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003007 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00003008 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
3009 return;
3010 }
3011
paul68980082003-03-25 05:07:42 +00003012 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
Stephen Hemminger3106a032009-08-06 12:58:05 -07003013 SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
paul718e3742002-12-13 20:15:29 +00003014
3015 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003016 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003017
paul68980082003-03-25 05:07:42 +00003018 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003019}
3020
paul4dadc292005-05-06 21:37:42 +00003021static int
paul68980082003-03-25 05:07:42 +00003022ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003023{
paul718e3742002-12-13 20:15:29 +00003024 /* Stay away from any Local Translated Type-7 LSAs */
3025 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3026 return 0;
paul718e3742002-12-13 20:15:29 +00003027
3028 if (IS_LSA_MAXAGE (lsa))
3029 /* Self-originated LSAs should NOT time-out instead,
3030 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00003031 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003032 {
3033 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003034 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003035
3036 switch (lsa->data->type)
3037 {
paul718e3742002-12-13 20:15:29 +00003038#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00003039 case OSPF_OPAQUE_LINK_LSA:
3040 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003041 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003042 /*
3043 * As a general rule, whenever network topology has changed
3044 * (due to an LSA removal in this case), routing recalculation
3045 * should be triggered. However, this is not true for opaque
3046 * LSAs. Even if an opaque LSA instance is going to be removed
3047 * from the routing domain, it does not mean a change in network
3048 * topology, and thus, routing recalculation is not needed here.
3049 */
3050 break;
paul718e3742002-12-13 20:15:29 +00003051#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00003052 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003053 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003054 ospf_ase_incremental_update (ospf, lsa);
3055 break;
paul718e3742002-12-13 20:15:29 +00003056 default:
paul68980082003-03-25 05:07:42 +00003057 ospf_spf_calculate_schedule (ospf);
3058 break;
paul718e3742002-12-13 20:15:29 +00003059 }
paul68980082003-03-25 05:07:42 +00003060 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003061 }
3062
3063 return 0;
3064}
3065
3066/* Periodical check of MaxAge LSA. */
3067int
paul68980082003-03-25 05:07:42 +00003068ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003069{
paul68980082003-03-25 05:07:42 +00003070 struct ospf *ospf = THREAD_ARG (thread);
3071 struct route_node *rn;
3072 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003073 struct ospf_area *area;
3074 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003075
paul68980082003-03-25 05:07:42 +00003076 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003077
paul1eb8ef22005-04-07 07:30:20 +00003078 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003079 {
paul68980082003-03-25 05:07:42 +00003080 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3081 ospf_lsa_maxage_walker_remover (ospf, lsa);
3082 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3083 ospf_lsa_maxage_walker_remover (ospf, lsa);
3084 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3085 ospf_lsa_maxage_walker_remover (ospf, lsa);
3086 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3087 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003088#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003089 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3090 ospf_lsa_maxage_walker_remover (ospf, lsa);
3091 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3092 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003093#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003094 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3095 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003096 }
3097
paul4fb949e2003-05-10 20:06:51 +00003098 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003099 if (ospf->lsdb)
3100 {
3101 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3102 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003103#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003104 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3105 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003106#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003107 }
paul718e3742002-12-13 20:15:29 +00003108
paul68980082003-03-25 05:07:42 +00003109 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3110 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003111 return 0;
3112}
3113
paul68980082003-03-25 05:07:42 +00003114struct ospf_lsa *
3115ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3116 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003117{
paul68980082003-03-25 05:07:42 +00003118 struct ospf_lsa *lsa;
3119 struct in_addr mask, id;
3120 struct lsa_header_mask
3121 {
3122 struct lsa_header header;
3123 struct in_addr mask;
3124 } *hmask;
paul718e3742002-12-13 20:15:29 +00003125
paul68980082003-03-25 05:07:42 +00003126 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3127 if (lsa == NULL)
3128 return NULL;
paul718e3742002-12-13 20:15:29 +00003129
paul68980082003-03-25 05:07:42 +00003130 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003131
paul68980082003-03-25 05:07:42 +00003132 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003133
paul68980082003-03-25 05:07:42 +00003134 if (mask.s_addr != hmask->mask.s_addr)
3135 {
3136 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3137 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3138 if (!lsa)
3139 return NULL;
3140 }
paul718e3742002-12-13 20:15:29 +00003141
paul68980082003-03-25 05:07:42 +00003142 return lsa;
paul718e3742002-12-13 20:15:29 +00003143}
3144
3145struct ospf_lsa *
3146ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3147 struct in_addr id, struct in_addr adv_router)
3148{
paule05fba42003-04-13 20:20:53 +00003149 struct ospf *ospf = ospf_lookup();
3150 assert(ospf);
3151
paul718e3742002-12-13 20:15:29 +00003152 switch (type)
3153 {
3154 case OSPF_ROUTER_LSA:
3155 case OSPF_NETWORK_LSA:
3156 case OSPF_SUMMARY_LSA:
3157 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003158 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003159#ifdef HAVE_OPAQUE_LSA
3160 case OSPF_OPAQUE_LINK_LSA:
3161 case OSPF_OPAQUE_AREA_LSA:
3162#endif /* HAVE_OPAQUE_LSA */
3163 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003164 case OSPF_AS_EXTERNAL_LSA:
3165#ifdef HAVE_OPAQUE_LSA
3166 case OSPF_OPAQUE_AS_LSA:
3167#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003168 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003169 default:
3170 break;
3171 }
3172
3173 return NULL;
3174}
3175
3176struct ospf_lsa *
3177ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3178 struct in_addr id)
3179{
3180 struct ospf_lsa *lsa;
3181 struct route_node *rn;
3182
3183 switch (type)
3184 {
3185 case OSPF_ROUTER_LSA:
3186 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003187 case OSPF_NETWORK_LSA:
3188 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3189 if ((lsa = rn->info))
3190 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3191 {
3192 route_unlock_node (rn);
3193 return lsa;
3194 }
3195 break;
3196 case OSPF_SUMMARY_LSA:
3197 case OSPF_ASBR_SUMMARY_LSA:
3198 /* Currently not used. */
3199 assert (1);
3200 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003201 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003202 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003203#ifdef HAVE_OPAQUE_LSA
3204 case OSPF_OPAQUE_LINK_LSA:
3205 case OSPF_OPAQUE_AREA_LSA:
3206 case OSPF_OPAQUE_AS_LSA:
3207 /* Currently not used. */
3208 break;
3209#endif /* HAVE_OPAQUE_LSA */
3210 default:
3211 break;
3212 }
3213
3214 return NULL;
3215}
3216
3217struct ospf_lsa *
3218ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3219{
3220 struct ospf_lsa *match;
3221
3222#ifdef HAVE_OPAQUE_LSA
3223 /*
3224 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3225 * is redefined to have two subfields; opaque-type and opaque-id.
3226 * However, it is harmless to treat the two sub fields together, as if
3227 * they two were forming a unique LSA-ID.
3228 */
3229#endif /* HAVE_OPAQUE_LSA */
3230
3231 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3232
3233 if (match == NULL)
3234 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003235 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003236 lsah->type, inet_ntoa (lsah->id));
3237
3238 return match;
3239}
3240
3241/* return +n, l1 is more recent.
3242 return -n, l2 is more recent.
3243 return 0, l1 and l2 is identical. */
3244int
3245ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3246{
3247 int r;
3248 int x, y;
3249
3250 if (l1 == NULL && l2 == NULL)
3251 return 0;
3252 if (l1 == NULL)
3253 return -1;
3254 if (l2 == NULL)
3255 return 1;
3256
3257 /* compare LS sequence number. */
3258 x = (int) ntohl (l1->data->ls_seqnum);
3259 y = (int) ntohl (l2->data->ls_seqnum);
3260 if (x > y)
3261 return 1;
3262 if (x < y)
3263 return -1;
3264
3265 /* compare LS checksum. */
3266 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3267 if (r)
3268 return r;
3269
3270 /* compare LS age. */
3271 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3272 return 1;
3273 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3274 return -1;
3275
3276 /* compare LS age with MaxAgeDiff. */
3277 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3278 return -1;
3279 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3280 return 1;
3281
3282 /* LSAs are identical. */
3283 return 0;
3284}
3285
3286/* If two LSAs are different, return 1, otherwise return 0. */
3287int
3288ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3289{
3290 char *p1, *p2;
3291 assert (l1);
3292 assert (l2);
3293 assert (l1->data);
3294 assert (l2->data);
3295
3296 if (l1->data->options != l2->data->options)
3297 return 1;
3298
3299 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3300 return 1;
3301
3302 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3303 return 1;
3304
3305 if (l1->data->length != l2->data->length)
3306 return 1;
3307
3308 if (l1->data->length == 0)
3309 return 1;
3310
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02003311 if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
3312 return 1; /* May be a stale LSA in the LSBD */
3313
pauld1825832003-04-03 01:27:01 +00003314 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003315
3316 p1 = (char *) l1->data;
3317 p2 = (char *) l2->data;
3318
3319 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3320 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3321 return 1;
3322
3323 return 0;
3324}
3325
3326#ifdef ORIGINAL_CODING
3327void
3328ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3329 struct ospf_lsa *self,
3330 struct ospf_lsa *new)
3331{
3332 u_int32_t seqnum;
3333
3334 /* Adjust LS Sequence Number. */
3335 seqnum = ntohl (new->data->ls_seqnum) + 1;
3336 self->data->ls_seqnum = htonl (seqnum);
3337
3338 /* Recalculate LSA checksum. */
3339 ospf_lsa_checksum (self->data);
3340
3341 /* Reflooding LSA. */
3342 /* RFC2328 Section 13.3
3343 On non-broadcast networks, separate Link State Update
3344 packets must be sent, as unicasts, to each adjacent neighbor
3345 (i.e., those in state Exchange or greater). The destination
3346 IP addresses for these packets are the neighbors' IP
3347 addresses. */
3348 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3349 {
3350 struct route_node *rn;
3351 struct ospf_neighbor *onbr;
3352
3353 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3354 if ((onbr = rn->info) != NULL)
3355 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3356 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3357 }
3358 else
3359 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3360
3361 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003362 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003363 self->data->type, inet_ntoa (self->data->id));
3364}
3365#else /* ORIGINAL_CODING */
3366static int
paul68980082003-03-25 05:07:42 +00003367ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003368{
3369 if (lsa == NULL || !IS_LSA_SELF (lsa))
3370 return 0;
3371
3372 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003373 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 +00003374
3375 /* Force given lsa's age to MaxAge. */
3376 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3377
3378 switch (lsa->data->type)
3379 {
3380#ifdef HAVE_OPAQUE_LSA
3381 case OSPF_OPAQUE_LINK_LSA:
3382 case OSPF_OPAQUE_AREA_LSA:
3383 case OSPF_OPAQUE_AS_LSA:
3384 ospf_opaque_lsa_refresh (lsa);
3385 break;
3386#endif /* HAVE_OPAQUE_LSA */
3387 default:
paul68980082003-03-25 05:07:42 +00003388 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003389 break;
3390 }
3391
3392 return 0;
3393}
3394
3395void
paul68980082003-03-25 05:07:42 +00003396ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003397{
paul1eb8ef22005-04-07 07:30:20 +00003398 struct listnode *node, *nnode;
3399 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003400 struct ospf_area *area;
3401 struct ospf_interface *oi;
3402 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003403 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003404 int need_to_flush_ase = 0;
3405
paul1eb8ef22005-04-07 07:30:20 +00003406 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003407 {
paul718e3742002-12-13 20:15:29 +00003408 if ((lsa = area->router_lsa_self) != NULL)
3409 {
3410 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003411 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 +00003412
3413 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003414 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003415 area->router_lsa_self = NULL;
3416 OSPF_TIMER_OFF (area->t_router_lsa_self);
3417 }
3418
paul1eb8ef22005-04-07 07:30:20 +00003419 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003420 {
paul718e3742002-12-13 20:15:29 +00003421 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003422 && oi->state == ISM_DR
3423 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003424 {
3425 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003426 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00003427
3428 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003429 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003430 oi->network_lsa_self = NULL;
3431 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3432 }
3433
3434 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3435 && area->external_routing == OSPF_AREA_DEFAULT)
3436 need_to_flush_ase = 1;
3437 }
3438
paul68980082003-03-25 05:07:42 +00003439 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3440 ospf_lsa_flush_schedule (ospf, lsa);
3441 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3442 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003443#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003444 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3445 ospf_lsa_flush_schedule (ospf, lsa);
3446 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3447 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003448#endif /* HAVE_OPAQUE_LSA */
3449 }
3450
3451 if (need_to_flush_ase)
3452 {
paul68980082003-03-25 05:07:42 +00003453 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3454 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003455#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003456 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3457 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003458#endif /* HAVE_OPAQUE_LSA */
3459 }
3460
3461 /*
3462 * Make sure that the MaxAge LSA remover is executed immediately,
3463 * without conflicting to other threads.
3464 */
paul68980082003-03-25 05:07:42 +00003465 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003466 {
paul68980082003-03-25 05:07:42 +00003467 OSPF_TIMER_OFF (ospf->t_maxage);
3468 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003469 }
3470
3471 return;
3472}
3473#endif /* ORIGINAL_CODING */
3474
3475/* If there is self-originated LSA, then return 1, otherwise return 0. */
3476/* An interface-independent version of ospf_lsa_is_self_originated */
3477int
paul68980082003-03-25 05:07:42 +00003478ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003479{
hasso52dc7ee2004-09-23 19:18:23 +00003480 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003481 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003482
3483 /* This LSA is already checked. */
3484 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3485 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3486
3487 /* Make sure LSA is self-checked. */
3488 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3489
3490 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003491 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003492 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3493
3494 /* LSA is router-LSA. */
3495 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003496 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003497 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3498
3499 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3500 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003501 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003502 {
paul718e3742002-12-13 20:15:29 +00003503 /* Ignore virtual link. */
3504 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3505 if (oi->address->family == AF_INET)
3506 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3507 {
3508 /* to make it easier later */
3509 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3510 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3511 }
3512 }
3513
3514 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3515}
3516
3517/* Get unique Link State ID. */
3518struct in_addr
paul68980082003-03-25 05:07:42 +00003519ospf_lsa_unique_id (struct ospf *ospf,
3520 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003521{
3522 struct ospf_lsa *lsa;
3523 struct in_addr mask, id;
3524
3525 id = p->prefix;
3526
3527 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003528 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003529 if (lsa)
3530 {
3531 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3532 if (ip_masklen (al->mask) == p->prefixlen)
3533 {
3534 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003535 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003536 "Can't get Link State ID for %s/%d",
3537 inet_ntoa (p->prefix), p->prefixlen);
3538 /* id.s_addr = 0; */
3539 id.s_addr = 0xffffffff;
3540 return id;
3541 }
3542 /* Masklen differs, then apply wildcard mask to Link State ID. */
3543 else
3544 {
3545 masklen2ip (p->prefixlen, &mask);
3546
3547 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003548 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3549 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003550 if (lsa)
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 }
3561 }
3562
3563 return id;
3564}
3565
3566
Paul Jakma70461d72006-05-12 22:57:57 +00003567#define LSA_ACTION_FLOOD_AREA 1
3568#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003569
3570struct lsa_action
3571{
3572 u_char action;
3573 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003574 struct ospf_lsa *lsa;
3575};
3576
paul4dadc292005-05-06 21:37:42 +00003577static int
paul718e3742002-12-13 20:15:29 +00003578ospf_lsa_action (struct thread *t)
3579{
3580 struct lsa_action *data;
3581
3582 data = THREAD_ARG (t);
3583
3584 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003585 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003586 data->action);
3587
3588 switch (data->action)
3589 {
paul718e3742002-12-13 20:15:29 +00003590 case LSA_ACTION_FLOOD_AREA:
3591 ospf_flood_through_area (data->area, NULL, data->lsa);
3592 break;
paul718e3742002-12-13 20:15:29 +00003593 case LSA_ACTION_FLUSH_AREA:
3594 ospf_lsa_flush_area (data->lsa, data->area);
3595 break;
paul718e3742002-12-13 20:15:29 +00003596 }
3597
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003598 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003599 XFREE (MTYPE_OSPF_MESSAGE, data);
3600 return 0;
3601}
3602
3603void
3604ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3605{
3606 struct lsa_action *data;
3607
Stephen Hemminger393deb92008-08-18 14:13:29 -07003608 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003609 data->action = LSA_ACTION_FLOOD_AREA;
3610 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003611 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003612
3613 thread_add_event (master, ospf_lsa_action, data, 0);
3614}
3615
3616void
3617ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3618{
3619 struct lsa_action *data;
3620
Stephen Hemminger393deb92008-08-18 14:13:29 -07003621 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003622 data->action = LSA_ACTION_FLUSH_AREA;
3623 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003624 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003625
3626 thread_add_event (master, ospf_lsa_action, data, 0);
3627}
3628
3629
3630/* LSA Refreshment functions. */
paul4dadc292005-05-06 21:37:42 +00003631static void
paul68980082003-03-25 05:07:42 +00003632ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003633{
3634 struct external_info *ei;
3635 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
Paul Jakma66349742010-04-13 22:33:54 +01003636 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003637
3638 switch (lsa->data->type)
3639 {
3640 /* Router and Network LSAs are processed differently. */
3641 case OSPF_ROUTER_LSA:
3642 case OSPF_NETWORK_LSA:
3643 break;
3644 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003645 ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003646 break;
3647 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003648 ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003649 break;
3650 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003651 /* Translated from NSSA Type-5s are refreshed when
3652 * from refresh of Type-7 - do not refresh these directly.
3653 */
3654 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3655 break;
paul718e3742002-12-13 20:15:29 +00003656 ei = ospf_external_info_check (lsa);
3657 if (ei)
pauld4a53d52003-07-12 21:30:57 +00003658 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003659 else
pauld4a53d52003-07-12 21:30:57 +00003660 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003661 break;
3662#ifdef HAVE_OPAQUE_LSA
3663 case OSPF_OPAQUE_LINK_LSA:
3664 case OSPF_OPAQUE_AREA_LSA:
3665 case OSPF_OPAQUE_AS_LSA:
3666 ospf_opaque_lsa_refresh (lsa);
3667 break;
pauld7480322003-05-16 17:31:51 +00003668#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003669 default:
3670 break;
paul718e3742002-12-13 20:15:29 +00003671 }
3672}
3673
3674void
paul68980082003-03-25 05:07:42 +00003675ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003676{
3677 u_int16_t index, current_index;
3678
Paul Jakma66349742010-04-13 22:33:54 +01003679 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003680 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3681
3682 if (lsa->refresh_list < 0)
3683 {
3684 int delay;
3685
3686 if (LS_AGE (lsa) == 0 &&
3687 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3688 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3689 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3690 else
3691 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3692 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3693 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3694
3695 if (delay < 0)
3696 delay = 0;
3697
paul68980082003-03-25 05:07:42 +00003698 current_index = ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003699 (quagga_time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003700
3701 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3702 % (OSPF_LSA_REFRESHER_SLOTS);
3703
3704 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003705 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003706 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003707 if (!ospf->lsa_refresh_queue.qs[index])
3708 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003709 listnode_add (ospf->lsa_refresh_queue.qs[index],
3710 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003711 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003712 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003713 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003714 "setting refresh_list on lsa %p (slod %d)",
3715 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003716 }
3717}
3718
3719void
paul68980082003-03-25 05:07:42 +00003720ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003721{
Paul Jakma66349742010-04-13 22:33:54 +01003722 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003723 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3724 if (lsa->refresh_list >= 0)
3725 {
hasso52dc7ee2004-09-23 19:18:23 +00003726 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003727 listnode_delete (refresh_list, lsa);
3728 if (!listcount (refresh_list))
3729 {
3730 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003731 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003732 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003733 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003734 lsa->refresh_list = -1;
3735 }
3736}
3737
3738int
3739ospf_lsa_refresh_walker (struct thread *t)
3740{
hasso52dc7ee2004-09-23 19:18:23 +00003741 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003742 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003743 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003744 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003745 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003746 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003747
3748 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003749 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003750
3751
paul68980082003-03-25 05:07:42 +00003752 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003753
ajs9dbc7972005-03-13 19:27:22 +00003754 /* Note: if clock has jumped backwards, then time change could be negative,
3755 so we are careful to cast the expression to unsigned before taking
3756 modulus. */
paul68980082003-03-25 05:07:42 +00003757 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003758 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003759 (quagga_time (NULL) - ospf->lsa_refresher_started) /
ajs9dbc7972005-03-13 19:27:22 +00003760 OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003761
3762 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003763 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003764 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003765
paul68980082003-03-25 05:07:42 +00003766 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003767 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3768 {
3769 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003770 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003771 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003772
paul68980082003-03-25 05:07:42 +00003773 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003774
Paul Jakma66349742010-04-13 22:33:54 +01003775 assert (i >= 0);
3776
paul68980082003-03-25 05:07:42 +00003777 ospf->lsa_refresh_queue.qs [i] = NULL;
3778
paul718e3742002-12-13 20:15:29 +00003779 if (refresh_list)
3780 {
paul1eb8ef22005-04-07 07:30:20 +00003781 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003782 {
paul718e3742002-12-13 20:15:29 +00003783 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003784 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003785 "refresh lsa %p (slot %d)",
3786 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003787
Paul Jakma66349742010-04-13 22:33:54 +01003788 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003789 list_delete_node (refresh_list, node);
paul718e3742002-12-13 20:15:29 +00003790 lsa->refresh_list = -1;
3791 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003792 }
3793 list_free (refresh_list);
3794 }
3795 }
3796
paul68980082003-03-25 05:07:42 +00003797 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3798 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003799 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003800
paul1eb8ef22005-04-07 07:30:20 +00003801 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
Paul Jakma66349742010-04-13 22:33:54 +01003802 {
3803 ospf_lsa_refresh (ospf, lsa);
3804 assert (lsa->lock > 0);
3805 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
3806 }
paul718e3742002-12-13 20:15:29 +00003807
3808 list_delete (lsa_to_refresh);
3809
3810 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003811 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003812
3813 return 0;
3814}
3815