blob: 3c9c73a3b9d0c213e1e22ee14ec55dc184274c8e [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));
204 memset (new, 0, sizeof (struct ospf_lsa));
205
206 new->flags = 0;
207 new->lock = 1;
208 new->retransmit_counter = 0;
Paul Jakma2518efd2006-08-27 06:49:29 +0000209 new->tv_recv = recent_relative_time ();
paul718e3742002-12-13 20:15:29 +0000210 new->tv_orig = new->tv_recv;
211 new->refresh_list = -1;
212
213 return new;
214}
215
216/* Duplicate OSPF LSA. */
217struct ospf_lsa *
218ospf_lsa_dup (struct ospf_lsa *lsa)
219{
220 struct ospf_lsa *new;
221
222 if (lsa == NULL)
223 return NULL;
224
225 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
226
227 memcpy (new, lsa, sizeof (struct ospf_lsa));
228 UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
229 new->lock = 1;
230 new->retransmit_counter = 0;
231 new->data = ospf_lsa_data_dup (lsa->data);
232
paulf2c80652002-12-13 21:44:27 +0000233 /* kevinm: Clear the refresh_list, otherwise there are going
234 to be problems when we try to remove the LSA from the
235 queue (which it's not a member of.)
236 XXX: Should we add the LSA to the refresh_list queue? */
237 new->refresh_list = -1;
238
239 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000240 zlog_debug ("LSA: duplicated %p (new: %p)", lsa, new);
paulf2c80652002-12-13 21:44:27 +0000241
paul718e3742002-12-13 20:15:29 +0000242 return new;
243}
244
245/* Free OSPF LSA. */
246void
247ospf_lsa_free (struct ospf_lsa *lsa)
248{
249 assert (lsa->lock == 0);
250
251 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000252 zlog_debug ("LSA: freed %p", lsa);
paul718e3742002-12-13 20:15:29 +0000253
254 /* Delete LSA data. */
255 if (lsa->data != NULL)
256 ospf_lsa_data_free (lsa->data);
257
258 assert (lsa->refresh_list < 0);
259
260 memset (lsa, 0, sizeof (struct ospf_lsa));
261 XFREE (MTYPE_OSPF_LSA, lsa);
262}
263
264/* Lock LSA. */
265struct ospf_lsa *
266ospf_lsa_lock (struct ospf_lsa *lsa)
267{
268 lsa->lock++;
269 return lsa;
270}
271
272/* Unlock LSA. */
273void
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000274ospf_lsa_unlock (struct ospf_lsa **lsa)
paul718e3742002-12-13 20:15:29 +0000275{
276 /* This is sanity check. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000277 if (!lsa || !*lsa)
paul718e3742002-12-13 20:15:29 +0000278 return;
279
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000280 (*lsa)->lock--;
paul718e3742002-12-13 20:15:29 +0000281
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000282 assert ((*lsa)->lock >= 0);
paul718e3742002-12-13 20:15:29 +0000283
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000284 if ((*lsa)->lock == 0)
paul718e3742002-12-13 20:15:29 +0000285 {
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000286 assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
287 ospf_lsa_free (*lsa);
288 *lsa = NULL;
paul718e3742002-12-13 20:15:29 +0000289 }
290}
291
292/* Check discard flag. */
293void
294ospf_lsa_discard (struct ospf_lsa *lsa)
295{
296 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
297 {
298 SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000299 ospf_lsa_unlock (&lsa);
paul718e3742002-12-13 20:15:29 +0000300 }
301}
302
303/* Create LSA data. */
304struct lsa_header *
305ospf_lsa_data_new (size_t size)
306{
Stephen Hemminger393deb92008-08-18 14:13:29 -0700307 return XCALLOC (MTYPE_OSPF_LSA_DATA, size);
paul718e3742002-12-13 20:15:29 +0000308}
309
310/* Duplicate LSA data. */
311struct lsa_header *
312ospf_lsa_data_dup (struct lsa_header *lsah)
313{
314 struct lsa_header *new;
315
316 new = ospf_lsa_data_new (ntohs (lsah->length));
317 memcpy (new, lsah, ntohs (lsah->length));
318
319 return new;
320}
321
322/* Free LSA data. */
323void
324ospf_lsa_data_free (struct lsa_header *lsah)
325{
326 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000327 zlog_debug ("LSA[Type%d:%s]: data freed %p",
paul718e3742002-12-13 20:15:29 +0000328 lsah->type, inet_ntoa (lsah->id), lsah);
329
330 XFREE (MTYPE_OSPF_LSA_DATA, lsah);
331}
332
333
334/* LSA general functions. */
335
336const char *
337dump_lsa_key (struct ospf_lsa *lsa)
338{
339 static char buf[] = {
hasso52dc7ee2004-09-23 19:18:23 +0000340 "Type255,id(255.255.255.255),ar(255.255.255.255)"
paul718e3742002-12-13 20:15:29 +0000341 };
342 struct lsa_header *lsah;
343
344 if (lsa != NULL && (lsah = lsa->data) != NULL)
345 {
346 char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
347 strcpy (id, inet_ntoa (lsah->id));
348 strcpy (ar, inet_ntoa (lsah->adv_router));
349
350 sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
351 }
352 else
353 strcpy (buf, "NULL");
354
355 return buf;
356}
357
358u_int32_t
359lsa_seqnum_increment (struct ospf_lsa *lsa)
360{
361 u_int32_t seqnum;
362
363 seqnum = ntohl (lsa->data->ls_seqnum) + 1;
364
365 return htonl (seqnum);
366}
367
368void
369lsa_header_set (struct stream *s, u_char options,
paul68980082003-03-25 05:07:42 +0000370 u_char type, struct in_addr id, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +0000371{
372 struct lsa_header *lsah;
373
374 lsah = (struct lsa_header *) STREAM_DATA (s);
375
376 lsah->ls_age = htons (0);
377 lsah->options = options;
378 lsah->type = type;
379 lsah->id = id;
paul68980082003-03-25 05:07:42 +0000380 lsah->adv_router = router_id;
paul718e3742002-12-13 20:15:29 +0000381 lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
382
paul9985f832005-02-09 15:51:56 +0000383 stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000384}
385
paul68980082003-03-25 05:07:42 +0000386
paul718e3742002-12-13 20:15:29 +0000387/* router-LSA related functions. */
388/* Get router-LSA flags. */
paul4dadc292005-05-06 21:37:42 +0000389static u_char
paul718e3742002-12-13 20:15:29 +0000390router_lsa_flags (struct ospf_area *area)
391{
392 u_char flags;
393
paul68980082003-03-25 05:07:42 +0000394 flags = area->ospf->flags;
paul718e3742002-12-13 20:15:29 +0000395
396 /* Set virtual link flag. */
397 if (ospf_full_virtual_nbrs (area))
398 SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
399 else
400 /* Just sanity check */
401 UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);
402
403 /* Set Shortcut ABR behabiour flag. */
404 UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
paul68980082003-03-25 05:07:42 +0000405 if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
paul718e3742002-12-13 20:15:29 +0000406 if (!OSPF_IS_AREA_BACKBONE (area))
407 if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
paul68980082003-03-25 05:07:42 +0000408 area->ospf->backbone == NULL) ||
paul718e3742002-12-13 20:15:29 +0000409 area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
410 SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
411
412 /* ASBR can't exit in stub area. */
Greg Troxelfc787e82007-08-06 15:50:20 +0000413 if (area->external_routing == OSPF_AREA_STUB)
paul942b6c12003-06-22 08:22:18 +0000414 UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
415 /* If ASBR set External flag */
416 else if (IS_OSPF_ASBR (area->ospf))
417 SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
418
419 /* Set ABR dependent flags */
420 if (IS_OSPF_ABR (area->ospf))
421 {
422 SET_FLAG (flags, ROUTER_LSA_BORDER);
paul942b6c12003-06-22 08:22:18 +0000423 /* If Area is NSSA and we are both ABR and unconditional translator,
pauld4a53d52003-07-12 21:30:57 +0000424 * set Nt bit to inform other routers.
paul942b6c12003-06-22 08:22:18 +0000425 */
pauld4a53d52003-07-12 21:30:57 +0000426 if ( (area->external_routing == OSPF_AREA_NSSA)
427 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
428 SET_FLAG (flags, ROUTER_LSA_NT);
paul942b6c12003-06-22 08:22:18 +0000429 }
paul718e3742002-12-13 20:15:29 +0000430 return flags;
431}
432
433/* Lookup neighbor other than myself.
434 And check neighbor count,
435 Point-to-Point link must have only 1 neighbor. */
436struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +0000437ospf_nbr_lookup_ptop (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +0000438{
paul718e3742002-12-13 20:15:29 +0000439 struct ospf_neighbor *nbr = NULL;
paul68980082003-03-25 05:07:42 +0000440 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000441
442 /* Search neighbor, there must be one of two nbrs. */
paul68980082003-03-25 05:07:42 +0000443 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
444 if ((nbr = rn->info))
445 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000446 if (nbr->state == NSM_Full)
paul68980082003-03-25 05:07:42 +0000447 {
448 route_unlock_node (rn);
449 break;
450 }
paul718e3742002-12-13 20:15:29 +0000451
452 /* PtoP link must have only 1 neighbor. */
paul68980082003-03-25 05:07:42 +0000453 if (ospf_nbr_count (oi, 0) > 1)
paul718e3742002-12-13 20:15:29 +0000454 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
455
456 return nbr;
457}
458
paul88d6cf32005-10-29 12:50:09 +0000459/* Determine cost of link, taking RFC3137 stub-router support into
460 * consideration
461 */
462static u_int16_t
463ospf_link_cost (struct ospf_interface *oi)
464{
465 /* RFC3137 stub router support */
466 if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
467 return oi->output_cost;
468 else
469 return OSPF_OUTPUT_COST_INFINITE;
470}
471
paul718e3742002-12-13 20:15:29 +0000472/* Set a link information. */
paul779adb02006-01-18 15:07:38 +0000473static char
paul718e3742002-12-13 20:15:29 +0000474link_info_set (struct stream *s, struct in_addr id,
475 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
476{
paul779adb02006-01-18 15:07:38 +0000477 /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
478 * vast majority of cases. Some rare routers with lots of links need more.
479 * we try accomodate those here.
480 */
481 if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
482 {
483 size_t ret = OSPF_MAX_LSA_SIZE;
484
485 /* Can we enlarge the stream still? */
486 if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
487 {
488 /* we futz the size here for simplicity, really we need to account
489 * for just:
490 * IP Header - (sizeof (struct ip))
491 * OSPF Header - OSPF_HEADER_SIZE
492 * LSA Header - OSPF_LSA_HEADER_SIZE
493 * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
494 *
495 * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
496 */
497 ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
498 }
499
500 if (ret == OSPF_MAX_LSA_SIZE)
501 {
502 zlog_warn ("%s: Out of space in LSA stream, left %ld, size %ld",
503 __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
504 return 0;
505 }
506 }
507
paul718e3742002-12-13 20:15:29 +0000508 /* TOS based routing is not supported. */
509 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
510 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
511 stream_putc (s, type); /* Link Type. */
512 stream_putc (s, tos); /* TOS = 0. */
513 stream_putw (s, cost); /* Link Cost. */
paul779adb02006-01-18 15:07:38 +0000514
515 return 1;
paul718e3742002-12-13 20:15:29 +0000516}
517
Andrew J. Schorre4529632006-12-12 19:18:21 +0000518/* Describe Point-to-Point link (Section 12.4.1.1). */
paul4dadc292005-05-06 21:37:42 +0000519static int
paul718e3742002-12-13 20:15:29 +0000520lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
521{
522 int links = 0;
523 struct ospf_neighbor *nbr;
524 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000525 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000526
527 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000528 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
paul718e3742002-12-13 20:15:29 +0000529
paul68980082003-03-25 05:07:42 +0000530 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000531 if (nbr->state == NSM_Full)
532 {
533 /* For unnumbered point-to-point networks, the Link Data field
534 should specify the interface's MIB-II ifIndex value. */
paul779adb02006-01-18 15:07:38 +0000535 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
536 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000537 }
538
Andrew J. Schorre4529632006-12-12 19:18:21 +0000539 /* Regardless of the state of the neighboring router, we must
540 add a Type 3 link (stub network).
541 N.B. Options 1 & 2 share basically the same logic. */
542 masklen2ip (oi->address->prefixlen, &mask);
543 id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
544 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
545 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000546 return links;
547}
548
549/* Describe Broadcast Link. */
paul4dadc292005-05-06 21:37:42 +0000550static int
paul718e3742002-12-13 20:15:29 +0000551lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
552{
553 struct ospf_neighbor *dr;
554 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000555 u_int16_t cost = ospf_link_cost (oi);
556
paul718e3742002-12-13 20:15:29 +0000557 /* Describe Type 3 Link. */
558 if (oi->state == ISM_Waiting)
559 {
560 masklen2ip (oi->address->prefixlen, &mask);
561 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000562 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
563 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000564 }
565
566 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
567 /* Describe Type 2 link. */
568 if (dr && (dr->state == NSM_Full ||
569 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000570 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000571 {
paul779adb02006-01-18 15:07:38 +0000572 return link_info_set (s, DR (oi), oi->address->u.prefix4,
573 LSA_LINK_TYPE_TRANSIT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000574 }
575 /* Describe type 3 link. */
576 else
577 {
578 masklen2ip (oi->address->prefixlen, &mask);
579 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000580 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
581 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000582 }
paul718e3742002-12-13 20:15:29 +0000583}
584
paul4dadc292005-05-06 21:37:42 +0000585static int
paul718e3742002-12-13 20:15:29 +0000586lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
587{
588 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000589
paul718e3742002-12-13 20:15:29 +0000590 /* Describe Type 3 Link. */
591 if (oi->state != ISM_Loopback)
592 return 0;
593
594 mask.s_addr = 0xffffffff;
595 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000596 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000597}
598
599/* Describe Virtual Link. */
paul4dadc292005-05-06 21:37:42 +0000600static int
paul718e3742002-12-13 20:15:29 +0000601lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
602{
603 struct ospf_neighbor *nbr;
paul88d6cf32005-10-29 12:50:09 +0000604 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000605
paul718e3742002-12-13 20:15:29 +0000606 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000607 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000608 if (nbr->state == NSM_Full)
609 {
paul779adb02006-01-18 15:07:38 +0000610 return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
611 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
paul718e3742002-12-13 20:15:29 +0000612 }
613
614 return 0;
615}
616
617#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
618
paul7afa08d2002-12-13 20:59:45 +0000619/* this function add for support point-to-multipoint ,see rfc2328
62012.4.1.4.*/
621/* from "edward rrr" <edward_rrr@hotmail.com>
622 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul4dadc292005-05-06 21:37:42 +0000623static int
paul68980082003-03-25 05:07:42 +0000624lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000625{
626 int links = 0;
627 struct route_node *rn;
628 struct ospf_neighbor *nbr = NULL;
629 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000630 u_int16_t cost = ospf_link_cost (oi);
paul7afa08d2002-12-13 20:59:45 +0000631
632 mask.s_addr = 0xffffffff;
633 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000634 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
paul7afa08d2002-12-13 20:59:45 +0000635
paul1cc8f762003-04-05 19:34:32 +0000636 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000637 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000638
639 /* Search neighbor, */
640 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
641 if ((nbr = rn->info) != NULL)
642 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000643 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000644 if (nbr->state == NSM_Full)
645
646 {
paul779adb02006-01-18 15:07:38 +0000647 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
648 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul1cc8f762003-04-05 19:34:32 +0000649 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000650 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000651 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000652 }
653
654 return links;
paul7afa08d2002-12-13 20:59:45 +0000655}
656
paul718e3742002-12-13 20:15:29 +0000657/* Set router-LSA link information. */
paul4dadc292005-05-06 21:37:42 +0000658static int
paul718e3742002-12-13 20:15:29 +0000659router_lsa_link_set (struct stream *s, struct ospf_area *area)
660{
hasso52dc7ee2004-09-23 19:18:23 +0000661 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000662 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000663 int links = 0;
664
paul1eb8ef22005-04-07 07:30:20 +0000665 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +0000666 {
paul718e3742002-12-13 20:15:29 +0000667 struct interface *ifp = oi->ifp;
668
669 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000670 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000671 {
672 if (oi->state != ISM_Down)
673 {
674 /* 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 }
695 }
696 }
697 }
698
699 return links;
700}
701
702/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000703static void
paul718e3742002-12-13 20:15:29 +0000704ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
705{
706 unsigned long putp;
707 u_int16_t cnt;
708
709 /* Set flags. */
710 stream_putc (s, router_lsa_flags (area));
711
712 /* Set Zero fields. */
713 stream_putc (s, 0);
714
715 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000716 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000717
718 /* Forward word */
719 stream_putw(s, 0);
720
721 /* Set all link information. */
722 cnt = router_lsa_link_set (s, area);
723
724 /* Set # of links here. */
725 stream_putw_at (s, putp, cnt);
726}
paul88d6cf32005-10-29 12:50:09 +0000727
728static int
729ospf_stub_router_timer (struct thread *t)
730{
731 struct ospf_area *area = THREAD_ARG (t);
732
733 area->t_stub_router = NULL;
734
735 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
736
737 /* clear stub route state and generate router-lsa refresh, don't
738 * clobber an administratively set stub-router state though.
739 */
740 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
741 return 0;
742
743 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
744
745 ospf_router_lsa_timer_add (area);
746
747 return 0;
748}
paul718e3742002-12-13 20:15:29 +0000749
paul88d6cf32005-10-29 12:50:09 +0000750inline static void
751ospf_stub_router_check (struct ospf_area *area)
752{
753 /* area must either be administratively configured to be stub
754 * or startup-time stub-router must be configured and we must in a pre-stub
755 * state.
756 */
757 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
758 {
759 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
760 return;
761 }
762
763 /* not admin-stubbed, check whether startup stubbing is configured and
764 * whether it's not been done yet
765 */
766 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
767 return;
768
769 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
770 {
771 /* stub-router is hence done forever for this area, even if someone
772 * tries configure it (take effect next restart).
773 */
774 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
775 return;
776 }
777
778 /* startup stub-router configured and not yet done */
779 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
780
781 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
782 area->ospf->stub_router_startup_time);
783}
784
paul718e3742002-12-13 20:15:29 +0000785/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000786static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000787ospf_router_lsa_new (struct ospf_area *area)
788{
paul68980082003-03-25 05:07:42 +0000789 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000790 struct stream *s;
791 struct lsa_header *lsah;
792 struct ospf_lsa *new;
793 int length;
794
795 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000796 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000797
paul88d6cf32005-10-29 12:50:09 +0000798 /* check whether stub-router is desired, and if this is the first
799 * router LSA.
800 */
801 ospf_stub_router_check (area);
802
paul718e3742002-12-13 20:15:29 +0000803 /* Create a stream for LSA. */
804 s = stream_new (OSPF_MAX_LSA_SIZE);
paul718e3742002-12-13 20:15:29 +0000805 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000806 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000807 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000808
809 /* Set router-LSA body fields. */
810 ospf_router_lsa_body_set (s, area);
811
812 /* Set length. */
813 length = stream_get_endp (s);
paul779adb02006-01-18 15:07:38 +0000814 lsah = (struct lsa_header *) STREAM_DATA (s);
paul718e3742002-12-13 20:15:29 +0000815 lsah->length = htons (length);
816
817 /* Now, create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000818 if ( (new = ospf_lsa_new ()) == NULL)
819 {
820 zlog_err ("%s: Unable to create new lsa", __func__);
821 return NULL;
822 }
823
paul718e3742002-12-13 20:15:29 +0000824 new->area = area;
825 SET_FLAG (new->flags, OSPF_LSA_SELF);
826
827 /* Copy LSA data to store, discard stream. */
828 new->data = ospf_lsa_data_new (length);
829 memcpy (new->data, lsah, length);
830 stream_free (s);
831
832 return new;
833}
834
835/* Originate Router-LSA. */
paul88d6cf32005-10-29 12:50:09 +0000836static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000837ospf_router_lsa_originate (struct ospf_area *area)
838{
839 struct ospf_lsa *new;
paul88d6cf32005-10-29 12:50:09 +0000840
paul718e3742002-12-13 20:15:29 +0000841 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000842 if ( (new = ospf_router_lsa_new (area)) == NULL)
843 {
844 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
845 return NULL;
846 }
paul718e3742002-12-13 20:15:29 +0000847
848 /* Sanity check. */
849 if (new->data->adv_router.s_addr == 0)
850 {
851 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000852 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000853 ospf_lsa_discard (new);
854 return NULL;
855 }
856
857 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000858 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000859
860 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000861 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000862
863 /* Flooding new LSA through area. */
864 ospf_flood_through_area (area, NULL, new);
865
866 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
867 {
ajse588f212004-12-08 18:12:06 +0000868 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
paul718e3742002-12-13 20:15:29 +0000869 new->data->type, inet_ntoa (new->data->id), new);
870 ospf_lsa_header_dump (new->data);
871 }
872
873 return new;
874}
875
876/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000877static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000878ospf_router_lsa_refresh (struct ospf_lsa *lsa)
879{
880 struct ospf_area *area = lsa->area;
881 struct ospf_lsa *new;
882
883 /* Sanity check. */
884 assert (lsa->data);
885
886 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000887 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000888
889 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000890 if ( (new = ospf_router_lsa_new (area)) == NULL)
891 {
892 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
893 return NULL;
894 }
895
paul718e3742002-12-13 20:15:29 +0000896 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
897
paul68980082003-03-25 05:07:42 +0000898 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000899
900 /* Flood LSA through area. */
901 ospf_flood_through_area (area, NULL, new);
902
903 /* Debug logging. */
904 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
905 {
ajse588f212004-12-08 18:12:06 +0000906 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000907 new->data->type, inet_ntoa (new->data->id));
908 ospf_lsa_header_dump (new->data);
909 }
910
911 return NULL;
912}
913
paul4dadc292005-05-06 21:37:42 +0000914static int
paul718e3742002-12-13 20:15:29 +0000915ospf_router_lsa_timer (struct thread *t)
916{
917 struct ospf_area *area;
918
919 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000920 zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
paul718e3742002-12-13 20:15:29 +0000921
922 area = THREAD_ARG (t);
923 area->t_router_lsa_self = NULL;
924
925 /* Now refresh router-LSA. */
926 if (area->router_lsa_self)
927 ospf_router_lsa_refresh (area->router_lsa_self);
928 /* Newly originate router-LSA. */
929 else
930 ospf_router_lsa_originate (area);
931
932 return 0;
933}
934
935void
936ospf_router_lsa_timer_add (struct ospf_area *area)
937{
938 /* Keep area's self-originated router-LSA. */
939 struct ospf_lsa *lsa = area->router_lsa_self;
940
941 /* Cancel previously scheduled router-LSA timer. */
942 if (area->t_router_lsa_self)
943 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000944 zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
paul718e3742002-12-13 20:15:29 +0000945
946 OSPF_TIMER_OFF (area->t_router_lsa_self);
947
948 /* If router-LSA is originated previously, check the interval time. */
949 if (lsa)
950 {
951 int delay;
952 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
953 {
954 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
955 ospf_router_lsa_timer, delay);
956 return;
957 }
958 }
959
960 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000961 zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
paul718e3742002-12-13 20:15:29 +0000962
963 /* Immediately refresh router-LSA. */
964 OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
965}
966
967int
paul68980082003-03-25 05:07:42 +0000968ospf_router_lsa_update_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000969{
paul68980082003-03-25 05:07:42 +0000970 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +0000971 struct listnode *node, *nnode;
972 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +0000973
974 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000975 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +0000976
paul68980082003-03-25 05:07:42 +0000977 ospf->t_router_lsa_update = NULL;
paul718e3742002-12-13 20:15:29 +0000978
paul1eb8ef22005-04-07 07:30:20 +0000979 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000980 {
paul718e3742002-12-13 20:15:29 +0000981 struct ospf_lsa *lsa = area->router_lsa_self;
982 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +0000983 const char *area_str;
paul718e3742002-12-13 20:15:29 +0000984
985 /* Keep Area ID string. */
986 area_str = AREA_NAME (area);
987
988 /* If LSA not exist in this Area, originate new. */
989 if (lsa == NULL)
990 {
991 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000992 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +0000993
994 ospf_router_lsa_originate (area);
995 }
996 /* If router-ID is changed, Link ID must change.
997 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +0000998 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000999 {
1000 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001001 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +00001002 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
1003 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001004 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00001005 area->router_lsa_self = NULL;
1006
1007 /* Refresh router-LSA, (not install) and flood through area. */
1008 ospf_router_lsa_timer_add (area);
1009 }
1010 else
1011 {
1012 rl = (struct router_lsa *) lsa->data;
1013 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +00001014 if (rl->flags != ospf->flags)
paul718e3742002-12-13 20:15:29 +00001015 ospf_router_lsa_timer_add (area);
1016 }
1017 }
1018
1019 return 0;
1020}
1021
1022
1023/* network-LSA related functions. */
1024/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001025static void
paul718e3742002-12-13 20:15:29 +00001026ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1027{
1028 struct in_addr mask;
1029 struct route_node *rn;
1030 struct ospf_neighbor *nbr;
1031
1032 masklen2ip (oi->address->prefixlen, &mask);
1033 stream_put_ipv4 (s, mask.s_addr);
1034
1035 /* The network-LSA lists those routers that are fully adjacent to
1036 the Designated Router; each fully adjacent router is identified by
1037 its OSPF Router ID. The Designated Router includes itself in this
1038 list. RFC2328, Section 12.4.2 */
1039
1040 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1041 if ((nbr = rn->info) != NULL)
1042 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1043 stream_put_ipv4 (s, nbr->router_id.s_addr);
1044}
1045
paul4dadc292005-05-06 21:37:42 +00001046static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001047ospf_network_lsa_new (struct ospf_interface *oi)
1048{
1049 struct stream *s;
1050 struct ospf_lsa *new;
1051 struct lsa_header *lsah;
1052 int length;
1053
1054 /* If there are no neighbours on this network (the net is stub),
1055 the router does not originate network-LSA (see RFC 12.4.2) */
1056 if (oi->full_nbrs == 0)
1057 return NULL;
1058
1059 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001060 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001061
1062 /* Create new stream for LSA. */
1063 s = stream_new (OSPF_MAX_LSA_SIZE);
1064 lsah = (struct lsa_header *) STREAM_DATA (s);
1065
1066 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001067 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001068
1069 /* Set network-LSA body fields. */
1070 ospf_network_lsa_body_set (s, oi);
1071
1072 /* Set length. */
1073 length = stream_get_endp (s);
1074 lsah->length = htons (length);
1075
1076 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001077 if ( (new = ospf_lsa_new ()) == NULL)
1078 {
1079 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1080 return NULL;
1081 }
1082
paul718e3742002-12-13 20:15:29 +00001083 new->area = oi->area;
1084 SET_FLAG (new->flags, OSPF_LSA_SELF);
1085
1086 /* Copy LSA to store. */
1087 new->data = ospf_lsa_data_new (length);
1088 memcpy (new->data, lsah, length);
1089 stream_free (s);
1090
1091 return new;
1092}
1093
1094/* Originate network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001095static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001096ospf_network_lsa_originate (struct ospf_interface *oi)
1097{
1098 struct ospf_lsa *new;
1099
1100 /* Create new network-LSA instance. */
1101 new = ospf_network_lsa_new (oi);
1102 if (new == NULL)
1103 return NULL;
1104
1105 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001106 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001107
1108 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001109 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001110
1111 /* Flooding new LSA through area. */
1112 ospf_flood_through_area (oi->area, NULL, new);
1113
1114 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1115 {
ajse588f212004-12-08 18:12:06 +00001116 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001117 new->data->type, inet_ntoa (new->data->id), new);
1118 ospf_lsa_header_dump (new->data);
1119 }
1120
1121 return new;
1122}
1123
1124int
1125ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1126{
1127 struct ospf_area *area = lsa->area;
1128 struct ospf_lsa *new;
1129
1130 assert (lsa->data);
1131
1132 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001133 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001134
1135 /* Create new network-LSA instance. */
1136 new = ospf_network_lsa_new (oi);
1137 if (new == NULL)
1138 return -1;
1139 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1140
paul68980082003-03-25 05:07:42 +00001141 ospf_lsa_install (area->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001142
1143 /* Flood LSA through aera. */
1144 ospf_flood_through_area (area, NULL, new);
1145
1146 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1147 {
ajse588f212004-12-08 18:12:06 +00001148 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001149 new->data->type, inet_ntoa (new->data->id));
1150 ospf_lsa_header_dump (new->data);
1151 }
1152
1153 return 0;
1154}
1155
paul4dadc292005-05-06 21:37:42 +00001156static int
paul718e3742002-12-13 20:15:29 +00001157ospf_network_lsa_refresh_timer (struct thread *t)
1158{
1159 struct ospf_interface *oi;
1160
1161 oi = THREAD_ARG (t);
1162 oi->t_network_lsa_self = NULL;
1163
1164 if (oi->network_lsa_self)
1165 /* Now refresh network-LSA. */
1166 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1167 else
1168 /* Newly create network-LSA. */
1169 ospf_network_lsa_originate (oi);
1170
1171 return 0;
1172}
1173
1174void
1175ospf_network_lsa_timer_add (struct ospf_interface *oi)
1176{
1177 /* Keep interface's self-originated network-LSA. */
1178 struct ospf_lsa *lsa = oi->network_lsa_self;
1179
1180 /* Cancel previously schedules network-LSA timer. */
1181 if (oi->t_network_lsa_self)
1182 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001183 zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
paul718e3742002-12-13 20:15:29 +00001184 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1185
1186 /* If network-LSA is originated previously, check the interval time. */
1187 if (lsa)
1188 {
1189 int delay;
1190 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1191 {
1192 oi->t_network_lsa_self =
1193 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1194 oi, delay);
1195 return;
1196 }
1197 }
1198
1199 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001200 zlog_debug ("Scheduling network-LSA origination right away");
paul718e3742002-12-13 20:15:29 +00001201
1202 /* Immediately refresh network-LSA. */
1203 oi->t_network_lsa_self =
1204 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1205}
1206
1207
paul4dadc292005-05-06 21:37:42 +00001208static void
paul718e3742002-12-13 20:15:29 +00001209stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1210{
1211 u_int32_t metric;
1212 char *mp;
1213
1214 /* Put 0 metric. TOS metric is not supported. */
1215 metric = htonl (metric_value);
1216 mp = (char *) &metric;
1217 mp++;
1218 stream_put (s, mp, 3);
1219}
1220
1221/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001222static void
paul718e3742002-12-13 20:15:29 +00001223ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1224 u_int32_t metric)
1225{
1226 struct in_addr mask;
1227
1228 masklen2ip (p->prefixlen, &mask);
1229
1230 /* Put Network Mask. */
1231 stream_put_ipv4 (s, mask.s_addr);
1232
1233 /* Set # TOS. */
1234 stream_putc (s, (u_char) 0);
1235
1236 /* Set metric. */
1237 stream_put_ospf_metric (s, metric);
1238}
1239
paul4dadc292005-05-06 21:37:42 +00001240static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001241ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1242 u_int32_t metric, struct in_addr id)
1243{
1244 struct stream *s;
1245 struct ospf_lsa *new;
1246 struct lsa_header *lsah;
1247 int length;
1248
paulc24d6022005-11-20 14:54:12 +00001249 if (id.s_addr == 0xffffffff)
1250 {
1251 /* Maybe Link State ID not available. */
1252 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1253 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1254 OSPF_SUMMARY_LSA);
1255 return NULL;
1256 }
1257
paul718e3742002-12-13 20:15:29 +00001258 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001259 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001260
1261 /* Create new stream for LSA. */
1262 s = stream_new (OSPF_MAX_LSA_SIZE);
1263 lsah = (struct lsa_header *) STREAM_DATA (s);
1264
paul68980082003-03-25 05:07:42 +00001265 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1266 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001267
1268 /* Set summary-LSA body fields. */
1269 ospf_summary_lsa_body_set (s, p, metric);
1270
1271 /* Set length. */
1272 length = stream_get_endp (s);
1273 lsah->length = htons (length);
1274
1275 /* Create OSPF LSA instance. */
1276 new = ospf_lsa_new ();
1277 new->area = area;
1278 SET_FLAG (new->flags, OSPF_LSA_SELF);
1279
1280 /* Copy LSA to store. */
1281 new->data = ospf_lsa_data_new (length);
1282 memcpy (new->data, lsah, length);
1283 stream_free (s);
1284
1285 return new;
1286}
1287
1288/* Originate Summary-LSA. */
1289struct ospf_lsa *
1290ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1291 struct ospf_area *area)
1292{
1293 struct ospf_lsa *new;
1294 struct in_addr id;
1295
paul68980082003-03-25 05:07:42 +00001296 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001297
paulc24d6022005-11-20 14:54:12 +00001298 if (id.s_addr == 0xffffffff)
1299 {
1300 /* Maybe Link State ID not available. */
1301 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1302 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1303 OSPF_SUMMARY_LSA);
1304 return NULL;
1305 }
1306
paul718e3742002-12-13 20:15:29 +00001307 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001308 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1309 return NULL;
paul718e3742002-12-13 20:15:29 +00001310
1311 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001312 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001313
1314 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001315 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001316
1317 /* Flooding new LSA through area. */
1318 ospf_flood_through_area (area, NULL, new);
1319
1320 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1321 {
ajse588f212004-12-08 18:12:06 +00001322 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001323 new->data->type, inet_ntoa (new->data->id), new);
1324 ospf_lsa_header_dump (new->data);
1325 }
1326
1327 return new;
1328}
1329
1330struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001331ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001332{
1333 struct ospf_lsa *new;
1334 struct summary_lsa *sl;
1335 struct prefix p;
1336
1337 /* Sanity check. */
1338 assert (lsa->data);
1339
1340 sl = (struct summary_lsa *)lsa->data;
1341 p.prefixlen = ip_masklen (sl->mask);
1342 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1343 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001344
1345 if (!new)
1346 return NULL;
1347
paul718e3742002-12-13 20:15:29 +00001348 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1349
1350 /* Re-calculate checksum. */
1351 ospf_lsa_checksum (new->data);
1352
paul68980082003-03-25 05:07:42 +00001353 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001354
1355 /* Flood LSA through AS. */
1356 ospf_flood_through_area (new->area, NULL, new);
1357
1358 /* Debug logging. */
1359 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1360 {
ajse588f212004-12-08 18:12:06 +00001361 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001362 new->data->type, inet_ntoa (new->data->id));
1363 ospf_lsa_header_dump (new->data);
1364 }
1365
1366 return new;
1367}
1368
1369
1370/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001371static void
paul718e3742002-12-13 20:15:29 +00001372ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1373 u_int32_t metric)
1374{
1375 struct in_addr mask;
1376
1377 masklen2ip (p->prefixlen, &mask);
1378
1379 /* Put Network Mask. */
1380 stream_put_ipv4 (s, mask.s_addr);
1381
1382 /* Set # TOS. */
1383 stream_putc (s, (u_char) 0);
1384
1385 /* Set metric. */
1386 stream_put_ospf_metric (s, metric);
1387}
1388
paul4dadc292005-05-06 21:37:42 +00001389static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001390ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1391 u_int32_t metric, struct in_addr id)
1392{
1393 struct stream *s;
1394 struct ospf_lsa *new;
1395 struct lsa_header *lsah;
1396 int length;
1397
paulc24d6022005-11-20 14:54:12 +00001398 if (id.s_addr == 0xffffffff)
1399 {
1400 /* Maybe Link State ID not available. */
1401 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1402 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1403 OSPF_ASBR_SUMMARY_LSA);
1404 return NULL;
1405 }
1406
paul718e3742002-12-13 20:15:29 +00001407 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001408 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001409
1410 /* Create new stream for LSA. */
1411 s = stream_new (OSPF_MAX_LSA_SIZE);
1412 lsah = (struct lsa_header *) STREAM_DATA (s);
1413
paul68980082003-03-25 05:07:42 +00001414 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1415 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001416
1417 /* Set summary-LSA body fields. */
1418 ospf_summary_asbr_lsa_body_set (s, p, metric);
1419
1420 /* Set length. */
1421 length = stream_get_endp (s);
1422 lsah->length = htons (length);
1423
1424 /* Create OSPF LSA instance. */
1425 new = ospf_lsa_new ();
1426 new->area = area;
1427 SET_FLAG (new->flags, OSPF_LSA_SELF);
1428
1429 /* Copy LSA to store. */
1430 new->data = ospf_lsa_data_new (length);
1431 memcpy (new->data, lsah, length);
1432 stream_free (s);
1433
1434 return new;
1435}
1436
1437/* Originate summary-ASBR-LSA. */
1438struct ospf_lsa *
1439ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1440 struct ospf_area *area)
1441{
1442 struct ospf_lsa *new;
1443 struct in_addr id;
1444
paul68980082003-03-25 05:07:42 +00001445 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001446
paulc24d6022005-11-20 14:54:12 +00001447 if (id.s_addr == 0xffffffff)
1448 {
1449 /* Maybe Link State ID not available. */
1450 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1451 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1452 OSPF_ASBR_SUMMARY_LSA);
1453 return NULL;
1454 }
1455
paul718e3742002-12-13 20:15:29 +00001456 /* Create new summary-LSA instance. */
1457 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001458 if (!new)
1459 return NULL;
paul718e3742002-12-13 20:15:29 +00001460
1461 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001462 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001463
1464 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001465 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001466
1467 /* Flooding new LSA through area. */
1468 ospf_flood_through_area (area, NULL, new);
1469
1470 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1471 {
ajse588f212004-12-08 18:12:06 +00001472 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001473 new->data->type, inet_ntoa (new->data->id), new);
1474 ospf_lsa_header_dump (new->data);
1475 }
1476
1477 return new;
1478}
1479
1480struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001481ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001482{
1483 struct ospf_lsa *new;
1484 struct summary_lsa *sl;
1485 struct prefix p;
1486
1487 /* Sanity check. */
1488 assert (lsa->data);
1489
1490 sl = (struct summary_lsa *)lsa->data;
1491 p.prefixlen = ip_masklen (sl->mask);
1492 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1493 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001494 if (!new)
1495 return NULL;
paul718e3742002-12-13 20:15:29 +00001496
1497 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1498
1499 /* Re-calculate checksum. */
1500 ospf_lsa_checksum (new->data);
1501
paul68980082003-03-25 05:07:42 +00001502 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001503
1504 /* Flood LSA through area. */
1505 ospf_flood_through_area (new->area, NULL, new);
1506
1507 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1508 {
ajse588f212004-12-08 18:12:06 +00001509 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001510 new->data->type, inet_ntoa (new->data->id));
1511 ospf_lsa_header_dump (new->data);
1512 }
1513
1514 return new;
1515}
1516
1517/* AS-external-LSA related functions. */
1518
1519/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1520 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001521static struct in_addr
paul68980082003-03-25 05:07:42 +00001522ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001523{
1524 struct in_addr fwd;
1525 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001526 struct listnode *node;
1527 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001528
1529 fwd.s_addr = 0;
1530
1531 if (!nexthop.s_addr)
1532 return fwd;
1533
1534 /* Check whether nexthop is covered by OSPF network. */
1535 nh.family = AF_INET;
1536 nh.u.prefix4 = nexthop;
1537 nh.prefixlen = IPV4_MAX_BITLEN;
1538
paul1eb8ef22005-04-07 07:30:20 +00001539 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1540 if (if_is_operative (oi->ifp))
1541 if (oi->address->family == AF_INET)
1542 if (prefix_match (oi->address, &nh))
1543 return nexthop;
paul718e3742002-12-13 20:15:29 +00001544
1545 return fwd;
1546}
1547
paul718e3742002-12-13 20:15:29 +00001548/* NSSA-external-LSA related functions. */
1549
1550/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001551
paul718e3742002-12-13 20:15:29 +00001552struct in_addr
1553ospf_get_ip_from_ifp (struct ospf_interface *oi)
1554{
1555 struct in_addr fwd;
1556
1557 fwd.s_addr = 0;
1558
paul2e3b2e42002-12-13 21:03:13 +00001559 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001560 return oi->address->u.prefix4;
1561
1562 return fwd;
1563}
1564
1565/* Get 1st IP connection for Forward Addr */
1566struct in_addr
paulf2c80652002-12-13 21:44:27 +00001567ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001568{
1569 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001570 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001571 struct listnode *node;
1572 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001573
1574 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001575 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001576
paul1eb8ef22005-04-07 07:30:20 +00001577 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001578 {
paul2e3b2e42002-12-13 21:03:13 +00001579 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001580 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001581 if (oi->address && oi->address->family == AF_INET)
1582 {
1583 if (best_default.s_addr == 0)
1584 best_default = oi->address->u.prefix4;
1585 if (oi->area == area)
1586 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001587 }
paul718e3742002-12-13 20:15:29 +00001588 }
paulf2c80652002-12-13 21:44:27 +00001589 if (best_default.s_addr != 0)
1590 return best_default;
paul718e3742002-12-13 20:15:29 +00001591
paul68980082003-03-25 05:07:42 +00001592 if (best_default.s_addr != 0)
1593 return best_default;
1594
paul718e3742002-12-13 20:15:29 +00001595 return fwd;
1596}
hassobeebba72004-06-20 21:00:27 +00001597
paul718e3742002-12-13 20:15:29 +00001598#define DEFAULT_DEFAULT_METRIC 20
1599#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1600#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1601
1602#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1603
1604int
paul68980082003-03-25 05:07:42 +00001605metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001606{
paul68980082003-03-25 05:07:42 +00001607 return (ospf->dmetric[src].type < 0 ?
1608 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001609}
1610
1611int
paul68980082003-03-25 05:07:42 +00001612metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001613{
paul68980082003-03-25 05:07:42 +00001614 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001615 {
1616 if (src == DEFAULT_ROUTE)
1617 {
paul68980082003-03-25 05:07:42 +00001618 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001619 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1620 else
1621 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1622 }
paul68980082003-03-25 05:07:42 +00001623 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001624 return DEFAULT_DEFAULT_METRIC;
1625 else
paul68980082003-03-25 05:07:42 +00001626 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001627 }
1628
paul68980082003-03-25 05:07:42 +00001629 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001630}
1631
1632/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001633static void
paul68980082003-03-25 05:07:42 +00001634ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1635 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001636{
1637 struct prefix_ipv4 *p = &ei->p;
1638 struct in_addr mask, fwd_addr;
1639 u_int32_t mvalue;
1640 int mtype;
1641 int type;
1642
1643 /* Put Network Mask. */
1644 masklen2ip (p->prefixlen, &mask);
1645 stream_put_ipv4 (s, mask.s_addr);
1646
1647 /* If prefix is default, specify DEFAULT_ROUTE. */
1648 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1649
1650 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001651 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001652
1653 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001654 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001655
1656 /* Put type of external metric. */
1657 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1658
1659 /* Put 0 metric. TOS metric is not supported. */
1660 stream_put_ospf_metric (s, mvalue);
1661
1662 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001663 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001664
1665 /* Put forwarding address. */
1666 stream_put_ipv4 (s, fwd_addr.s_addr);
1667
1668 /* Put route tag -- This value should be introduced from configuration. */
1669 stream_putl (s, 0);
1670}
1671
1672/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001673static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001674ospf_external_lsa_new (struct ospf *ospf,
1675 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001676{
1677 struct stream *s;
1678 struct lsa_header *lsah;
1679 struct ospf_lsa *new;
1680 struct in_addr id;
1681 int length;
1682
1683 if (ei == NULL)
1684 {
1685 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001686 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
paul718e3742002-12-13 20:15:29 +00001687 return NULL;
1688 }
1689
1690 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001691 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001692
1693 /* If old Link State ID is specified, refresh LSA with same ID. */
1694 if (old_id)
1695 id = *old_id;
1696 /* Get Link State with unique ID. */
1697 else
1698 {
paul68980082003-03-25 05:07:42 +00001699 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001700 if (id.s_addr == 0xffffffff)
1701 {
1702 /* Maybe Link State ID not available. */
1703 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001704 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001705 return NULL;
1706 }
1707 }
1708
1709 /* Create new stream for LSA. */
1710 s = stream_new (OSPF_MAX_LSA_SIZE);
1711 lsah = (struct lsa_header *) STREAM_DATA (s);
1712
1713 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001714 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1715 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001716
1717 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001718 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001719
1720 /* Set length. */
1721 length = stream_get_endp (s);
1722 lsah->length = htons (length);
1723
1724 /* Now, create OSPF LSA instance. */
1725 new = ospf_lsa_new ();
1726 new->area = NULL;
1727 SET_FLAG (new->flags, OSPF_LSA_SELF|OSPF_LSA_APPROVED);
1728
1729 /* Copy LSA data to store, discard stream. */
1730 new->data = ospf_lsa_data_new (length);
1731 memcpy (new->data, lsah, length);
1732 stream_free (s);
1733
1734 return new;
1735}
1736
paul718e3742002-12-13 20:15:29 +00001737/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001738static void
paul68980082003-03-25 05:07:42 +00001739ospf_install_flood_nssa (struct ospf *ospf,
1740 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001741{
pauld4a53d52003-07-12 21:30:57 +00001742 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001743 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001744 struct ospf_area *area;
1745 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001746
pauld4a53d52003-07-12 21:30:57 +00001747 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1748 * which originated from an NSSA area. In which case it should not be
1749 * flooded back to NSSA areas.
1750 */
1751 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1752 return;
1753
paul718e3742002-12-13 20:15:29 +00001754 /* NSSA Originate or Refresh (If anyNSSA)
1755
1756 LSA is self-originated. And just installed as Type-5.
1757 Additionally, install as Type-7 LSDB for every attached NSSA.
1758
1759 P-Bit controls which ABR performs translation to outside world; If
1760 we are an ABR....do not set the P-bit, because we send the Type-5,
1761 not as the ABR Translator, but as the ASBR owner within the AS!
1762
1763 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1764 elected ABR Translator will see the P-bit, Translate, and re-flood.
1765
1766 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1767 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1768
paul1eb8ef22005-04-07 07:30:20 +00001769 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001770 {
hasso0c14ad82003-07-03 08:36:02 +00001771 /* Don't install Type-7 LSA's into nonNSSA area */
1772 if (area->external_routing != OSPF_AREA_NSSA)
1773 continue;
paul718e3742002-12-13 20:15:29 +00001774
paul68980082003-03-25 05:07:42 +00001775 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001776 new = ospf_lsa_dup (lsa);
1777 new->area = area;
1778 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001779
paul68980082003-03-25 05:07:42 +00001780 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001781 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001782 {
pauld4a53d52003-07-12 21:30:57 +00001783 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001784
1785 /* set non-zero FWD ADDR
1786
1787 draft-ietf-ospf-nssa-update-09.txt
1788
1789 if the network between the NSSA AS boundary router and the
1790 adjacent AS is advertised into OSPF as an internal OSPF route,
1791 the forwarding address should be the next op address as is cu
1792 currently done with type-5 LSAs. If the intervening network is
1793 not adversited into OSPF as an internal OSPF route and the
1794 type-7 LSA's P-bit is set a forwarding address should be
1795 selected from one of the router's active OSPF inteface addresses
1796 which belong to the NSSA. If no such addresses exist, then
1797 no type-7 LSA's with the P-bit set should originate from this
1798 router. */
1799
pauld4a53d52003-07-12 21:30:57 +00001800 /* kevinm: not updating lsa anymore, just new */
1801 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001802
1803 if (extlsa->e[0].fwd_addr.s_addr == 0)
1804 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001805
pauld7480322003-05-16 17:31:51 +00001806 if (extlsa->e[0].fwd_addr.s_addr == 0)
1807 {
1808 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001809 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001810 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001811 return;
1812 }
paulf2c80652002-12-13 21:44:27 +00001813 }
paul68980082003-03-25 05:07:42 +00001814 /* Re-calculate checksum. */
pauld4a53d52003-07-12 21:30:57 +00001815 ospf_lsa_checksum (new->data);
paul718e3742002-12-13 20:15:29 +00001816
paul68980082003-03-25 05:07:42 +00001817 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001818 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001819
1820 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001821 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001822 }
paul718e3742002-12-13 20:15:29 +00001823}
pauld4a53d52003-07-12 21:30:57 +00001824
paul4dadc292005-05-06 21:37:42 +00001825static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001826ospf_lsa_translated_nssa_new (struct ospf *ospf,
1827 struct ospf_lsa *type7)
1828{
1829
1830 struct ospf_lsa *new;
1831 struct as_external_lsa *ext, *extnew;
1832 struct external_info ei;
1833
1834 ext = (struct as_external_lsa *)(type7->data);
1835
1836 /* need external_info struct, fill in bare minimum */
1837 ei.p.family = AF_INET;
1838 ei.p.prefix = type7->data->id;
1839 ei.p.prefixlen = ip_masklen (ext->mask);
1840 ei.type = ZEBRA_ROUTE_OSPF;
1841 ei.nexthop = ext->header.adv_router;
1842 ei.route_map_set.metric = -1;
1843 ei.route_map_set.metric_type = -1;
1844 ei.tag = 0;
1845
1846 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1847 {
1848 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001849 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001850 "Translated Type-5 for %s",
1851 inet_ntoa (ei.p.prefix));
1852 return NULL;
1853 }
1854
1855 extnew = (struct as_external_lsa *)(new->data);
1856
1857 /* copy over Type-7 data to new */
1858 extnew->e[0].tos = ext->e[0].tos;
1859 extnew->e[0].route_tag = ext->e[0].route_tag;
1860 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1861 new->data->ls_seqnum = type7->data->ls_seqnum;
1862
1863 /* add translated flag, checksum and lock new lsa */
1864 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
1865 ospf_lsa_checksum (new->data);
1866 new = ospf_lsa_lock (new);
1867
1868 return new;
1869}
1870
1871/* compare type-5 to type-7
1872 * -1: err, 0: same, 1: different
1873 */
paul4dadc292005-05-06 21:37:42 +00001874static int
pauld4a53d52003-07-12 21:30:57 +00001875ospf_lsa_translated_nssa_compare (struct ospf_lsa *t7, struct ospf_lsa *t5)
1876{
1877
1878 struct as_external_lsa *e5 = (struct as_external_lsa *)t5,
1879 *e7 = (struct as_external_lsa *)t7;
1880
1881
1882 /* sanity checks */
1883 if (! ((t5->data->type == OSPF_AS_EXTERNAL_LSA)
1884 && (t7->data->type == OSPF_AS_NSSA_LSA)))
1885 return -1;
1886
1887 if (t5->data->id.s_addr != t7->data->id.s_addr)
1888 return -1;
1889
1890 if (t5->data->ls_seqnum != t7->data->ls_seqnum)
1891 return LSA_REFRESH_FORCE;
1892
1893 if (e5->mask.s_addr != e7->mask.s_addr)
1894 return LSA_REFRESH_FORCE;
1895
1896 if (e5->e[0].fwd_addr.s_addr != e7->e[0].fwd_addr.s_addr)
1897 return LSA_REFRESH_FORCE;
1898
1899 if (e5->e[0].route_tag != e7->e[0].route_tag)
1900 return LSA_REFRESH_FORCE;
1901
1902 if (GET_METRIC (e5->e[0].metric) != GET_METRIC (e7->e[0].metric))
1903 return LSA_REFRESH_FORCE;
1904
1905 return LSA_REFRESH_IF_CHANGED;
1906}
1907
1908/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1909struct ospf_lsa *
1910ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1911{
1912 struct ospf_lsa *new;
1913 struct as_external_lsa *extnew;
1914
1915 /* we cant use ospf_external_lsa_originate() as we need to set
1916 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1917 */
1918
1919 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1920 {
1921 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001922 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001923 "Type-7, Id %s, to Type-5",
1924 inet_ntoa (type7->data->id));
1925 return NULL;
1926 }
1927
1928 extnew = (struct as_external_lsa *)new;
1929
1930 if (IS_DEBUG_OSPF_NSSA)
1931 {
ajse588f212004-12-08 18:12:06 +00001932 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001933 "translated Type 7, installed:");
1934 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001935 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1936 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001937 }
1938
1939 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1940 {
1941 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001942 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001943 "Could not install LSA "
1944 "id %s", inet_ntoa (type7->data->id));
1945 return NULL;
1946 }
1947
1948 ospf->lsa_originate_count++;
1949 ospf_flood_through_as (ospf, NULL, new);
1950
1951 return new;
1952}
1953
1954/* Refresh Translated from NSSA AS-external-LSA. */
1955struct ospf_lsa *
1956ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1957 struct ospf_lsa *type5)
1958{
1959 struct ospf_lsa *new = NULL;
1960
1961 /* Sanity checks. */
1962 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00001963 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00001964 return NULL;
pauld4a53d52003-07-12 21:30:57 +00001965 if (type7)
1966 assert (type7->data);
1967 if (type5)
1968 assert (type5->data);
1969 assert (ospf->anyNSSA);
1970
1971 /* get required data according to what has been given */
1972 if (type7 && type5 == NULL)
1973 {
1974 /* find the translated Type-5 for this Type-7 */
1975 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1976 struct prefix_ipv4 p =
1977 {
1978 .prefix = type7->data->id,
1979 .prefixlen = ip_masklen (ext->mask),
1980 .family = AF_INET,
1981 };
1982
1983 type5 = ospf_external_info_find_lsa (ospf, &p);
1984 }
1985 else if (type5 && type7 == NULL)
1986 {
1987 /* find the type-7 from which supplied type-5 was translated,
1988 * ie find first type-7 with same LSA Id.
1989 */
paul1eb8ef22005-04-07 07:30:20 +00001990 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00001991 struct route_node *rn;
1992 struct ospf_lsa *lsa;
1993 struct ospf_area *area;
1994
paul1eb8ef22005-04-07 07:30:20 +00001995 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00001996 {
1997 if (area->external_routing != OSPF_AREA_NSSA
1998 && !type7)
1999 continue;
2000
2001 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
2002 {
2003 if (lsa->data->id.s_addr == type5->data->id.s_addr)
2004 {
2005 type7 = lsa;
2006 break;
2007 }
2008 }
2009 }
2010 }
2011
2012 /* do we have type7? */
2013 if (!type7)
2014 {
2015 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002016 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00002017 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00002018 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00002019 return NULL;
2020 }
2021
2022 /* do we have valid translated type5? */
2023 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
2024 {
2025 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002026 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00002027 "found for Type-7 with Id %s",
2028 inet_ntoa (type7->data->id));
2029 return NULL;
2030 }
2031
2032 /* Delete LSA from neighbor retransmit-list. */
2033 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
2034
2035 /* create new translated LSA */
2036 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
2037 {
2038 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002039 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00002040 "Type-7 for %s to Type-5",
2041 inet_ntoa (type7->data->id));
2042 return NULL;
2043 }
2044
2045 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
2046 {
2047 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002048 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00002049 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00002050 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00002051 return NULL;
2052 }
2053
2054 /* Flood LSA through area. */
2055 ospf_flood_through_as (ospf, NULL, new);
2056
2057 return new;
2058}
paul718e3742002-12-13 20:15:29 +00002059
2060int
2061is_prefix_default (struct prefix_ipv4 *p)
2062{
2063 struct prefix_ipv4 q;
2064
2065 q.family = AF_INET;
2066 q.prefix.s_addr = 0;
2067 q.prefixlen = 0;
2068
2069 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
2070}
2071
2072/* Originate an AS-external-LSA, install and flood. */
2073struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002074ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00002075{
2076 struct ospf_lsa *new;
2077
2078 /* Added for NSSA project....
2079
2080 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2081 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2082 every area. The Type-7's are flooded to every IR and every ABR; We
2083 install the Type-5 LSDB so that the normal "refresh" code operates
2084 as usual, and flag them as not used during ASE calculations. The
2085 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2086 Address of non-zero.
2087
2088 If an ABR is the elected NSSA translator, following SPF and during
2089 the ABR task it will translate all the scanned Type-7's, with P-bit
2090 ON and not-self generated, and translate to Type-5's throughout the
2091 non-NSSA/STUB AS.
2092
2093 A difference in operation depends whether this ASBR is an ABR
2094 or not. If not an ABR, the P-bit is ON, to indicate that any
2095 elected NSSA-ABR can perform its translation.
2096
2097 If an ABR, the P-bit is OFF; No ABR will perform translation and
2098 this ASBR will flood the Type-5 LSA as usual.
2099
2100 For the case where this ASBR is not an ABR, the ASE calculations
2101 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2102 demonstrate to the user that there are LSA's that belong to any
2103 attached NSSA.
2104
2105 Finally, it just so happens that when the ABR is translating every
2106 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2107 approved Type-5 (translated from Type-7); at the end of translation
2108 if any Translated Type-5's remain unapproved, then they must be
2109 flushed from the AS.
2110
2111 */
2112
2113 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002114 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002115 return NULL;
2116
2117 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002118 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002119 {
2120 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002121 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002122 inet_ntoa (ei->p.prefix));
2123 return NULL;
2124 }
2125
2126 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002127 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002128
2129 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002130 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002131
2132 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002133 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002134
paul718e3742002-12-13 20:15:29 +00002135 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002136 if (ospf->anyNSSA &&
2137 /* stay away from translated LSAs! */
2138 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002139 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002140
2141 /* Debug logging. */
2142 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2143 {
ajse588f212004-12-08 18:12:06 +00002144 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002145 new->data->type, inet_ntoa (new->data->id), new);
2146 ospf_lsa_header_dump (new->data);
2147 }
2148
2149 return new;
2150}
2151
2152/* Originate AS-external-LSA from external info with initial flag. */
2153int
paul68980082003-03-25 05:07:42 +00002154ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002155{
paul68980082003-03-25 05:07:42 +00002156 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002157 struct route_node *rn;
2158 struct external_info *ei;
2159 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002160 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002161
paul68980082003-03-25 05:07:42 +00002162 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002163
2164 /* Originate As-external-LSA from all type of distribute source. */
2165 if ((rt = EXTERNAL_INFO (type)))
2166 for (rn = route_top (rt); rn; rn = route_next (rn))
2167 if ((ei = rn->info) != NULL)
2168 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002169 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002170 zlog_warn ("LSA: AS-external-LSA was not originated.");
2171
2172 return 0;
2173}
2174
paul4dadc292005-05-06 21:37:42 +00002175static struct external_info *
paul020709f2003-04-04 02:44:16 +00002176ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002177{
2178 int type;
2179 struct route_node *rn;
2180 struct prefix_ipv4 p;
2181
2182 p.family = AF_INET;
2183 p.prefix.s_addr = 0;
2184 p.prefixlen = 0;
2185
2186 /* First, lookup redistributed default route. */
2187 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2188 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2189 {
2190 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2191 if (rn != NULL)
2192 {
2193 route_unlock_node (rn);
2194 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002195 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002196 return rn->info;
2197 }
2198 }
2199
2200 return NULL;
2201}
2202
2203int
paul68980082003-03-25 05:07:42 +00002204ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002205{
paul718e3742002-12-13 20:15:29 +00002206 struct prefix_ipv4 p;
2207 struct in_addr nexthop;
2208 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002209 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002210
Paul Jakma4021b602006-05-12 22:55:41 +00002211 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002212
2213 p.family = AF_INET;
2214 p.prefix.s_addr = 0;
2215 p.prefixlen = 0;
2216
Paul Jakma4021b602006-05-12 22:55:41 +00002217 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002218 {
2219 /* If there is no default route via redistribute,
2220 then originate AS-external-LSA with nexthop 0 (self). */
2221 nexthop.s_addr = 0;
2222 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2223 }
2224
paul020709f2003-04-04 02:44:16 +00002225 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002226 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002227
2228 return 0;
2229}
2230
paul645878f2003-04-13 21:42:11 +00002231/* Flush any NSSA LSAs for given prefix */
2232void
2233ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2234{
paul1eb8ef22005-04-07 07:30:20 +00002235 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002236 struct ospf_lsa *lsa;
2237 struct ospf_area *area;
2238
paul1eb8ef22005-04-07 07:30:20 +00002239 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002240 {
paul1eb8ef22005-04-07 07:30:20 +00002241 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002242 {
2243 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2244 ospf->router_id)))
2245 {
2246 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002247 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002248 inet_ntoa (p->prefix), p->prefixlen);
2249 continue;
2250 }
2251 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2252 if (!IS_LSA_MAXAGE (lsa))
2253 {
2254 ospf_refresher_unregister_lsa (ospf, lsa);
2255 ospf_lsa_flush_area (lsa, area);
2256 }
2257 }
paul645878f2003-04-13 21:42:11 +00002258 }
2259}
paul645878f2003-04-13 21:42:11 +00002260
paul718e3742002-12-13 20:15:29 +00002261/* Flush an AS-external-LSA from LSDB and routing domain. */
2262void
paul68980082003-03-25 05:07:42 +00002263ospf_external_lsa_flush (struct ospf *ospf,
2264 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002265 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002266{
2267 struct ospf_lsa *lsa;
2268
2269 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002270 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002271 inet_ntoa (p->prefix), p->prefixlen);
2272
2273 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002274 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002275 {
2276 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002277 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002278 inet_ntoa (p->prefix), p->prefixlen);
2279 return;
2280 }
hassobeebba72004-06-20 21:00:27 +00002281
pauld4a53d52003-07-12 21:30:57 +00002282 /* If LSA is selforiginated, not a translated LSA, and there is
2283 * NSSA area, flush Type-7 LSA's at first.
2284 */
2285 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2286 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002287 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002288
2289 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002290 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002291
2292 /* There must be no self-originated LSA in rtrs_external. */
2293#if 0
2294 /* Remove External route from Zebra. */
2295 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2296#endif
2297
2298 if (!IS_LSA_MAXAGE (lsa))
2299 {
2300 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002301 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002302
2303 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002304 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002305 }
2306
2307 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002308 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002309}
2310
2311void
paul68980082003-03-25 05:07:42 +00002312ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002313{
2314 struct prefix_ipv4 p;
2315 struct external_info *ei;
2316 struct ospf_lsa *lsa;
2317
2318 p.family = AF_INET;
2319 p.prefixlen = 0;
2320 p.prefix.s_addr = 0;
2321
paul020709f2003-04-04 02:44:16 +00002322 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002323 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002324
2325 if (ei)
2326 {
2327 if (lsa)
2328 {
2329 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002330 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002331 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002332 }
2333 else
2334 {
2335 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002336 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002337 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002338 }
2339 }
2340 else
2341 {
2342 if (lsa)
2343 {
2344 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002345 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002346 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002347 }
2348 }
2349}
2350
2351void
paul68980082003-03-25 05:07:42 +00002352ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002353{
2354 struct route_node *rn;
2355 struct external_info *ei;
2356
2357 if (type != DEFAULT_ROUTE)
2358 if (EXTERNAL_INFO(type))
2359 /* Refresh each redistributed AS-external-LSAs. */
2360 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2361 if ((ei = rn->info))
2362 if (!is_prefix_default (&ei->p))
2363 {
2364 struct ospf_lsa *lsa;
2365
paul68980082003-03-25 05:07:42 +00002366 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2367 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002368 else
paul68980082003-03-25 05:07:42 +00002369 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002370 }
2371}
2372
2373/* Refresh AS-external-LSA. */
2374void
paul68980082003-03-25 05:07:42 +00002375ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002376 struct external_info *ei, int force)
2377{
2378 struct ospf_lsa *new;
2379 int changed;
2380
2381 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002382 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002383 {
pauld4a53d52003-07-12 21:30:57 +00002384 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002385 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002386 "redist check fail",
2387 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002388 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002389 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +00002390 return;
2391 }
2392
2393 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002394 {
2395 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002396 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002397 lsa->data->type, inet_ntoa (lsa->data->id));
2398 return;
2399 }
paul718e3742002-12-13 20:15:29 +00002400
2401 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002402 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002403
2404 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002405 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002406
paul68980082003-03-25 05:07:42 +00002407 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002408
2409 if (new == NULL)
2410 {
2411 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002412 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002413 inet_ntoa (lsa->data->id));
2414 return;
2415 }
2416
2417 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2418
paul718e3742002-12-13 20:15:29 +00002419 /* Re-calculate checksum. */
2420 ospf_lsa_checksum (new->data);
2421
paul68980082003-03-25 05:07:42 +00002422 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002423
2424 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002425 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002426
paul718e3742002-12-13 20:15:29 +00002427 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002428 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002429 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002430
pauld4a53d52003-07-12 21:30:57 +00002431 /* Register self-originated LSA to refresh queue.
2432 * Translated LSAs should not be registered, but refreshed upon
2433 * refresh of the Type-7
2434 */
2435 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2436 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002437
2438 /* Debug logging. */
2439 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2440 {
ajse588f212004-12-08 18:12:06 +00002441 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002442 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002443 ospf_lsa_header_dump (new->data);
2444 }
2445
2446 return;
2447}
2448
2449
2450/* LSA installation functions. */
2451
2452/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002453static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002454ospf_router_lsa_install (struct ospf *ospf,
2455 struct ospf_lsa *new, int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002456{
2457 struct ospf_area *area = new->area;
2458
2459 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2460 The entire routing table must be recalculated, starting with
2461 the shortest path calculations for each area (not just the
2462 area whose link-state database has changed).
2463 */
2464 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002465 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002466
2467 if (IS_LSA_SELF (new))
2468 {
2469 /* Set router-LSA refresh timer. */
2470 OSPF_TIMER_OFF (area->t_router_lsa_self);
2471 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
pauld4a53d52003-07-12 21:30:57 +00002472 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
paul718e3742002-12-13 20:15:29 +00002473
2474 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002475 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002476 area->router_lsa_self = ospf_lsa_lock (new);
2477
2478 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002479 zlog_debug("LSA[Type%d]: ID %s seq 0x%x is self-originated",
paul0c2be262004-05-31 14:16:54 +00002480 new->data->type, inet_ntoa (new->data->id),
2481 ntohl(new->data->ls_seqnum));
paul718e3742002-12-13 20:15:29 +00002482 }
2483
2484 return new;
2485}
2486
2487#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2488 if (!(T)) \
2489 (T) = thread_add_timer (master, (F), oi, (V))
2490
2491/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002492static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002493ospf_network_lsa_install (struct ospf *ospf,
2494 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002495 struct ospf_lsa *new,
2496 int rt_recalc)
2497{
2498
2499 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2500 The entire routing table must be recalculated, starting with
2501 the shortest path calculations for each area (not just the
2502 area whose link-state database has changed).
2503 */
2504 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002505 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002506
2507 /* We supposed that when LSA is originated by us, we pass the int
2508 for which it was originated. If LSA was received by flooding,
2509 the RECEIVED flag is set, so we do not link the LSA to the int. */
2510 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2511 {
2512 /* Set LSRefresh timer. */
2513 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2514
2515 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2516 ospf_network_lsa_refresh_timer,
2517 OSPF_LS_REFRESH_TIME);
2518
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002519 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002520 oi->network_lsa_self = ospf_lsa_lock (new);
2521 }
2522
2523 return new;
2524}
2525
2526/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002527static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002528ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2529 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002530{
paul718e3742002-12-13 20:15:29 +00002531 if (rt_recalc && !IS_LSA_SELF (new))
2532 {
2533 /* RFC 2328 Section 13.2 Summary-LSAs
2534 The best route to the destination described by the summary-
2535 LSA must be recalculated (see Section 16.5). If this
2536 destination is an AS boundary router, it may also be
2537 necessary to re-examine all the AS-external-LSAs.
2538 */
2539
2540#if 0
2541 /* This doesn't exist yet... */
2542 ospf_summary_incremental_update(new); */
2543#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002544 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002545#endif /* #if 0 */
2546
2547 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002548 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002549 }
2550
2551 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002552 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002553
2554 return new;
2555}
2556
2557/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002558static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002559ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2560 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002561{
2562 if (rt_recalc && !IS_LSA_SELF (new))
2563 {
2564 /* RFC 2328 Section 13.2 Summary-LSAs
2565 The best route to the destination described by the summary-
2566 LSA must be recalculated (see Section 16.5). If this
2567 destination is an AS boundary router, it may also be
2568 necessary to re-examine all the AS-external-LSAs.
2569 */
2570#if 0
2571 /* These don't exist yet... */
2572 ospf_summary_incremental_update(new);
2573 /* Isn't this done by the above call?
2574 - RFC 2328 Section 16.5 implies it should be */
2575 /* ospf_ase_calculate_schedule(); */
2576#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002577 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002578#endif /* #if 0 */
2579 }
2580
2581 /* register LSA to refresh-list. */
2582 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002583 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002584
2585 return new;
2586}
2587
2588/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002589static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002590ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2591 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002592{
paul68980082003-03-25 05:07:42 +00002593 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002594 /* If LSA is not self-originated, calculate an external route. */
2595 if (rt_recalc)
2596 {
2597 /* RFC 2328 Section 13.2 AS-external-LSAs
2598 The best route to the destination described by the AS-
2599 external-LSA must be recalculated (see Section 16.6).
2600 */
2601
2602 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002603 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002604 }
2605
pauld4a53d52003-07-12 21:30:57 +00002606 if (new->data->type == OSPF_AS_NSSA_LSA)
2607 {
2608 /* There is no point to register selforiginate Type-7 LSA for
2609 * refreshing. We rely on refreshing Type-5 LSA's
2610 */
2611 if (IS_LSA_SELF (new))
2612 return new;
2613 else
2614 {
2615 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2616 * New translations will be taken care of by the abr_task.
2617 */
2618 ospf_translated_nssa_refresh (ospf, new, NULL);
2619 }
2620 }
pauld7480322003-05-16 17:31:51 +00002621
pauld4a53d52003-07-12 21:30:57 +00002622 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002623 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002624 */
hassobeebba72004-06-20 21:00:27 +00002625 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002626 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002627
2628 return new;
2629}
2630
2631void
paul68980082003-03-25 05:07:42 +00002632ospf_discard_from_db (struct ospf *ospf,
2633 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002634{
2635 struct ospf_lsa *old;
2636
Paul Jakmaac904de2006-06-15 12:04:57 +00002637 if (!lsdb)
2638 {
2639 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2640 if (!lsa)
2641 zlog_warn ("%s: and NULL LSA!", __func__);
2642 else
2643 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2644 lsa->data->type, inet_ntoa (lsa->data->id));
2645 return;
2646 }
2647
paul718e3742002-12-13 20:15:29 +00002648 old = ospf_lsdb_lookup (lsdb, lsa);
2649
2650 if (!old)
2651 return;
2652
2653 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002654 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002655
2656 switch (old->data->type)
2657 {
2658 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002659 ospf_ase_unregister_external_lsa (old, ospf);
2660 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2661 break;
paul718e3742002-12-13 20:15:29 +00002662#ifdef HAVE_OPAQUE_LSA
2663 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002664 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002665 break;
paul69310a62005-05-11 18:09:59 +00002666#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002667 case OSPF_AS_NSSA_LSA:
2668 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2669 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002670 break;
paul718e3742002-12-13 20:15:29 +00002671 default:
paul68980082003-03-25 05:07:42 +00002672 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002673 break;
2674 }
2675
paul68980082003-03-25 05:07:42 +00002676 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002677 ospf_lsa_discard (old);
2678}
2679
paul718e3742002-12-13 20:15:29 +00002680struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002681ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2682 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002683{
2684 struct ospf_lsa *new = NULL;
2685 struct ospf_lsa *old = NULL;
2686 struct ospf_lsdb *lsdb = NULL;
2687 int rt_recalc;
2688
2689 /* Set LSDB. */
2690 switch (lsa->data->type)
2691 {
paulf2c80652002-12-13 21:44:27 +00002692 /* kevinm */
2693 case OSPF_AS_NSSA_LSA:
2694 if (lsa->area)
2695 lsdb = lsa->area->lsdb;
2696 else
paul68980082003-03-25 05:07:42 +00002697 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002698 break;
paul718e3742002-12-13 20:15:29 +00002699 case OSPF_AS_EXTERNAL_LSA:
2700#ifdef HAVE_OPAQUE_LSA
2701 case OSPF_OPAQUE_AS_LSA:
2702#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002703 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002704 break;
2705 default:
2706 lsdb = lsa->area->lsdb;
2707 break;
2708 }
2709
paul718e3742002-12-13 20:15:29 +00002710 assert (lsdb);
2711
2712 /* RFC 2328 13.2. Installing LSAs in the database
2713
2714 Installing a new LSA in the database, either as the result of
2715 flooding or a newly self-originated LSA, may cause the OSPF
2716 routing table structure to be recalculated. The contents of the
2717 new LSA should be compared to the old instance, if present. If
2718 there is no difference, there is no need to recalculate the
2719 routing table. When comparing an LSA to its previous instance,
2720 the following are all considered to be differences in contents:
2721
2722 o The LSA's Options field has changed.
2723
2724 o One of the LSA instances has LS age set to MaxAge, and
2725 the other does not.
2726
2727 o The length field in the LSA header has changed.
2728
2729 o The body of the LSA (i.e., anything outside the 20-byte
2730 LSA header) has changed. Note that this excludes changes
2731 in LS Sequence Number and LS Checksum.
2732
2733 */
2734 /* Look up old LSA and determine if any SPF calculation or incremental
2735 update is needed */
2736 old = ospf_lsdb_lookup (lsdb, lsa);
2737
2738 /* Do comparision and record if recalc needed. */
2739 rt_recalc = 0;
2740 if ( old == NULL || ospf_lsa_different(old, lsa))
2741 rt_recalc = 1;
2742
paul7ddf1d62003-10-13 09:06:46 +00002743 /*
2744 Sequence number check (Section 14.1 of rfc 2328)
2745 "Premature aging is used when it is time for a self-originated
2746 LSA's sequence number field to wrap. At this point, the current
2747 LSA instance (having LS sequence number MaxSequenceNumber) must
2748 be prematurely aged and flushed from the routing domain before a
2749 new instance with sequence number equal to InitialSequenceNumber
2750 can be originated. "
2751 */
2752
Paul Jakmac2b478d2006-03-30 14:16:11 +00002753 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002754 {
2755 if (ospf_lsa_is_self_originated(ospf, lsa))
2756 {
paul0c2be262004-05-31 14:16:54 +00002757 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2758
2759 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002760 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2761 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2762
2763 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2764 {
ajse588f212004-12-08 18:12:06 +00002765 zlog_debug ("ospf_lsa_install() Premature Aging "
paul7ddf1d62003-10-13 09:06:46 +00002766 "lsa 0x%lx", (u_long)lsa);
2767 ospf_lsa_header_dump (lsa->data);
2768 }
2769 }
2770 else
2771 {
2772 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2773 {
ajse588f212004-12-08 18:12:06 +00002774 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002775 "that was not self originated. Ignoring\n");
2776 ospf_lsa_header_dump (lsa->data);
2777 }
2778 return old;
2779 }
2780 }
2781
paul718e3742002-12-13 20:15:29 +00002782 /* discard old LSA from LSDB */
2783 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002784 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002785
paul718e3742002-12-13 20:15:29 +00002786 /* Calculate Checksum if self-originated?. */
2787 if (IS_LSA_SELF (lsa))
2788 ospf_lsa_checksum (lsa->data);
2789
hassofe71a972004-12-22 16:16:02 +00002790 /* Insert LSA to LSDB. */
2791 ospf_lsdb_add (lsdb, lsa);
2792 lsa->lsdb = lsdb;
2793
paul718e3742002-12-13 20:15:29 +00002794 /* Do LSA specific installation process. */
2795 switch (lsa->data->type)
2796 {
2797 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002798 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002799 break;
2800 case OSPF_NETWORK_LSA:
2801 assert (oi);
paul68980082003-03-25 05:07:42 +00002802 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002803 break;
2804 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002805 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002806 break;
2807 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002808 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002809 break;
2810 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002811 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002812 break;
2813#ifdef HAVE_OPAQUE_LSA
2814 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002815 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002816 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002817 else
paul68980082003-03-25 05:07:42 +00002818 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002819 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002820 case OSPF_OPAQUE_AREA_LSA:
2821 case OSPF_OPAQUE_AS_LSA:
2822 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2823 break;
2824#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002825 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002826 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002827 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002828 break;
2829 }
2830
2831 if (new == NULL)
2832 return new; /* Installation failed, cannot proceed further -- endo. */
2833
2834 /* Debug logs. */
2835 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2836 {
2837 char area_str[INET_ADDRSTRLEN];
2838
2839 switch (lsa->data->type)
2840 {
2841 case OSPF_AS_EXTERNAL_LSA:
2842#ifdef HAVE_OPAQUE_LSA
2843 case OSPF_OPAQUE_AS_LSA:
2844#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002845 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002846 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002847 dump_lsa_key (new),
2848 LOOKUP (ospf_lsa_type_msg, new->data->type));
2849 break;
2850 default:
2851 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002852 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002853 dump_lsa_key (new),
2854 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2855 break;
2856 }
2857 }
2858
paul7ddf1d62003-10-13 09:06:46 +00002859 /*
2860 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2861 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2862 */
2863 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2864 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002865 {
paul7ddf1d62003-10-13 09:06:46 +00002866 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002867 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002868 new->data->type,
2869 inet_ntoa (new->data->id),
2870 lsa);
paul68980082003-03-25 05:07:42 +00002871 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002872 }
2873
2874 return new;
2875}
2876
2877
paul4dadc292005-05-06 21:37:42 +00002878static int
paul68980082003-03-25 05:07:42 +00002879ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002880{
paul1eb8ef22005-04-07 07:30:20 +00002881 struct listnode *node, *nnode;
2882 struct ospf_interface *oi;
2883
2884 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002885 {
paul718e3742002-12-13 20:15:29 +00002886 struct route_node *rn;
2887 struct ospf_neighbor *nbr;
2888
2889 if (ospf_if_is_enable (oi))
2890 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2891 if ((nbr = rn->info) != NULL)
2892 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2893 {
2894 route_unlock_node (rn);
2895 return 0;
2896 }
2897 }
2898
2899 return 1;
2900}
2901
2902
2903#ifdef ORIGINAL_CODING
2904/* This function flood the maxaged LSA to DR. */
2905void
2906ospf_maxage_flood (struct ospf_lsa *lsa)
2907{
2908 switch (lsa->data->type)
2909 {
2910 case OSPF_ROUTER_LSA:
2911 case OSPF_NETWORK_LSA:
2912 case OSPF_SUMMARY_LSA:
2913 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00002914 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00002915#ifdef HAVE_OPAQUE_LSA
2916 case OSPF_OPAQUE_LINK_LSA:
2917 case OSPF_OPAQUE_AREA_LSA:
2918#endif /* HAVE_OPAQUE_LSA */
2919 ospf_flood_through_area (lsa->area, NULL, lsa);
2920 break;
2921 case OSPF_AS_EXTERNAL_LSA:
2922#ifdef HAVE_OPAQUE_LSA
2923 case OSPF_OPAQUE_AS_LSA:
2924#endif /* HAVE_OPAQUE_LSA */
2925 ospf_flood_through_as (NULL, lsa);
2926 break;
2927 default:
2928 break;
2929 }
2930}
2931#endif /* ORIGINAL_CODING */
2932
paul4dadc292005-05-06 21:37:42 +00002933static int
paul718e3742002-12-13 20:15:29 +00002934ospf_maxage_lsa_remover (struct thread *thread)
2935{
paul68980082003-03-25 05:07:42 +00002936 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002937 struct ospf_lsa *lsa;
2938 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002939 int reschedule = 0;
2940
paul68980082003-03-25 05:07:42 +00002941 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002942
2943 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002944 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002945
paul68980082003-03-25 05:07:42 +00002946 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002947
2948 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002949 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002950 {
paul718e3742002-12-13 20:15:29 +00002951 if (lsa->retransmit_counter > 0)
2952 {
2953 reschedule = 1;
2954 continue;
2955 }
2956
2957 /* Remove LSA from the LSDB */
2958 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2959 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002960 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
paul7ddf1d62003-10-13 09:06:46 +00002961 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002962
2963 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002964 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002965 lsa->data->type, inet_ntoa (lsa->data->id));
2966
2967 /* Flood max age LSA. */
2968#ifdef ORIGINAL_CODING
2969 ospf_maxage_flood (lsa);
2970#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00002971 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00002972#endif /* ORIGINAL_CODING */
2973
paul7ddf1d62003-10-13 09:06:46 +00002974 if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
2975 {
2976 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002977 zlog_debug ("originating new router lsa for lsa 0x%lx \n",
paul7ddf1d62003-10-13 09:06:46 +00002978 (u_long)lsa);
2979 ospf_router_lsa_originate(lsa->area);
2980 }
2981
paul718e3742002-12-13 20:15:29 +00002982 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002983 if (lsa->lsdb)
2984 {
2985 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2986 ospf_lsdb_delete (lsa->lsdb, lsa);
2987 }
2988 else
2989 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2990 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002991 }
2992
2993 /* A MaxAge LSA must be removed immediately from the router's link
2994 state database as soon as both a) it is no longer contained on any
2995 neighbor Link state retransmission lists and b) none of the router's
2996 neighbors are in states Exchange or Loading. */
2997 if (reschedule)
paul68980082003-03-25 05:07:42 +00002998 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00002999
3000 return 0;
3001}
3002
paul4dadc292005-05-06 21:37:42 +00003003static int
paul68980082003-03-25 05:07:42 +00003004ospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new)
paul718e3742002-12-13 20:15:29 +00003005{
hasso52dc7ee2004-09-23 19:18:23 +00003006 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003007 struct ospf_lsa *lsa;
3008
3009 for (ALL_LIST_ELEMENTS_RO (ospf->maxage_lsa, node, lsa))
3010 if (lsa == new)
paul718e3742002-12-13 20:15:29 +00003011 return 1;
3012
3013 return 0;
3014}
3015
3016void
paul68980082003-03-25 05:07:42 +00003017ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003018{
hasso52dc7ee2004-09-23 19:18:23 +00003019 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003020
paul68980082003-03-25 05:07:42 +00003021 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00003022 {
paul68980082003-03-25 05:07:42 +00003023 list_delete_node (ospf->maxage_lsa, n);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003024 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +00003025 }
3026}
3027
3028void
paul68980082003-03-25 05:07:42 +00003029ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003030{
3031 /* When we saw a MaxAge LSA flooded to us, we put it on the list
3032 and schedule the MaxAge LSA remover. */
paul68980082003-03-25 05:07:42 +00003033 if (ospf_lsa_maxage_exist (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003034 {
3035 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003036 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00003037 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
3038 return;
3039 }
3040
paul68980082003-03-25 05:07:42 +00003041 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00003042
3043 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003044 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003045
paul68980082003-03-25 05:07:42 +00003046 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003047}
3048
paul4dadc292005-05-06 21:37:42 +00003049static int
paul68980082003-03-25 05:07:42 +00003050ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003051{
paul718e3742002-12-13 20:15:29 +00003052 /* Stay away from any Local Translated Type-7 LSAs */
3053 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3054 return 0;
paul718e3742002-12-13 20:15:29 +00003055
3056 if (IS_LSA_MAXAGE (lsa))
3057 /* Self-originated LSAs should NOT time-out instead,
3058 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00003059 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003060 {
3061 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003062 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003063
3064 switch (lsa->data->type)
3065 {
paul718e3742002-12-13 20:15:29 +00003066#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00003067 case OSPF_OPAQUE_LINK_LSA:
3068 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003069 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003070 /*
3071 * As a general rule, whenever network topology has changed
3072 * (due to an LSA removal in this case), routing recalculation
3073 * should be triggered. However, this is not true for opaque
3074 * LSAs. Even if an opaque LSA instance is going to be removed
3075 * from the routing domain, it does not mean a change in network
3076 * topology, and thus, routing recalculation is not needed here.
3077 */
3078 break;
paul718e3742002-12-13 20:15:29 +00003079#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00003080 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003081 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003082 ospf_ase_incremental_update (ospf, lsa);
3083 break;
paul718e3742002-12-13 20:15:29 +00003084 default:
paul68980082003-03-25 05:07:42 +00003085 ospf_spf_calculate_schedule (ospf);
3086 break;
paul718e3742002-12-13 20:15:29 +00003087 }
paul68980082003-03-25 05:07:42 +00003088 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003089 }
3090
3091 return 0;
3092}
3093
3094/* Periodical check of MaxAge LSA. */
3095int
paul68980082003-03-25 05:07:42 +00003096ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003097{
paul68980082003-03-25 05:07:42 +00003098 struct ospf *ospf = THREAD_ARG (thread);
3099 struct route_node *rn;
3100 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003101 struct ospf_area *area;
3102 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003103
paul68980082003-03-25 05:07:42 +00003104 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003105
paul1eb8ef22005-04-07 07:30:20 +00003106 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003107 {
paul68980082003-03-25 05:07:42 +00003108 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3109 ospf_lsa_maxage_walker_remover (ospf, lsa);
3110 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3111 ospf_lsa_maxage_walker_remover (ospf, lsa);
3112 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3113 ospf_lsa_maxage_walker_remover (ospf, lsa);
3114 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3115 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003116#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003117 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3118 ospf_lsa_maxage_walker_remover (ospf, lsa);
3119 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3120 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003121#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003122 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3123 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003124 }
3125
paul4fb949e2003-05-10 20:06:51 +00003126 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003127 if (ospf->lsdb)
3128 {
3129 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3130 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003131#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003132 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3133 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003134#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003135 }
paul718e3742002-12-13 20:15:29 +00003136
paul68980082003-03-25 05:07:42 +00003137 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3138 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003139 return 0;
3140}
3141
paul68980082003-03-25 05:07:42 +00003142struct ospf_lsa *
3143ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3144 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003145{
paul68980082003-03-25 05:07:42 +00003146 struct ospf_lsa *lsa;
3147 struct in_addr mask, id;
3148 struct lsa_header_mask
3149 {
3150 struct lsa_header header;
3151 struct in_addr mask;
3152 } *hmask;
paul718e3742002-12-13 20:15:29 +00003153
paul68980082003-03-25 05:07:42 +00003154 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3155 if (lsa == NULL)
3156 return NULL;
paul718e3742002-12-13 20:15:29 +00003157
paul68980082003-03-25 05:07:42 +00003158 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003159
paul68980082003-03-25 05:07:42 +00003160 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003161
paul68980082003-03-25 05:07:42 +00003162 if (mask.s_addr != hmask->mask.s_addr)
3163 {
3164 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3165 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3166 if (!lsa)
3167 return NULL;
3168 }
paul718e3742002-12-13 20:15:29 +00003169
paul68980082003-03-25 05:07:42 +00003170 return lsa;
paul718e3742002-12-13 20:15:29 +00003171}
3172
3173struct ospf_lsa *
3174ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3175 struct in_addr id, struct in_addr adv_router)
3176{
paule05fba42003-04-13 20:20:53 +00003177 struct ospf *ospf = ospf_lookup();
3178 assert(ospf);
3179
paul718e3742002-12-13 20:15:29 +00003180 switch (type)
3181 {
3182 case OSPF_ROUTER_LSA:
3183 case OSPF_NETWORK_LSA:
3184 case OSPF_SUMMARY_LSA:
3185 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003186 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003187#ifdef HAVE_OPAQUE_LSA
3188 case OSPF_OPAQUE_LINK_LSA:
3189 case OSPF_OPAQUE_AREA_LSA:
3190#endif /* HAVE_OPAQUE_LSA */
3191 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003192 case OSPF_AS_EXTERNAL_LSA:
3193#ifdef HAVE_OPAQUE_LSA
3194 case OSPF_OPAQUE_AS_LSA:
3195#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003196 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003197 default:
3198 break;
3199 }
3200
3201 return NULL;
3202}
3203
3204struct ospf_lsa *
3205ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3206 struct in_addr id)
3207{
3208 struct ospf_lsa *lsa;
3209 struct route_node *rn;
3210
3211 switch (type)
3212 {
3213 case OSPF_ROUTER_LSA:
3214 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003215 case OSPF_NETWORK_LSA:
3216 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3217 if ((lsa = rn->info))
3218 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3219 {
3220 route_unlock_node (rn);
3221 return lsa;
3222 }
3223 break;
3224 case OSPF_SUMMARY_LSA:
3225 case OSPF_ASBR_SUMMARY_LSA:
3226 /* Currently not used. */
3227 assert (1);
3228 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003229 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003230 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003231#ifdef HAVE_OPAQUE_LSA
3232 case OSPF_OPAQUE_LINK_LSA:
3233 case OSPF_OPAQUE_AREA_LSA:
3234 case OSPF_OPAQUE_AS_LSA:
3235 /* Currently not used. */
3236 break;
3237#endif /* HAVE_OPAQUE_LSA */
3238 default:
3239 break;
3240 }
3241
3242 return NULL;
3243}
3244
3245struct ospf_lsa *
3246ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3247{
3248 struct ospf_lsa *match;
3249
3250#ifdef HAVE_OPAQUE_LSA
3251 /*
3252 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3253 * is redefined to have two subfields; opaque-type and opaque-id.
3254 * However, it is harmless to treat the two sub fields together, as if
3255 * they two were forming a unique LSA-ID.
3256 */
3257#endif /* HAVE_OPAQUE_LSA */
3258
3259 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3260
3261 if (match == NULL)
3262 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003263 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003264 lsah->type, inet_ntoa (lsah->id));
3265
3266 return match;
3267}
3268
3269/* return +n, l1 is more recent.
3270 return -n, l2 is more recent.
3271 return 0, l1 and l2 is identical. */
3272int
3273ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3274{
3275 int r;
3276 int x, y;
3277
3278 if (l1 == NULL && l2 == NULL)
3279 return 0;
3280 if (l1 == NULL)
3281 return -1;
3282 if (l2 == NULL)
3283 return 1;
3284
3285 /* compare LS sequence number. */
3286 x = (int) ntohl (l1->data->ls_seqnum);
3287 y = (int) ntohl (l2->data->ls_seqnum);
3288 if (x > y)
3289 return 1;
3290 if (x < y)
3291 return -1;
3292
3293 /* compare LS checksum. */
3294 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3295 if (r)
3296 return r;
3297
3298 /* compare LS age. */
3299 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3300 return 1;
3301 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3302 return -1;
3303
3304 /* compare LS age with MaxAgeDiff. */
3305 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3306 return -1;
3307 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3308 return 1;
3309
3310 /* LSAs are identical. */
3311 return 0;
3312}
3313
3314/* If two LSAs are different, return 1, otherwise return 0. */
3315int
3316ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3317{
3318 char *p1, *p2;
3319 assert (l1);
3320 assert (l2);
3321 assert (l1->data);
3322 assert (l2->data);
3323
3324 if (l1->data->options != l2->data->options)
3325 return 1;
3326
3327 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3328 return 1;
3329
3330 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3331 return 1;
3332
3333 if (l1->data->length != l2->data->length)
3334 return 1;
3335
3336 if (l1->data->length == 0)
3337 return 1;
3338
pauld1825832003-04-03 01:27:01 +00003339 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003340
3341 p1 = (char *) l1->data;
3342 p2 = (char *) l2->data;
3343
3344 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3345 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3346 return 1;
3347
3348 return 0;
3349}
3350
3351#ifdef ORIGINAL_CODING
3352void
3353ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3354 struct ospf_lsa *self,
3355 struct ospf_lsa *new)
3356{
3357 u_int32_t seqnum;
3358
3359 /* Adjust LS Sequence Number. */
3360 seqnum = ntohl (new->data->ls_seqnum) + 1;
3361 self->data->ls_seqnum = htonl (seqnum);
3362
3363 /* Recalculate LSA checksum. */
3364 ospf_lsa_checksum (self->data);
3365
3366 /* Reflooding LSA. */
3367 /* RFC2328 Section 13.3
3368 On non-broadcast networks, separate Link State Update
3369 packets must be sent, as unicasts, to each adjacent neighbor
3370 (i.e., those in state Exchange or greater). The destination
3371 IP addresses for these packets are the neighbors' IP
3372 addresses. */
3373 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3374 {
3375 struct route_node *rn;
3376 struct ospf_neighbor *onbr;
3377
3378 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3379 if ((onbr = rn->info) != NULL)
3380 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3381 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3382 }
3383 else
3384 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3385
3386 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003387 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003388 self->data->type, inet_ntoa (self->data->id));
3389}
3390#else /* ORIGINAL_CODING */
3391static int
paul68980082003-03-25 05:07:42 +00003392ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003393{
3394 if (lsa == NULL || !IS_LSA_SELF (lsa))
3395 return 0;
3396
3397 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003398 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 +00003399
3400 /* Force given lsa's age to MaxAge. */
3401 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3402
3403 switch (lsa->data->type)
3404 {
3405#ifdef HAVE_OPAQUE_LSA
3406 case OSPF_OPAQUE_LINK_LSA:
3407 case OSPF_OPAQUE_AREA_LSA:
3408 case OSPF_OPAQUE_AS_LSA:
3409 ospf_opaque_lsa_refresh (lsa);
3410 break;
3411#endif /* HAVE_OPAQUE_LSA */
3412 default:
paul68980082003-03-25 05:07:42 +00003413 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003414 break;
3415 }
3416
3417 return 0;
3418}
3419
3420void
paul68980082003-03-25 05:07:42 +00003421ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003422{
paul1eb8ef22005-04-07 07:30:20 +00003423 struct listnode *node, *nnode;
3424 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003425 struct ospf_area *area;
3426 struct ospf_interface *oi;
3427 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003428 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003429 int need_to_flush_ase = 0;
3430
paul1eb8ef22005-04-07 07:30:20 +00003431 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003432 {
paul718e3742002-12-13 20:15:29 +00003433 if ((lsa = area->router_lsa_self) != NULL)
3434 {
3435 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003436 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 +00003437
3438 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003439 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003440 area->router_lsa_self = NULL;
3441 OSPF_TIMER_OFF (area->t_router_lsa_self);
3442 }
3443
paul1eb8ef22005-04-07 07:30:20 +00003444 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003445 {
paul718e3742002-12-13 20:15:29 +00003446 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003447 && oi->state == ISM_DR
3448 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003449 {
3450 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003451 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 +00003452
3453 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003454 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003455 oi->network_lsa_self = NULL;
3456 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3457 }
3458
3459 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3460 && area->external_routing == OSPF_AREA_DEFAULT)
3461 need_to_flush_ase = 1;
3462 }
3463
paul68980082003-03-25 05:07:42 +00003464 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3465 ospf_lsa_flush_schedule (ospf, lsa);
3466 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3467 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003468#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003469 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3470 ospf_lsa_flush_schedule (ospf, lsa);
3471 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3472 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003473#endif /* HAVE_OPAQUE_LSA */
3474 }
3475
3476 if (need_to_flush_ase)
3477 {
paul68980082003-03-25 05:07:42 +00003478 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3479 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003480#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003481 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3482 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003483#endif /* HAVE_OPAQUE_LSA */
3484 }
3485
3486 /*
3487 * Make sure that the MaxAge LSA remover is executed immediately,
3488 * without conflicting to other threads.
3489 */
paul68980082003-03-25 05:07:42 +00003490 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003491 {
paul68980082003-03-25 05:07:42 +00003492 OSPF_TIMER_OFF (ospf->t_maxage);
3493 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003494 }
3495
3496 return;
3497}
3498#endif /* ORIGINAL_CODING */
3499
3500/* If there is self-originated LSA, then return 1, otherwise return 0. */
3501/* An interface-independent version of ospf_lsa_is_self_originated */
3502int
paul68980082003-03-25 05:07:42 +00003503ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003504{
hasso52dc7ee2004-09-23 19:18:23 +00003505 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003506 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003507
3508 /* This LSA is already checked. */
3509 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3510 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3511
3512 /* Make sure LSA is self-checked. */
3513 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3514
3515 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003516 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003517 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3518
3519 /* LSA is router-LSA. */
3520 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003521 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003522 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3523
3524 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3525 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003526 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003527 {
paul718e3742002-12-13 20:15:29 +00003528 /* Ignore virtual link. */
3529 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3530 if (oi->address->family == AF_INET)
3531 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3532 {
3533 /* to make it easier later */
3534 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3535 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3536 }
3537 }
3538
3539 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3540}
3541
3542/* Get unique Link State ID. */
3543struct in_addr
paul68980082003-03-25 05:07:42 +00003544ospf_lsa_unique_id (struct ospf *ospf,
3545 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003546{
3547 struct ospf_lsa *lsa;
3548 struct in_addr mask, id;
3549
3550 id = p->prefix;
3551
3552 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003553 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003554 if (lsa)
3555 {
3556 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3557 if (ip_masklen (al->mask) == p->prefixlen)
3558 {
3559 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003560 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003561 "Can't get Link State ID for %s/%d",
3562 inet_ntoa (p->prefix), p->prefixlen);
3563 /* id.s_addr = 0; */
3564 id.s_addr = 0xffffffff;
3565 return id;
3566 }
3567 /* Masklen differs, then apply wildcard mask to Link State ID. */
3568 else
3569 {
3570 masklen2ip (p->prefixlen, &mask);
3571
3572 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003573 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3574 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003575 if (lsa)
3576 {
3577 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003578 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003579 "Can't get Link State ID for %s/%d",
3580 inet_ntoa (p->prefix), p->prefixlen);
3581 /* id.s_addr = 0; */
3582 id.s_addr = 0xffffffff;
3583 return id;
3584 }
3585 }
3586 }
3587
3588 return id;
3589}
3590
3591
Paul Jakma70461d72006-05-12 22:57:57 +00003592#define LSA_ACTION_FLOOD_AREA 1
3593#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003594
3595struct lsa_action
3596{
3597 u_char action;
3598 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003599 struct ospf_lsa *lsa;
3600};
3601
paul4dadc292005-05-06 21:37:42 +00003602static int
paul718e3742002-12-13 20:15:29 +00003603ospf_lsa_action (struct thread *t)
3604{
3605 struct lsa_action *data;
3606
3607 data = THREAD_ARG (t);
3608
3609 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003610 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003611 data->action);
3612
3613 switch (data->action)
3614 {
paul718e3742002-12-13 20:15:29 +00003615 case LSA_ACTION_FLOOD_AREA:
3616 ospf_flood_through_area (data->area, NULL, data->lsa);
3617 break;
paul718e3742002-12-13 20:15:29 +00003618 case LSA_ACTION_FLUSH_AREA:
3619 ospf_lsa_flush_area (data->lsa, data->area);
3620 break;
paul718e3742002-12-13 20:15:29 +00003621 }
3622
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003623 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003624 XFREE (MTYPE_OSPF_MESSAGE, data);
3625 return 0;
3626}
3627
3628void
3629ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3630{
3631 struct lsa_action *data;
3632
Stephen Hemminger393deb92008-08-18 14:13:29 -07003633 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003634 data->action = LSA_ACTION_FLOOD_AREA;
3635 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003636 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003637
3638 thread_add_event (master, ospf_lsa_action, data, 0);
3639}
3640
3641void
3642ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3643{
3644 struct lsa_action *data;
3645
Stephen Hemminger393deb92008-08-18 14:13:29 -07003646 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003647 data->action = LSA_ACTION_FLUSH_AREA;
3648 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003649 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003650
3651 thread_add_event (master, ospf_lsa_action, data, 0);
3652}
3653
3654
3655/* LSA Refreshment functions. */
paul4dadc292005-05-06 21:37:42 +00003656static void
paul68980082003-03-25 05:07:42 +00003657ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003658{
3659 struct external_info *ei;
3660 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3661
3662 switch (lsa->data->type)
3663 {
3664 /* Router and Network LSAs are processed differently. */
3665 case OSPF_ROUTER_LSA:
3666 case OSPF_NETWORK_LSA:
3667 break;
3668 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003669 ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003670 break;
3671 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003672 ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003673 break;
3674 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003675 /* Translated from NSSA Type-5s are refreshed when
3676 * from refresh of Type-7 - do not refresh these directly.
3677 */
3678 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3679 break;
paul718e3742002-12-13 20:15:29 +00003680 ei = ospf_external_info_check (lsa);
3681 if (ei)
pauld4a53d52003-07-12 21:30:57 +00003682 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003683 else
pauld4a53d52003-07-12 21:30:57 +00003684 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003685 break;
3686#ifdef HAVE_OPAQUE_LSA
3687 case OSPF_OPAQUE_LINK_LSA:
3688 case OSPF_OPAQUE_AREA_LSA:
3689 case OSPF_OPAQUE_AS_LSA:
3690 ospf_opaque_lsa_refresh (lsa);
3691 break;
pauld7480322003-05-16 17:31:51 +00003692#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003693 default:
3694 break;
paul718e3742002-12-13 20:15:29 +00003695 }
3696}
3697
3698void
paul68980082003-03-25 05:07:42 +00003699ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003700{
3701 u_int16_t index, current_index;
3702
3703 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3704
3705 if (lsa->refresh_list < 0)
3706 {
3707 int delay;
3708
3709 if (LS_AGE (lsa) == 0 &&
3710 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3711 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3712 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3713 else
3714 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3715 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3716 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3717
3718 if (delay < 0)
3719 delay = 0;
3720
paul68980082003-03-25 05:07:42 +00003721 current_index = ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003722 (quagga_time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003723
3724 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3725 % (OSPF_LSA_REFRESHER_SLOTS);
3726
3727 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003728 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003729 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003730 if (!ospf->lsa_refresh_queue.qs[index])
3731 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003732 listnode_add (ospf->lsa_refresh_queue.qs[index],
3733 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003734 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003735 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003736 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003737 "setting refresh_list on lsa %p (slod %d)",
3738 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003739 }
3740}
3741
3742void
paul68980082003-03-25 05:07:42 +00003743ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003744{
3745 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3746 if (lsa->refresh_list >= 0)
3747 {
hasso52dc7ee2004-09-23 19:18:23 +00003748 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003749 listnode_delete (refresh_list, lsa);
3750 if (!listcount (refresh_list))
3751 {
3752 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003753 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003754 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003755 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003756 lsa->refresh_list = -1;
3757 }
3758}
3759
3760int
3761ospf_lsa_refresh_walker (struct thread *t)
3762{
hasso52dc7ee2004-09-23 19:18:23 +00003763 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003764 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003765 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003766 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003767 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003768 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003769
3770 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003771 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003772
3773
paul68980082003-03-25 05:07:42 +00003774 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003775
ajs9dbc7972005-03-13 19:27:22 +00003776 /* Note: if clock has jumped backwards, then time change could be negative,
3777 so we are careful to cast the expression to unsigned before taking
3778 modulus. */
paul68980082003-03-25 05:07:42 +00003779 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003780 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003781 (quagga_time (NULL) - ospf->lsa_refresher_started) /
ajs9dbc7972005-03-13 19:27:22 +00003782 OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003783
3784 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003785 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003786 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003787
paul68980082003-03-25 05:07:42 +00003788 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003789 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3790 {
3791 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003792 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003793 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003794
paul68980082003-03-25 05:07:42 +00003795 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003796
paul68980082003-03-25 05:07:42 +00003797 ospf->lsa_refresh_queue.qs [i] = NULL;
3798
paul718e3742002-12-13 20:15:29 +00003799 if (refresh_list)
3800 {
paul1eb8ef22005-04-07 07:30:20 +00003801 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003802 {
paul718e3742002-12-13 20:15:29 +00003803 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003804 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003805 "refresh lsa %p (slot %d)",
3806 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003807
3808 list_delete_node (refresh_list, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003809 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003810 lsa->refresh_list = -1;
3811 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003812 }
3813 list_free (refresh_list);
3814 }
3815 }
3816
paul68980082003-03-25 05:07:42 +00003817 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3818 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003819 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003820
paul1eb8ef22005-04-07 07:30:20 +00003821 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
3822 ospf_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003823
3824 list_delete (lsa_to_refresh);
3825
3826 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003827 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003828
3829 return 0;
3830}
3831