blob: 493209a0bbfe75db25aa04eb05496c73fd3f5363 [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 {
Joakim Tjernlundc81ee5c2012-07-07 17:06:11 +0200673 oi->lsa_pos_beg = links;
paul718e3742002-12-13 20:15:29 +0000674 /* Describe each link. */
675 switch (oi->type)
676 {
677 case OSPF_IFTYPE_POINTOPOINT:
678 links += lsa_link_ptop_set (s, oi);
679 break;
680 case OSPF_IFTYPE_BROADCAST:
681 links += lsa_link_broadcast_set (s, oi);
682 break;
683 case OSPF_IFTYPE_NBMA:
684 links += lsa_link_nbma_set (s, oi);
685 break;
686 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000687 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000688 break;
689 case OSPF_IFTYPE_VIRTUALLINK:
690 links += lsa_link_virtuallink_set (s, oi);
691 break;
692 case OSPF_IFTYPE_LOOPBACK:
693 links += lsa_link_loopback_set (s, oi);
694 }
Joakim Tjernlundc81ee5c2012-07-07 17:06:11 +0200695 oi->lsa_pos_end = links;
paul718e3742002-12-13 20:15:29 +0000696 }
697 }
698 }
699
700 return links;
701}
702
703/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000704static void
paul718e3742002-12-13 20:15:29 +0000705ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
706{
707 unsigned long putp;
708 u_int16_t cnt;
709
710 /* Set flags. */
711 stream_putc (s, router_lsa_flags (area));
712
713 /* Set Zero fields. */
714 stream_putc (s, 0);
715
716 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000717 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000718
719 /* Forward word */
720 stream_putw(s, 0);
721
722 /* Set all link information. */
723 cnt = router_lsa_link_set (s, area);
724
725 /* Set # of links here. */
726 stream_putw_at (s, putp, cnt);
727}
paul88d6cf32005-10-29 12:50:09 +0000728
729static int
730ospf_stub_router_timer (struct thread *t)
731{
732 struct ospf_area *area = THREAD_ARG (t);
733
734 area->t_stub_router = NULL;
735
736 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
737
738 /* clear stub route state and generate router-lsa refresh, don't
739 * clobber an administratively set stub-router state though.
740 */
741 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
742 return 0;
743
744 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
745
Paul Jakmac363d382010-01-24 22:42:13 +0000746 ospf_router_lsa_update_area (area);
paul88d6cf32005-10-29 12:50:09 +0000747
748 return 0;
749}
paul718e3742002-12-13 20:15:29 +0000750
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100751static void
paul88d6cf32005-10-29 12:50:09 +0000752ospf_stub_router_check (struct ospf_area *area)
753{
754 /* area must either be administratively configured to be stub
755 * or startup-time stub-router must be configured and we must in a pre-stub
756 * state.
757 */
758 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
759 {
760 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
761 return;
762 }
763
764 /* not admin-stubbed, check whether startup stubbing is configured and
765 * whether it's not been done yet
766 */
767 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
768 return;
769
770 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
771 {
772 /* stub-router is hence done forever for this area, even if someone
773 * tries configure it (take effect next restart).
774 */
775 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
776 return;
777 }
778
779 /* startup stub-router configured and not yet done */
780 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
781
782 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
783 area->ospf->stub_router_startup_time);
784}
785
paul718e3742002-12-13 20:15:29 +0000786/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000787static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000788ospf_router_lsa_new (struct ospf_area *area)
789{
paul68980082003-03-25 05:07:42 +0000790 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000791 struct stream *s;
792 struct lsa_header *lsah;
793 struct ospf_lsa *new;
794 int length;
795
796 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000797 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000798
paul88d6cf32005-10-29 12:50:09 +0000799 /* check whether stub-router is desired, and if this is the first
800 * router LSA.
801 */
802 ospf_stub_router_check (area);
803
paul718e3742002-12-13 20:15:29 +0000804 /* Create a stream for LSA. */
805 s = stream_new (OSPF_MAX_LSA_SIZE);
paul718e3742002-12-13 20:15:29 +0000806 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000807 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000808 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000809
810 /* Set router-LSA body fields. */
811 ospf_router_lsa_body_set (s, area);
812
813 /* Set length. */
814 length = stream_get_endp (s);
paul779adb02006-01-18 15:07:38 +0000815 lsah = (struct lsa_header *) STREAM_DATA (s);
paul718e3742002-12-13 20:15:29 +0000816 lsah->length = htons (length);
817
818 /* Now, create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000819 if ( (new = ospf_lsa_new ()) == NULL)
820 {
821 zlog_err ("%s: Unable to create new lsa", __func__);
822 return NULL;
823 }
824
paul718e3742002-12-13 20:15:29 +0000825 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +0000826 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +0000827
828 /* Copy LSA data to store, discard stream. */
829 new->data = ospf_lsa_data_new (length);
830 memcpy (new->data, lsah, length);
831 stream_free (s);
832
833 return new;
834}
835
836/* Originate Router-LSA. */
paul88d6cf32005-10-29 12:50:09 +0000837static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000838ospf_router_lsa_originate (struct ospf_area *area)
839{
840 struct ospf_lsa *new;
paul88d6cf32005-10-29 12:50:09 +0000841
paul718e3742002-12-13 20:15:29 +0000842 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000843 if ( (new = ospf_router_lsa_new (area)) == NULL)
844 {
845 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
846 return NULL;
847 }
paul718e3742002-12-13 20:15:29 +0000848
849 /* Sanity check. */
850 if (new->data->adv_router.s_addr == 0)
851 {
852 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000853 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000854 ospf_lsa_discard (new);
855 return NULL;
856 }
857
858 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000859 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000860
861 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000862 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000863
864 /* Flooding new LSA through area. */
865 ospf_flood_through_area (area, NULL, new);
866
867 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
868 {
ajse588f212004-12-08 18:12:06 +0000869 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
paul718e3742002-12-13 20:15:29 +0000870 new->data->type, inet_ntoa (new->data->id), new);
871 ospf_lsa_header_dump (new->data);
872 }
873
874 return new;
875}
876
877/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000878static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000879ospf_router_lsa_refresh (struct ospf_lsa *lsa)
880{
881 struct ospf_area *area = lsa->area;
882 struct ospf_lsa *new;
883
884 /* Sanity check. */
885 assert (lsa->data);
886
887 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000888 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000889
Paul Jakmac363d382010-01-24 22:42:13 +0000890 /* Unregister LSA from refresh-list */
891 ospf_refresher_unregister_lsa (area->ospf, lsa);
892
paul718e3742002-12-13 20:15:29 +0000893 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000894 if ( (new = ospf_router_lsa_new (area)) == NULL)
895 {
896 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
897 return NULL;
898 }
899
paul718e3742002-12-13 20:15:29 +0000900 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
901
paul68980082003-03-25 05:07:42 +0000902 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000903
904 /* Flood LSA through area. */
905 ospf_flood_through_area (area, NULL, new);
906
907 /* Debug logging. */
908 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
909 {
ajse588f212004-12-08 18:12:06 +0000910 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000911 new->data->type, inet_ntoa (new->data->id));
912 ospf_lsa_header_dump (new->data);
913 }
914
915 return NULL;
916}
917
Paul Jakmac363d382010-01-24 22:42:13 +0000918int
919ospf_router_lsa_update_area (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000920{
paul718e3742002-12-13 20:15:29 +0000921 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmac363d382010-01-24 22:42:13 +0000922 zlog_debug ("[router-LSA]: (router-LSA area update)");
paul718e3742002-12-13 20:15:29 +0000923
924 /* Now refresh router-LSA. */
925 if (area->router_lsa_self)
Paul Jakmac363d382010-01-24 22:42:13 +0000926 ospf_lsa_refresh (area->ospf, area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000927 /* Newly originate router-LSA. */
928 else
929 ospf_router_lsa_originate (area);
930
931 return 0;
932}
933
paul718e3742002-12-13 20:15:29 +0000934int
Paul Jakmac363d382010-01-24 22:42:13 +0000935ospf_router_lsa_update (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000936{
paul1eb8ef22005-04-07 07:30:20 +0000937 struct listnode *node, *nnode;
938 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +0000939
940 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000941 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +0000942
paul1eb8ef22005-04-07 07:30:20 +0000943 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000944 {
paul718e3742002-12-13 20:15:29 +0000945 struct ospf_lsa *lsa = area->router_lsa_self;
946 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +0000947 const char *area_str;
paul718e3742002-12-13 20:15:29 +0000948
949 /* Keep Area ID string. */
950 area_str = AREA_NAME (area);
951
952 /* If LSA not exist in this Area, originate new. */
953 if (lsa == NULL)
954 {
955 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000956 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +0000957
958 ospf_router_lsa_originate (area);
959 }
960 /* If router-ID is changed, Link ID must change.
961 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +0000962 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000963 {
964 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000965 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +0000966 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
Paul Jakmadfbd5172010-04-14 10:32:12 +0100967 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +0000968 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000969 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000970 area->router_lsa_self = NULL;
971
972 /* Refresh router-LSA, (not install) and flood through area. */
Paul Jakmac363d382010-01-24 22:42:13 +0000973 ospf_router_lsa_update_area (area);
paul718e3742002-12-13 20:15:29 +0000974 }
975 else
976 {
977 rl = (struct router_lsa *) lsa->data;
978 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +0000979 if (rl->flags != ospf->flags)
Paul Jakmac363d382010-01-24 22:42:13 +0000980 ospf_router_lsa_update_area (area);
paul718e3742002-12-13 20:15:29 +0000981 }
982 }
983
984 return 0;
985}
986
987
988/* network-LSA related functions. */
989/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +0000990static void
paul718e3742002-12-13 20:15:29 +0000991ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
992{
993 struct in_addr mask;
994 struct route_node *rn;
995 struct ospf_neighbor *nbr;
996
997 masklen2ip (oi->address->prefixlen, &mask);
998 stream_put_ipv4 (s, mask.s_addr);
999
1000 /* The network-LSA lists those routers that are fully adjacent to
1001 the Designated Router; each fully adjacent router is identified by
1002 its OSPF Router ID. The Designated Router includes itself in this
1003 list. RFC2328, Section 12.4.2 */
1004
1005 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1006 if ((nbr = rn->info) != NULL)
1007 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1008 stream_put_ipv4 (s, nbr->router_id.s_addr);
1009}
1010
paul4dadc292005-05-06 21:37:42 +00001011static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001012ospf_network_lsa_new (struct ospf_interface *oi)
1013{
1014 struct stream *s;
1015 struct ospf_lsa *new;
1016 struct lsa_header *lsah;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001017 struct ospf_if_params *oip;
paul718e3742002-12-13 20:15:29 +00001018 int length;
1019
1020 /* If there are no neighbours on this network (the net is stub),
1021 the router does not originate network-LSA (see RFC 12.4.2) */
1022 if (oi->full_nbrs == 0)
1023 return NULL;
1024
1025 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001026 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001027
1028 /* Create new stream for LSA. */
1029 s = stream_new (OSPF_MAX_LSA_SIZE);
1030 lsah = (struct lsa_header *) STREAM_DATA (s);
1031
1032 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001033 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001034
1035 /* Set network-LSA body fields. */
1036 ospf_network_lsa_body_set (s, oi);
1037
1038 /* Set length. */
1039 length = stream_get_endp (s);
1040 lsah->length = htons (length);
1041
1042 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001043 if ( (new = ospf_lsa_new ()) == NULL)
1044 {
1045 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1046 return NULL;
1047 }
1048
paul718e3742002-12-13 20:15:29 +00001049 new->area = oi->area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001050 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001051
1052 /* Copy LSA to store. */
1053 new->data = ospf_lsa_data_new (length);
1054 memcpy (new->data, lsah, length);
1055 stream_free (s);
Paul Jakma7eb5b472009-10-13 16:13:13 +01001056
1057 /* Remember prior network LSA sequence numbers, even if we stop
1058 * originating one for this oi, to try avoid re-originating LSAs with a
1059 * prior sequence number, and thus speed up adjency forming & convergence.
1060 */
1061 if ((oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4)))
1062 {
1063 new->data->ls_seqnum = oip->network_lsa_seqnum;
1064 new->data->ls_seqnum = lsa_seqnum_increment (new);
1065 }
1066 else
1067 {
1068 oip = ospf_get_if_params (oi->ifp, oi->address->u.prefix4);
1069 ospf_if_update_params (oi->ifp, oi->address->u.prefix4);
1070 }
1071 oip->network_lsa_seqnum = new->data->ls_seqnum;
1072
paul718e3742002-12-13 20:15:29 +00001073 return new;
1074}
1075
1076/* Originate network-LSA. */
Paul Jakmac363d382010-01-24 22:42:13 +00001077void
1078ospf_network_lsa_update (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001079{
1080 struct ospf_lsa *new;
Paul Jakmac363d382010-01-24 22:42:13 +00001081
1082 if (oi->network_lsa_self != NULL)
1083 {
1084 ospf_lsa_refresh (oi->ospf, oi->network_lsa_self);
1085 return;
1086 }
1087
paul718e3742002-12-13 20:15:29 +00001088 /* Create new network-LSA instance. */
1089 new = ospf_network_lsa_new (oi);
1090 if (new == NULL)
Paul Jakmac363d382010-01-24 22:42:13 +00001091 return;
paul718e3742002-12-13 20:15:29 +00001092
1093 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001094 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001095
1096 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001097 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001098
1099 /* Flooding new LSA through area. */
1100 ospf_flood_through_area (oi->area, NULL, new);
1101
1102 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1103 {
ajse588f212004-12-08 18:12:06 +00001104 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001105 new->data->type, inet_ntoa (new->data->id), new);
1106 ospf_lsa_header_dump (new->data);
1107 }
1108
Paul Jakmac363d382010-01-24 22:42:13 +00001109 return;
paul718e3742002-12-13 20:15:29 +00001110}
1111
Paul Jakmac363d382010-01-24 22:42:13 +00001112static struct ospf_lsa *
1113ospf_network_lsa_refresh (struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001114{
1115 struct ospf_area *area = lsa->area;
Paul Jakmac363d382010-01-24 22:42:13 +00001116 struct ospf_lsa *new, *new2;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001117 struct ospf_if_params *oip;
Paul Jakma4dd87df2010-04-15 08:11:51 +01001118 struct ospf_interface *oi;
Paul Jakmac363d382010-01-24 22:42:13 +00001119
paul718e3742002-12-13 20:15:29 +00001120 assert (lsa->data);
Paul Jakma4dd87df2010-04-15 08:11:51 +01001121
1122 /* Retrieve the oi for the network LSA */
1123 oi = ospf_if_lookup_by_local_addr (area->ospf, NULL, lsa->data->id);
1124 if (oi == NULL)
1125 {
1126 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1127 {
1128 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh: "
1129 "no oi found, ick, ignoring.",
1130 lsa->data->type, inet_ntoa (lsa->data->id));
1131 ospf_lsa_header_dump (lsa->data);
1132 }
1133 return NULL;
1134 }
paul718e3742002-12-13 20:15:29 +00001135 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001136 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001137
Paul Jakmac363d382010-01-24 22:42:13 +00001138 /* Unregister LSA from refresh-list */
1139 ospf_refresher_unregister_lsa (area->ospf, lsa);
1140
paul718e3742002-12-13 20:15:29 +00001141 /* Create new network-LSA instance. */
1142 new = ospf_network_lsa_new (oi);
1143 if (new == NULL)
Paul Jakmac363d382010-01-24 22:42:13 +00001144 return NULL;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001145
1146 oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4);
1147 assert (oip != NULL);
1148 oip->network_lsa_seqnum = new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001149
Paul Jakmac363d382010-01-24 22:42:13 +00001150 new2 = ospf_lsa_install (area->ospf, oi, new);
1151
1152 assert (new2 == new);
1153
paul718e3742002-12-13 20:15:29 +00001154 /* Flood LSA through aera. */
1155 ospf_flood_through_area (area, NULL, new);
1156
1157 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1158 {
ajse588f212004-12-08 18:12:06 +00001159 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001160 new->data->type, inet_ntoa (new->data->id));
1161 ospf_lsa_header_dump (new->data);
1162 }
1163
Paul Jakmac363d382010-01-24 22:42:13 +00001164 return new;
paul718e3742002-12-13 20:15:29 +00001165}
paul718e3742002-12-13 20:15:29 +00001166
paul4dadc292005-05-06 21:37:42 +00001167static void
paul718e3742002-12-13 20:15:29 +00001168stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1169{
1170 u_int32_t metric;
1171 char *mp;
1172
1173 /* Put 0 metric. TOS metric is not supported. */
1174 metric = htonl (metric_value);
1175 mp = (char *) &metric;
1176 mp++;
1177 stream_put (s, mp, 3);
1178}
1179
1180/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001181static void
paul718e3742002-12-13 20:15:29 +00001182ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1183 u_int32_t metric)
1184{
1185 struct in_addr mask;
1186
1187 masklen2ip (p->prefixlen, &mask);
1188
1189 /* Put Network Mask. */
1190 stream_put_ipv4 (s, mask.s_addr);
1191
1192 /* Set # TOS. */
1193 stream_putc (s, (u_char) 0);
1194
1195 /* Set metric. */
1196 stream_put_ospf_metric (s, metric);
1197}
1198
paul4dadc292005-05-06 21:37:42 +00001199static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001200ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1201 u_int32_t metric, struct in_addr id)
1202{
1203 struct stream *s;
1204 struct ospf_lsa *new;
1205 struct lsa_header *lsah;
1206 int length;
1207
paulc24d6022005-11-20 14:54:12 +00001208 if (id.s_addr == 0xffffffff)
1209 {
1210 /* Maybe Link State ID not available. */
1211 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1212 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1213 OSPF_SUMMARY_LSA);
1214 return NULL;
1215 }
1216
paul718e3742002-12-13 20:15:29 +00001217 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001218 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001219
1220 /* Create new stream for LSA. */
1221 s = stream_new (OSPF_MAX_LSA_SIZE);
1222 lsah = (struct lsa_header *) STREAM_DATA (s);
1223
paul68980082003-03-25 05:07:42 +00001224 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1225 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001226
1227 /* Set summary-LSA body fields. */
1228 ospf_summary_lsa_body_set (s, p, metric);
1229
1230 /* Set length. */
1231 length = stream_get_endp (s);
1232 lsah->length = htons (length);
1233
1234 /* Create OSPF LSA instance. */
1235 new = ospf_lsa_new ();
1236 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001237 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001238
1239 /* Copy LSA to store. */
1240 new->data = ospf_lsa_data_new (length);
1241 memcpy (new->data, lsah, length);
1242 stream_free (s);
1243
1244 return new;
1245}
1246
1247/* Originate Summary-LSA. */
1248struct ospf_lsa *
1249ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1250 struct ospf_area *area)
1251{
1252 struct ospf_lsa *new;
1253 struct in_addr id;
1254
paul68980082003-03-25 05:07:42 +00001255 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001256
paulc24d6022005-11-20 14:54:12 +00001257 if (id.s_addr == 0xffffffff)
1258 {
1259 /* Maybe Link State ID not available. */
1260 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1261 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1262 OSPF_SUMMARY_LSA);
1263 return NULL;
1264 }
1265
paul718e3742002-12-13 20:15:29 +00001266 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001267 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1268 return NULL;
paul718e3742002-12-13 20:15:29 +00001269
1270 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001271 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001272
1273 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001274 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001275
1276 /* Flooding new LSA through area. */
1277 ospf_flood_through_area (area, NULL, new);
1278
1279 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1280 {
ajse588f212004-12-08 18:12:06 +00001281 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001282 new->data->type, inet_ntoa (new->data->id), new);
1283 ospf_lsa_header_dump (new->data);
1284 }
1285
1286 return new;
1287}
1288
Paul Jakmac363d382010-01-24 22:42:13 +00001289static struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001290ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001291{
1292 struct ospf_lsa *new;
1293 struct summary_lsa *sl;
1294 struct prefix p;
1295
1296 /* Sanity check. */
1297 assert (lsa->data);
1298
1299 sl = (struct summary_lsa *)lsa->data;
1300 p.prefixlen = ip_masklen (sl->mask);
1301 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1302 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001303
1304 if (!new)
1305 return NULL;
1306
paul718e3742002-12-13 20:15:29 +00001307 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001308
paul68980082003-03-25 05:07:42 +00001309 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001310
1311 /* Flood LSA through AS. */
1312 ospf_flood_through_area (new->area, NULL, new);
1313
1314 /* Debug logging. */
1315 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1316 {
ajse588f212004-12-08 18:12:06 +00001317 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001318 new->data->type, inet_ntoa (new->data->id));
1319 ospf_lsa_header_dump (new->data);
1320 }
1321
1322 return new;
1323}
1324
1325
1326/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001327static void
paul718e3742002-12-13 20:15:29 +00001328ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1329 u_int32_t metric)
1330{
1331 struct in_addr mask;
1332
1333 masklen2ip (p->prefixlen, &mask);
1334
1335 /* Put Network Mask. */
1336 stream_put_ipv4 (s, mask.s_addr);
1337
1338 /* Set # TOS. */
1339 stream_putc (s, (u_char) 0);
1340
1341 /* Set metric. */
1342 stream_put_ospf_metric (s, metric);
1343}
1344
paul4dadc292005-05-06 21:37:42 +00001345static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001346ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1347 u_int32_t metric, struct in_addr id)
1348{
1349 struct stream *s;
1350 struct ospf_lsa *new;
1351 struct lsa_header *lsah;
1352 int length;
1353
paulc24d6022005-11-20 14:54:12 +00001354 if (id.s_addr == 0xffffffff)
1355 {
1356 /* Maybe Link State ID not available. */
1357 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1358 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1359 OSPF_ASBR_SUMMARY_LSA);
1360 return NULL;
1361 }
1362
paul718e3742002-12-13 20:15:29 +00001363 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001364 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001365
1366 /* Create new stream for LSA. */
1367 s = stream_new (OSPF_MAX_LSA_SIZE);
1368 lsah = (struct lsa_header *) STREAM_DATA (s);
1369
paul68980082003-03-25 05:07:42 +00001370 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1371 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001372
1373 /* Set summary-LSA body fields. */
1374 ospf_summary_asbr_lsa_body_set (s, p, metric);
1375
1376 /* Set length. */
1377 length = stream_get_endp (s);
1378 lsah->length = htons (length);
1379
1380 /* Create OSPF LSA instance. */
1381 new = ospf_lsa_new ();
1382 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001383 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001384
1385 /* Copy LSA to store. */
1386 new->data = ospf_lsa_data_new (length);
1387 memcpy (new->data, lsah, length);
1388 stream_free (s);
1389
1390 return new;
1391}
1392
1393/* Originate summary-ASBR-LSA. */
1394struct ospf_lsa *
1395ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1396 struct ospf_area *area)
1397{
1398 struct ospf_lsa *new;
1399 struct in_addr id;
1400
paul68980082003-03-25 05:07:42 +00001401 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001402
paulc24d6022005-11-20 14:54:12 +00001403 if (id.s_addr == 0xffffffff)
1404 {
1405 /* Maybe Link State ID not available. */
1406 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1407 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1408 OSPF_ASBR_SUMMARY_LSA);
1409 return NULL;
1410 }
1411
paul718e3742002-12-13 20:15:29 +00001412 /* Create new summary-LSA instance. */
1413 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001414 if (!new)
1415 return NULL;
paul718e3742002-12-13 20:15:29 +00001416
1417 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001418 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001419
1420 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001421 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001422
1423 /* Flooding new LSA through area. */
1424 ospf_flood_through_area (area, NULL, new);
1425
1426 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1427 {
ajse588f212004-12-08 18:12:06 +00001428 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001429 new->data->type, inet_ntoa (new->data->id), new);
1430 ospf_lsa_header_dump (new->data);
1431 }
1432
1433 return new;
1434}
1435
Paul Jakmac363d382010-01-24 22:42:13 +00001436static struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001437ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001438{
1439 struct ospf_lsa *new;
1440 struct summary_lsa *sl;
1441 struct prefix p;
1442
1443 /* Sanity check. */
1444 assert (lsa->data);
1445
1446 sl = (struct summary_lsa *)lsa->data;
1447 p.prefixlen = ip_masklen (sl->mask);
1448 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1449 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001450 if (!new)
1451 return NULL;
paul718e3742002-12-13 20:15:29 +00001452
1453 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001454
paul68980082003-03-25 05:07:42 +00001455 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001456
1457 /* Flood LSA through area. */
1458 ospf_flood_through_area (new->area, NULL, new);
1459
1460 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1461 {
ajse588f212004-12-08 18:12:06 +00001462 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001463 new->data->type, inet_ntoa (new->data->id));
1464 ospf_lsa_header_dump (new->data);
1465 }
1466
1467 return new;
1468}
1469
1470/* AS-external-LSA related functions. */
1471
1472/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1473 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001474static struct in_addr
paul68980082003-03-25 05:07:42 +00001475ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001476{
1477 struct in_addr fwd;
1478 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001479 struct listnode *node;
1480 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001481
1482 fwd.s_addr = 0;
1483
1484 if (!nexthop.s_addr)
1485 return fwd;
1486
1487 /* Check whether nexthop is covered by OSPF network. */
1488 nh.family = AF_INET;
1489 nh.u.prefix4 = nexthop;
1490 nh.prefixlen = IPV4_MAX_BITLEN;
Paul Jakma4ca15d42009-08-03 15:16:41 +01001491
1492 /* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be
1493 * better to make use of the per-ifp table of ois.
1494 */
paul1eb8ef22005-04-07 07:30:20 +00001495 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1496 if (if_is_operative (oi->ifp))
1497 if (oi->address->family == AF_INET)
1498 if (prefix_match (oi->address, &nh))
1499 return nexthop;
paul718e3742002-12-13 20:15:29 +00001500
1501 return fwd;
1502}
1503
paul718e3742002-12-13 20:15:29 +00001504/* NSSA-external-LSA related functions. */
1505
1506/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001507
paul718e3742002-12-13 20:15:29 +00001508struct in_addr
1509ospf_get_ip_from_ifp (struct ospf_interface *oi)
1510{
1511 struct in_addr fwd;
1512
1513 fwd.s_addr = 0;
1514
paul2e3b2e42002-12-13 21:03:13 +00001515 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001516 return oi->address->u.prefix4;
1517
1518 return fwd;
1519}
1520
1521/* Get 1st IP connection for Forward Addr */
1522struct in_addr
paulf2c80652002-12-13 21:44:27 +00001523ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001524{
1525 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001526 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001527 struct listnode *node;
1528 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001529
1530 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001531 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001532
paul1eb8ef22005-04-07 07:30:20 +00001533 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001534 {
paul2e3b2e42002-12-13 21:03:13 +00001535 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001536 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001537 if (oi->address && oi->address->family == AF_INET)
1538 {
1539 if (best_default.s_addr == 0)
1540 best_default = oi->address->u.prefix4;
1541 if (oi->area == area)
1542 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001543 }
paul718e3742002-12-13 20:15:29 +00001544 }
paulf2c80652002-12-13 21:44:27 +00001545 if (best_default.s_addr != 0)
1546 return best_default;
paul718e3742002-12-13 20:15:29 +00001547
paul68980082003-03-25 05:07:42 +00001548 if (best_default.s_addr != 0)
1549 return best_default;
1550
paul718e3742002-12-13 20:15:29 +00001551 return fwd;
1552}
hassobeebba72004-06-20 21:00:27 +00001553
paul718e3742002-12-13 20:15:29 +00001554#define DEFAULT_DEFAULT_METRIC 20
1555#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1556#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1557
1558#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1559
1560int
paul68980082003-03-25 05:07:42 +00001561metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001562{
paul68980082003-03-25 05:07:42 +00001563 return (ospf->dmetric[src].type < 0 ?
1564 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001565}
1566
1567int
paul68980082003-03-25 05:07:42 +00001568metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001569{
paul68980082003-03-25 05:07:42 +00001570 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001571 {
1572 if (src == DEFAULT_ROUTE)
1573 {
paul68980082003-03-25 05:07:42 +00001574 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001575 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1576 else
1577 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1578 }
paul68980082003-03-25 05:07:42 +00001579 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001580 return DEFAULT_DEFAULT_METRIC;
1581 else
paul68980082003-03-25 05:07:42 +00001582 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001583 }
1584
paul68980082003-03-25 05:07:42 +00001585 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001586}
1587
1588/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001589static void
paul68980082003-03-25 05:07:42 +00001590ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1591 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001592{
1593 struct prefix_ipv4 *p = &ei->p;
1594 struct in_addr mask, fwd_addr;
1595 u_int32_t mvalue;
1596 int mtype;
1597 int type;
1598
1599 /* Put Network Mask. */
1600 masklen2ip (p->prefixlen, &mask);
1601 stream_put_ipv4 (s, mask.s_addr);
1602
1603 /* If prefix is default, specify DEFAULT_ROUTE. */
1604 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1605
1606 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001607 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001608
1609 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001610 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001611
1612 /* Put type of external metric. */
1613 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1614
1615 /* Put 0 metric. TOS metric is not supported. */
1616 stream_put_ospf_metric (s, mvalue);
1617
1618 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001619 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001620
1621 /* Put forwarding address. */
1622 stream_put_ipv4 (s, fwd_addr.s_addr);
1623
1624 /* Put route tag -- This value should be introduced from configuration. */
1625 stream_putl (s, 0);
1626}
1627
1628/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001629static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001630ospf_external_lsa_new (struct ospf *ospf,
1631 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001632{
1633 struct stream *s;
1634 struct lsa_header *lsah;
1635 struct ospf_lsa *new;
1636 struct in_addr id;
1637 int length;
1638
1639 if (ei == NULL)
1640 {
1641 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
Denis Ovsienkoad8d4802011-12-02 20:02:40 +04001642 zlog_debug ("LSA[Type5]: External info is NULL, can't originate");
paul718e3742002-12-13 20:15:29 +00001643 return NULL;
1644 }
1645
1646 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001647 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001648
1649 /* If old Link State ID is specified, refresh LSA with same ID. */
1650 if (old_id)
1651 id = *old_id;
1652 /* Get Link State with unique ID. */
1653 else
1654 {
paul68980082003-03-25 05:07:42 +00001655 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001656 if (id.s_addr == 0xffffffff)
1657 {
1658 /* Maybe Link State ID not available. */
1659 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001660 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001661 return NULL;
1662 }
1663 }
1664
1665 /* Create new stream for LSA. */
1666 s = stream_new (OSPF_MAX_LSA_SIZE);
1667 lsah = (struct lsa_header *) STREAM_DATA (s);
1668
1669 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001670 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1671 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001672
1673 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001674 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001675
1676 /* Set length. */
1677 length = stream_get_endp (s);
1678 lsah->length = htons (length);
1679
1680 /* Now, create OSPF LSA instance. */
1681 new = ospf_lsa_new ();
1682 new->area = NULL;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001683 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001684
1685 /* Copy LSA data to store, discard stream. */
1686 new->data = ospf_lsa_data_new (length);
1687 memcpy (new->data, lsah, length);
1688 stream_free (s);
1689
1690 return new;
1691}
1692
paul718e3742002-12-13 20:15:29 +00001693/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001694static void
paul68980082003-03-25 05:07:42 +00001695ospf_install_flood_nssa (struct ospf *ospf,
1696 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001697{
pauld4a53d52003-07-12 21:30:57 +00001698 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001699 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001700 struct ospf_area *area;
1701 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001702
pauld4a53d52003-07-12 21:30:57 +00001703 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1704 * which originated from an NSSA area. In which case it should not be
1705 * flooded back to NSSA areas.
1706 */
1707 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1708 return;
1709
paul718e3742002-12-13 20:15:29 +00001710 /* NSSA Originate or Refresh (If anyNSSA)
1711
1712 LSA is self-originated. And just installed as Type-5.
1713 Additionally, install as Type-7 LSDB for every attached NSSA.
1714
1715 P-Bit controls which ABR performs translation to outside world; If
1716 we are an ABR....do not set the P-bit, because we send the Type-5,
1717 not as the ABR Translator, but as the ASBR owner within the AS!
1718
1719 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1720 elected ABR Translator will see the P-bit, Translate, and re-flood.
1721
1722 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1723 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1724
paul1eb8ef22005-04-07 07:30:20 +00001725 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001726 {
hasso0c14ad82003-07-03 08:36:02 +00001727 /* Don't install Type-7 LSA's into nonNSSA area */
1728 if (area->external_routing != OSPF_AREA_NSSA)
1729 continue;
paul718e3742002-12-13 20:15:29 +00001730
paul68980082003-03-25 05:07:42 +00001731 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001732 new = ospf_lsa_dup (lsa);
1733 new->area = area;
1734 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001735
paul68980082003-03-25 05:07:42 +00001736 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001737 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001738 {
pauld4a53d52003-07-12 21:30:57 +00001739 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001740
1741 /* set non-zero FWD ADDR
1742
1743 draft-ietf-ospf-nssa-update-09.txt
1744
1745 if the network between the NSSA AS boundary router and the
1746 adjacent AS is advertised into OSPF as an internal OSPF route,
1747 the forwarding address should be the next op address as is cu
1748 currently done with type-5 LSAs. If the intervening network is
1749 not adversited into OSPF as an internal OSPF route and the
1750 type-7 LSA's P-bit is set a forwarding address should be
1751 selected from one of the router's active OSPF inteface addresses
1752 which belong to the NSSA. If no such addresses exist, then
1753 no type-7 LSA's with the P-bit set should originate from this
1754 router. */
1755
pauld4a53d52003-07-12 21:30:57 +00001756 /* kevinm: not updating lsa anymore, just new */
1757 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001758
1759 if (extlsa->e[0].fwd_addr.s_addr == 0)
1760 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001761
pauld7480322003-05-16 17:31:51 +00001762 if (extlsa->e[0].fwd_addr.s_addr == 0)
1763 {
1764 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001765 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001766 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001767 return;
1768 }
paulf2c80652002-12-13 21:44:27 +00001769 }
paul718e3742002-12-13 20:15:29 +00001770
paul68980082003-03-25 05:07:42 +00001771 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001772 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001773
1774 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001775 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001776 }
paul718e3742002-12-13 20:15:29 +00001777}
pauld4a53d52003-07-12 21:30:57 +00001778
paul4dadc292005-05-06 21:37:42 +00001779static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001780ospf_lsa_translated_nssa_new (struct ospf *ospf,
1781 struct ospf_lsa *type7)
1782{
1783
1784 struct ospf_lsa *new;
1785 struct as_external_lsa *ext, *extnew;
1786 struct external_info ei;
1787
1788 ext = (struct as_external_lsa *)(type7->data);
1789
1790 /* need external_info struct, fill in bare minimum */
1791 ei.p.family = AF_INET;
1792 ei.p.prefix = type7->data->id;
1793 ei.p.prefixlen = ip_masklen (ext->mask);
1794 ei.type = ZEBRA_ROUTE_OSPF;
1795 ei.nexthop = ext->header.adv_router;
1796 ei.route_map_set.metric = -1;
1797 ei.route_map_set.metric_type = -1;
1798 ei.tag = 0;
1799
1800 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1801 {
1802 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001803 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001804 "Translated Type-5 for %s",
1805 inet_ntoa (ei.p.prefix));
1806 return NULL;
1807 }
1808
1809 extnew = (struct as_external_lsa *)(new->data);
1810
1811 /* copy over Type-7 data to new */
1812 extnew->e[0].tos = ext->e[0].tos;
1813 extnew->e[0].route_tag = ext->e[0].route_tag;
1814 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1815 new->data->ls_seqnum = type7->data->ls_seqnum;
1816
1817 /* add translated flag, checksum and lock new lsa */
1818 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
pauld4a53d52003-07-12 21:30:57 +00001819 new = ospf_lsa_lock (new);
1820
1821 return new;
1822}
1823
pauld4a53d52003-07-12 21:30:57 +00001824/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1825struct ospf_lsa *
1826ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1827{
1828 struct ospf_lsa *new;
1829 struct as_external_lsa *extnew;
1830
1831 /* we cant use ospf_external_lsa_originate() as we need to set
1832 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1833 */
1834
1835 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1836 {
1837 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001838 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001839 "Type-7, Id %s, to Type-5",
1840 inet_ntoa (type7->data->id));
1841 return NULL;
1842 }
1843
1844 extnew = (struct as_external_lsa *)new;
1845
1846 if (IS_DEBUG_OSPF_NSSA)
1847 {
ajse588f212004-12-08 18:12:06 +00001848 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001849 "translated Type 7, installed:");
1850 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001851 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1852 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001853 }
1854
1855 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1856 {
1857 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001858 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001859 "Could not install LSA "
1860 "id %s", inet_ntoa (type7->data->id));
1861 return NULL;
1862 }
1863
1864 ospf->lsa_originate_count++;
1865 ospf_flood_through_as (ospf, NULL, new);
1866
1867 return new;
1868}
1869
1870/* Refresh Translated from NSSA AS-external-LSA. */
1871struct ospf_lsa *
1872ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1873 struct ospf_lsa *type5)
1874{
1875 struct ospf_lsa *new = NULL;
1876
1877 /* Sanity checks. */
1878 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00001879 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00001880 return NULL;
pauld4a53d52003-07-12 21:30:57 +00001881 if (type7)
1882 assert (type7->data);
1883 if (type5)
1884 assert (type5->data);
1885 assert (ospf->anyNSSA);
1886
1887 /* get required data according to what has been given */
1888 if (type7 && type5 == NULL)
1889 {
1890 /* find the translated Type-5 for this Type-7 */
1891 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1892 struct prefix_ipv4 p =
1893 {
1894 .prefix = type7->data->id,
1895 .prefixlen = ip_masklen (ext->mask),
1896 .family = AF_INET,
1897 };
1898
1899 type5 = ospf_external_info_find_lsa (ospf, &p);
1900 }
1901 else if (type5 && type7 == NULL)
1902 {
1903 /* find the type-7 from which supplied type-5 was translated,
1904 * ie find first type-7 with same LSA Id.
1905 */
paul1eb8ef22005-04-07 07:30:20 +00001906 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00001907 struct route_node *rn;
1908 struct ospf_lsa *lsa;
1909 struct ospf_area *area;
1910
paul1eb8ef22005-04-07 07:30:20 +00001911 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00001912 {
1913 if (area->external_routing != OSPF_AREA_NSSA
1914 && !type7)
1915 continue;
1916
1917 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
1918 {
1919 if (lsa->data->id.s_addr == type5->data->id.s_addr)
1920 {
1921 type7 = lsa;
1922 break;
1923 }
1924 }
1925 }
1926 }
1927
1928 /* do we have type7? */
1929 if (!type7)
1930 {
1931 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001932 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00001933 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00001934 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00001935 return NULL;
1936 }
1937
1938 /* do we have valid translated type5? */
1939 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
1940 {
1941 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001942 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00001943 "found for Type-7 with Id %s",
1944 inet_ntoa (type7->data->id));
1945 return NULL;
1946 }
1947
1948 /* Delete LSA from neighbor retransmit-list. */
1949 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
1950
1951 /* create new translated LSA */
1952 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1953 {
1954 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001955 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001956 "Type-7 for %s to Type-5",
1957 inet_ntoa (type7->data->id));
1958 return NULL;
1959 }
1960
1961 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
1962 {
1963 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001964 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00001965 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00001966 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00001967 return NULL;
1968 }
1969
1970 /* Flood LSA through area. */
1971 ospf_flood_through_as (ospf, NULL, new);
1972
1973 return new;
1974}
paul718e3742002-12-13 20:15:29 +00001975
1976int
1977is_prefix_default (struct prefix_ipv4 *p)
1978{
1979 struct prefix_ipv4 q;
1980
1981 q.family = AF_INET;
1982 q.prefix.s_addr = 0;
1983 q.prefixlen = 0;
1984
1985 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
1986}
1987
1988/* Originate an AS-external-LSA, install and flood. */
1989struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001990ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001991{
1992 struct ospf_lsa *new;
1993
1994 /* Added for NSSA project....
1995
1996 External LSAs are originated in ASBRs as usual, but for NSSA systems.
1997 there is the global Type-5 LSDB and a Type-7 LSDB installed for
1998 every area. The Type-7's are flooded to every IR and every ABR; We
1999 install the Type-5 LSDB so that the normal "refresh" code operates
2000 as usual, and flag them as not used during ASE calculations. The
2001 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2002 Address of non-zero.
2003
2004 If an ABR is the elected NSSA translator, following SPF and during
2005 the ABR task it will translate all the scanned Type-7's, with P-bit
2006 ON and not-self generated, and translate to Type-5's throughout the
2007 non-NSSA/STUB AS.
2008
2009 A difference in operation depends whether this ASBR is an ABR
2010 or not. If not an ABR, the P-bit is ON, to indicate that any
2011 elected NSSA-ABR can perform its translation.
2012
2013 If an ABR, the P-bit is OFF; No ABR will perform translation and
2014 this ASBR will flood the Type-5 LSA as usual.
2015
2016 For the case where this ASBR is not an ABR, the ASE calculations
2017 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2018 demonstrate to the user that there are LSA's that belong to any
2019 attached NSSA.
2020
2021 Finally, it just so happens that when the ABR is translating every
2022 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2023 approved Type-5 (translated from Type-7); at the end of translation
2024 if any Translated Type-5's remain unapproved, then they must be
2025 flushed from the AS.
2026
2027 */
2028
2029 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002030 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002031 return NULL;
2032
2033 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002034 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002035 {
2036 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002037 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002038 inet_ntoa (ei->p.prefix));
2039 return NULL;
2040 }
2041
2042 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002043 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002044
2045 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002046 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002047
2048 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002049 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002050
paul718e3742002-12-13 20:15:29 +00002051 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002052 if (ospf->anyNSSA &&
2053 /* stay away from translated LSAs! */
2054 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002055 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002056
2057 /* Debug logging. */
2058 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2059 {
ajse588f212004-12-08 18:12:06 +00002060 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002061 new->data->type, inet_ntoa (new->data->id), new);
2062 ospf_lsa_header_dump (new->data);
2063 }
2064
2065 return new;
2066}
2067
2068/* Originate AS-external-LSA from external info with initial flag. */
2069int
paul68980082003-03-25 05:07:42 +00002070ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002071{
paul68980082003-03-25 05:07:42 +00002072 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002073 struct route_node *rn;
2074 struct external_info *ei;
2075 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002076 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002077
paul68980082003-03-25 05:07:42 +00002078 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002079
2080 /* Originate As-external-LSA from all type of distribute source. */
2081 if ((rt = EXTERNAL_INFO (type)))
2082 for (rn = route_top (rt); rn; rn = route_next (rn))
2083 if ((ei = rn->info) != NULL)
2084 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002085 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002086 zlog_warn ("LSA: AS-external-LSA was not originated.");
2087
2088 return 0;
2089}
2090
paul4dadc292005-05-06 21:37:42 +00002091static struct external_info *
paul020709f2003-04-04 02:44:16 +00002092ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002093{
2094 int type;
2095 struct route_node *rn;
2096 struct prefix_ipv4 p;
2097
2098 p.family = AF_INET;
2099 p.prefix.s_addr = 0;
2100 p.prefixlen = 0;
2101
2102 /* First, lookup redistributed default route. */
2103 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2104 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2105 {
2106 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2107 if (rn != NULL)
2108 {
2109 route_unlock_node (rn);
2110 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002111 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002112 return rn->info;
2113 }
2114 }
2115
2116 return NULL;
2117}
2118
2119int
paul68980082003-03-25 05:07:42 +00002120ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002121{
paul718e3742002-12-13 20:15:29 +00002122 struct prefix_ipv4 p;
2123 struct in_addr nexthop;
2124 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002125 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002126
Paul Jakma4021b602006-05-12 22:55:41 +00002127 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002128
2129 p.family = AF_INET;
2130 p.prefix.s_addr = 0;
2131 p.prefixlen = 0;
2132
Paul Jakma4021b602006-05-12 22:55:41 +00002133 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002134 {
2135 /* If there is no default route via redistribute,
2136 then originate AS-external-LSA with nexthop 0 (self). */
2137 nexthop.s_addr = 0;
2138 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2139 }
2140
paul020709f2003-04-04 02:44:16 +00002141 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002142 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002143
2144 return 0;
2145}
2146
paul645878f2003-04-13 21:42:11 +00002147/* Flush any NSSA LSAs for given prefix */
2148void
2149ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2150{
paul1eb8ef22005-04-07 07:30:20 +00002151 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002152 struct ospf_lsa *lsa;
2153 struct ospf_area *area;
2154
paul1eb8ef22005-04-07 07:30:20 +00002155 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002156 {
paul1eb8ef22005-04-07 07:30:20 +00002157 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002158 {
2159 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2160 ospf->router_id)))
2161 {
2162 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002163 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002164 inet_ntoa (p->prefix), p->prefixlen);
2165 continue;
2166 }
2167 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2168 if (!IS_LSA_MAXAGE (lsa))
2169 {
2170 ospf_refresher_unregister_lsa (ospf, lsa);
2171 ospf_lsa_flush_area (lsa, area);
2172 }
2173 }
paul645878f2003-04-13 21:42:11 +00002174 }
2175}
paul645878f2003-04-13 21:42:11 +00002176
paul718e3742002-12-13 20:15:29 +00002177/* Flush an AS-external-LSA from LSDB and routing domain. */
2178void
paul68980082003-03-25 05:07:42 +00002179ospf_external_lsa_flush (struct ospf *ospf,
2180 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002181 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002182{
2183 struct ospf_lsa *lsa;
2184
2185 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002186 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002187 inet_ntoa (p->prefix), p->prefixlen);
2188
2189 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002190 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002191 {
2192 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002193 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002194 inet_ntoa (p->prefix), p->prefixlen);
2195 return;
2196 }
hassobeebba72004-06-20 21:00:27 +00002197
pauld4a53d52003-07-12 21:30:57 +00002198 /* If LSA is selforiginated, not a translated LSA, and there is
2199 * NSSA area, flush Type-7 LSA's at first.
2200 */
2201 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2202 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002203 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002204
2205 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002206 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002207
2208 /* There must be no self-originated LSA in rtrs_external. */
2209#if 0
2210 /* Remove External route from Zebra. */
2211 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2212#endif
2213
2214 if (!IS_LSA_MAXAGE (lsa))
2215 {
2216 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002217 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002218
2219 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002220 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002221 }
2222
2223 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002224 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002225}
2226
2227void
paul68980082003-03-25 05:07:42 +00002228ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002229{
2230 struct prefix_ipv4 p;
2231 struct external_info *ei;
2232 struct ospf_lsa *lsa;
2233
2234 p.family = AF_INET;
2235 p.prefixlen = 0;
2236 p.prefix.s_addr = 0;
2237
paul020709f2003-04-04 02:44:16 +00002238 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002239 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002240
2241 if (ei)
2242 {
2243 if (lsa)
2244 {
2245 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002246 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002247 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002248 }
2249 else
2250 {
2251 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002252 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002253 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002254 }
2255 }
2256 else
2257 {
2258 if (lsa)
2259 {
2260 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002261 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
Paul Jakmadfbd5172010-04-14 10:32:12 +01002262 ospf_refresher_unregister_lsa (ospf, lsa);
paul68980082003-03-25 05:07:42 +00002263 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002264 }
2265 }
2266}
2267
2268void
paul68980082003-03-25 05:07:42 +00002269ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002270{
2271 struct route_node *rn;
2272 struct external_info *ei;
2273
2274 if (type != DEFAULT_ROUTE)
2275 if (EXTERNAL_INFO(type))
2276 /* Refresh each redistributed AS-external-LSAs. */
2277 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2278 if ((ei = rn->info))
2279 if (!is_prefix_default (&ei->p))
2280 {
2281 struct ospf_lsa *lsa;
2282
paul68980082003-03-25 05:07:42 +00002283 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2284 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002285 else
paul68980082003-03-25 05:07:42 +00002286 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002287 }
2288}
2289
2290/* Refresh AS-external-LSA. */
Paul Jakmac363d382010-01-24 22:42:13 +00002291struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002292ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002293 struct external_info *ei, int force)
2294{
2295 struct ospf_lsa *new;
2296 int changed;
2297
2298 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002299 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002300 {
pauld4a53d52003-07-12 21:30:57 +00002301 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002302 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002303 "redist check fail",
2304 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002305 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002306 ei->ifindex /*, ei->nexthop */);
Paul Jakmac363d382010-01-24 22:42:13 +00002307 return NULL;
paul718e3742002-12-13 20:15:29 +00002308 }
2309
2310 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002311 {
2312 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002313 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002314 lsa->data->type, inet_ntoa (lsa->data->id));
Paul Jakmac363d382010-01-24 22:42:13 +00002315 return NULL;
pauld4a53d52003-07-12 21:30:57 +00002316 }
paul718e3742002-12-13 20:15:29 +00002317
2318 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002319 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002320
2321 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002322 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002323
paul68980082003-03-25 05:07:42 +00002324 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002325
2326 if (new == NULL)
2327 {
2328 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002329 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002330 inet_ntoa (lsa->data->id));
Paul Jakmac363d382010-01-24 22:42:13 +00002331 return NULL;
paul718e3742002-12-13 20:15:29 +00002332 }
2333
2334 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2335
paul68980082003-03-25 05:07:42 +00002336 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002337
2338 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002339 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002340
paul718e3742002-12-13 20:15:29 +00002341 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002342 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002343 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002344
pauld4a53d52003-07-12 21:30:57 +00002345 /* Register self-originated LSA to refresh queue.
2346 * Translated LSAs should not be registered, but refreshed upon
2347 * refresh of the Type-7
2348 */
2349 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2350 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002351
2352 /* Debug logging. */
2353 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2354 {
ajse588f212004-12-08 18:12:06 +00002355 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002356 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002357 ospf_lsa_header_dump (new->data);
2358 }
2359
Paul Jakmac363d382010-01-24 22:42:13 +00002360 return new;
paul718e3742002-12-13 20:15:29 +00002361}
2362
2363
2364/* LSA installation functions. */
2365
2366/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002367static struct ospf_lsa *
Paul Jakmac363d382010-01-24 22:42:13 +00002368ospf_router_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2369 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002370{
2371 struct ospf_area *area = new->area;
2372
2373 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2374 The entire routing table must be recalculated, starting with
2375 the shortest path calculations for each area (not just the
2376 area whose link-state database has changed).
2377 */
paul718e3742002-12-13 20:15:29 +00002378
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002379 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002380 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002381
2382 /* Only install LSA if it is originated/refreshed by us.
2383 * If LSA was received by flooding, the RECEIVED flag is set so do
2384 * not link the LSA */
2385 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2386 return new; /* ignore stale LSA */
2387
paul718e3742002-12-13 20:15:29 +00002388 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002389 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002390 area->router_lsa_self = ospf_lsa_lock (new);
2391
Paul Jakmac363d382010-01-24 22:42:13 +00002392 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002393 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002394 if (rt_recalc)
2395 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002396
2397 return new;
2398}
2399
2400#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2401 if (!(T)) \
2402 (T) = thread_add_timer (master, (F), oi, (V))
2403
2404/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002405static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002406ospf_network_lsa_install (struct ospf *ospf,
2407 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002408 struct ospf_lsa *new,
2409 int rt_recalc)
2410{
2411
2412 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2413 The entire routing table must be recalculated, starting with
2414 the shortest path calculations for each area (not just the
2415 area whose link-state database has changed).
2416 */
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002417 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002418 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002419 /* We supposed that when LSA is originated by us, we pass the int
2420 for which it was originated. If LSA was received by flooding,
2421 the RECEIVED flag is set, so we do not link the LSA to the int. */
2422 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2423 return new; /* ignore stale LSA */
2424
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002425 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002426 oi->network_lsa_self = ospf_lsa_lock (new);
Paul Jakmac363d382010-01-24 22:42:13 +00002427 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002428 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002429 if (rt_recalc)
2430 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002431
2432 return new;
2433}
2434
2435/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002436static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002437ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2438 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002439{
paul718e3742002-12-13 20:15:29 +00002440 if (rt_recalc && !IS_LSA_SELF (new))
2441 {
2442 /* RFC 2328 Section 13.2 Summary-LSAs
2443 The best route to the destination described by the summary-
2444 LSA must be recalculated (see Section 16.5). If this
2445 destination is an AS boundary router, it may also be
2446 necessary to re-examine all the AS-external-LSAs.
2447 */
2448
2449#if 0
2450 /* This doesn't exist yet... */
2451 ospf_summary_incremental_update(new); */
2452#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002453 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002454#endif /* #if 0 */
2455
2456 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002457 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002458 }
2459
2460 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002461 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002462
2463 return new;
2464}
2465
2466/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002467static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002468ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2469 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002470{
2471 if (rt_recalc && !IS_LSA_SELF (new))
2472 {
2473 /* RFC 2328 Section 13.2 Summary-LSAs
2474 The best route to the destination described by the summary-
2475 LSA must be recalculated (see Section 16.5). If this
2476 destination is an AS boundary router, it may also be
2477 necessary to re-examine all the AS-external-LSAs.
2478 */
2479#if 0
2480 /* These don't exist yet... */
2481 ospf_summary_incremental_update(new);
2482 /* Isn't this done by the above call?
2483 - RFC 2328 Section 16.5 implies it should be */
2484 /* ospf_ase_calculate_schedule(); */
2485#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002486 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002487#endif /* #if 0 */
2488 }
2489
2490 /* register LSA to refresh-list. */
2491 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002492 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002493
2494 return new;
2495}
2496
2497/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002498static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002499ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2500 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002501{
paul68980082003-03-25 05:07:42 +00002502 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002503 /* If LSA is not self-originated, calculate an external route. */
2504 if (rt_recalc)
2505 {
2506 /* RFC 2328 Section 13.2 AS-external-LSAs
2507 The best route to the destination described by the AS-
2508 external-LSA must be recalculated (see Section 16.6).
2509 */
2510
2511 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002512 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002513 }
2514
pauld4a53d52003-07-12 21:30:57 +00002515 if (new->data->type == OSPF_AS_NSSA_LSA)
2516 {
2517 /* There is no point to register selforiginate Type-7 LSA for
2518 * refreshing. We rely on refreshing Type-5 LSA's
2519 */
2520 if (IS_LSA_SELF (new))
2521 return new;
2522 else
2523 {
2524 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2525 * New translations will be taken care of by the abr_task.
2526 */
2527 ospf_translated_nssa_refresh (ospf, new, NULL);
2528 }
2529 }
pauld7480322003-05-16 17:31:51 +00002530
pauld4a53d52003-07-12 21:30:57 +00002531 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002532 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002533 */
hassobeebba72004-06-20 21:00:27 +00002534 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002535 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002536
2537 return new;
2538}
2539
2540void
paul68980082003-03-25 05:07:42 +00002541ospf_discard_from_db (struct ospf *ospf,
2542 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002543{
2544 struct ospf_lsa *old;
2545
Paul Jakmaac904de2006-06-15 12:04:57 +00002546 if (!lsdb)
2547 {
2548 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2549 if (!lsa)
2550 zlog_warn ("%s: and NULL LSA!", __func__);
2551 else
2552 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2553 lsa->data->type, inet_ntoa (lsa->data->id));
2554 return;
2555 }
2556
paul718e3742002-12-13 20:15:29 +00002557 old = ospf_lsdb_lookup (lsdb, lsa);
2558
2559 if (!old)
2560 return;
2561
2562 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002563 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002564
2565 switch (old->data->type)
2566 {
2567 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002568 ospf_ase_unregister_external_lsa (old, ospf);
2569 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2570 break;
paul718e3742002-12-13 20:15:29 +00002571#ifdef HAVE_OPAQUE_LSA
2572 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002573 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002574 break;
paul69310a62005-05-11 18:09:59 +00002575#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002576 case OSPF_AS_NSSA_LSA:
2577 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2578 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002579 break;
paul718e3742002-12-13 20:15:29 +00002580 default:
paul68980082003-03-25 05:07:42 +00002581 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002582 break;
2583 }
2584
paul68980082003-03-25 05:07:42 +00002585 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002586 ospf_lsa_discard (old);
2587}
2588
paul718e3742002-12-13 20:15:29 +00002589struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002590ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2591 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002592{
2593 struct ospf_lsa *new = NULL;
2594 struct ospf_lsa *old = NULL;
2595 struct ospf_lsdb *lsdb = NULL;
2596 int rt_recalc;
2597
2598 /* Set LSDB. */
2599 switch (lsa->data->type)
2600 {
paulf2c80652002-12-13 21:44:27 +00002601 /* kevinm */
2602 case OSPF_AS_NSSA_LSA:
2603 if (lsa->area)
2604 lsdb = lsa->area->lsdb;
2605 else
paul68980082003-03-25 05:07:42 +00002606 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002607 break;
paul718e3742002-12-13 20:15:29 +00002608 case OSPF_AS_EXTERNAL_LSA:
2609#ifdef HAVE_OPAQUE_LSA
2610 case OSPF_OPAQUE_AS_LSA:
2611#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002612 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002613 break;
2614 default:
2615 lsdb = lsa->area->lsdb;
2616 break;
2617 }
2618
paul718e3742002-12-13 20:15:29 +00002619 assert (lsdb);
2620
2621 /* RFC 2328 13.2. Installing LSAs in the database
2622
2623 Installing a new LSA in the database, either as the result of
2624 flooding or a newly self-originated LSA, may cause the OSPF
2625 routing table structure to be recalculated. The contents of the
2626 new LSA should be compared to the old instance, if present. If
2627 there is no difference, there is no need to recalculate the
2628 routing table. When comparing an LSA to its previous instance,
2629 the following are all considered to be differences in contents:
2630
2631 o The LSA's Options field has changed.
2632
2633 o One of the LSA instances has LS age set to MaxAge, and
2634 the other does not.
2635
2636 o The length field in the LSA header has changed.
2637
2638 o The body of the LSA (i.e., anything outside the 20-byte
2639 LSA header) has changed. Note that this excludes changes
2640 in LS Sequence Number and LS Checksum.
2641
2642 */
2643 /* Look up old LSA and determine if any SPF calculation or incremental
2644 update is needed */
2645 old = ospf_lsdb_lookup (lsdb, lsa);
2646
2647 /* Do comparision and record if recalc needed. */
2648 rt_recalc = 0;
2649 if ( old == NULL || ospf_lsa_different(old, lsa))
2650 rt_recalc = 1;
2651
paul7ddf1d62003-10-13 09:06:46 +00002652 /*
2653 Sequence number check (Section 14.1 of rfc 2328)
2654 "Premature aging is used when it is time for a self-originated
2655 LSA's sequence number field to wrap. At this point, the current
2656 LSA instance (having LS sequence number MaxSequenceNumber) must
2657 be prematurely aged and flushed from the routing domain before a
2658 new instance with sequence number equal to InitialSequenceNumber
2659 can be originated. "
2660 */
2661
Paul Jakmac2b478d2006-03-30 14:16:11 +00002662 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002663 {
2664 if (ospf_lsa_is_self_originated(ospf, lsa))
2665 {
paul0c2be262004-05-31 14:16:54 +00002666 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2667
2668 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002669 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2670 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2671
2672 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2673 {
ajse588f212004-12-08 18:12:06 +00002674 zlog_debug ("ospf_lsa_install() Premature Aging "
Paul Jakmac363d382010-01-24 22:42:13 +00002675 "lsa 0x%p, seqnum 0x%x",
2676 lsa, ntohl(lsa->data->ls_seqnum));
paul7ddf1d62003-10-13 09:06:46 +00002677 ospf_lsa_header_dump (lsa->data);
2678 }
2679 }
2680 else
2681 {
2682 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2683 {
ajse588f212004-12-08 18:12:06 +00002684 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002685 "that was not self originated. Ignoring\n");
2686 ospf_lsa_header_dump (lsa->data);
2687 }
2688 return old;
2689 }
2690 }
2691
paul718e3742002-12-13 20:15:29 +00002692 /* discard old LSA from LSDB */
2693 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002694 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002695
paul718e3742002-12-13 20:15:29 +00002696 /* Calculate Checksum if self-originated?. */
2697 if (IS_LSA_SELF (lsa))
2698 ospf_lsa_checksum (lsa->data);
2699
hassofe71a972004-12-22 16:16:02 +00002700 /* Insert LSA to LSDB. */
2701 ospf_lsdb_add (lsdb, lsa);
2702 lsa->lsdb = lsdb;
2703
paul718e3742002-12-13 20:15:29 +00002704 /* Do LSA specific installation process. */
2705 switch (lsa->data->type)
2706 {
2707 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002708 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002709 break;
2710 case OSPF_NETWORK_LSA:
2711 assert (oi);
paul68980082003-03-25 05:07:42 +00002712 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002713 break;
2714 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002715 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002716 break;
2717 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002718 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002719 break;
2720 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002721 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002722 break;
2723#ifdef HAVE_OPAQUE_LSA
2724 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002725 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002726 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002727 else
paul68980082003-03-25 05:07:42 +00002728 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002729 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002730 case OSPF_OPAQUE_AREA_LSA:
2731 case OSPF_OPAQUE_AS_LSA:
2732 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2733 break;
2734#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002735 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002736 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002737 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002738 break;
2739 }
2740
2741 if (new == NULL)
2742 return new; /* Installation failed, cannot proceed further -- endo. */
2743
2744 /* Debug logs. */
2745 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2746 {
2747 char area_str[INET_ADDRSTRLEN];
2748
2749 switch (lsa->data->type)
2750 {
2751 case OSPF_AS_EXTERNAL_LSA:
2752#ifdef HAVE_OPAQUE_LSA
2753 case OSPF_OPAQUE_AS_LSA:
2754#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002755 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002756 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002757 dump_lsa_key (new),
2758 LOOKUP (ospf_lsa_type_msg, new->data->type));
2759 break;
2760 default:
2761 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002762 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002763 dump_lsa_key (new),
2764 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2765 break;
2766 }
2767 }
2768
paul7ddf1d62003-10-13 09:06:46 +00002769 /*
2770 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2771 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2772 */
2773 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2774 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002775 {
paul7ddf1d62003-10-13 09:06:46 +00002776 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002777 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002778 new->data->type,
2779 inet_ntoa (new->data->id),
2780 lsa);
Paul Jakma02d942c2010-01-24 23:36:20 +00002781 ospf_lsa_flush (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002782 }
2783
2784 return new;
2785}
2786
2787
paul4dadc292005-05-06 21:37:42 +00002788static int
paul68980082003-03-25 05:07:42 +00002789ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002790{
paul1eb8ef22005-04-07 07:30:20 +00002791 struct listnode *node, *nnode;
2792 struct ospf_interface *oi;
2793
2794 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002795 {
paul718e3742002-12-13 20:15:29 +00002796 struct route_node *rn;
2797 struct ospf_neighbor *nbr;
2798
2799 if (ospf_if_is_enable (oi))
2800 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2801 if ((nbr = rn->info) != NULL)
2802 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2803 {
2804 route_unlock_node (rn);
2805 return 0;
2806 }
2807 }
2808
2809 return 1;
2810}
2811
2812
paul718e3742002-12-13 20:15:29 +00002813
paul4dadc292005-05-06 21:37:42 +00002814static int
paul718e3742002-12-13 20:15:29 +00002815ospf_maxage_lsa_remover (struct thread *thread)
2816{
paul68980082003-03-25 05:07:42 +00002817 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002818 struct ospf_lsa *lsa;
2819 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002820 int reschedule = 0;
2821
paul68980082003-03-25 05:07:42 +00002822 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002823
2824 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002825 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002826
paul68980082003-03-25 05:07:42 +00002827 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002828
2829 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002830 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002831 {
paul718e3742002-12-13 20:15:29 +00002832 if (lsa->retransmit_counter > 0)
2833 {
2834 reschedule = 1;
2835 continue;
2836 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002837
2838 /* TODO: maybe convert this function to a work-queue */
2839 if (thread_should_yield (thread))
2840 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);
2841
paul718e3742002-12-13 20:15:29 +00002842 /* Remove LSA from the LSDB */
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04002843 if (IS_LSA_SELF (lsa))
paul718e3742002-12-13 20:15:29 +00002844 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
Denis Ovsienkoad8d4802011-12-02 20:02:40 +04002845 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-originated: ",
paul7ddf1d62003-10-13 09:06:46 +00002846 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002847
2848 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002849 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002850 lsa->data->type, inet_ntoa (lsa->data->id));
2851
Paul Jakmac363d382010-01-24 22:42:13 +00002852 if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))
paul7ddf1d62003-10-13 09:06:46 +00002853 {
2854 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
Paul Jakmac363d382010-01-24 22:42:13 +00002855 zlog_debug ("originating new lsa for lsa 0x%p\n", lsa);
2856 ospf_lsa_refresh (ospf, lsa);
paul7ddf1d62003-10-13 09:06:46 +00002857 }
2858
paul718e3742002-12-13 20:15:29 +00002859 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002860 if (lsa->lsdb)
2861 {
2862 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2863 ospf_lsdb_delete (lsa->lsdb, lsa);
2864 }
2865 else
2866 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2867 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002868 }
2869
2870 /* A MaxAge LSA must be removed immediately from the router's link
2871 state database as soon as both a) it is no longer contained on any
2872 neighbor Link state retransmission lists and b) none of the router's
2873 neighbors are in states Exchange or Loading. */
2874 if (reschedule)
Paul Jakma02d942c2010-01-24 23:36:20 +00002875 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2876 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002877
2878 return 0;
2879}
2880
paul718e3742002-12-13 20:15:29 +00002881void
paul68980082003-03-25 05:07:42 +00002882ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002883{
hasso52dc7ee2004-09-23 19:18:23 +00002884 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00002885
paul68980082003-03-25 05:07:42 +00002886 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00002887 {
paul68980082003-03-25 05:07:42 +00002888 list_delete_node (ospf->maxage_lsa, n);
Stephen Hemminger3106a032009-08-06 12:58:05 -07002889 UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002890 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +00002891 }
2892}
2893
Paul Jakma02d942c2010-01-24 23:36:20 +00002894/* Add LSA onto the MaxAge list, and schedule for removal.
2895 * This does *not* lead to the LSA being flooded, that must be taken
2896 * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
2897 * function).
2898 */
paul718e3742002-12-13 20:15:29 +00002899void
paul68980082003-03-25 05:07:42 +00002900ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002901{
2902 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2903 and schedule the MaxAge LSA remover. */
Stephen Hemminger3106a032009-08-06 12:58:05 -07002904 if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
paul718e3742002-12-13 20:15:29 +00002905 {
2906 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002907 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00002908 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2909 return;
2910 }
2911
paul68980082003-03-25 05:07:42 +00002912 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
Stephen Hemminger3106a032009-08-06 12:58:05 -07002913 SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
paul718e3742002-12-13 20:15:29 +00002914
2915 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002916 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002917
Paul Jakma02d942c2010-01-24 23:36:20 +00002918 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2919 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002920}
2921
paul4dadc292005-05-06 21:37:42 +00002922static int
paul68980082003-03-25 05:07:42 +00002923ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002924{
paul718e3742002-12-13 20:15:29 +00002925 /* Stay away from any Local Translated Type-7 LSAs */
2926 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2927 return 0;
paul718e3742002-12-13 20:15:29 +00002928
2929 if (IS_LSA_MAXAGE (lsa))
2930 /* Self-originated LSAs should NOT time-out instead,
2931 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00002932 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002933 {
2934 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002935 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002936
2937 switch (lsa->data->type)
2938 {
paul718e3742002-12-13 20:15:29 +00002939#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00002940 case OSPF_OPAQUE_LINK_LSA:
2941 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00002942 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00002943 /*
2944 * As a general rule, whenever network topology has changed
2945 * (due to an LSA removal in this case), routing recalculation
2946 * should be triggered. However, this is not true for opaque
2947 * LSAs. Even if an opaque LSA instance is going to be removed
2948 * from the routing domain, it does not mean a change in network
2949 * topology, and thus, routing recalculation is not needed here.
2950 */
2951 break;
paul718e3742002-12-13 20:15:29 +00002952#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00002953 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00002954 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002955 ospf_ase_incremental_update (ospf, lsa);
2956 break;
paul718e3742002-12-13 20:15:29 +00002957 default:
paul68980082003-03-25 05:07:42 +00002958 ospf_spf_calculate_schedule (ospf);
2959 break;
paul718e3742002-12-13 20:15:29 +00002960 }
paul68980082003-03-25 05:07:42 +00002961 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002962 }
2963
Paul Jakmac363d382010-01-24 22:42:13 +00002964 if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa))
2965 if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30)
2966 printf ("Eek! Shouldn't happen!\n");
2967
paul718e3742002-12-13 20:15:29 +00002968 return 0;
2969}
2970
2971/* Periodical check of MaxAge LSA. */
2972int
paul68980082003-03-25 05:07:42 +00002973ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002974{
paul68980082003-03-25 05:07:42 +00002975 struct ospf *ospf = THREAD_ARG (thread);
2976 struct route_node *rn;
2977 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00002978 struct ospf_area *area;
2979 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002980
paul68980082003-03-25 05:07:42 +00002981 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00002982
paul1eb8ef22005-04-07 07:30:20 +00002983 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00002984 {
paul68980082003-03-25 05:07:42 +00002985 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
2986 ospf_lsa_maxage_walker_remover (ospf, lsa);
2987 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
2988 ospf_lsa_maxage_walker_remover (ospf, lsa);
2989 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
2990 ospf_lsa_maxage_walker_remover (ospf, lsa);
2991 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
2992 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002993#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00002994 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
2995 ospf_lsa_maxage_walker_remover (ospf, lsa);
2996 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
2997 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002998#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00002999 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3000 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003001 }
3002
paul4fb949e2003-05-10 20:06:51 +00003003 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003004 if (ospf->lsdb)
3005 {
3006 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3007 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003008#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003009 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3010 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003011#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003012 }
paul718e3742002-12-13 20:15:29 +00003013
paul68980082003-03-25 05:07:42 +00003014 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3015 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003016 return 0;
3017}
3018
paul68980082003-03-25 05:07:42 +00003019struct ospf_lsa *
3020ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3021 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003022{
paul68980082003-03-25 05:07:42 +00003023 struct ospf_lsa *lsa;
3024 struct in_addr mask, id;
3025 struct lsa_header_mask
3026 {
3027 struct lsa_header header;
3028 struct in_addr mask;
3029 } *hmask;
paul718e3742002-12-13 20:15:29 +00003030
paul68980082003-03-25 05:07:42 +00003031 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3032 if (lsa == NULL)
3033 return NULL;
paul718e3742002-12-13 20:15:29 +00003034
paul68980082003-03-25 05:07:42 +00003035 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003036
paul68980082003-03-25 05:07:42 +00003037 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003038
paul68980082003-03-25 05:07:42 +00003039 if (mask.s_addr != hmask->mask.s_addr)
3040 {
3041 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3042 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3043 if (!lsa)
3044 return NULL;
3045 }
paul718e3742002-12-13 20:15:29 +00003046
paul68980082003-03-25 05:07:42 +00003047 return lsa;
paul718e3742002-12-13 20:15:29 +00003048}
3049
3050struct ospf_lsa *
3051ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3052 struct in_addr id, struct in_addr adv_router)
3053{
paule05fba42003-04-13 20:20:53 +00003054 struct ospf *ospf = ospf_lookup();
3055 assert(ospf);
3056
paul718e3742002-12-13 20:15:29 +00003057 switch (type)
3058 {
3059 case OSPF_ROUTER_LSA:
3060 case OSPF_NETWORK_LSA:
3061 case OSPF_SUMMARY_LSA:
3062 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003063 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003064#ifdef HAVE_OPAQUE_LSA
3065 case OSPF_OPAQUE_LINK_LSA:
3066 case OSPF_OPAQUE_AREA_LSA:
3067#endif /* HAVE_OPAQUE_LSA */
3068 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003069 case OSPF_AS_EXTERNAL_LSA:
3070#ifdef HAVE_OPAQUE_LSA
3071 case OSPF_OPAQUE_AS_LSA:
3072#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003073 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003074 default:
3075 break;
3076 }
3077
3078 return NULL;
3079}
3080
3081struct ospf_lsa *
3082ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3083 struct in_addr id)
3084{
3085 struct ospf_lsa *lsa;
3086 struct route_node *rn;
3087
3088 switch (type)
3089 {
3090 case OSPF_ROUTER_LSA:
3091 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003092 case OSPF_NETWORK_LSA:
3093 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3094 if ((lsa = rn->info))
3095 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3096 {
3097 route_unlock_node (rn);
3098 return lsa;
3099 }
3100 break;
3101 case OSPF_SUMMARY_LSA:
3102 case OSPF_ASBR_SUMMARY_LSA:
3103 /* Currently not used. */
3104 assert (1);
3105 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003106 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003107 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003108#ifdef HAVE_OPAQUE_LSA
3109 case OSPF_OPAQUE_LINK_LSA:
3110 case OSPF_OPAQUE_AREA_LSA:
3111 case OSPF_OPAQUE_AS_LSA:
3112 /* Currently not used. */
3113 break;
3114#endif /* HAVE_OPAQUE_LSA */
3115 default:
3116 break;
3117 }
3118
3119 return NULL;
3120}
3121
3122struct ospf_lsa *
3123ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3124{
3125 struct ospf_lsa *match;
3126
3127#ifdef HAVE_OPAQUE_LSA
3128 /*
3129 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3130 * is redefined to have two subfields; opaque-type and opaque-id.
3131 * However, it is harmless to treat the two sub fields together, as if
3132 * they two were forming a unique LSA-ID.
3133 */
3134#endif /* HAVE_OPAQUE_LSA */
3135
3136 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3137
3138 if (match == NULL)
3139 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003140 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003141 lsah->type, inet_ntoa (lsah->id));
3142
3143 return match;
3144}
3145
3146/* return +n, l1 is more recent.
3147 return -n, l2 is more recent.
3148 return 0, l1 and l2 is identical. */
3149int
3150ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3151{
3152 int r;
3153 int x, y;
3154
3155 if (l1 == NULL && l2 == NULL)
3156 return 0;
3157 if (l1 == NULL)
3158 return -1;
3159 if (l2 == NULL)
3160 return 1;
3161
3162 /* compare LS sequence number. */
3163 x = (int) ntohl (l1->data->ls_seqnum);
3164 y = (int) ntohl (l2->data->ls_seqnum);
3165 if (x > y)
3166 return 1;
3167 if (x < y)
3168 return -1;
3169
3170 /* compare LS checksum. */
3171 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3172 if (r)
3173 return r;
3174
3175 /* compare LS age. */
3176 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3177 return 1;
3178 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3179 return -1;
3180
3181 /* compare LS age with MaxAgeDiff. */
3182 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3183 return -1;
3184 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3185 return 1;
3186
3187 /* LSAs are identical. */
3188 return 0;
3189}
3190
3191/* If two LSAs are different, return 1, otherwise return 0. */
3192int
3193ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3194{
3195 char *p1, *p2;
3196 assert (l1);
3197 assert (l2);
3198 assert (l1->data);
3199 assert (l2->data);
3200
3201 if (l1->data->options != l2->data->options)
3202 return 1;
3203
3204 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3205 return 1;
3206
3207 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3208 return 1;
3209
3210 if (l1->data->length != l2->data->length)
3211 return 1;
3212
3213 if (l1->data->length == 0)
3214 return 1;
3215
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02003216 if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
3217 return 1; /* May be a stale LSA in the LSBD */
3218
pauld1825832003-04-03 01:27:01 +00003219 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003220
3221 p1 = (char *) l1->data;
3222 p2 = (char *) l2->data;
3223
3224 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3225 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3226 return 1;
3227
3228 return 0;
3229}
3230
3231#ifdef ORIGINAL_CODING
3232void
3233ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3234 struct ospf_lsa *self,
3235 struct ospf_lsa *new)
3236{
3237 u_int32_t seqnum;
3238
3239 /* Adjust LS Sequence Number. */
3240 seqnum = ntohl (new->data->ls_seqnum) + 1;
3241 self->data->ls_seqnum = htonl (seqnum);
3242
3243 /* Recalculate LSA checksum. */
3244 ospf_lsa_checksum (self->data);
3245
3246 /* Reflooding LSA. */
3247 /* RFC2328 Section 13.3
3248 On non-broadcast networks, separate Link State Update
3249 packets must be sent, as unicasts, to each adjacent neighbor
3250 (i.e., those in state Exchange or greater). The destination
3251 IP addresses for these packets are the neighbors' IP
3252 addresses. */
3253 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3254 {
3255 struct route_node *rn;
3256 struct ospf_neighbor *onbr;
3257
3258 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3259 if ((onbr = rn->info) != NULL)
3260 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3261 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3262 }
3263 else
3264 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3265
3266 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003267 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003268 self->data->type, inet_ntoa (self->data->id));
3269}
3270#else /* ORIGINAL_CODING */
3271static int
paul68980082003-03-25 05:07:42 +00003272ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003273{
3274 if (lsa == NULL || !IS_LSA_SELF (lsa))
3275 return 0;
3276
3277 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003278 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 +00003279
3280 /* Force given lsa's age to MaxAge. */
3281 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3282
3283 switch (lsa->data->type)
3284 {
3285#ifdef HAVE_OPAQUE_LSA
Paul Jakma02d942c2010-01-24 23:36:20 +00003286 /* Opaque wants to be notified of flushes */
paul718e3742002-12-13 20:15:29 +00003287 case OSPF_OPAQUE_LINK_LSA:
3288 case OSPF_OPAQUE_AREA_LSA:
3289 case OSPF_OPAQUE_AS_LSA:
3290 ospf_opaque_lsa_refresh (lsa);
3291 break;
3292#endif /* HAVE_OPAQUE_LSA */
3293 default:
Paul Jakmadfbd5172010-04-14 10:32:12 +01003294 ospf_refresher_unregister_lsa (ospf, lsa);
Paul Jakma02d942c2010-01-24 23:36:20 +00003295 ospf_lsa_flush (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003296 break;
3297 }
3298
3299 return 0;
3300}
3301
3302void
paul68980082003-03-25 05:07:42 +00003303ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003304{
paul1eb8ef22005-04-07 07:30:20 +00003305 struct listnode *node, *nnode;
3306 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003307 struct ospf_area *area;
3308 struct ospf_interface *oi;
3309 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003310 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003311 int need_to_flush_ase = 0;
3312
paul1eb8ef22005-04-07 07:30:20 +00003313 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003314 {
paul718e3742002-12-13 20:15:29 +00003315 if ((lsa = area->router_lsa_self) != NULL)
3316 {
3317 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003318 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3319 lsa->data->type, inet_ntoa (lsa->data->id));
3320
3321 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003322 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003323 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003324 area->router_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003325 }
3326
paul1eb8ef22005-04-07 07:30:20 +00003327 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003328 {
paul718e3742002-12-13 20:15:29 +00003329 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003330 && oi->state == ISM_DR
3331 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003332 {
3333 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003334 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3335 lsa->data->type, inet_ntoa (lsa->data->id));
3336
3337 ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003338 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003339 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003340 oi->network_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003341 }
3342
3343 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3344 && area->external_routing == OSPF_AREA_DEFAULT)
3345 need_to_flush_ase = 1;
3346 }
3347
paul68980082003-03-25 05:07:42 +00003348 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3349 ospf_lsa_flush_schedule (ospf, lsa);
3350 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3351 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003352#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003353 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3354 ospf_lsa_flush_schedule (ospf, lsa);
3355 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3356 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003357#endif /* HAVE_OPAQUE_LSA */
3358 }
3359
3360 if (need_to_flush_ase)
3361 {
paul68980082003-03-25 05:07:42 +00003362 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3363 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003364#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003365 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3366 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003367#endif /* HAVE_OPAQUE_LSA */
3368 }
3369
3370 /*
3371 * Make sure that the MaxAge LSA remover is executed immediately,
3372 * without conflicting to other threads.
3373 */
paul68980082003-03-25 05:07:42 +00003374 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003375 {
paul68980082003-03-25 05:07:42 +00003376 OSPF_TIMER_OFF (ospf->t_maxage);
3377 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003378 }
3379
3380 return;
3381}
3382#endif /* ORIGINAL_CODING */
3383
3384/* If there is self-originated LSA, then return 1, otherwise return 0. */
3385/* An interface-independent version of ospf_lsa_is_self_originated */
3386int
paul68980082003-03-25 05:07:42 +00003387ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003388{
hasso52dc7ee2004-09-23 19:18:23 +00003389 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003390 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003391
3392 /* This LSA is already checked. */
3393 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003394 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003395
3396 /* Make sure LSA is self-checked. */
3397 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3398
3399 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003400 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003401 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3402
3403 /* LSA is router-LSA. */
3404 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003405 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003406 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3407
3408 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3409 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003410 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003411 {
paul718e3742002-12-13 20:15:29 +00003412 /* Ignore virtual link. */
3413 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3414 if (oi->address->family == AF_INET)
3415 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3416 {
3417 /* to make it easier later */
3418 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003419 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003420 }
3421 }
3422
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003423 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003424}
3425
3426/* Get unique Link State ID. */
3427struct in_addr
paul68980082003-03-25 05:07:42 +00003428ospf_lsa_unique_id (struct ospf *ospf,
3429 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003430{
3431 struct ospf_lsa *lsa;
3432 struct in_addr mask, id;
3433
3434 id = p->prefix;
3435
3436 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003437 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003438 if (lsa)
3439 {
3440 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3441 if (ip_masklen (al->mask) == p->prefixlen)
3442 {
3443 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003444 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003445 "Can't get Link State ID for %s/%d",
3446 inet_ntoa (p->prefix), p->prefixlen);
3447 /* id.s_addr = 0; */
3448 id.s_addr = 0xffffffff;
3449 return id;
3450 }
3451 /* Masklen differs, then apply wildcard mask to Link State ID. */
3452 else
3453 {
3454 masklen2ip (p->prefixlen, &mask);
3455
3456 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003457 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3458 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003459 if (lsa)
3460 {
3461 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003462 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003463 "Can't get Link State ID for %s/%d",
3464 inet_ntoa (p->prefix), p->prefixlen);
3465 /* id.s_addr = 0; */
3466 id.s_addr = 0xffffffff;
3467 return id;
3468 }
3469 }
3470 }
3471
3472 return id;
3473}
3474
3475
Paul Jakma70461d72006-05-12 22:57:57 +00003476#define LSA_ACTION_FLOOD_AREA 1
3477#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003478
3479struct lsa_action
3480{
3481 u_char action;
3482 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003483 struct ospf_lsa *lsa;
3484};
3485
paul4dadc292005-05-06 21:37:42 +00003486static int
paul718e3742002-12-13 20:15:29 +00003487ospf_lsa_action (struct thread *t)
3488{
3489 struct lsa_action *data;
3490
3491 data = THREAD_ARG (t);
3492
3493 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003494 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003495 data->action);
3496
3497 switch (data->action)
3498 {
paul718e3742002-12-13 20:15:29 +00003499 case LSA_ACTION_FLOOD_AREA:
3500 ospf_flood_through_area (data->area, NULL, data->lsa);
3501 break;
paul718e3742002-12-13 20:15:29 +00003502 case LSA_ACTION_FLUSH_AREA:
3503 ospf_lsa_flush_area (data->lsa, data->area);
3504 break;
paul718e3742002-12-13 20:15:29 +00003505 }
3506
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003507 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003508 XFREE (MTYPE_OSPF_MESSAGE, data);
3509 return 0;
3510}
3511
3512void
3513ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3514{
3515 struct lsa_action *data;
3516
Stephen Hemminger393deb92008-08-18 14:13:29 -07003517 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003518 data->action = LSA_ACTION_FLOOD_AREA;
3519 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003520 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003521
3522 thread_add_event (master, ospf_lsa_action, data, 0);
3523}
3524
3525void
3526ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3527{
3528 struct lsa_action *data;
3529
Stephen Hemminger393deb92008-08-18 14:13:29 -07003530 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003531 data->action = LSA_ACTION_FLUSH_AREA;
3532 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003533 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003534
3535 thread_add_event (master, ospf_lsa_action, data, 0);
3536}
3537
3538
3539/* LSA Refreshment functions. */
Paul Jakmac363d382010-01-24 22:42:13 +00003540struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00003541ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003542{
3543 struct external_info *ei;
Paul Jakmac363d382010-01-24 22:42:13 +00003544 struct ospf_lsa *new = NULL;
paul718e3742002-12-13 20:15:29 +00003545 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003546 assert (IS_LSA_SELF (lsa));
Paul Jakma66349742010-04-13 22:33:54 +01003547 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003548
3549 switch (lsa->data->type)
3550 {
3551 /* Router and Network LSAs are processed differently. */
3552 case OSPF_ROUTER_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003553 new = ospf_router_lsa_refresh (lsa);
3554 break;
paul718e3742002-12-13 20:15:29 +00003555 case OSPF_NETWORK_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003556 new = ospf_network_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003557 break;
3558 case OSPF_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003559 new = ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003560 break;
3561 case OSPF_ASBR_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003562 new = ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003563 break;
3564 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003565 /* Translated from NSSA Type-5s are refreshed when
3566 * from refresh of Type-7 - do not refresh these directly.
3567 */
3568 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3569 break;
paul718e3742002-12-13 20:15:29 +00003570 ei = ospf_external_info_check (lsa);
3571 if (ei)
Paul Jakmac363d382010-01-24 22:42:13 +00003572 new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003573 else
pauld4a53d52003-07-12 21:30:57 +00003574 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003575 break;
3576#ifdef HAVE_OPAQUE_LSA
3577 case OSPF_OPAQUE_LINK_LSA:
3578 case OSPF_OPAQUE_AREA_LSA:
3579 case OSPF_OPAQUE_AS_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003580 new = ospf_opaque_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003581 break;
pauld7480322003-05-16 17:31:51 +00003582#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003583 default:
3584 break;
paul718e3742002-12-13 20:15:29 +00003585 }
Paul Jakmac363d382010-01-24 22:42:13 +00003586 return new;
paul718e3742002-12-13 20:15:29 +00003587}
3588
3589void
paul68980082003-03-25 05:07:42 +00003590ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003591{
3592 u_int16_t index, current_index;
3593
Paul Jakma66349742010-04-13 22:33:54 +01003594 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003595 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003596
3597 if (lsa->refresh_list < 0)
3598 {
3599 int delay;
3600
3601 if (LS_AGE (lsa) == 0 &&
3602 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3603 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3604 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3605 else
3606 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3607 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3608 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3609
3610 if (delay < 0)
3611 delay = 0;
3612
Paul Jakmac363d382010-01-24 22:42:13 +00003613 current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL)
3614 - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003615
3616 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
Paul Jakmac363d382010-01-24 22:42:13 +00003617 % (OSPF_LSA_REFRESHER_SLOTS);
paul718e3742002-12-13 20:15:29 +00003618
3619 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003620 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003621 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003622 if (!ospf->lsa_refresh_queue.qs[index])
3623 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003624 listnode_add (ospf->lsa_refresh_queue.qs[index],
3625 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003626 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003627 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003628 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003629 "setting refresh_list on lsa %p (slod %d)",
3630 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003631 }
3632}
3633
3634void
paul68980082003-03-25 05:07:42 +00003635ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003636{
Paul Jakma66349742010-04-13 22:33:54 +01003637 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003638 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003639 if (lsa->refresh_list >= 0)
3640 {
hasso52dc7ee2004-09-23 19:18:23 +00003641 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003642 listnode_delete (refresh_list, lsa);
3643 if (!listcount (refresh_list))
3644 {
3645 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003646 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003647 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003648 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003649 lsa->refresh_list = -1;
3650 }
3651}
3652
3653int
3654ospf_lsa_refresh_walker (struct thread *t)
3655{
hasso52dc7ee2004-09-23 19:18:23 +00003656 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003657 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003658 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003659 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003660 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003661 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003662
3663 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003664 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003665
3666
paul68980082003-03-25 05:07:42 +00003667 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003668
ajs9dbc7972005-03-13 19:27:22 +00003669 /* Note: if clock has jumped backwards, then time change could be negative,
3670 so we are careful to cast the expression to unsigned before taking
3671 modulus. */
paul68980082003-03-25 05:07:42 +00003672 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003673 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakmac363d382010-01-24 22:42:13 +00003674 (quagga_time (NULL) - ospf->lsa_refresher_started)
3675 / OSPF_LSA_REFRESHER_GRANULARITY))
3676 % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003677
3678 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003679 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003680 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003681
paul68980082003-03-25 05:07:42 +00003682 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003683 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3684 {
3685 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003686 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003687 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003688
paul68980082003-03-25 05:07:42 +00003689 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003690
Paul Jakma66349742010-04-13 22:33:54 +01003691 assert (i >= 0);
3692
paul68980082003-03-25 05:07:42 +00003693 ospf->lsa_refresh_queue.qs [i] = NULL;
3694
paul718e3742002-12-13 20:15:29 +00003695 if (refresh_list)
3696 {
paul1eb8ef22005-04-07 07:30:20 +00003697 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003698 {
paul718e3742002-12-13 20:15:29 +00003699 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003700 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003701 "refresh lsa %p (slot %d)",
3702 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003703
Paul Jakma66349742010-04-13 22:33:54 +01003704 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003705 list_delete_node (refresh_list, node);
paul718e3742002-12-13 20:15:29 +00003706 lsa->refresh_list = -1;
3707 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003708 }
3709 list_free (refresh_list);
3710 }
3711 }
3712
paul68980082003-03-25 05:07:42 +00003713 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3714 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003715 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003716
paul1eb8ef22005-04-07 07:30:20 +00003717 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
Paul Jakma66349742010-04-13 22:33:54 +01003718 {
3719 ospf_lsa_refresh (ospf, lsa);
3720 assert (lsa->lock > 0);
3721 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
3722 }
paul718e3742002-12-13 20:15:29 +00003723
3724 list_delete (lsa_to_refresh);
3725
3726 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003727 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003728
3729 return 0;
3730}
3731