blob: 842df49c0c9afebd63359be74927cdd64b733041 [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
Paul Jakma02d942c2010-01-24 23:36:20 +0000375 lsah->ls_age = htons (OSPF_LSA_INITIAL_AGE);
paul718e3742002-12-13 20:15:29 +0000376 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
Paul Jakmac363d382010-01-24 22:42:13 +0000744 ospf_router_lsa_update_area (area);
paul88d6cf32005-10-29 12:50:09 +0000745
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
Paul Jakmac363d382010-01-24 22:42:13 +0000888 /* Unregister LSA from refresh-list */
889 ospf_refresher_unregister_lsa (area->ospf, lsa);
890
paul718e3742002-12-13 20:15:29 +0000891 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000892 if ( (new = ospf_router_lsa_new (area)) == NULL)
893 {
894 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
895 return NULL;
896 }
897
paul718e3742002-12-13 20:15:29 +0000898 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
899
paul68980082003-03-25 05:07:42 +0000900 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000901
902 /* Flood LSA through area. */
903 ospf_flood_through_area (area, NULL, new);
904
905 /* Debug logging. */
906 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
907 {
ajse588f212004-12-08 18:12:06 +0000908 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000909 new->data->type, inet_ntoa (new->data->id));
910 ospf_lsa_header_dump (new->data);
911 }
912
913 return NULL;
914}
915
Paul Jakmac363d382010-01-24 22:42:13 +0000916int
917ospf_router_lsa_update_area (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000918{
paul718e3742002-12-13 20:15:29 +0000919 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmac363d382010-01-24 22:42:13 +0000920 zlog_debug ("[router-LSA]: (router-LSA area update)");
paul718e3742002-12-13 20:15:29 +0000921
922 /* Now refresh router-LSA. */
923 if (area->router_lsa_self)
Paul Jakmac363d382010-01-24 22:42:13 +0000924 ospf_lsa_refresh (area->ospf, area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000925 /* Newly originate router-LSA. */
926 else
927 ospf_router_lsa_originate (area);
928
929 return 0;
930}
931
paul718e3742002-12-13 20:15:29 +0000932int
Paul Jakmac363d382010-01-24 22:42:13 +0000933ospf_router_lsa_update (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000934{
paul1eb8ef22005-04-07 07:30:20 +0000935 struct listnode *node, *nnode;
936 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +0000937
938 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000939 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +0000940
paul1eb8ef22005-04-07 07:30:20 +0000941 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000942 {
paul718e3742002-12-13 20:15:29 +0000943 struct ospf_lsa *lsa = area->router_lsa_self;
944 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +0000945 const char *area_str;
paul718e3742002-12-13 20:15:29 +0000946
947 /* Keep Area ID string. */
948 area_str = AREA_NAME (area);
949
950 /* If LSA not exist in this Area, originate new. */
951 if (lsa == NULL)
952 {
953 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000954 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +0000955
956 ospf_router_lsa_originate (area);
957 }
958 /* If router-ID is changed, Link ID must change.
959 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +0000960 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000961 {
962 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000963 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +0000964 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
Paul Jakmadfbd5172010-04-14 10:32:12 +0100965 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +0000966 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000967 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000968 area->router_lsa_self = NULL;
969
970 /* Refresh router-LSA, (not install) and flood through area. */
Paul Jakmac363d382010-01-24 22:42:13 +0000971 ospf_router_lsa_update_area (area);
paul718e3742002-12-13 20:15:29 +0000972 }
973 else
974 {
975 rl = (struct router_lsa *) lsa->data;
976 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +0000977 if (rl->flags != ospf->flags)
Paul Jakmac363d382010-01-24 22:42:13 +0000978 ospf_router_lsa_update_area (area);
paul718e3742002-12-13 20:15:29 +0000979 }
980 }
981
982 return 0;
983}
984
985
986/* network-LSA related functions. */
987/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +0000988static void
paul718e3742002-12-13 20:15:29 +0000989ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
990{
991 struct in_addr mask;
992 struct route_node *rn;
993 struct ospf_neighbor *nbr;
994
995 masklen2ip (oi->address->prefixlen, &mask);
996 stream_put_ipv4 (s, mask.s_addr);
997
998 /* The network-LSA lists those routers that are fully adjacent to
999 the Designated Router; each fully adjacent router is identified by
1000 its OSPF Router ID. The Designated Router includes itself in this
1001 list. RFC2328, Section 12.4.2 */
1002
1003 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1004 if ((nbr = rn->info) != NULL)
1005 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1006 stream_put_ipv4 (s, nbr->router_id.s_addr);
1007}
1008
paul4dadc292005-05-06 21:37:42 +00001009static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001010ospf_network_lsa_new (struct ospf_interface *oi)
1011{
1012 struct stream *s;
1013 struct ospf_lsa *new;
1014 struct lsa_header *lsah;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001015 struct ospf_if_params *oip;
paul718e3742002-12-13 20:15:29 +00001016 int length;
1017
1018 /* If there are no neighbours on this network (the net is stub),
1019 the router does not originate network-LSA (see RFC 12.4.2) */
1020 if (oi->full_nbrs == 0)
1021 return NULL;
1022
1023 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001024 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001025
1026 /* Create new stream for LSA. */
1027 s = stream_new (OSPF_MAX_LSA_SIZE);
1028 lsah = (struct lsa_header *) STREAM_DATA (s);
1029
1030 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001031 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001032
1033 /* Set network-LSA body fields. */
1034 ospf_network_lsa_body_set (s, oi);
1035
1036 /* Set length. */
1037 length = stream_get_endp (s);
1038 lsah->length = htons (length);
1039
1040 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001041 if ( (new = ospf_lsa_new ()) == NULL)
1042 {
1043 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1044 return NULL;
1045 }
1046
paul718e3742002-12-13 20:15:29 +00001047 new->area = oi->area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001048 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001049
1050 /* Copy LSA to store. */
1051 new->data = ospf_lsa_data_new (length);
1052 memcpy (new->data, lsah, length);
1053 stream_free (s);
Paul Jakma7eb5b472009-10-13 16:13:13 +01001054
1055 /* Remember prior network LSA sequence numbers, even if we stop
1056 * originating one for this oi, to try avoid re-originating LSAs with a
1057 * prior sequence number, and thus speed up adjency forming & convergence.
1058 */
1059 if ((oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4)))
1060 {
1061 new->data->ls_seqnum = oip->network_lsa_seqnum;
1062 new->data->ls_seqnum = lsa_seqnum_increment (new);
1063 }
1064 else
1065 {
1066 oip = ospf_get_if_params (oi->ifp, oi->address->u.prefix4);
1067 ospf_if_update_params (oi->ifp, oi->address->u.prefix4);
1068 }
1069 oip->network_lsa_seqnum = new->data->ls_seqnum;
1070
paul718e3742002-12-13 20:15:29 +00001071 return new;
1072}
1073
1074/* Originate network-LSA. */
Paul Jakmac363d382010-01-24 22:42:13 +00001075void
1076ospf_network_lsa_update (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001077{
1078 struct ospf_lsa *new;
Paul Jakmac363d382010-01-24 22:42:13 +00001079
1080 if (oi->network_lsa_self != NULL)
1081 {
1082 ospf_lsa_refresh (oi->ospf, oi->network_lsa_self);
1083 return;
1084 }
1085
paul718e3742002-12-13 20:15:29 +00001086 /* Create new network-LSA instance. */
1087 new = ospf_network_lsa_new (oi);
1088 if (new == NULL)
Paul Jakmac363d382010-01-24 22:42:13 +00001089 return;
paul718e3742002-12-13 20:15:29 +00001090
1091 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001092 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001093
1094 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001095 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001096
1097 /* Flooding new LSA through area. */
1098 ospf_flood_through_area (oi->area, NULL, new);
1099
1100 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1101 {
ajse588f212004-12-08 18:12:06 +00001102 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001103 new->data->type, inet_ntoa (new->data->id), new);
1104 ospf_lsa_header_dump (new->data);
1105 }
1106
Paul Jakmac363d382010-01-24 22:42:13 +00001107 return;
paul718e3742002-12-13 20:15:29 +00001108}
1109
Paul Jakmac363d382010-01-24 22:42:13 +00001110static struct ospf_lsa *
1111ospf_network_lsa_refresh (struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001112{
1113 struct ospf_area *area = lsa->area;
Paul Jakmac363d382010-01-24 22:42:13 +00001114 struct ospf_lsa *new, *new2;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001115 struct ospf_if_params *oip;
Paul Jakma4dd87df2010-04-15 08:11:51 +01001116 struct ospf_interface *oi;
Paul Jakmac363d382010-01-24 22:42:13 +00001117
paul718e3742002-12-13 20:15:29 +00001118 assert (lsa->data);
Paul Jakma4dd87df2010-04-15 08:11:51 +01001119
1120 /* Retrieve the oi for the network LSA */
1121 oi = ospf_if_lookup_by_local_addr (area->ospf, NULL, lsa->data->id);
1122 if (oi == NULL)
1123 {
1124 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1125 {
1126 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh: "
1127 "no oi found, ick, ignoring.",
1128 lsa->data->type, inet_ntoa (lsa->data->id));
1129 ospf_lsa_header_dump (lsa->data);
1130 }
1131 return NULL;
1132 }
paul718e3742002-12-13 20:15:29 +00001133 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001134 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001135
Paul Jakmac363d382010-01-24 22:42:13 +00001136 /* Unregister LSA from refresh-list */
1137 ospf_refresher_unregister_lsa (area->ospf, lsa);
1138
paul718e3742002-12-13 20:15:29 +00001139 /* Create new network-LSA instance. */
1140 new = ospf_network_lsa_new (oi);
1141 if (new == NULL)
Paul Jakmac363d382010-01-24 22:42:13 +00001142 return NULL;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001143
1144 oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4);
1145 assert (oip != NULL);
1146 oip->network_lsa_seqnum = new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001147
Paul Jakmac363d382010-01-24 22:42:13 +00001148 new2 = ospf_lsa_install (area->ospf, oi, new);
1149
1150 assert (new2 == new);
1151
paul718e3742002-12-13 20:15:29 +00001152 /* Flood LSA through aera. */
1153 ospf_flood_through_area (area, NULL, new);
1154
1155 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1156 {
ajse588f212004-12-08 18:12:06 +00001157 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001158 new->data->type, inet_ntoa (new->data->id));
1159 ospf_lsa_header_dump (new->data);
1160 }
1161
Paul Jakmac363d382010-01-24 22:42:13 +00001162 return new;
paul718e3742002-12-13 20:15:29 +00001163}
paul718e3742002-12-13 20:15:29 +00001164
paul4dadc292005-05-06 21:37:42 +00001165static void
paul718e3742002-12-13 20:15:29 +00001166stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1167{
1168 u_int32_t metric;
1169 char *mp;
1170
1171 /* Put 0 metric. TOS metric is not supported. */
1172 metric = htonl (metric_value);
1173 mp = (char *) &metric;
1174 mp++;
1175 stream_put (s, mp, 3);
1176}
1177
1178/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001179static void
paul718e3742002-12-13 20:15:29 +00001180ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1181 u_int32_t metric)
1182{
1183 struct in_addr mask;
1184
1185 masklen2ip (p->prefixlen, &mask);
1186
1187 /* Put Network Mask. */
1188 stream_put_ipv4 (s, mask.s_addr);
1189
1190 /* Set # TOS. */
1191 stream_putc (s, (u_char) 0);
1192
1193 /* Set metric. */
1194 stream_put_ospf_metric (s, metric);
1195}
1196
paul4dadc292005-05-06 21:37:42 +00001197static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001198ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1199 u_int32_t metric, struct in_addr id)
1200{
1201 struct stream *s;
1202 struct ospf_lsa *new;
1203 struct lsa_header *lsah;
1204 int length;
1205
paulc24d6022005-11-20 14:54:12 +00001206 if (id.s_addr == 0xffffffff)
1207 {
1208 /* Maybe Link State ID not available. */
1209 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1210 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1211 OSPF_SUMMARY_LSA);
1212 return NULL;
1213 }
1214
paul718e3742002-12-13 20:15:29 +00001215 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001216 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001217
1218 /* Create new stream for LSA. */
1219 s = stream_new (OSPF_MAX_LSA_SIZE);
1220 lsah = (struct lsa_header *) STREAM_DATA (s);
1221
paul68980082003-03-25 05:07:42 +00001222 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1223 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001224
1225 /* Set summary-LSA body fields. */
1226 ospf_summary_lsa_body_set (s, p, metric);
1227
1228 /* Set length. */
1229 length = stream_get_endp (s);
1230 lsah->length = htons (length);
1231
1232 /* Create OSPF LSA instance. */
1233 new = ospf_lsa_new ();
1234 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001235 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001236
1237 /* Copy LSA to store. */
1238 new->data = ospf_lsa_data_new (length);
1239 memcpy (new->data, lsah, length);
1240 stream_free (s);
1241
1242 return new;
1243}
1244
1245/* Originate Summary-LSA. */
1246struct ospf_lsa *
1247ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1248 struct ospf_area *area)
1249{
1250 struct ospf_lsa *new;
1251 struct in_addr id;
1252
paul68980082003-03-25 05:07:42 +00001253 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001254
paulc24d6022005-11-20 14:54:12 +00001255 if (id.s_addr == 0xffffffff)
1256 {
1257 /* Maybe Link State ID not available. */
1258 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1259 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1260 OSPF_SUMMARY_LSA);
1261 return NULL;
1262 }
1263
paul718e3742002-12-13 20:15:29 +00001264 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001265 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1266 return NULL;
paul718e3742002-12-13 20:15:29 +00001267
1268 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001269 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001270
1271 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001272 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001273
1274 /* Flooding new LSA through area. */
1275 ospf_flood_through_area (area, NULL, new);
1276
1277 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1278 {
ajse588f212004-12-08 18:12:06 +00001279 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001280 new->data->type, inet_ntoa (new->data->id), new);
1281 ospf_lsa_header_dump (new->data);
1282 }
1283
1284 return new;
1285}
1286
Paul Jakmac363d382010-01-24 22:42:13 +00001287static struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001288ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001289{
1290 struct ospf_lsa *new;
1291 struct summary_lsa *sl;
1292 struct prefix p;
1293
1294 /* Sanity check. */
1295 assert (lsa->data);
1296
1297 sl = (struct summary_lsa *)lsa->data;
1298 p.prefixlen = ip_masklen (sl->mask);
1299 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1300 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001301
1302 if (!new)
1303 return NULL;
1304
paul718e3742002-12-13 20:15:29 +00001305 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001306
paul68980082003-03-25 05:07:42 +00001307 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001308
1309 /* Flood LSA through AS. */
1310 ospf_flood_through_area (new->area, NULL, new);
1311
1312 /* Debug logging. */
1313 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1314 {
ajse588f212004-12-08 18:12:06 +00001315 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001316 new->data->type, inet_ntoa (new->data->id));
1317 ospf_lsa_header_dump (new->data);
1318 }
1319
1320 return new;
1321}
1322
1323
1324/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001325static void
paul718e3742002-12-13 20:15:29 +00001326ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1327 u_int32_t metric)
1328{
1329 struct in_addr mask;
1330
1331 masklen2ip (p->prefixlen, &mask);
1332
1333 /* Put Network Mask. */
1334 stream_put_ipv4 (s, mask.s_addr);
1335
1336 /* Set # TOS. */
1337 stream_putc (s, (u_char) 0);
1338
1339 /* Set metric. */
1340 stream_put_ospf_metric (s, metric);
1341}
1342
paul4dadc292005-05-06 21:37:42 +00001343static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001344ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1345 u_int32_t metric, struct in_addr id)
1346{
1347 struct stream *s;
1348 struct ospf_lsa *new;
1349 struct lsa_header *lsah;
1350 int length;
1351
paulc24d6022005-11-20 14:54:12 +00001352 if (id.s_addr == 0xffffffff)
1353 {
1354 /* Maybe Link State ID not available. */
1355 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1356 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1357 OSPF_ASBR_SUMMARY_LSA);
1358 return NULL;
1359 }
1360
paul718e3742002-12-13 20:15:29 +00001361 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001362 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001363
1364 /* Create new stream for LSA. */
1365 s = stream_new (OSPF_MAX_LSA_SIZE);
1366 lsah = (struct lsa_header *) STREAM_DATA (s);
1367
paul68980082003-03-25 05:07:42 +00001368 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1369 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001370
1371 /* Set summary-LSA body fields. */
1372 ospf_summary_asbr_lsa_body_set (s, p, metric);
1373
1374 /* Set length. */
1375 length = stream_get_endp (s);
1376 lsah->length = htons (length);
1377
1378 /* Create OSPF LSA instance. */
1379 new = ospf_lsa_new ();
1380 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001381 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001382
1383 /* Copy LSA to store. */
1384 new->data = ospf_lsa_data_new (length);
1385 memcpy (new->data, lsah, length);
1386 stream_free (s);
1387
1388 return new;
1389}
1390
1391/* Originate summary-ASBR-LSA. */
1392struct ospf_lsa *
1393ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1394 struct ospf_area *area)
1395{
1396 struct ospf_lsa *new;
1397 struct in_addr id;
1398
paul68980082003-03-25 05:07:42 +00001399 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001400
paulc24d6022005-11-20 14:54:12 +00001401 if (id.s_addr == 0xffffffff)
1402 {
1403 /* Maybe Link State ID not available. */
1404 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1405 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1406 OSPF_ASBR_SUMMARY_LSA);
1407 return NULL;
1408 }
1409
paul718e3742002-12-13 20:15:29 +00001410 /* Create new summary-LSA instance. */
1411 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001412 if (!new)
1413 return NULL;
paul718e3742002-12-13 20:15:29 +00001414
1415 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001416 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001417
1418 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001419 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001420
1421 /* Flooding new LSA through area. */
1422 ospf_flood_through_area (area, NULL, new);
1423
1424 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1425 {
ajse588f212004-12-08 18:12:06 +00001426 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001427 new->data->type, inet_ntoa (new->data->id), new);
1428 ospf_lsa_header_dump (new->data);
1429 }
1430
1431 return new;
1432}
1433
Paul Jakmac363d382010-01-24 22:42:13 +00001434static struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001435ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001436{
1437 struct ospf_lsa *new;
1438 struct summary_lsa *sl;
1439 struct prefix p;
1440
1441 /* Sanity check. */
1442 assert (lsa->data);
1443
1444 sl = (struct summary_lsa *)lsa->data;
1445 p.prefixlen = ip_masklen (sl->mask);
1446 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1447 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001448 if (!new)
1449 return NULL;
paul718e3742002-12-13 20:15:29 +00001450
1451 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001452
paul68980082003-03-25 05:07:42 +00001453 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001454
1455 /* Flood LSA through area. */
1456 ospf_flood_through_area (new->area, NULL, new);
1457
1458 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1459 {
ajse588f212004-12-08 18:12:06 +00001460 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001461 new->data->type, inet_ntoa (new->data->id));
1462 ospf_lsa_header_dump (new->data);
1463 }
1464
1465 return new;
1466}
1467
1468/* AS-external-LSA related functions. */
1469
1470/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1471 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001472static struct in_addr
paul68980082003-03-25 05:07:42 +00001473ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001474{
1475 struct in_addr fwd;
1476 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001477 struct listnode *node;
1478 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001479
1480 fwd.s_addr = 0;
1481
1482 if (!nexthop.s_addr)
1483 return fwd;
1484
1485 /* Check whether nexthop is covered by OSPF network. */
1486 nh.family = AF_INET;
1487 nh.u.prefix4 = nexthop;
1488 nh.prefixlen = IPV4_MAX_BITLEN;
Paul Jakma4ca15d42009-08-03 15:16:41 +01001489
1490 /* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be
1491 * better to make use of the per-ifp table of ois.
1492 */
paul1eb8ef22005-04-07 07:30:20 +00001493 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1494 if (if_is_operative (oi->ifp))
1495 if (oi->address->family == AF_INET)
1496 if (prefix_match (oi->address, &nh))
1497 return nexthop;
paul718e3742002-12-13 20:15:29 +00001498
1499 return fwd;
1500}
1501
paul718e3742002-12-13 20:15:29 +00001502/* NSSA-external-LSA related functions. */
1503
1504/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001505
paul718e3742002-12-13 20:15:29 +00001506struct in_addr
1507ospf_get_ip_from_ifp (struct ospf_interface *oi)
1508{
1509 struct in_addr fwd;
1510
1511 fwd.s_addr = 0;
1512
paul2e3b2e42002-12-13 21:03:13 +00001513 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001514 return oi->address->u.prefix4;
1515
1516 return fwd;
1517}
1518
1519/* Get 1st IP connection for Forward Addr */
1520struct in_addr
paulf2c80652002-12-13 21:44:27 +00001521ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001522{
1523 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001524 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001525 struct listnode *node;
1526 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001527
1528 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001529 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001530
paul1eb8ef22005-04-07 07:30:20 +00001531 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001532 {
paul2e3b2e42002-12-13 21:03:13 +00001533 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001534 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001535 if (oi->address && oi->address->family == AF_INET)
1536 {
1537 if (best_default.s_addr == 0)
1538 best_default = oi->address->u.prefix4;
1539 if (oi->area == area)
1540 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001541 }
paul718e3742002-12-13 20:15:29 +00001542 }
paulf2c80652002-12-13 21:44:27 +00001543 if (best_default.s_addr != 0)
1544 return best_default;
paul718e3742002-12-13 20:15:29 +00001545
paul68980082003-03-25 05:07:42 +00001546 if (best_default.s_addr != 0)
1547 return best_default;
1548
paul718e3742002-12-13 20:15:29 +00001549 return fwd;
1550}
hassobeebba72004-06-20 21:00:27 +00001551
paul718e3742002-12-13 20:15:29 +00001552#define DEFAULT_DEFAULT_METRIC 20
1553#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1554#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1555
1556#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1557
1558int
paul68980082003-03-25 05:07:42 +00001559metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001560{
paul68980082003-03-25 05:07:42 +00001561 return (ospf->dmetric[src].type < 0 ?
1562 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001563}
1564
1565int
paul68980082003-03-25 05:07:42 +00001566metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001567{
paul68980082003-03-25 05:07:42 +00001568 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001569 {
1570 if (src == DEFAULT_ROUTE)
1571 {
paul68980082003-03-25 05:07:42 +00001572 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001573 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1574 else
1575 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1576 }
paul68980082003-03-25 05:07:42 +00001577 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001578 return DEFAULT_DEFAULT_METRIC;
1579 else
paul68980082003-03-25 05:07:42 +00001580 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001581 }
1582
paul68980082003-03-25 05:07:42 +00001583 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001584}
1585
1586/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001587static void
paul68980082003-03-25 05:07:42 +00001588ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1589 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001590{
1591 struct prefix_ipv4 *p = &ei->p;
1592 struct in_addr mask, fwd_addr;
1593 u_int32_t mvalue;
1594 int mtype;
1595 int type;
1596
1597 /* Put Network Mask. */
1598 masklen2ip (p->prefixlen, &mask);
1599 stream_put_ipv4 (s, mask.s_addr);
1600
1601 /* If prefix is default, specify DEFAULT_ROUTE. */
1602 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1603
1604 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001605 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001606
1607 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001608 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001609
1610 /* Put type of external metric. */
1611 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1612
1613 /* Put 0 metric. TOS metric is not supported. */
1614 stream_put_ospf_metric (s, mvalue);
1615
1616 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001617 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001618
1619 /* Put forwarding address. */
1620 stream_put_ipv4 (s, fwd_addr.s_addr);
1621
1622 /* Put route tag -- This value should be introduced from configuration. */
1623 stream_putl (s, 0);
1624}
1625
1626/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001627static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001628ospf_external_lsa_new (struct ospf *ospf,
1629 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001630{
1631 struct stream *s;
1632 struct lsa_header *lsah;
1633 struct ospf_lsa *new;
1634 struct in_addr id;
1635 int length;
1636
1637 if (ei == NULL)
1638 {
1639 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001640 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
paul718e3742002-12-13 20:15:29 +00001641 return NULL;
1642 }
1643
1644 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001645 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001646
1647 /* If old Link State ID is specified, refresh LSA with same ID. */
1648 if (old_id)
1649 id = *old_id;
1650 /* Get Link State with unique ID. */
1651 else
1652 {
paul68980082003-03-25 05:07:42 +00001653 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001654 if (id.s_addr == 0xffffffff)
1655 {
1656 /* Maybe Link State ID not available. */
1657 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001658 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001659 return NULL;
1660 }
1661 }
1662
1663 /* Create new stream for LSA. */
1664 s = stream_new (OSPF_MAX_LSA_SIZE);
1665 lsah = (struct lsa_header *) STREAM_DATA (s);
1666
1667 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001668 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1669 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001670
1671 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001672 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001673
1674 /* Set length. */
1675 length = stream_get_endp (s);
1676 lsah->length = htons (length);
1677
1678 /* Now, create OSPF LSA instance. */
1679 new = ospf_lsa_new ();
1680 new->area = NULL;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001681 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001682
1683 /* Copy LSA data to store, discard stream. */
1684 new->data = ospf_lsa_data_new (length);
1685 memcpy (new->data, lsah, length);
1686 stream_free (s);
1687
1688 return new;
1689}
1690
paul718e3742002-12-13 20:15:29 +00001691/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001692static void
paul68980082003-03-25 05:07:42 +00001693ospf_install_flood_nssa (struct ospf *ospf,
1694 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001695{
pauld4a53d52003-07-12 21:30:57 +00001696 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001697 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001698 struct ospf_area *area;
1699 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001700
pauld4a53d52003-07-12 21:30:57 +00001701 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1702 * which originated from an NSSA area. In which case it should not be
1703 * flooded back to NSSA areas.
1704 */
1705 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1706 return;
1707
paul718e3742002-12-13 20:15:29 +00001708 /* NSSA Originate or Refresh (If anyNSSA)
1709
1710 LSA is self-originated. And just installed as Type-5.
1711 Additionally, install as Type-7 LSDB for every attached NSSA.
1712
1713 P-Bit controls which ABR performs translation to outside world; If
1714 we are an ABR....do not set the P-bit, because we send the Type-5,
1715 not as the ABR Translator, but as the ASBR owner within the AS!
1716
1717 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1718 elected ABR Translator will see the P-bit, Translate, and re-flood.
1719
1720 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1721 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1722
paul1eb8ef22005-04-07 07:30:20 +00001723 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001724 {
hasso0c14ad82003-07-03 08:36:02 +00001725 /* Don't install Type-7 LSA's into nonNSSA area */
1726 if (area->external_routing != OSPF_AREA_NSSA)
1727 continue;
paul718e3742002-12-13 20:15:29 +00001728
paul68980082003-03-25 05:07:42 +00001729 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001730 new = ospf_lsa_dup (lsa);
1731 new->area = area;
1732 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001733
paul68980082003-03-25 05:07:42 +00001734 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001735 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001736 {
pauld4a53d52003-07-12 21:30:57 +00001737 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001738
1739 /* set non-zero FWD ADDR
1740
1741 draft-ietf-ospf-nssa-update-09.txt
1742
1743 if the network between the NSSA AS boundary router and the
1744 adjacent AS is advertised into OSPF as an internal OSPF route,
1745 the forwarding address should be the next op address as is cu
1746 currently done with type-5 LSAs. If the intervening network is
1747 not adversited into OSPF as an internal OSPF route and the
1748 type-7 LSA's P-bit is set a forwarding address should be
1749 selected from one of the router's active OSPF inteface addresses
1750 which belong to the NSSA. If no such addresses exist, then
1751 no type-7 LSA's with the P-bit set should originate from this
1752 router. */
1753
pauld4a53d52003-07-12 21:30:57 +00001754 /* kevinm: not updating lsa anymore, just new */
1755 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001756
1757 if (extlsa->e[0].fwd_addr.s_addr == 0)
1758 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001759
pauld7480322003-05-16 17:31:51 +00001760 if (extlsa->e[0].fwd_addr.s_addr == 0)
1761 {
1762 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001763 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001764 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001765 return;
1766 }
paulf2c80652002-12-13 21:44:27 +00001767 }
paul718e3742002-12-13 20:15:29 +00001768
paul68980082003-03-25 05:07:42 +00001769 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001770 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001771
1772 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001773 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001774 }
paul718e3742002-12-13 20:15:29 +00001775}
pauld4a53d52003-07-12 21:30:57 +00001776
paul4dadc292005-05-06 21:37:42 +00001777static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001778ospf_lsa_translated_nssa_new (struct ospf *ospf,
1779 struct ospf_lsa *type7)
1780{
1781
1782 struct ospf_lsa *new;
1783 struct as_external_lsa *ext, *extnew;
1784 struct external_info ei;
1785
1786 ext = (struct as_external_lsa *)(type7->data);
1787
1788 /* need external_info struct, fill in bare minimum */
1789 ei.p.family = AF_INET;
1790 ei.p.prefix = type7->data->id;
1791 ei.p.prefixlen = ip_masklen (ext->mask);
1792 ei.type = ZEBRA_ROUTE_OSPF;
1793 ei.nexthop = ext->header.adv_router;
1794 ei.route_map_set.metric = -1;
1795 ei.route_map_set.metric_type = -1;
1796 ei.tag = 0;
1797
1798 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1799 {
1800 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001801 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001802 "Translated Type-5 for %s",
1803 inet_ntoa (ei.p.prefix));
1804 return NULL;
1805 }
1806
1807 extnew = (struct as_external_lsa *)(new->data);
1808
1809 /* copy over Type-7 data to new */
1810 extnew->e[0].tos = ext->e[0].tos;
1811 extnew->e[0].route_tag = ext->e[0].route_tag;
1812 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1813 new->data->ls_seqnum = type7->data->ls_seqnum;
1814
1815 /* add translated flag, checksum and lock new lsa */
1816 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
pauld4a53d52003-07-12 21:30:57 +00001817 new = ospf_lsa_lock (new);
1818
1819 return new;
1820}
1821
pauld4a53d52003-07-12 21:30:57 +00001822/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1823struct ospf_lsa *
1824ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1825{
1826 struct ospf_lsa *new;
1827 struct as_external_lsa *extnew;
1828
1829 /* we cant use ospf_external_lsa_originate() as we need to set
1830 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1831 */
1832
1833 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1834 {
1835 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001836 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001837 "Type-7, Id %s, to Type-5",
1838 inet_ntoa (type7->data->id));
1839 return NULL;
1840 }
1841
1842 extnew = (struct as_external_lsa *)new;
1843
1844 if (IS_DEBUG_OSPF_NSSA)
1845 {
ajse588f212004-12-08 18:12:06 +00001846 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001847 "translated Type 7, installed:");
1848 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001849 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1850 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001851 }
1852
1853 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1854 {
1855 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001856 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001857 "Could not install LSA "
1858 "id %s", inet_ntoa (type7->data->id));
1859 return NULL;
1860 }
1861
1862 ospf->lsa_originate_count++;
1863 ospf_flood_through_as (ospf, NULL, new);
1864
1865 return new;
1866}
1867
1868/* Refresh Translated from NSSA AS-external-LSA. */
1869struct ospf_lsa *
1870ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1871 struct ospf_lsa *type5)
1872{
1873 struct ospf_lsa *new = NULL;
1874
1875 /* Sanity checks. */
1876 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00001877 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00001878 return NULL;
pauld4a53d52003-07-12 21:30:57 +00001879 if (type7)
1880 assert (type7->data);
1881 if (type5)
1882 assert (type5->data);
1883 assert (ospf->anyNSSA);
1884
1885 /* get required data according to what has been given */
1886 if (type7 && type5 == NULL)
1887 {
1888 /* find the translated Type-5 for this Type-7 */
1889 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1890 struct prefix_ipv4 p =
1891 {
1892 .prefix = type7->data->id,
1893 .prefixlen = ip_masklen (ext->mask),
1894 .family = AF_INET,
1895 };
1896
1897 type5 = ospf_external_info_find_lsa (ospf, &p);
1898 }
1899 else if (type5 && type7 == NULL)
1900 {
1901 /* find the type-7 from which supplied type-5 was translated,
1902 * ie find first type-7 with same LSA Id.
1903 */
paul1eb8ef22005-04-07 07:30:20 +00001904 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00001905 struct route_node *rn;
1906 struct ospf_lsa *lsa;
1907 struct ospf_area *area;
1908
paul1eb8ef22005-04-07 07:30:20 +00001909 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00001910 {
1911 if (area->external_routing != OSPF_AREA_NSSA
1912 && !type7)
1913 continue;
1914
1915 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
1916 {
1917 if (lsa->data->id.s_addr == type5->data->id.s_addr)
1918 {
1919 type7 = lsa;
1920 break;
1921 }
1922 }
1923 }
1924 }
1925
1926 /* do we have type7? */
1927 if (!type7)
1928 {
1929 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001930 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00001931 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00001932 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00001933 return NULL;
1934 }
1935
1936 /* do we have valid translated type5? */
1937 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
1938 {
1939 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001940 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00001941 "found for Type-7 with Id %s",
1942 inet_ntoa (type7->data->id));
1943 return NULL;
1944 }
1945
1946 /* Delete LSA from neighbor retransmit-list. */
1947 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
1948
1949 /* create new translated LSA */
1950 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1951 {
1952 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001953 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001954 "Type-7 for %s to Type-5",
1955 inet_ntoa (type7->data->id));
1956 return NULL;
1957 }
1958
1959 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
1960 {
1961 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001962 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00001963 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00001964 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00001965 return NULL;
1966 }
1967
1968 /* Flood LSA through area. */
1969 ospf_flood_through_as (ospf, NULL, new);
1970
1971 return new;
1972}
paul718e3742002-12-13 20:15:29 +00001973
1974int
1975is_prefix_default (struct prefix_ipv4 *p)
1976{
1977 struct prefix_ipv4 q;
1978
1979 q.family = AF_INET;
1980 q.prefix.s_addr = 0;
1981 q.prefixlen = 0;
1982
1983 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
1984}
1985
1986/* Originate an AS-external-LSA, install and flood. */
1987struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001988ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001989{
1990 struct ospf_lsa *new;
1991
1992 /* Added for NSSA project....
1993
1994 External LSAs are originated in ASBRs as usual, but for NSSA systems.
1995 there is the global Type-5 LSDB and a Type-7 LSDB installed for
1996 every area. The Type-7's are flooded to every IR and every ABR; We
1997 install the Type-5 LSDB so that the normal "refresh" code operates
1998 as usual, and flag them as not used during ASE calculations. The
1999 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2000 Address of non-zero.
2001
2002 If an ABR is the elected NSSA translator, following SPF and during
2003 the ABR task it will translate all the scanned Type-7's, with P-bit
2004 ON and not-self generated, and translate to Type-5's throughout the
2005 non-NSSA/STUB AS.
2006
2007 A difference in operation depends whether this ASBR is an ABR
2008 or not. If not an ABR, the P-bit is ON, to indicate that any
2009 elected NSSA-ABR can perform its translation.
2010
2011 If an ABR, the P-bit is OFF; No ABR will perform translation and
2012 this ASBR will flood the Type-5 LSA as usual.
2013
2014 For the case where this ASBR is not an ABR, the ASE calculations
2015 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2016 demonstrate to the user that there are LSA's that belong to any
2017 attached NSSA.
2018
2019 Finally, it just so happens that when the ABR is translating every
2020 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2021 approved Type-5 (translated from Type-7); at the end of translation
2022 if any Translated Type-5's remain unapproved, then they must be
2023 flushed from the AS.
2024
2025 */
2026
2027 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002028 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002029 return NULL;
2030
2031 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002032 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002033 {
2034 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002035 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002036 inet_ntoa (ei->p.prefix));
2037 return NULL;
2038 }
2039
2040 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002041 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002042
2043 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002044 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002045
2046 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002047 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002048
paul718e3742002-12-13 20:15:29 +00002049 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002050 if (ospf->anyNSSA &&
2051 /* stay away from translated LSAs! */
2052 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002053 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002054
2055 /* Debug logging. */
2056 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2057 {
ajse588f212004-12-08 18:12:06 +00002058 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002059 new->data->type, inet_ntoa (new->data->id), new);
2060 ospf_lsa_header_dump (new->data);
2061 }
2062
2063 return new;
2064}
2065
2066/* Originate AS-external-LSA from external info with initial flag. */
2067int
paul68980082003-03-25 05:07:42 +00002068ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002069{
paul68980082003-03-25 05:07:42 +00002070 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002071 struct route_node *rn;
2072 struct external_info *ei;
2073 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002074 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002075
paul68980082003-03-25 05:07:42 +00002076 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002077
2078 /* Originate As-external-LSA from all type of distribute source. */
2079 if ((rt = EXTERNAL_INFO (type)))
2080 for (rn = route_top (rt); rn; rn = route_next (rn))
2081 if ((ei = rn->info) != NULL)
2082 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002083 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002084 zlog_warn ("LSA: AS-external-LSA was not originated.");
2085
2086 return 0;
2087}
2088
paul4dadc292005-05-06 21:37:42 +00002089static struct external_info *
paul020709f2003-04-04 02:44:16 +00002090ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002091{
2092 int type;
2093 struct route_node *rn;
2094 struct prefix_ipv4 p;
2095
2096 p.family = AF_INET;
2097 p.prefix.s_addr = 0;
2098 p.prefixlen = 0;
2099
2100 /* First, lookup redistributed default route. */
2101 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2102 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2103 {
2104 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2105 if (rn != NULL)
2106 {
2107 route_unlock_node (rn);
2108 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002109 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002110 return rn->info;
2111 }
2112 }
2113
2114 return NULL;
2115}
2116
2117int
paul68980082003-03-25 05:07:42 +00002118ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002119{
paul718e3742002-12-13 20:15:29 +00002120 struct prefix_ipv4 p;
2121 struct in_addr nexthop;
2122 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002123 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002124
Paul Jakma4021b602006-05-12 22:55:41 +00002125 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002126
2127 p.family = AF_INET;
2128 p.prefix.s_addr = 0;
2129 p.prefixlen = 0;
2130
Paul Jakma4021b602006-05-12 22:55:41 +00002131 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002132 {
2133 /* If there is no default route via redistribute,
2134 then originate AS-external-LSA with nexthop 0 (self). */
2135 nexthop.s_addr = 0;
2136 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2137 }
2138
paul020709f2003-04-04 02:44:16 +00002139 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002140 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002141
2142 return 0;
2143}
2144
paul645878f2003-04-13 21:42:11 +00002145/* Flush any NSSA LSAs for given prefix */
2146void
2147ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2148{
paul1eb8ef22005-04-07 07:30:20 +00002149 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002150 struct ospf_lsa *lsa;
2151 struct ospf_area *area;
2152
paul1eb8ef22005-04-07 07:30:20 +00002153 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002154 {
paul1eb8ef22005-04-07 07:30:20 +00002155 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002156 {
2157 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2158 ospf->router_id)))
2159 {
2160 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002161 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002162 inet_ntoa (p->prefix), p->prefixlen);
2163 continue;
2164 }
2165 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2166 if (!IS_LSA_MAXAGE (lsa))
2167 {
2168 ospf_refresher_unregister_lsa (ospf, lsa);
2169 ospf_lsa_flush_area (lsa, area);
2170 }
2171 }
paul645878f2003-04-13 21:42:11 +00002172 }
2173}
paul645878f2003-04-13 21:42:11 +00002174
paul718e3742002-12-13 20:15:29 +00002175/* Flush an AS-external-LSA from LSDB and routing domain. */
2176void
paul68980082003-03-25 05:07:42 +00002177ospf_external_lsa_flush (struct ospf *ospf,
2178 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002179 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002180{
2181 struct ospf_lsa *lsa;
2182
2183 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002184 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002185 inet_ntoa (p->prefix), p->prefixlen);
2186
2187 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002188 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002189 {
2190 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002191 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002192 inet_ntoa (p->prefix), p->prefixlen);
2193 return;
2194 }
hassobeebba72004-06-20 21:00:27 +00002195
pauld4a53d52003-07-12 21:30:57 +00002196 /* If LSA is selforiginated, not a translated LSA, and there is
2197 * NSSA area, flush Type-7 LSA's at first.
2198 */
2199 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2200 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002201 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002202
2203 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002204 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002205
2206 /* There must be no self-originated LSA in rtrs_external. */
2207#if 0
2208 /* Remove External route from Zebra. */
2209 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2210#endif
2211
2212 if (!IS_LSA_MAXAGE (lsa))
2213 {
2214 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002215 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002216
2217 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002218 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002219 }
2220
2221 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002222 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002223}
2224
2225void
paul68980082003-03-25 05:07:42 +00002226ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002227{
2228 struct prefix_ipv4 p;
2229 struct external_info *ei;
2230 struct ospf_lsa *lsa;
2231
2232 p.family = AF_INET;
2233 p.prefixlen = 0;
2234 p.prefix.s_addr = 0;
2235
paul020709f2003-04-04 02:44:16 +00002236 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002237 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002238
2239 if (ei)
2240 {
2241 if (lsa)
2242 {
2243 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002244 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002245 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002246 }
2247 else
2248 {
2249 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002250 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002251 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002252 }
2253 }
2254 else
2255 {
2256 if (lsa)
2257 {
2258 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002259 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
Paul Jakmadfbd5172010-04-14 10:32:12 +01002260 ospf_refresher_unregister_lsa (ospf, lsa);
paul68980082003-03-25 05:07:42 +00002261 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002262 }
2263 }
2264}
2265
2266void
paul68980082003-03-25 05:07:42 +00002267ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002268{
2269 struct route_node *rn;
2270 struct external_info *ei;
2271
2272 if (type != DEFAULT_ROUTE)
2273 if (EXTERNAL_INFO(type))
2274 /* Refresh each redistributed AS-external-LSAs. */
2275 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2276 if ((ei = rn->info))
2277 if (!is_prefix_default (&ei->p))
2278 {
2279 struct ospf_lsa *lsa;
2280
paul68980082003-03-25 05:07:42 +00002281 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2282 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002283 else
paul68980082003-03-25 05:07:42 +00002284 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002285 }
2286}
2287
2288/* Refresh AS-external-LSA. */
Paul Jakmac363d382010-01-24 22:42:13 +00002289struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002290ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002291 struct external_info *ei, int force)
2292{
2293 struct ospf_lsa *new;
2294 int changed;
2295
2296 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002297 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002298 {
pauld4a53d52003-07-12 21:30:57 +00002299 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002300 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002301 "redist check fail",
2302 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002303 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002304 ei->ifindex /*, ei->nexthop */);
Paul Jakmac363d382010-01-24 22:42:13 +00002305 return NULL;
paul718e3742002-12-13 20:15:29 +00002306 }
2307
2308 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002309 {
2310 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002311 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002312 lsa->data->type, inet_ntoa (lsa->data->id));
Paul Jakmac363d382010-01-24 22:42:13 +00002313 return NULL;
pauld4a53d52003-07-12 21:30:57 +00002314 }
paul718e3742002-12-13 20:15:29 +00002315
2316 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002317 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002318
2319 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002320 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002321
paul68980082003-03-25 05:07:42 +00002322 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002323
2324 if (new == NULL)
2325 {
2326 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002327 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002328 inet_ntoa (lsa->data->id));
Paul Jakmac363d382010-01-24 22:42:13 +00002329 return NULL;
paul718e3742002-12-13 20:15:29 +00002330 }
2331
2332 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2333
paul68980082003-03-25 05:07:42 +00002334 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002335
2336 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002337 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002338
paul718e3742002-12-13 20:15:29 +00002339 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002340 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002341 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002342
pauld4a53d52003-07-12 21:30:57 +00002343 /* Register self-originated LSA to refresh queue.
2344 * Translated LSAs should not be registered, but refreshed upon
2345 * refresh of the Type-7
2346 */
2347 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2348 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002349
2350 /* Debug logging. */
2351 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2352 {
ajse588f212004-12-08 18:12:06 +00002353 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002354 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002355 ospf_lsa_header_dump (new->data);
2356 }
2357
Paul Jakmac363d382010-01-24 22:42:13 +00002358 return new;
paul718e3742002-12-13 20:15:29 +00002359}
2360
2361
2362/* LSA installation functions. */
2363
2364/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002365static struct ospf_lsa *
Paul Jakmac363d382010-01-24 22:42:13 +00002366ospf_router_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2367 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002368{
2369 struct ospf_area *area = new->area;
2370
2371 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2372 The entire routing table must be recalculated, starting with
2373 the shortest path calculations for each area (not just the
2374 area whose link-state database has changed).
2375 */
paul718e3742002-12-13 20:15:29 +00002376
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002377 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002378 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002379
2380 /* Only install LSA if it is originated/refreshed by us.
2381 * If LSA was received by flooding, the RECEIVED flag is set so do
2382 * not link the LSA */
2383 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2384 return new; /* ignore stale LSA */
2385
paul718e3742002-12-13 20:15:29 +00002386 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002387 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002388 area->router_lsa_self = ospf_lsa_lock (new);
2389
Paul Jakmac363d382010-01-24 22:42:13 +00002390 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002391 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002392 if (rt_recalc)
2393 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002394
2395 return new;
2396}
2397
2398#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2399 if (!(T)) \
2400 (T) = thread_add_timer (master, (F), oi, (V))
2401
2402/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002403static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002404ospf_network_lsa_install (struct ospf *ospf,
2405 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002406 struct ospf_lsa *new,
2407 int rt_recalc)
2408{
2409
2410 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2411 The entire routing table must be recalculated, starting with
2412 the shortest path calculations for each area (not just the
2413 area whose link-state database has changed).
2414 */
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002415 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002416 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002417 /* We supposed that when LSA is originated by us, we pass the int
2418 for which it was originated. If LSA was received by flooding,
2419 the RECEIVED flag is set, so we do not link the LSA to the int. */
2420 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2421 return new; /* ignore stale LSA */
2422
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002423 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002424 oi->network_lsa_self = ospf_lsa_lock (new);
Paul Jakmac363d382010-01-24 22:42:13 +00002425 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002426 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002427 if (rt_recalc)
2428 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002429
2430 return new;
2431}
2432
2433/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002434static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002435ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2436 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002437{
paul718e3742002-12-13 20:15:29 +00002438 if (rt_recalc && !IS_LSA_SELF (new))
2439 {
2440 /* RFC 2328 Section 13.2 Summary-LSAs
2441 The best route to the destination described by the summary-
2442 LSA must be recalculated (see Section 16.5). If this
2443 destination is an AS boundary router, it may also be
2444 necessary to re-examine all the AS-external-LSAs.
2445 */
2446
2447#if 0
2448 /* This doesn't exist yet... */
2449 ospf_summary_incremental_update(new); */
2450#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002451 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002452#endif /* #if 0 */
2453
2454 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002455 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002456 }
2457
2458 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002459 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002460
2461 return new;
2462}
2463
2464/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002465static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002466ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2467 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002468{
2469 if (rt_recalc && !IS_LSA_SELF (new))
2470 {
2471 /* RFC 2328 Section 13.2 Summary-LSAs
2472 The best route to the destination described by the summary-
2473 LSA must be recalculated (see Section 16.5). If this
2474 destination is an AS boundary router, it may also be
2475 necessary to re-examine all the AS-external-LSAs.
2476 */
2477#if 0
2478 /* These don't exist yet... */
2479 ospf_summary_incremental_update(new);
2480 /* Isn't this done by the above call?
2481 - RFC 2328 Section 16.5 implies it should be */
2482 /* ospf_ase_calculate_schedule(); */
2483#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002484 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002485#endif /* #if 0 */
2486 }
2487
2488 /* register LSA to refresh-list. */
2489 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002490 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002491
2492 return new;
2493}
2494
2495/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002496static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002497ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2498 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002499{
paul68980082003-03-25 05:07:42 +00002500 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002501 /* If LSA is not self-originated, calculate an external route. */
2502 if (rt_recalc)
2503 {
2504 /* RFC 2328 Section 13.2 AS-external-LSAs
2505 The best route to the destination described by the AS-
2506 external-LSA must be recalculated (see Section 16.6).
2507 */
2508
2509 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002510 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002511 }
2512
pauld4a53d52003-07-12 21:30:57 +00002513 if (new->data->type == OSPF_AS_NSSA_LSA)
2514 {
2515 /* There is no point to register selforiginate Type-7 LSA for
2516 * refreshing. We rely on refreshing Type-5 LSA's
2517 */
2518 if (IS_LSA_SELF (new))
2519 return new;
2520 else
2521 {
2522 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2523 * New translations will be taken care of by the abr_task.
2524 */
2525 ospf_translated_nssa_refresh (ospf, new, NULL);
2526 }
2527 }
pauld7480322003-05-16 17:31:51 +00002528
pauld4a53d52003-07-12 21:30:57 +00002529 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002530 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002531 */
hassobeebba72004-06-20 21:00:27 +00002532 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002533 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002534
2535 return new;
2536}
2537
2538void
paul68980082003-03-25 05:07:42 +00002539ospf_discard_from_db (struct ospf *ospf,
2540 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002541{
2542 struct ospf_lsa *old;
2543
Paul Jakmaac904de2006-06-15 12:04:57 +00002544 if (!lsdb)
2545 {
2546 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2547 if (!lsa)
2548 zlog_warn ("%s: and NULL LSA!", __func__);
2549 else
2550 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2551 lsa->data->type, inet_ntoa (lsa->data->id));
2552 return;
2553 }
2554
paul718e3742002-12-13 20:15:29 +00002555 old = ospf_lsdb_lookup (lsdb, lsa);
2556
2557 if (!old)
2558 return;
2559
2560 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002561 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002562
2563 switch (old->data->type)
2564 {
2565 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002566 ospf_ase_unregister_external_lsa (old, ospf);
2567 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2568 break;
paul718e3742002-12-13 20:15:29 +00002569#ifdef HAVE_OPAQUE_LSA
2570 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002571 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002572 break;
paul69310a62005-05-11 18:09:59 +00002573#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002574 case OSPF_AS_NSSA_LSA:
2575 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2576 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002577 break;
paul718e3742002-12-13 20:15:29 +00002578 default:
paul68980082003-03-25 05:07:42 +00002579 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002580 break;
2581 }
2582
paul68980082003-03-25 05:07:42 +00002583 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002584 ospf_lsa_discard (old);
2585}
2586
paul718e3742002-12-13 20:15:29 +00002587struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002588ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2589 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002590{
2591 struct ospf_lsa *new = NULL;
2592 struct ospf_lsa *old = NULL;
2593 struct ospf_lsdb *lsdb = NULL;
2594 int rt_recalc;
2595
2596 /* Set LSDB. */
2597 switch (lsa->data->type)
2598 {
paulf2c80652002-12-13 21:44:27 +00002599 /* kevinm */
2600 case OSPF_AS_NSSA_LSA:
2601 if (lsa->area)
2602 lsdb = lsa->area->lsdb;
2603 else
paul68980082003-03-25 05:07:42 +00002604 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002605 break;
paul718e3742002-12-13 20:15:29 +00002606 case OSPF_AS_EXTERNAL_LSA:
2607#ifdef HAVE_OPAQUE_LSA
2608 case OSPF_OPAQUE_AS_LSA:
2609#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002610 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002611 break;
2612 default:
2613 lsdb = lsa->area->lsdb;
2614 break;
2615 }
2616
paul718e3742002-12-13 20:15:29 +00002617 assert (lsdb);
2618
2619 /* RFC 2328 13.2. Installing LSAs in the database
2620
2621 Installing a new LSA in the database, either as the result of
2622 flooding or a newly self-originated LSA, may cause the OSPF
2623 routing table structure to be recalculated. The contents of the
2624 new LSA should be compared to the old instance, if present. If
2625 there is no difference, there is no need to recalculate the
2626 routing table. When comparing an LSA to its previous instance,
2627 the following are all considered to be differences in contents:
2628
2629 o The LSA's Options field has changed.
2630
2631 o One of the LSA instances has LS age set to MaxAge, and
2632 the other does not.
2633
2634 o The length field in the LSA header has changed.
2635
2636 o The body of the LSA (i.e., anything outside the 20-byte
2637 LSA header) has changed. Note that this excludes changes
2638 in LS Sequence Number and LS Checksum.
2639
2640 */
2641 /* Look up old LSA and determine if any SPF calculation or incremental
2642 update is needed */
2643 old = ospf_lsdb_lookup (lsdb, lsa);
2644
2645 /* Do comparision and record if recalc needed. */
2646 rt_recalc = 0;
2647 if ( old == NULL || ospf_lsa_different(old, lsa))
2648 rt_recalc = 1;
2649
paul7ddf1d62003-10-13 09:06:46 +00002650 /*
2651 Sequence number check (Section 14.1 of rfc 2328)
2652 "Premature aging is used when it is time for a self-originated
2653 LSA's sequence number field to wrap. At this point, the current
2654 LSA instance (having LS sequence number MaxSequenceNumber) must
2655 be prematurely aged and flushed from the routing domain before a
2656 new instance with sequence number equal to InitialSequenceNumber
2657 can be originated. "
2658 */
2659
Paul Jakmac2b478d2006-03-30 14:16:11 +00002660 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002661 {
2662 if (ospf_lsa_is_self_originated(ospf, lsa))
2663 {
paul0c2be262004-05-31 14:16:54 +00002664 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2665
2666 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002667 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2668 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2669
2670 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2671 {
ajse588f212004-12-08 18:12:06 +00002672 zlog_debug ("ospf_lsa_install() Premature Aging "
Paul Jakmac363d382010-01-24 22:42:13 +00002673 "lsa 0x%p, seqnum 0x%x",
2674 lsa, ntohl(lsa->data->ls_seqnum));
paul7ddf1d62003-10-13 09:06:46 +00002675 ospf_lsa_header_dump (lsa->data);
2676 }
2677 }
2678 else
2679 {
2680 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2681 {
ajse588f212004-12-08 18:12:06 +00002682 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002683 "that was not self originated. Ignoring\n");
2684 ospf_lsa_header_dump (lsa->data);
2685 }
2686 return old;
2687 }
2688 }
2689
paul718e3742002-12-13 20:15:29 +00002690 /* discard old LSA from LSDB */
2691 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002692 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002693
paul718e3742002-12-13 20:15:29 +00002694 /* Calculate Checksum if self-originated?. */
2695 if (IS_LSA_SELF (lsa))
2696 ospf_lsa_checksum (lsa->data);
2697
hassofe71a972004-12-22 16:16:02 +00002698 /* Insert LSA to LSDB. */
2699 ospf_lsdb_add (lsdb, lsa);
2700 lsa->lsdb = lsdb;
2701
paul718e3742002-12-13 20:15:29 +00002702 /* Do LSA specific installation process. */
2703 switch (lsa->data->type)
2704 {
2705 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002706 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002707 break;
2708 case OSPF_NETWORK_LSA:
2709 assert (oi);
paul68980082003-03-25 05:07:42 +00002710 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002711 break;
2712 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002713 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002714 break;
2715 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002716 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002717 break;
2718 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002719 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002720 break;
2721#ifdef HAVE_OPAQUE_LSA
2722 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002723 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002724 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002725 else
paul68980082003-03-25 05:07:42 +00002726 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002727 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002728 case OSPF_OPAQUE_AREA_LSA:
2729 case OSPF_OPAQUE_AS_LSA:
2730 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2731 break;
2732#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002733 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002734 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002735 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002736 break;
2737 }
2738
2739 if (new == NULL)
2740 return new; /* Installation failed, cannot proceed further -- endo. */
2741
2742 /* Debug logs. */
2743 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2744 {
2745 char area_str[INET_ADDRSTRLEN];
2746
2747 switch (lsa->data->type)
2748 {
2749 case OSPF_AS_EXTERNAL_LSA:
2750#ifdef HAVE_OPAQUE_LSA
2751 case OSPF_OPAQUE_AS_LSA:
2752#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002753 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002754 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002755 dump_lsa_key (new),
2756 LOOKUP (ospf_lsa_type_msg, new->data->type));
2757 break;
2758 default:
2759 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002760 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002761 dump_lsa_key (new),
2762 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2763 break;
2764 }
2765 }
2766
paul7ddf1d62003-10-13 09:06:46 +00002767 /*
2768 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2769 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2770 */
2771 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2772 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002773 {
paul7ddf1d62003-10-13 09:06:46 +00002774 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002775 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002776 new->data->type,
2777 inet_ntoa (new->data->id),
2778 lsa);
Paul Jakma02d942c2010-01-24 23:36:20 +00002779 ospf_lsa_flush (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002780 }
2781
2782 return new;
2783}
2784
2785
paul4dadc292005-05-06 21:37:42 +00002786static int
paul68980082003-03-25 05:07:42 +00002787ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002788{
paul1eb8ef22005-04-07 07:30:20 +00002789 struct listnode *node, *nnode;
2790 struct ospf_interface *oi;
2791
2792 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002793 {
paul718e3742002-12-13 20:15:29 +00002794 struct route_node *rn;
2795 struct ospf_neighbor *nbr;
2796
2797 if (ospf_if_is_enable (oi))
2798 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2799 if ((nbr = rn->info) != NULL)
2800 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2801 {
2802 route_unlock_node (rn);
2803 return 0;
2804 }
2805 }
2806
2807 return 1;
2808}
2809
2810
paul718e3742002-12-13 20:15:29 +00002811
paul4dadc292005-05-06 21:37:42 +00002812static int
paul718e3742002-12-13 20:15:29 +00002813ospf_maxage_lsa_remover (struct thread *thread)
2814{
paul68980082003-03-25 05:07:42 +00002815 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002816 struct ospf_lsa *lsa;
2817 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002818 int reschedule = 0;
2819
paul68980082003-03-25 05:07:42 +00002820 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002821
2822 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002823 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002824
paul68980082003-03-25 05:07:42 +00002825 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002826
2827 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002828 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002829 {
paul718e3742002-12-13 20:15:29 +00002830 if (lsa->retransmit_counter > 0)
2831 {
2832 reschedule = 1;
2833 continue;
2834 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002835
2836 /* TODO: maybe convert this function to a work-queue */
2837 if (thread_should_yield (thread))
2838 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);
2839
paul718e3742002-12-13 20:15:29 +00002840 /* Remove LSA from the LSDB */
2841 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2842 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002843 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
paul7ddf1d62003-10-13 09:06:46 +00002844 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002845
2846 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002847 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002848 lsa->data->type, inet_ntoa (lsa->data->id));
2849
Paul Jakmac363d382010-01-24 22:42:13 +00002850 if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))
paul7ddf1d62003-10-13 09:06:46 +00002851 {
2852 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
Paul Jakmac363d382010-01-24 22:42:13 +00002853 zlog_debug ("originating new lsa for lsa 0x%p\n", lsa);
2854 ospf_lsa_refresh (ospf, lsa);
paul7ddf1d62003-10-13 09:06:46 +00002855 }
2856
paul718e3742002-12-13 20:15:29 +00002857 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002858 if (lsa->lsdb)
2859 {
2860 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2861 ospf_lsdb_delete (lsa->lsdb, lsa);
2862 }
2863 else
2864 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2865 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002866 }
2867
2868 /* A MaxAge LSA must be removed immediately from the router's link
2869 state database as soon as both a) it is no longer contained on any
2870 neighbor Link state retransmission lists and b) none of the router's
2871 neighbors are in states Exchange or Loading. */
2872 if (reschedule)
Paul Jakma02d942c2010-01-24 23:36:20 +00002873 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2874 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002875
2876 return 0;
2877}
2878
paul718e3742002-12-13 20:15:29 +00002879void
paul68980082003-03-25 05:07:42 +00002880ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002881{
hasso52dc7ee2004-09-23 19:18:23 +00002882 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00002883
paul68980082003-03-25 05:07:42 +00002884 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00002885 {
paul68980082003-03-25 05:07:42 +00002886 list_delete_node (ospf->maxage_lsa, n);
Stephen Hemminger3106a032009-08-06 12:58:05 -07002887 UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002888 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +00002889 }
2890}
2891
Paul Jakma02d942c2010-01-24 23:36:20 +00002892/* Add LSA onto the MaxAge list, and schedule for removal.
2893 * This does *not* lead to the LSA being flooded, that must be taken
2894 * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
2895 * function).
2896 */
paul718e3742002-12-13 20:15:29 +00002897void
paul68980082003-03-25 05:07:42 +00002898ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002899{
2900 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2901 and schedule the MaxAge LSA remover. */
Stephen Hemminger3106a032009-08-06 12:58:05 -07002902 if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
paul718e3742002-12-13 20:15:29 +00002903 {
2904 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002905 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00002906 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2907 return;
2908 }
2909
paul68980082003-03-25 05:07:42 +00002910 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
Stephen Hemminger3106a032009-08-06 12:58:05 -07002911 SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
paul718e3742002-12-13 20:15:29 +00002912
2913 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002914 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002915
Paul Jakma02d942c2010-01-24 23:36:20 +00002916 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2917 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002918}
2919
paul4dadc292005-05-06 21:37:42 +00002920static int
paul68980082003-03-25 05:07:42 +00002921ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002922{
paul718e3742002-12-13 20:15:29 +00002923 /* Stay away from any Local Translated Type-7 LSAs */
2924 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2925 return 0;
paul718e3742002-12-13 20:15:29 +00002926
2927 if (IS_LSA_MAXAGE (lsa))
2928 /* Self-originated LSAs should NOT time-out instead,
2929 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00002930 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002931 {
2932 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002933 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002934
2935 switch (lsa->data->type)
2936 {
paul718e3742002-12-13 20:15:29 +00002937#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00002938 case OSPF_OPAQUE_LINK_LSA:
2939 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00002940 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00002941 /*
2942 * As a general rule, whenever network topology has changed
2943 * (due to an LSA removal in this case), routing recalculation
2944 * should be triggered. However, this is not true for opaque
2945 * LSAs. Even if an opaque LSA instance is going to be removed
2946 * from the routing domain, it does not mean a change in network
2947 * topology, and thus, routing recalculation is not needed here.
2948 */
2949 break;
paul718e3742002-12-13 20:15:29 +00002950#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00002951 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00002952 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002953 ospf_ase_incremental_update (ospf, lsa);
2954 break;
paul718e3742002-12-13 20:15:29 +00002955 default:
paul68980082003-03-25 05:07:42 +00002956 ospf_spf_calculate_schedule (ospf);
2957 break;
paul718e3742002-12-13 20:15:29 +00002958 }
paul68980082003-03-25 05:07:42 +00002959 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002960 }
2961
Paul Jakmac363d382010-01-24 22:42:13 +00002962 if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa))
2963 if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30)
2964 printf ("Eek! Shouldn't happen!\n");
2965
paul718e3742002-12-13 20:15:29 +00002966 return 0;
2967}
2968
2969/* Periodical check of MaxAge LSA. */
2970int
paul68980082003-03-25 05:07:42 +00002971ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002972{
paul68980082003-03-25 05:07:42 +00002973 struct ospf *ospf = THREAD_ARG (thread);
2974 struct route_node *rn;
2975 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00002976 struct ospf_area *area;
2977 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002978
paul68980082003-03-25 05:07:42 +00002979 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00002980
paul1eb8ef22005-04-07 07:30:20 +00002981 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00002982 {
paul68980082003-03-25 05:07:42 +00002983 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
2984 ospf_lsa_maxage_walker_remover (ospf, lsa);
2985 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
2986 ospf_lsa_maxage_walker_remover (ospf, lsa);
2987 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
2988 ospf_lsa_maxage_walker_remover (ospf, lsa);
2989 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
2990 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002991#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002992 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
2993 ospf_lsa_maxage_walker_remover (ospf, lsa);
2994 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
2995 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002996#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00002997 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
2998 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002999 }
3000
paul4fb949e2003-05-10 20:06:51 +00003001 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003002 if (ospf->lsdb)
3003 {
3004 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3005 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003006#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003007 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3008 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003009#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003010 }
paul718e3742002-12-13 20:15:29 +00003011
paul68980082003-03-25 05:07:42 +00003012 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3013 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003014 return 0;
3015}
3016
paul68980082003-03-25 05:07:42 +00003017struct ospf_lsa *
3018ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3019 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003020{
paul68980082003-03-25 05:07:42 +00003021 struct ospf_lsa *lsa;
3022 struct in_addr mask, id;
3023 struct lsa_header_mask
3024 {
3025 struct lsa_header header;
3026 struct in_addr mask;
3027 } *hmask;
paul718e3742002-12-13 20:15:29 +00003028
paul68980082003-03-25 05:07:42 +00003029 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3030 if (lsa == NULL)
3031 return NULL;
paul718e3742002-12-13 20:15:29 +00003032
paul68980082003-03-25 05:07:42 +00003033 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003034
paul68980082003-03-25 05:07:42 +00003035 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003036
paul68980082003-03-25 05:07:42 +00003037 if (mask.s_addr != hmask->mask.s_addr)
3038 {
3039 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3040 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3041 if (!lsa)
3042 return NULL;
3043 }
paul718e3742002-12-13 20:15:29 +00003044
paul68980082003-03-25 05:07:42 +00003045 return lsa;
paul718e3742002-12-13 20:15:29 +00003046}
3047
3048struct ospf_lsa *
3049ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3050 struct in_addr id, struct in_addr adv_router)
3051{
paule05fba42003-04-13 20:20:53 +00003052 struct ospf *ospf = ospf_lookup();
3053 assert(ospf);
3054
paul718e3742002-12-13 20:15:29 +00003055 switch (type)
3056 {
3057 case OSPF_ROUTER_LSA:
3058 case OSPF_NETWORK_LSA:
3059 case OSPF_SUMMARY_LSA:
3060 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003061 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003062#ifdef HAVE_OPAQUE_LSA
3063 case OSPF_OPAQUE_LINK_LSA:
3064 case OSPF_OPAQUE_AREA_LSA:
3065#endif /* HAVE_OPAQUE_LSA */
3066 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003067 case OSPF_AS_EXTERNAL_LSA:
3068#ifdef HAVE_OPAQUE_LSA
3069 case OSPF_OPAQUE_AS_LSA:
3070#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003071 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003072 default:
3073 break;
3074 }
3075
3076 return NULL;
3077}
3078
3079struct ospf_lsa *
3080ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3081 struct in_addr id)
3082{
3083 struct ospf_lsa *lsa;
3084 struct route_node *rn;
3085
3086 switch (type)
3087 {
3088 case OSPF_ROUTER_LSA:
3089 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003090 case OSPF_NETWORK_LSA:
3091 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3092 if ((lsa = rn->info))
3093 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3094 {
3095 route_unlock_node (rn);
3096 return lsa;
3097 }
3098 break;
3099 case OSPF_SUMMARY_LSA:
3100 case OSPF_ASBR_SUMMARY_LSA:
3101 /* Currently not used. */
3102 assert (1);
3103 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003104 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003105 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003106#ifdef HAVE_OPAQUE_LSA
3107 case OSPF_OPAQUE_LINK_LSA:
3108 case OSPF_OPAQUE_AREA_LSA:
3109 case OSPF_OPAQUE_AS_LSA:
3110 /* Currently not used. */
3111 break;
3112#endif /* HAVE_OPAQUE_LSA */
3113 default:
3114 break;
3115 }
3116
3117 return NULL;
3118}
3119
3120struct ospf_lsa *
3121ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3122{
3123 struct ospf_lsa *match;
3124
3125#ifdef HAVE_OPAQUE_LSA
3126 /*
3127 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3128 * is redefined to have two subfields; opaque-type and opaque-id.
3129 * However, it is harmless to treat the two sub fields together, as if
3130 * they two were forming a unique LSA-ID.
3131 */
3132#endif /* HAVE_OPAQUE_LSA */
3133
3134 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3135
3136 if (match == NULL)
3137 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003138 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003139 lsah->type, inet_ntoa (lsah->id));
3140
3141 return match;
3142}
3143
3144/* return +n, l1 is more recent.
3145 return -n, l2 is more recent.
3146 return 0, l1 and l2 is identical. */
3147int
3148ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3149{
3150 int r;
3151 int x, y;
3152
3153 if (l1 == NULL && l2 == NULL)
3154 return 0;
3155 if (l1 == NULL)
3156 return -1;
3157 if (l2 == NULL)
3158 return 1;
3159
3160 /* compare LS sequence number. */
3161 x = (int) ntohl (l1->data->ls_seqnum);
3162 y = (int) ntohl (l2->data->ls_seqnum);
3163 if (x > y)
3164 return 1;
3165 if (x < y)
3166 return -1;
3167
3168 /* compare LS checksum. */
3169 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3170 if (r)
3171 return r;
3172
3173 /* compare LS age. */
3174 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3175 return 1;
3176 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3177 return -1;
3178
3179 /* compare LS age with MaxAgeDiff. */
3180 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3181 return -1;
3182 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3183 return 1;
3184
3185 /* LSAs are identical. */
3186 return 0;
3187}
3188
3189/* If two LSAs are different, return 1, otherwise return 0. */
3190int
3191ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3192{
3193 char *p1, *p2;
3194 assert (l1);
3195 assert (l2);
3196 assert (l1->data);
3197 assert (l2->data);
3198
3199 if (l1->data->options != l2->data->options)
3200 return 1;
3201
3202 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3203 return 1;
3204
3205 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3206 return 1;
3207
3208 if (l1->data->length != l2->data->length)
3209 return 1;
3210
3211 if (l1->data->length == 0)
3212 return 1;
3213
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02003214 if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
3215 return 1; /* May be a stale LSA in the LSBD */
3216
pauld1825832003-04-03 01:27:01 +00003217 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003218
3219 p1 = (char *) l1->data;
3220 p2 = (char *) l2->data;
3221
3222 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3223 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3224 return 1;
3225
3226 return 0;
3227}
3228
3229#ifdef ORIGINAL_CODING
3230void
3231ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3232 struct ospf_lsa *self,
3233 struct ospf_lsa *new)
3234{
3235 u_int32_t seqnum;
3236
3237 /* Adjust LS Sequence Number. */
3238 seqnum = ntohl (new->data->ls_seqnum) + 1;
3239 self->data->ls_seqnum = htonl (seqnum);
3240
3241 /* Recalculate LSA checksum. */
3242 ospf_lsa_checksum (self->data);
3243
3244 /* Reflooding LSA. */
3245 /* RFC2328 Section 13.3
3246 On non-broadcast networks, separate Link State Update
3247 packets must be sent, as unicasts, to each adjacent neighbor
3248 (i.e., those in state Exchange or greater). The destination
3249 IP addresses for these packets are the neighbors' IP
3250 addresses. */
3251 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3252 {
3253 struct route_node *rn;
3254 struct ospf_neighbor *onbr;
3255
3256 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3257 if ((onbr = rn->info) != NULL)
3258 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3259 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3260 }
3261 else
3262 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3263
3264 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003265 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003266 self->data->type, inet_ntoa (self->data->id));
3267}
3268#else /* ORIGINAL_CODING */
3269static int
paul68980082003-03-25 05:07:42 +00003270ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003271{
3272 if (lsa == NULL || !IS_LSA_SELF (lsa))
3273 return 0;
3274
3275 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003276 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 +00003277
3278 /* Force given lsa's age to MaxAge. */
3279 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3280
3281 switch (lsa->data->type)
3282 {
3283#ifdef HAVE_OPAQUE_LSA
Paul Jakma02d942c2010-01-24 23:36:20 +00003284 /* Opaque wants to be notified of flushes */
paul718e3742002-12-13 20:15:29 +00003285 case OSPF_OPAQUE_LINK_LSA:
3286 case OSPF_OPAQUE_AREA_LSA:
3287 case OSPF_OPAQUE_AS_LSA:
3288 ospf_opaque_lsa_refresh (lsa);
3289 break;
3290#endif /* HAVE_OPAQUE_LSA */
3291 default:
Paul Jakmadfbd5172010-04-14 10:32:12 +01003292 ospf_refresher_unregister_lsa (ospf, lsa);
Paul Jakma02d942c2010-01-24 23:36:20 +00003293 ospf_lsa_flush (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003294 break;
3295 }
3296
3297 return 0;
3298}
3299
3300void
paul68980082003-03-25 05:07:42 +00003301ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003302{
paul1eb8ef22005-04-07 07:30:20 +00003303 struct listnode *node, *nnode;
3304 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003305 struct ospf_area *area;
3306 struct ospf_interface *oi;
3307 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003308 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003309 int need_to_flush_ase = 0;
3310
paul1eb8ef22005-04-07 07:30:20 +00003311 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003312 {
paul718e3742002-12-13 20:15:29 +00003313 if ((lsa = area->router_lsa_self) != NULL)
3314 {
3315 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003316 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3317 lsa->data->type, inet_ntoa (lsa->data->id));
3318
3319 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003320 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003321 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003322 area->router_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003323 }
3324
paul1eb8ef22005-04-07 07:30:20 +00003325 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003326 {
paul718e3742002-12-13 20:15:29 +00003327 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003328 && oi->state == ISM_DR
3329 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003330 {
3331 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003332 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3333 lsa->data->type, inet_ntoa (lsa->data->id));
3334
3335 ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003336 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003337 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003338 oi->network_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003339 }
3340
3341 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3342 && area->external_routing == OSPF_AREA_DEFAULT)
3343 need_to_flush_ase = 1;
3344 }
3345
paul68980082003-03-25 05:07:42 +00003346 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3347 ospf_lsa_flush_schedule (ospf, lsa);
3348 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3349 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003350#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003351 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3352 ospf_lsa_flush_schedule (ospf, lsa);
3353 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3354 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003355#endif /* HAVE_OPAQUE_LSA */
3356 }
3357
3358 if (need_to_flush_ase)
3359 {
paul68980082003-03-25 05:07:42 +00003360 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3361 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003362#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003363 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3364 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003365#endif /* HAVE_OPAQUE_LSA */
3366 }
3367
3368 /*
3369 * Make sure that the MaxAge LSA remover is executed immediately,
3370 * without conflicting to other threads.
3371 */
paul68980082003-03-25 05:07:42 +00003372 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003373 {
paul68980082003-03-25 05:07:42 +00003374 OSPF_TIMER_OFF (ospf->t_maxage);
3375 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003376 }
3377
3378 return;
3379}
3380#endif /* ORIGINAL_CODING */
3381
3382/* If there is self-originated LSA, then return 1, otherwise return 0. */
3383/* An interface-independent version of ospf_lsa_is_self_originated */
3384int
paul68980082003-03-25 05:07:42 +00003385ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003386{
hasso52dc7ee2004-09-23 19:18:23 +00003387 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003388 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003389
3390 /* This LSA is already checked. */
3391 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3392 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3393
3394 /* Make sure LSA is self-checked. */
3395 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3396
3397 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003398 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003399 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3400
3401 /* LSA is router-LSA. */
3402 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003403 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003404 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3405
3406 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3407 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003408 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003409 {
paul718e3742002-12-13 20:15:29 +00003410 /* Ignore virtual link. */
3411 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3412 if (oi->address->family == AF_INET)
3413 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3414 {
3415 /* to make it easier later */
3416 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3417 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3418 }
3419 }
3420
3421 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3422}
3423
3424/* Get unique Link State ID. */
3425struct in_addr
paul68980082003-03-25 05:07:42 +00003426ospf_lsa_unique_id (struct ospf *ospf,
3427 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003428{
3429 struct ospf_lsa *lsa;
3430 struct in_addr mask, id;
3431
3432 id = p->prefix;
3433
3434 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003435 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003436 if (lsa)
3437 {
3438 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3439 if (ip_masklen (al->mask) == p->prefixlen)
3440 {
3441 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003442 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003443 "Can't get Link State ID for %s/%d",
3444 inet_ntoa (p->prefix), p->prefixlen);
3445 /* id.s_addr = 0; */
3446 id.s_addr = 0xffffffff;
3447 return id;
3448 }
3449 /* Masklen differs, then apply wildcard mask to Link State ID. */
3450 else
3451 {
3452 masklen2ip (p->prefixlen, &mask);
3453
3454 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003455 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3456 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003457 if (lsa)
3458 {
3459 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003460 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003461 "Can't get Link State ID for %s/%d",
3462 inet_ntoa (p->prefix), p->prefixlen);
3463 /* id.s_addr = 0; */
3464 id.s_addr = 0xffffffff;
3465 return id;
3466 }
3467 }
3468 }
3469
3470 return id;
3471}
3472
3473
Paul Jakma70461d72006-05-12 22:57:57 +00003474#define LSA_ACTION_FLOOD_AREA 1
3475#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003476
3477struct lsa_action
3478{
3479 u_char action;
3480 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003481 struct ospf_lsa *lsa;
3482};
3483
paul4dadc292005-05-06 21:37:42 +00003484static int
paul718e3742002-12-13 20:15:29 +00003485ospf_lsa_action (struct thread *t)
3486{
3487 struct lsa_action *data;
3488
3489 data = THREAD_ARG (t);
3490
3491 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003492 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003493 data->action);
3494
3495 switch (data->action)
3496 {
paul718e3742002-12-13 20:15:29 +00003497 case LSA_ACTION_FLOOD_AREA:
3498 ospf_flood_through_area (data->area, NULL, data->lsa);
3499 break;
paul718e3742002-12-13 20:15:29 +00003500 case LSA_ACTION_FLUSH_AREA:
3501 ospf_lsa_flush_area (data->lsa, data->area);
3502 break;
paul718e3742002-12-13 20:15:29 +00003503 }
3504
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003505 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003506 XFREE (MTYPE_OSPF_MESSAGE, data);
3507 return 0;
3508}
3509
3510void
3511ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3512{
3513 struct lsa_action *data;
3514
Stephen Hemminger393deb92008-08-18 14:13:29 -07003515 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003516 data->action = LSA_ACTION_FLOOD_AREA;
3517 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003518 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003519
3520 thread_add_event (master, ospf_lsa_action, data, 0);
3521}
3522
3523void
3524ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3525{
3526 struct lsa_action *data;
3527
Stephen Hemminger393deb92008-08-18 14:13:29 -07003528 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003529 data->action = LSA_ACTION_FLUSH_AREA;
3530 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003531 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003532
3533 thread_add_event (master, ospf_lsa_action, data, 0);
3534}
3535
3536
3537/* LSA Refreshment functions. */
Paul Jakmac363d382010-01-24 22:42:13 +00003538struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00003539ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003540{
3541 struct external_info *ei;
Paul Jakmac363d382010-01-24 22:42:13 +00003542 struct ospf_lsa *new = NULL;
paul718e3742002-12-13 20:15:29 +00003543 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
Paul Jakma66349742010-04-13 22:33:54 +01003544 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003545
3546 switch (lsa->data->type)
3547 {
3548 /* Router and Network LSAs are processed differently. */
3549 case OSPF_ROUTER_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003550 new = ospf_router_lsa_refresh (lsa);
3551 break;
paul718e3742002-12-13 20:15:29 +00003552 case OSPF_NETWORK_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003553 new = ospf_network_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003554 break;
3555 case OSPF_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003556 new = ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003557 break;
3558 case OSPF_ASBR_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003559 new = ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003560 break;
3561 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003562 /* Translated from NSSA Type-5s are refreshed when
3563 * from refresh of Type-7 - do not refresh these directly.
3564 */
3565 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3566 break;
paul718e3742002-12-13 20:15:29 +00003567 ei = ospf_external_info_check (lsa);
3568 if (ei)
Paul Jakmac363d382010-01-24 22:42:13 +00003569 new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003570 else
pauld4a53d52003-07-12 21:30:57 +00003571 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003572 break;
3573#ifdef HAVE_OPAQUE_LSA
3574 case OSPF_OPAQUE_LINK_LSA:
3575 case OSPF_OPAQUE_AREA_LSA:
3576 case OSPF_OPAQUE_AS_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003577 new = ospf_opaque_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003578 break;
pauld7480322003-05-16 17:31:51 +00003579#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003580 default:
3581 break;
paul718e3742002-12-13 20:15:29 +00003582 }
Paul Jakmac363d382010-01-24 22:42:13 +00003583 return new;
paul718e3742002-12-13 20:15:29 +00003584}
3585
3586void
paul68980082003-03-25 05:07:42 +00003587ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003588{
3589 u_int16_t index, current_index;
3590
Paul Jakma66349742010-04-13 22:33:54 +01003591 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003592 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3593
3594 if (lsa->refresh_list < 0)
3595 {
3596 int delay;
3597
3598 if (LS_AGE (lsa) == 0 &&
3599 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3600 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3601 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3602 else
3603 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3604 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3605 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3606
3607 if (delay < 0)
3608 delay = 0;
3609
Paul Jakmac363d382010-01-24 22:42:13 +00003610 current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL)
3611 - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003612
3613 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
Paul Jakmac363d382010-01-24 22:42:13 +00003614 % (OSPF_LSA_REFRESHER_SLOTS);
paul718e3742002-12-13 20:15:29 +00003615
3616 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003617 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003618 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003619 if (!ospf->lsa_refresh_queue.qs[index])
3620 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003621 listnode_add (ospf->lsa_refresh_queue.qs[index],
3622 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003623 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003624 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003625 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003626 "setting refresh_list on lsa %p (slod %d)",
3627 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003628 }
3629}
3630
3631void
paul68980082003-03-25 05:07:42 +00003632ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003633{
Paul Jakma66349742010-04-13 22:33:54 +01003634 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003635 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3636 if (lsa->refresh_list >= 0)
3637 {
hasso52dc7ee2004-09-23 19:18:23 +00003638 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003639 listnode_delete (refresh_list, lsa);
3640 if (!listcount (refresh_list))
3641 {
3642 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003643 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003644 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003645 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003646 lsa->refresh_list = -1;
3647 }
3648}
3649
3650int
3651ospf_lsa_refresh_walker (struct thread *t)
3652{
hasso52dc7ee2004-09-23 19:18:23 +00003653 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003654 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003655 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003656 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003657 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003658 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003659
3660 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003661 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003662
3663
paul68980082003-03-25 05:07:42 +00003664 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003665
ajs9dbc7972005-03-13 19:27:22 +00003666 /* Note: if clock has jumped backwards, then time change could be negative,
3667 so we are careful to cast the expression to unsigned before taking
3668 modulus. */
paul68980082003-03-25 05:07:42 +00003669 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003670 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakmac363d382010-01-24 22:42:13 +00003671 (quagga_time (NULL) - ospf->lsa_refresher_started)
3672 / OSPF_LSA_REFRESHER_GRANULARITY))
3673 % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003674
3675 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003676 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003677 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003678
paul68980082003-03-25 05:07:42 +00003679 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003680 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3681 {
3682 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003683 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003684 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003685
paul68980082003-03-25 05:07:42 +00003686 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003687
Paul Jakma66349742010-04-13 22:33:54 +01003688 assert (i >= 0);
3689
paul68980082003-03-25 05:07:42 +00003690 ospf->lsa_refresh_queue.qs [i] = NULL;
3691
paul718e3742002-12-13 20:15:29 +00003692 if (refresh_list)
3693 {
paul1eb8ef22005-04-07 07:30:20 +00003694 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003695 {
paul718e3742002-12-13 20:15:29 +00003696 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003697 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003698 "refresh lsa %p (slot %d)",
3699 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003700
Paul Jakma66349742010-04-13 22:33:54 +01003701 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003702 list_delete_node (refresh_list, node);
paul718e3742002-12-13 20:15:29 +00003703 lsa->refresh_list = -1;
3704 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003705 }
3706 list_free (refresh_list);
3707 }
3708 }
3709
paul68980082003-03-25 05:07:42 +00003710 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3711 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003712 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003713
paul1eb8ef22005-04-07 07:30:20 +00003714 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
Paul Jakma66349742010-04-13 22:33:54 +01003715 {
3716 ospf_lsa_refresh (ospf, lsa);
3717 assert (lsa->lock > 0);
3718 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
3719 }
paul718e3742002-12-13 20:15:29 +00003720
3721 list_delete (lsa_to_refresh);
3722
3723 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003724 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003725
3726 return 0;
3727}
3728