blob: b9a70a665862f0e1b569b7a46c977295637802a4 [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() */
35
36#include "ospfd/ospfd.h"
37#include "ospfd/ospf_interface.h"
38#include "ospfd/ospf_ism.h"
39#include "ospfd/ospf_asbr.h"
40#include "ospfd/ospf_lsa.h"
41#include "ospfd/ospf_lsdb.h"
42#include "ospfd/ospf_neighbor.h"
43#include "ospfd/ospf_nsm.h"
44#include "ospfd/ospf_flood.h"
45#include "ospfd/ospf_packet.h"
46#include "ospfd/ospf_spf.h"
47#include "ospfd/ospf_dump.h"
48#include "ospfd/ospf_route.h"
49#include "ospfd/ospf_ase.h"
50#include "ospfd/ospf_zebra.h"
51
52
53u_int32_t
54get_metric (u_char *metric)
55{
56 u_int32_t m;
57 m = metric[0];
58 m = (m << 8) + metric[1];
59 m = (m << 8) + metric[2];
60 return m;
61}
62
63
64struct timeval
65tv_adjust (struct timeval a)
66{
67 while (a.tv_usec >= 1000000)
68 {
69 a.tv_usec -= 1000000;
70 a.tv_sec++;
71 }
72
73 while (a.tv_usec < 0)
74 {
75 a.tv_usec += 1000000;
76 a.tv_sec--;
77 }
78
79 return a;
80}
81
82int
83tv_ceil (struct timeval a)
84{
85 a = tv_adjust (a);
86
87 return (a.tv_usec ? a.tv_sec + 1 : a.tv_sec);
88}
89
90int
91tv_floor (struct timeval a)
92{
93 a = tv_adjust (a);
94
95 return a.tv_sec;
96}
97
98struct timeval
99int2tv (int a)
100{
101 struct timeval ret;
102
103 ret.tv_sec = a;
104 ret.tv_usec = 0;
105
106 return ret;
107}
108
109struct timeval
110tv_add (struct timeval a, struct timeval b)
111{
112 struct timeval ret;
113
114 ret.tv_sec = a.tv_sec + b.tv_sec;
115 ret.tv_usec = a.tv_usec + b.tv_usec;
116
117 return tv_adjust (ret);
118}
119
120struct timeval
121tv_sub (struct timeval a, struct timeval b)
122{
123 struct timeval ret;
124
125 ret.tv_sec = a.tv_sec - b.tv_sec;
126 ret.tv_usec = a.tv_usec - b.tv_usec;
127
128 return tv_adjust (ret);
129}
130
131int
132tv_cmp (struct timeval a, struct timeval b)
133{
134 return (a.tv_sec == b.tv_sec ?
135 a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
136}
137
138int
139ospf_lsa_refresh_delay (struct ospf_lsa *lsa)
140{
141 struct timeval delta, now;
142 int delay = 0;
143
Paul Jakma2518efd2006-08-27 06:49:29 +0000144 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +0000145 delta = tv_sub (now, lsa->tv_orig);
146
147 if (tv_cmp (delta, int2tv (OSPF_MIN_LS_INTERVAL)) < 0)
148 {
149 delay = tv_ceil (tv_sub (int2tv (OSPF_MIN_LS_INTERVAL), delta));
150
151 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000152 zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
paul718e3742002-12-13 20:15:29 +0000153 lsa->data->type, inet_ntoa (lsa->data->id), delay);
154
155 assert (delay > 0);
156 }
157
158 return delay;
159}
160
161
162int
163get_age (struct ospf_lsa *lsa)
164{
165 int age;
paul718e3742002-12-13 20:15:29 +0000166
Paul Jakma2518efd2006-08-27 06:49:29 +0000167 age = ntohs (lsa->data->ls_age)
168 + tv_floor (tv_sub (recent_relative_time (), lsa->tv_recv));
paul718e3742002-12-13 20:15:29 +0000169
170 return age;
171}
172
173
174/* Fletcher Checksum -- Refer to RFC1008. */
175#define MODX 4102
176#define LSA_CHECKSUM_OFFSET 15
177
178u_int16_t
179ospf_lsa_checksum (struct lsa_header *lsa)
180{
181 u_char *sp, *ep, *p, *q;
182 int c0 = 0, c1 = 0;
183 int x, y;
184 u_int16_t length;
185
186 lsa->checksum = 0;
187 length = ntohs (lsa->length) - 2;
hassoc9e52be2004-09-26 16:09:34 +0000188 sp = (u_char *) &lsa->options;
paul718e3742002-12-13 20:15:29 +0000189
190 for (ep = sp + length; sp < ep; sp = q)
191 {
192 q = sp + MODX;
193 if (q > ep)
194 q = ep;
195 for (p = sp; p < q; p++)
196 {
197 c0 += *p;
198 c1 += c0;
199 }
200 c0 %= 255;
201 c1 %= 255;
202 }
203
Paul Jakma075c2012006-03-30 14:34:31 +0000204 x = (((int)length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255;
paul718e3742002-12-13 20:15:29 +0000205 if (x <= 0)
206 x += 255;
207 y = 510 - c0 - x;
208 if (y > 255)
209 y -= 255;
210
211 /* take care endian issue. */
212 lsa->checksum = htons ((x << 8) + y);
213
214 return (lsa->checksum);
215}
216
217
218
219/* Create OSPF LSA. */
220struct ospf_lsa *
221ospf_lsa_new ()
222{
223 struct ospf_lsa *new;
224
225 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
226 memset (new, 0, sizeof (struct ospf_lsa));
227
228 new->flags = 0;
229 new->lock = 1;
230 new->retransmit_counter = 0;
Paul Jakma2518efd2006-08-27 06:49:29 +0000231 new->tv_recv = recent_relative_time ();
paul718e3742002-12-13 20:15:29 +0000232 new->tv_orig = new->tv_recv;
233 new->refresh_list = -1;
234
235 return new;
236}
237
238/* Duplicate OSPF LSA. */
239struct ospf_lsa *
240ospf_lsa_dup (struct ospf_lsa *lsa)
241{
242 struct ospf_lsa *new;
243
244 if (lsa == NULL)
245 return NULL;
246
247 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
248
249 memcpy (new, lsa, sizeof (struct ospf_lsa));
250 UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
251 new->lock = 1;
252 new->retransmit_counter = 0;
253 new->data = ospf_lsa_data_dup (lsa->data);
254
paulf2c80652002-12-13 21:44:27 +0000255 /* kevinm: Clear the refresh_list, otherwise there are going
256 to be problems when we try to remove the LSA from the
257 queue (which it's not a member of.)
258 XXX: Should we add the LSA to the refresh_list queue? */
259 new->refresh_list = -1;
260
261 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000262 zlog_debug ("LSA: duplicated %p (new: %p)", lsa, new);
paulf2c80652002-12-13 21:44:27 +0000263
paul718e3742002-12-13 20:15:29 +0000264 return new;
265}
266
267/* Free OSPF LSA. */
268void
269ospf_lsa_free (struct ospf_lsa *lsa)
270{
271 assert (lsa->lock == 0);
272
273 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000274 zlog_debug ("LSA: freed %p", lsa);
paul718e3742002-12-13 20:15:29 +0000275
276 /* Delete LSA data. */
277 if (lsa->data != NULL)
278 ospf_lsa_data_free (lsa->data);
279
280 assert (lsa->refresh_list < 0);
281
282 memset (lsa, 0, sizeof (struct ospf_lsa));
283 XFREE (MTYPE_OSPF_LSA, lsa);
284}
285
286/* Lock LSA. */
287struct ospf_lsa *
288ospf_lsa_lock (struct ospf_lsa *lsa)
289{
290 lsa->lock++;
291 return lsa;
292}
293
294/* Unlock LSA. */
295void
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000296ospf_lsa_unlock (struct ospf_lsa **lsa)
paul718e3742002-12-13 20:15:29 +0000297{
298 /* This is sanity check. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000299 if (!lsa || !*lsa)
paul718e3742002-12-13 20:15:29 +0000300 return;
301
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000302 (*lsa)->lock--;
paul718e3742002-12-13 20:15:29 +0000303
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000304 assert ((*lsa)->lock >= 0);
paul718e3742002-12-13 20:15:29 +0000305
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000306 if ((*lsa)->lock == 0)
paul718e3742002-12-13 20:15:29 +0000307 {
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000308 assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
309 ospf_lsa_free (*lsa);
310 *lsa = NULL;
paul718e3742002-12-13 20:15:29 +0000311 }
312}
313
314/* Check discard flag. */
315void
316ospf_lsa_discard (struct ospf_lsa *lsa)
317{
318 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
319 {
320 SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000321 ospf_lsa_unlock (&lsa);
paul718e3742002-12-13 20:15:29 +0000322 }
323}
324
325/* Create LSA data. */
326struct lsa_header *
327ospf_lsa_data_new (size_t size)
328{
329 struct lsa_header *new;
330
331 new = (struct lsa_header *) XMALLOC (MTYPE_OSPF_LSA_DATA, size);
332 memset (new, 0, size);
333
334 return new;
335}
336
337/* Duplicate LSA data. */
338struct lsa_header *
339ospf_lsa_data_dup (struct lsa_header *lsah)
340{
341 struct lsa_header *new;
342
343 new = ospf_lsa_data_new (ntohs (lsah->length));
344 memcpy (new, lsah, ntohs (lsah->length));
345
346 return new;
347}
348
349/* Free LSA data. */
350void
351ospf_lsa_data_free (struct lsa_header *lsah)
352{
353 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000354 zlog_debug ("LSA[Type%d:%s]: data freed %p",
paul718e3742002-12-13 20:15:29 +0000355 lsah->type, inet_ntoa (lsah->id), lsah);
356
357 XFREE (MTYPE_OSPF_LSA_DATA, lsah);
358}
359
360
361/* LSA general functions. */
362
363const char *
364dump_lsa_key (struct ospf_lsa *lsa)
365{
366 static char buf[] = {
hasso52dc7ee2004-09-23 19:18:23 +0000367 "Type255,id(255.255.255.255),ar(255.255.255.255)"
paul718e3742002-12-13 20:15:29 +0000368 };
369 struct lsa_header *lsah;
370
371 if (lsa != NULL && (lsah = lsa->data) != NULL)
372 {
373 char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
374 strcpy (id, inet_ntoa (lsah->id));
375 strcpy (ar, inet_ntoa (lsah->adv_router));
376
377 sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
378 }
379 else
380 strcpy (buf, "NULL");
381
382 return buf;
383}
384
385u_int32_t
386lsa_seqnum_increment (struct ospf_lsa *lsa)
387{
388 u_int32_t seqnum;
389
390 seqnum = ntohl (lsa->data->ls_seqnum) + 1;
391
392 return htonl (seqnum);
393}
394
395void
396lsa_header_set (struct stream *s, u_char options,
paul68980082003-03-25 05:07:42 +0000397 u_char type, struct in_addr id, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +0000398{
399 struct lsa_header *lsah;
400
401 lsah = (struct lsa_header *) STREAM_DATA (s);
402
403 lsah->ls_age = htons (0);
404 lsah->options = options;
405 lsah->type = type;
406 lsah->id = id;
paul68980082003-03-25 05:07:42 +0000407 lsah->adv_router = router_id;
paul718e3742002-12-13 20:15:29 +0000408 lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
409
paul9985f832005-02-09 15:51:56 +0000410 stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000411}
412
paul68980082003-03-25 05:07:42 +0000413
paul718e3742002-12-13 20:15:29 +0000414/* router-LSA related functions. */
415/* Get router-LSA flags. */
paul4dadc292005-05-06 21:37:42 +0000416static u_char
paul718e3742002-12-13 20:15:29 +0000417router_lsa_flags (struct ospf_area *area)
418{
419 u_char flags;
420
paul68980082003-03-25 05:07:42 +0000421 flags = area->ospf->flags;
paul718e3742002-12-13 20:15:29 +0000422
423 /* Set virtual link flag. */
424 if (ospf_full_virtual_nbrs (area))
425 SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
426 else
427 /* Just sanity check */
428 UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);
429
430 /* Set Shortcut ABR behabiour flag. */
431 UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
paul68980082003-03-25 05:07:42 +0000432 if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
paul718e3742002-12-13 20:15:29 +0000433 if (!OSPF_IS_AREA_BACKBONE (area))
434 if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
paul68980082003-03-25 05:07:42 +0000435 area->ospf->backbone == NULL) ||
paul718e3742002-12-13 20:15:29 +0000436 area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
437 SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
438
439 /* ASBR can't exit in stub area. */
Paul Jakma9560fa82006-06-26 12:50:06 +0000440 if (area->external_routing == OSPF_AREA_STUB
441 || area->external_routing == OSPF_AREA_NSSA)
paul942b6c12003-06-22 08:22:18 +0000442 UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
443 /* If ASBR set External flag */
444 else if (IS_OSPF_ASBR (area->ospf))
445 SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
446
447 /* Set ABR dependent flags */
448 if (IS_OSPF_ABR (area->ospf))
449 {
450 SET_FLAG (flags, ROUTER_LSA_BORDER);
paul942b6c12003-06-22 08:22:18 +0000451 /* If Area is NSSA and we are both ABR and unconditional translator,
pauld4a53d52003-07-12 21:30:57 +0000452 * set Nt bit to inform other routers.
paul942b6c12003-06-22 08:22:18 +0000453 */
pauld4a53d52003-07-12 21:30:57 +0000454 if ( (area->external_routing == OSPF_AREA_NSSA)
455 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
456 SET_FLAG (flags, ROUTER_LSA_NT);
paul942b6c12003-06-22 08:22:18 +0000457 }
paul718e3742002-12-13 20:15:29 +0000458 return flags;
459}
460
461/* Lookup neighbor other than myself.
462 And check neighbor count,
463 Point-to-Point link must have only 1 neighbor. */
464struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +0000465ospf_nbr_lookup_ptop (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +0000466{
paul718e3742002-12-13 20:15:29 +0000467 struct ospf_neighbor *nbr = NULL;
paul68980082003-03-25 05:07:42 +0000468 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000469
470 /* Search neighbor, there must be one of two nbrs. */
paul68980082003-03-25 05:07:42 +0000471 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
472 if ((nbr = rn->info))
473 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000474 if (nbr->state == NSM_Full)
paul68980082003-03-25 05:07:42 +0000475 {
476 route_unlock_node (rn);
477 break;
478 }
paul718e3742002-12-13 20:15:29 +0000479
480 /* PtoP link must have only 1 neighbor. */
paul68980082003-03-25 05:07:42 +0000481 if (ospf_nbr_count (oi, 0) > 1)
paul718e3742002-12-13 20:15:29 +0000482 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
483
484 return nbr;
485}
486
paul88d6cf32005-10-29 12:50:09 +0000487/* Determine cost of link, taking RFC3137 stub-router support into
488 * consideration
489 */
490static u_int16_t
491ospf_link_cost (struct ospf_interface *oi)
492{
493 /* RFC3137 stub router support */
494 if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
495 return oi->output_cost;
496 else
497 return OSPF_OUTPUT_COST_INFINITE;
498}
499
paul718e3742002-12-13 20:15:29 +0000500/* Set a link information. */
paul779adb02006-01-18 15:07:38 +0000501static char
paul718e3742002-12-13 20:15:29 +0000502link_info_set (struct stream *s, struct in_addr id,
503 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
504{
paul779adb02006-01-18 15:07:38 +0000505 /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
506 * vast majority of cases. Some rare routers with lots of links need more.
507 * we try accomodate those here.
508 */
509 if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
510 {
511 size_t ret = OSPF_MAX_LSA_SIZE;
512
513 /* Can we enlarge the stream still? */
514 if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
515 {
516 /* we futz the size here for simplicity, really we need to account
517 * for just:
518 * IP Header - (sizeof (struct ip))
519 * OSPF Header - OSPF_HEADER_SIZE
520 * LSA Header - OSPF_LSA_HEADER_SIZE
521 * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
522 *
523 * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
524 */
525 ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
526 }
527
528 if (ret == OSPF_MAX_LSA_SIZE)
529 {
530 zlog_warn ("%s: Out of space in LSA stream, left %ld, size %ld",
531 __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
532 return 0;
533 }
534 }
535
paul718e3742002-12-13 20:15:29 +0000536 /* TOS based routing is not supported. */
537 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
538 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
539 stream_putc (s, type); /* Link Type. */
540 stream_putc (s, tos); /* TOS = 0. */
541 stream_putw (s, cost); /* Link Cost. */
paul779adb02006-01-18 15:07:38 +0000542
543 return 1;
paul718e3742002-12-13 20:15:29 +0000544}
545
Andrew J. Schorre4529632006-12-12 19:18:21 +0000546/* Describe Point-to-Point link (Section 12.4.1.1). */
paul4dadc292005-05-06 21:37:42 +0000547static int
paul718e3742002-12-13 20:15:29 +0000548lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
549{
550 int links = 0;
551 struct ospf_neighbor *nbr;
552 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000553 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000554
555 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000556 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
paul718e3742002-12-13 20:15:29 +0000557
paul68980082003-03-25 05:07:42 +0000558 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000559 if (nbr->state == NSM_Full)
560 {
561 /* For unnumbered point-to-point networks, the Link Data field
562 should specify the interface's MIB-II ifIndex value. */
paul779adb02006-01-18 15:07:38 +0000563 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
564 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000565 }
566
Andrew J. Schorre4529632006-12-12 19:18:21 +0000567 /* Regardless of the state of the neighboring router, we must
568 add a Type 3 link (stub network).
569 N.B. Options 1 & 2 share basically the same logic. */
570 masklen2ip (oi->address->prefixlen, &mask);
571 id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
572 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
573 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000574 return links;
575}
576
577/* Describe Broadcast Link. */
paul4dadc292005-05-06 21:37:42 +0000578static int
paul718e3742002-12-13 20:15:29 +0000579lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
580{
581 struct ospf_neighbor *dr;
582 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000583 u_int16_t cost = ospf_link_cost (oi);
584
paul718e3742002-12-13 20:15:29 +0000585 /* Describe Type 3 Link. */
586 if (oi->state == ISM_Waiting)
587 {
588 masklen2ip (oi->address->prefixlen, &mask);
589 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000590 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
591 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000592 }
593
594 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
595 /* Describe Type 2 link. */
596 if (dr && (dr->state == NSM_Full ||
597 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000598 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000599 {
paul779adb02006-01-18 15:07:38 +0000600 return link_info_set (s, DR (oi), oi->address->u.prefix4,
601 LSA_LINK_TYPE_TRANSIT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000602 }
603 /* Describe type 3 link. */
604 else
605 {
606 masklen2ip (oi->address->prefixlen, &mask);
607 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000608 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
609 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000610 }
paul718e3742002-12-13 20:15:29 +0000611}
612
paul4dadc292005-05-06 21:37:42 +0000613static int
paul718e3742002-12-13 20:15:29 +0000614lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
615{
616 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000617
paul718e3742002-12-13 20:15:29 +0000618 /* Describe Type 3 Link. */
619 if (oi->state != ISM_Loopback)
620 return 0;
621
622 mask.s_addr = 0xffffffff;
623 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000624 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000625}
626
627/* Describe Virtual Link. */
paul4dadc292005-05-06 21:37:42 +0000628static int
paul718e3742002-12-13 20:15:29 +0000629lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
630{
631 struct ospf_neighbor *nbr;
paul88d6cf32005-10-29 12:50:09 +0000632 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000633
paul718e3742002-12-13 20:15:29 +0000634 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000635 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000636 if (nbr->state == NSM_Full)
637 {
paul779adb02006-01-18 15:07:38 +0000638 return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
639 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
paul718e3742002-12-13 20:15:29 +0000640 }
641
642 return 0;
643}
644
645#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
646
paul7afa08d2002-12-13 20:59:45 +0000647/* this function add for support point-to-multipoint ,see rfc2328
64812.4.1.4.*/
649/* from "edward rrr" <edward_rrr@hotmail.com>
650 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul4dadc292005-05-06 21:37:42 +0000651static int
paul68980082003-03-25 05:07:42 +0000652lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000653{
654 int links = 0;
655 struct route_node *rn;
656 struct ospf_neighbor *nbr = NULL;
657 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000658 u_int16_t cost = ospf_link_cost (oi);
paul7afa08d2002-12-13 20:59:45 +0000659
660 mask.s_addr = 0xffffffff;
661 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000662 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
paul7afa08d2002-12-13 20:59:45 +0000663
paul1cc8f762003-04-05 19:34:32 +0000664 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000665 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000666
667 /* Search neighbor, */
668 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
669 if ((nbr = rn->info) != NULL)
670 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000671 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000672 if (nbr->state == NSM_Full)
673
674 {
paul779adb02006-01-18 15:07:38 +0000675 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
676 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul1cc8f762003-04-05 19:34:32 +0000677 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000678 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000679 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000680 }
681
682 return links;
paul7afa08d2002-12-13 20:59:45 +0000683}
684
paul718e3742002-12-13 20:15:29 +0000685/* Set router-LSA link information. */
paul4dadc292005-05-06 21:37:42 +0000686static int
paul718e3742002-12-13 20:15:29 +0000687router_lsa_link_set (struct stream *s, struct ospf_area *area)
688{
hasso52dc7ee2004-09-23 19:18:23 +0000689 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000690 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000691 int links = 0;
692
paul1eb8ef22005-04-07 07:30:20 +0000693 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +0000694 {
paul718e3742002-12-13 20:15:29 +0000695 struct interface *ifp = oi->ifp;
696
697 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000698 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000699 {
700 if (oi->state != ISM_Down)
701 {
702 /* Describe each link. */
703 switch (oi->type)
704 {
705 case OSPF_IFTYPE_POINTOPOINT:
706 links += lsa_link_ptop_set (s, oi);
707 break;
708 case OSPF_IFTYPE_BROADCAST:
709 links += lsa_link_broadcast_set (s, oi);
710 break;
711 case OSPF_IFTYPE_NBMA:
712 links += lsa_link_nbma_set (s, oi);
713 break;
714 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000715 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000716 break;
717 case OSPF_IFTYPE_VIRTUALLINK:
718 links += lsa_link_virtuallink_set (s, oi);
719 break;
720 case OSPF_IFTYPE_LOOPBACK:
721 links += lsa_link_loopback_set (s, oi);
722 }
723 }
724 }
725 }
726
727 return links;
728}
729
730/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000731static void
paul718e3742002-12-13 20:15:29 +0000732ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
733{
734 unsigned long putp;
735 u_int16_t cnt;
736
737 /* Set flags. */
738 stream_putc (s, router_lsa_flags (area));
739
740 /* Set Zero fields. */
741 stream_putc (s, 0);
742
743 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000744 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000745
746 /* Forward word */
747 stream_putw(s, 0);
748
749 /* Set all link information. */
750 cnt = router_lsa_link_set (s, area);
751
752 /* Set # of links here. */
753 stream_putw_at (s, putp, cnt);
754}
paul88d6cf32005-10-29 12:50:09 +0000755
756static int
757ospf_stub_router_timer (struct thread *t)
758{
759 struct ospf_area *area = THREAD_ARG (t);
760
761 area->t_stub_router = NULL;
762
763 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
764
765 /* clear stub route state and generate router-lsa refresh, don't
766 * clobber an administratively set stub-router state though.
767 */
768 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
769 return 0;
770
771 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
772
773 ospf_router_lsa_timer_add (area);
774
775 return 0;
776}
paul718e3742002-12-13 20:15:29 +0000777
paul88d6cf32005-10-29 12:50:09 +0000778inline static void
779ospf_stub_router_check (struct ospf_area *area)
780{
781 /* area must either be administratively configured to be stub
782 * or startup-time stub-router must be configured and we must in a pre-stub
783 * state.
784 */
785 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
786 {
787 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
788 return;
789 }
790
791 /* not admin-stubbed, check whether startup stubbing is configured and
792 * whether it's not been done yet
793 */
794 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
795 return;
796
797 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
798 {
799 /* stub-router is hence done forever for this area, even if someone
800 * tries configure it (take effect next restart).
801 */
802 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
803 return;
804 }
805
806 /* startup stub-router configured and not yet done */
807 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
808
809 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
810 area->ospf->stub_router_startup_time);
811}
812
paul718e3742002-12-13 20:15:29 +0000813/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000814static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000815ospf_router_lsa_new (struct ospf_area *area)
816{
paul68980082003-03-25 05:07:42 +0000817 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000818 struct stream *s;
819 struct lsa_header *lsah;
820 struct ospf_lsa *new;
821 int length;
822
823 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000824 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000825
paul88d6cf32005-10-29 12:50:09 +0000826 /* check whether stub-router is desired, and if this is the first
827 * router LSA.
828 */
829 ospf_stub_router_check (area);
830
paul718e3742002-12-13 20:15:29 +0000831 /* Create a stream for LSA. */
832 s = stream_new (OSPF_MAX_LSA_SIZE);
paul718e3742002-12-13 20:15:29 +0000833 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000834 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000835 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000836
837 /* Set router-LSA body fields. */
838 ospf_router_lsa_body_set (s, area);
839
840 /* Set length. */
841 length = stream_get_endp (s);
paul779adb02006-01-18 15:07:38 +0000842 lsah = (struct lsa_header *) STREAM_DATA (s);
paul718e3742002-12-13 20:15:29 +0000843 lsah->length = htons (length);
844
845 /* Now, create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000846 if ( (new = ospf_lsa_new ()) == NULL)
847 {
848 zlog_err ("%s: Unable to create new lsa", __func__);
849 return NULL;
850 }
851
paul718e3742002-12-13 20:15:29 +0000852 new->area = area;
853 SET_FLAG (new->flags, OSPF_LSA_SELF);
854
855 /* Copy LSA data to store, discard stream. */
856 new->data = ospf_lsa_data_new (length);
857 memcpy (new->data, lsah, length);
858 stream_free (s);
859
860 return new;
861}
862
863/* Originate Router-LSA. */
paul88d6cf32005-10-29 12:50:09 +0000864static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000865ospf_router_lsa_originate (struct ospf_area *area)
866{
867 struct ospf_lsa *new;
paul88d6cf32005-10-29 12:50:09 +0000868
paul718e3742002-12-13 20:15:29 +0000869 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000870 if ( (new = ospf_router_lsa_new (area)) == NULL)
871 {
872 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
873 return NULL;
874 }
paul718e3742002-12-13 20:15:29 +0000875
876 /* Sanity check. */
877 if (new->data->adv_router.s_addr == 0)
878 {
879 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000880 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000881 ospf_lsa_discard (new);
882 return NULL;
883 }
884
885 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000886 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000887
888 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000889 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000890
891 /* Flooding new LSA through area. */
892 ospf_flood_through_area (area, NULL, new);
893
894 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
895 {
ajse588f212004-12-08 18:12:06 +0000896 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
paul718e3742002-12-13 20:15:29 +0000897 new->data->type, inet_ntoa (new->data->id), new);
898 ospf_lsa_header_dump (new->data);
899 }
900
901 return new;
902}
903
904/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000905static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000906ospf_router_lsa_refresh (struct ospf_lsa *lsa)
907{
908 struct ospf_area *area = lsa->area;
909 struct ospf_lsa *new;
910
911 /* Sanity check. */
912 assert (lsa->data);
913
914 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000915 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000916
917 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000918 if ( (new = ospf_router_lsa_new (area)) == NULL)
919 {
920 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
921 return NULL;
922 }
923
paul718e3742002-12-13 20:15:29 +0000924 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
925
paul68980082003-03-25 05:07:42 +0000926 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000927
928 /* Flood LSA through area. */
929 ospf_flood_through_area (area, NULL, new);
930
931 /* Debug logging. */
932 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
933 {
ajse588f212004-12-08 18:12:06 +0000934 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000935 new->data->type, inet_ntoa (new->data->id));
936 ospf_lsa_header_dump (new->data);
937 }
938
939 return NULL;
940}
941
paul4dadc292005-05-06 21:37:42 +0000942static int
paul718e3742002-12-13 20:15:29 +0000943ospf_router_lsa_timer (struct thread *t)
944{
945 struct ospf_area *area;
946
947 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000948 zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
paul718e3742002-12-13 20:15:29 +0000949
950 area = THREAD_ARG (t);
951 area->t_router_lsa_self = NULL;
952
953 /* Now refresh router-LSA. */
954 if (area->router_lsa_self)
955 ospf_router_lsa_refresh (area->router_lsa_self);
956 /* Newly originate router-LSA. */
957 else
958 ospf_router_lsa_originate (area);
959
960 return 0;
961}
962
963void
964ospf_router_lsa_timer_add (struct ospf_area *area)
965{
966 /* Keep area's self-originated router-LSA. */
967 struct ospf_lsa *lsa = area->router_lsa_self;
968
969 /* Cancel previously scheduled router-LSA timer. */
970 if (area->t_router_lsa_self)
971 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000972 zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
paul718e3742002-12-13 20:15:29 +0000973
974 OSPF_TIMER_OFF (area->t_router_lsa_self);
975
976 /* If router-LSA is originated previously, check the interval time. */
977 if (lsa)
978 {
979 int delay;
980 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
981 {
982 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
983 ospf_router_lsa_timer, delay);
984 return;
985 }
986 }
987
988 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000989 zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
paul718e3742002-12-13 20:15:29 +0000990
991 /* Immediately refresh router-LSA. */
992 OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
993}
994
995int
paul68980082003-03-25 05:07:42 +0000996ospf_router_lsa_update_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +0000997{
paul68980082003-03-25 05:07:42 +0000998 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +0000999 struct listnode *node, *nnode;
1000 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00001001
1002 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001003 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +00001004
paul68980082003-03-25 05:07:42 +00001005 ospf->t_router_lsa_update = NULL;
paul718e3742002-12-13 20:15:29 +00001006
paul1eb8ef22005-04-07 07:30:20 +00001007 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00001008 {
paul718e3742002-12-13 20:15:29 +00001009 struct ospf_lsa *lsa = area->router_lsa_self;
1010 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +00001011 const char *area_str;
paul718e3742002-12-13 20:15:29 +00001012
1013 /* Keep Area ID string. */
1014 area_str = AREA_NAME (area);
1015
1016 /* If LSA not exist in this Area, originate new. */
1017 if (lsa == NULL)
1018 {
1019 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001020 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +00001021
1022 ospf_router_lsa_originate (area);
1023 }
1024 /* If router-ID is changed, Link ID must change.
1025 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +00001026 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001027 {
1028 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001029 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +00001030 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
1031 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001032 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00001033 area->router_lsa_self = NULL;
1034
1035 /* Refresh router-LSA, (not install) and flood through area. */
1036 ospf_router_lsa_timer_add (area);
1037 }
1038 else
1039 {
1040 rl = (struct router_lsa *) lsa->data;
1041 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +00001042 if (rl->flags != ospf->flags)
paul718e3742002-12-13 20:15:29 +00001043 ospf_router_lsa_timer_add (area);
1044 }
1045 }
1046
1047 return 0;
1048}
1049
1050
1051/* network-LSA related functions. */
1052/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001053static void
paul718e3742002-12-13 20:15:29 +00001054ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1055{
1056 struct in_addr mask;
1057 struct route_node *rn;
1058 struct ospf_neighbor *nbr;
1059
1060 masklen2ip (oi->address->prefixlen, &mask);
1061 stream_put_ipv4 (s, mask.s_addr);
1062
1063 /* The network-LSA lists those routers that are fully adjacent to
1064 the Designated Router; each fully adjacent router is identified by
1065 its OSPF Router ID. The Designated Router includes itself in this
1066 list. RFC2328, Section 12.4.2 */
1067
1068 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1069 if ((nbr = rn->info) != NULL)
1070 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1071 stream_put_ipv4 (s, nbr->router_id.s_addr);
1072}
1073
paul4dadc292005-05-06 21:37:42 +00001074static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001075ospf_network_lsa_new (struct ospf_interface *oi)
1076{
1077 struct stream *s;
1078 struct ospf_lsa *new;
1079 struct lsa_header *lsah;
1080 int length;
1081
1082 /* If there are no neighbours on this network (the net is stub),
1083 the router does not originate network-LSA (see RFC 12.4.2) */
1084 if (oi->full_nbrs == 0)
1085 return NULL;
1086
1087 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001088 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001089
1090 /* Create new stream for LSA. */
1091 s = stream_new (OSPF_MAX_LSA_SIZE);
1092 lsah = (struct lsa_header *) STREAM_DATA (s);
1093
1094 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001095 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001096
1097 /* Set network-LSA body fields. */
1098 ospf_network_lsa_body_set (s, oi);
1099
1100 /* Set length. */
1101 length = stream_get_endp (s);
1102 lsah->length = htons (length);
1103
1104 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001105 if ( (new = ospf_lsa_new ()) == NULL)
1106 {
1107 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1108 return NULL;
1109 }
1110
paul718e3742002-12-13 20:15:29 +00001111 new->area = oi->area;
1112 SET_FLAG (new->flags, OSPF_LSA_SELF);
1113
1114 /* Copy LSA to store. */
1115 new->data = ospf_lsa_data_new (length);
1116 memcpy (new->data, lsah, length);
1117 stream_free (s);
1118
1119 return new;
1120}
1121
1122/* Originate network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001123static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001124ospf_network_lsa_originate (struct ospf_interface *oi)
1125{
1126 struct ospf_lsa *new;
1127
1128 /* Create new network-LSA instance. */
1129 new = ospf_network_lsa_new (oi);
1130 if (new == NULL)
1131 return NULL;
1132
1133 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001134 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001135
1136 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001137 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001138
1139 /* Flooding new LSA through area. */
1140 ospf_flood_through_area (oi->area, NULL, new);
1141
1142 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1143 {
ajse588f212004-12-08 18:12:06 +00001144 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001145 new->data->type, inet_ntoa (new->data->id), new);
1146 ospf_lsa_header_dump (new->data);
1147 }
1148
1149 return new;
1150}
1151
1152int
1153ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1154{
1155 struct ospf_area *area = lsa->area;
1156 struct ospf_lsa *new;
1157
1158 assert (lsa->data);
1159
1160 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001161 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001162
1163 /* Create new network-LSA instance. */
1164 new = ospf_network_lsa_new (oi);
1165 if (new == NULL)
1166 return -1;
1167 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1168
paul68980082003-03-25 05:07:42 +00001169 ospf_lsa_install (area->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001170
1171 /* Flood LSA through aera. */
1172 ospf_flood_through_area (area, NULL, new);
1173
1174 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1175 {
ajse588f212004-12-08 18:12:06 +00001176 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001177 new->data->type, inet_ntoa (new->data->id));
1178 ospf_lsa_header_dump (new->data);
1179 }
1180
1181 return 0;
1182}
1183
paul4dadc292005-05-06 21:37:42 +00001184static int
paul718e3742002-12-13 20:15:29 +00001185ospf_network_lsa_refresh_timer (struct thread *t)
1186{
1187 struct ospf_interface *oi;
1188
1189 oi = THREAD_ARG (t);
1190 oi->t_network_lsa_self = NULL;
1191
1192 if (oi->network_lsa_self)
1193 /* Now refresh network-LSA. */
1194 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1195 else
1196 /* Newly create network-LSA. */
1197 ospf_network_lsa_originate (oi);
1198
1199 return 0;
1200}
1201
1202void
1203ospf_network_lsa_timer_add (struct ospf_interface *oi)
1204{
1205 /* Keep interface's self-originated network-LSA. */
1206 struct ospf_lsa *lsa = oi->network_lsa_self;
1207
1208 /* Cancel previously schedules network-LSA timer. */
1209 if (oi->t_network_lsa_self)
1210 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001211 zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
paul718e3742002-12-13 20:15:29 +00001212 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1213
1214 /* If network-LSA is originated previously, check the interval time. */
1215 if (lsa)
1216 {
1217 int delay;
1218 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1219 {
1220 oi->t_network_lsa_self =
1221 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1222 oi, delay);
1223 return;
1224 }
1225 }
1226
1227 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001228 zlog_debug ("Scheduling network-LSA origination right away");
paul718e3742002-12-13 20:15:29 +00001229
1230 /* Immediately refresh network-LSA. */
1231 oi->t_network_lsa_self =
1232 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1233}
1234
1235
paul4dadc292005-05-06 21:37:42 +00001236static void
paul718e3742002-12-13 20:15:29 +00001237stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1238{
1239 u_int32_t metric;
1240 char *mp;
1241
1242 /* Put 0 metric. TOS metric is not supported. */
1243 metric = htonl (metric_value);
1244 mp = (char *) &metric;
1245 mp++;
1246 stream_put (s, mp, 3);
1247}
1248
1249/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001250static void
paul718e3742002-12-13 20:15:29 +00001251ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1252 u_int32_t metric)
1253{
1254 struct in_addr mask;
1255
1256 masklen2ip (p->prefixlen, &mask);
1257
1258 /* Put Network Mask. */
1259 stream_put_ipv4 (s, mask.s_addr);
1260
1261 /* Set # TOS. */
1262 stream_putc (s, (u_char) 0);
1263
1264 /* Set metric. */
1265 stream_put_ospf_metric (s, metric);
1266}
1267
paul4dadc292005-05-06 21:37:42 +00001268static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001269ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1270 u_int32_t metric, struct in_addr id)
1271{
1272 struct stream *s;
1273 struct ospf_lsa *new;
1274 struct lsa_header *lsah;
1275 int length;
1276
paulc24d6022005-11-20 14:54:12 +00001277 if (id.s_addr == 0xffffffff)
1278 {
1279 /* Maybe Link State ID not available. */
1280 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1281 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1282 OSPF_SUMMARY_LSA);
1283 return NULL;
1284 }
1285
paul718e3742002-12-13 20:15:29 +00001286 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001287 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001288
1289 /* Create new stream for LSA. */
1290 s = stream_new (OSPF_MAX_LSA_SIZE);
1291 lsah = (struct lsa_header *) STREAM_DATA (s);
1292
paul68980082003-03-25 05:07:42 +00001293 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1294 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001295
1296 /* Set summary-LSA body fields. */
1297 ospf_summary_lsa_body_set (s, p, metric);
1298
1299 /* Set length. */
1300 length = stream_get_endp (s);
1301 lsah->length = htons (length);
1302
1303 /* Create OSPF LSA instance. */
1304 new = ospf_lsa_new ();
1305 new->area = area;
1306 SET_FLAG (new->flags, OSPF_LSA_SELF);
1307
1308 /* Copy LSA to store. */
1309 new->data = ospf_lsa_data_new (length);
1310 memcpy (new->data, lsah, length);
1311 stream_free (s);
1312
1313 return new;
1314}
1315
1316/* Originate Summary-LSA. */
1317struct ospf_lsa *
1318ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1319 struct ospf_area *area)
1320{
1321 struct ospf_lsa *new;
1322 struct in_addr id;
1323
paul68980082003-03-25 05:07:42 +00001324 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001325
paulc24d6022005-11-20 14:54:12 +00001326 if (id.s_addr == 0xffffffff)
1327 {
1328 /* Maybe Link State ID not available. */
1329 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1330 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1331 OSPF_SUMMARY_LSA);
1332 return NULL;
1333 }
1334
paul718e3742002-12-13 20:15:29 +00001335 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001336 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1337 return NULL;
paul718e3742002-12-13 20:15:29 +00001338
1339 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001340 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001341
1342 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001343 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001344
1345 /* Flooding new LSA through area. */
1346 ospf_flood_through_area (area, NULL, new);
1347
1348 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1349 {
ajse588f212004-12-08 18:12:06 +00001350 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001351 new->data->type, inet_ntoa (new->data->id), new);
1352 ospf_lsa_header_dump (new->data);
1353 }
1354
1355 return new;
1356}
1357
1358struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001359ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001360{
1361 struct ospf_lsa *new;
1362 struct summary_lsa *sl;
1363 struct prefix p;
1364
1365 /* Sanity check. */
1366 assert (lsa->data);
1367
1368 sl = (struct summary_lsa *)lsa->data;
1369 p.prefixlen = ip_masklen (sl->mask);
1370 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1371 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001372
1373 if (!new)
1374 return NULL;
1375
paul718e3742002-12-13 20:15:29 +00001376 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1377
1378 /* Re-calculate checksum. */
1379 ospf_lsa_checksum (new->data);
1380
paul68980082003-03-25 05:07:42 +00001381 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001382
1383 /* Flood LSA through AS. */
1384 ospf_flood_through_area (new->area, NULL, new);
1385
1386 /* Debug logging. */
1387 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1388 {
ajse588f212004-12-08 18:12:06 +00001389 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001390 new->data->type, inet_ntoa (new->data->id));
1391 ospf_lsa_header_dump (new->data);
1392 }
1393
1394 return new;
1395}
1396
1397
1398/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001399static void
paul718e3742002-12-13 20:15:29 +00001400ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1401 u_int32_t metric)
1402{
1403 struct in_addr mask;
1404
1405 masklen2ip (p->prefixlen, &mask);
1406
1407 /* Put Network Mask. */
1408 stream_put_ipv4 (s, mask.s_addr);
1409
1410 /* Set # TOS. */
1411 stream_putc (s, (u_char) 0);
1412
1413 /* Set metric. */
1414 stream_put_ospf_metric (s, metric);
1415}
1416
paul4dadc292005-05-06 21:37:42 +00001417static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001418ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1419 u_int32_t metric, struct in_addr id)
1420{
1421 struct stream *s;
1422 struct ospf_lsa *new;
1423 struct lsa_header *lsah;
1424 int length;
1425
paulc24d6022005-11-20 14:54:12 +00001426 if (id.s_addr == 0xffffffff)
1427 {
1428 /* Maybe Link State ID not available. */
1429 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1430 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1431 OSPF_ASBR_SUMMARY_LSA);
1432 return NULL;
1433 }
1434
paul718e3742002-12-13 20:15:29 +00001435 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001436 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001437
1438 /* Create new stream for LSA. */
1439 s = stream_new (OSPF_MAX_LSA_SIZE);
1440 lsah = (struct lsa_header *) STREAM_DATA (s);
1441
paul68980082003-03-25 05:07:42 +00001442 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1443 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001444
1445 /* Set summary-LSA body fields. */
1446 ospf_summary_asbr_lsa_body_set (s, p, metric);
1447
1448 /* Set length. */
1449 length = stream_get_endp (s);
1450 lsah->length = htons (length);
1451
1452 /* Create OSPF LSA instance. */
1453 new = ospf_lsa_new ();
1454 new->area = area;
1455 SET_FLAG (new->flags, OSPF_LSA_SELF);
1456
1457 /* Copy LSA to store. */
1458 new->data = ospf_lsa_data_new (length);
1459 memcpy (new->data, lsah, length);
1460 stream_free (s);
1461
1462 return new;
1463}
1464
1465/* Originate summary-ASBR-LSA. */
1466struct ospf_lsa *
1467ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1468 struct ospf_area *area)
1469{
1470 struct ospf_lsa *new;
1471 struct in_addr id;
1472
paul68980082003-03-25 05:07:42 +00001473 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001474
paulc24d6022005-11-20 14:54:12 +00001475 if (id.s_addr == 0xffffffff)
1476 {
1477 /* Maybe Link State ID not available. */
1478 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1479 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1480 OSPF_ASBR_SUMMARY_LSA);
1481 return NULL;
1482 }
1483
paul718e3742002-12-13 20:15:29 +00001484 /* Create new summary-LSA instance. */
1485 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001486 if (!new)
1487 return NULL;
paul718e3742002-12-13 20:15:29 +00001488
1489 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001490 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001491
1492 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001493 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001494
1495 /* Flooding new LSA through area. */
1496 ospf_flood_through_area (area, NULL, new);
1497
1498 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1499 {
ajse588f212004-12-08 18:12:06 +00001500 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001501 new->data->type, inet_ntoa (new->data->id), new);
1502 ospf_lsa_header_dump (new->data);
1503 }
1504
1505 return new;
1506}
1507
1508struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001509ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001510{
1511 struct ospf_lsa *new;
1512 struct summary_lsa *sl;
1513 struct prefix p;
1514
1515 /* Sanity check. */
1516 assert (lsa->data);
1517
1518 sl = (struct summary_lsa *)lsa->data;
1519 p.prefixlen = ip_masklen (sl->mask);
1520 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1521 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001522 if (!new)
1523 return NULL;
paul718e3742002-12-13 20:15:29 +00001524
1525 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1526
1527 /* Re-calculate checksum. */
1528 ospf_lsa_checksum (new->data);
1529
paul68980082003-03-25 05:07:42 +00001530 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001531
1532 /* Flood LSA through area. */
1533 ospf_flood_through_area (new->area, NULL, new);
1534
1535 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1536 {
ajse588f212004-12-08 18:12:06 +00001537 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001538 new->data->type, inet_ntoa (new->data->id));
1539 ospf_lsa_header_dump (new->data);
1540 }
1541
1542 return new;
1543}
1544
1545/* AS-external-LSA related functions. */
1546
1547/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1548 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001549static struct in_addr
paul68980082003-03-25 05:07:42 +00001550ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001551{
1552 struct in_addr fwd;
1553 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001554 struct listnode *node;
1555 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001556
1557 fwd.s_addr = 0;
1558
1559 if (!nexthop.s_addr)
1560 return fwd;
1561
1562 /* Check whether nexthop is covered by OSPF network. */
1563 nh.family = AF_INET;
1564 nh.u.prefix4 = nexthop;
1565 nh.prefixlen = IPV4_MAX_BITLEN;
1566
paul1eb8ef22005-04-07 07:30:20 +00001567 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1568 if (if_is_operative (oi->ifp))
1569 if (oi->address->family == AF_INET)
1570 if (prefix_match (oi->address, &nh))
1571 return nexthop;
paul718e3742002-12-13 20:15:29 +00001572
1573 return fwd;
1574}
1575
paul718e3742002-12-13 20:15:29 +00001576/* NSSA-external-LSA related functions. */
1577
1578/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001579
paul718e3742002-12-13 20:15:29 +00001580struct in_addr
1581ospf_get_ip_from_ifp (struct ospf_interface *oi)
1582{
1583 struct in_addr fwd;
1584
1585 fwd.s_addr = 0;
1586
paul2e3b2e42002-12-13 21:03:13 +00001587 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001588 return oi->address->u.prefix4;
1589
1590 return fwd;
1591}
1592
1593/* Get 1st IP connection for Forward Addr */
1594struct in_addr
paulf2c80652002-12-13 21:44:27 +00001595ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001596{
1597 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001598 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001599 struct listnode *node;
1600 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001601
1602 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001603 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001604
paul1eb8ef22005-04-07 07:30:20 +00001605 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001606 {
paul2e3b2e42002-12-13 21:03:13 +00001607 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001608 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001609 if (oi->address && oi->address->family == AF_INET)
1610 {
1611 if (best_default.s_addr == 0)
1612 best_default = oi->address->u.prefix4;
1613 if (oi->area == area)
1614 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001615 }
paul718e3742002-12-13 20:15:29 +00001616 }
paulf2c80652002-12-13 21:44:27 +00001617 if (best_default.s_addr != 0)
1618 return best_default;
paul718e3742002-12-13 20:15:29 +00001619
paul68980082003-03-25 05:07:42 +00001620 if (best_default.s_addr != 0)
1621 return best_default;
1622
paul718e3742002-12-13 20:15:29 +00001623 return fwd;
1624}
hassobeebba72004-06-20 21:00:27 +00001625
paul718e3742002-12-13 20:15:29 +00001626#define DEFAULT_DEFAULT_METRIC 20
1627#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1628#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1629
1630#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1631
1632int
paul68980082003-03-25 05:07:42 +00001633metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001634{
paul68980082003-03-25 05:07:42 +00001635 return (ospf->dmetric[src].type < 0 ?
1636 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001637}
1638
1639int
paul68980082003-03-25 05:07:42 +00001640metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001641{
paul68980082003-03-25 05:07:42 +00001642 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001643 {
1644 if (src == DEFAULT_ROUTE)
1645 {
paul68980082003-03-25 05:07:42 +00001646 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001647 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1648 else
1649 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1650 }
paul68980082003-03-25 05:07:42 +00001651 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001652 return DEFAULT_DEFAULT_METRIC;
1653 else
paul68980082003-03-25 05:07:42 +00001654 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001655 }
1656
paul68980082003-03-25 05:07:42 +00001657 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001658}
1659
1660/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001661static void
paul68980082003-03-25 05:07:42 +00001662ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1663 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001664{
1665 struct prefix_ipv4 *p = &ei->p;
1666 struct in_addr mask, fwd_addr;
1667 u_int32_t mvalue;
1668 int mtype;
1669 int type;
1670
1671 /* Put Network Mask. */
1672 masklen2ip (p->prefixlen, &mask);
1673 stream_put_ipv4 (s, mask.s_addr);
1674
1675 /* If prefix is default, specify DEFAULT_ROUTE. */
1676 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1677
1678 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001679 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001680
1681 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001682 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001683
1684 /* Put type of external metric. */
1685 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1686
1687 /* Put 0 metric. TOS metric is not supported. */
1688 stream_put_ospf_metric (s, mvalue);
1689
1690 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001691 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001692
1693 /* Put forwarding address. */
1694 stream_put_ipv4 (s, fwd_addr.s_addr);
1695
1696 /* Put route tag -- This value should be introduced from configuration. */
1697 stream_putl (s, 0);
1698}
1699
1700/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001701static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001702ospf_external_lsa_new (struct ospf *ospf,
1703 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001704{
1705 struct stream *s;
1706 struct lsa_header *lsah;
1707 struct ospf_lsa *new;
1708 struct in_addr id;
1709 int length;
1710
1711 if (ei == NULL)
1712 {
1713 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001714 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
paul718e3742002-12-13 20:15:29 +00001715 return NULL;
1716 }
1717
1718 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001719 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001720
1721 /* If old Link State ID is specified, refresh LSA with same ID. */
1722 if (old_id)
1723 id = *old_id;
1724 /* Get Link State with unique ID. */
1725 else
1726 {
paul68980082003-03-25 05:07:42 +00001727 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001728 if (id.s_addr == 0xffffffff)
1729 {
1730 /* Maybe Link State ID not available. */
1731 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001732 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001733 return NULL;
1734 }
1735 }
1736
1737 /* Create new stream for LSA. */
1738 s = stream_new (OSPF_MAX_LSA_SIZE);
1739 lsah = (struct lsa_header *) STREAM_DATA (s);
1740
1741 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001742 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1743 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001744
1745 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001746 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001747
1748 /* Set length. */
1749 length = stream_get_endp (s);
1750 lsah->length = htons (length);
1751
1752 /* Now, create OSPF LSA instance. */
1753 new = ospf_lsa_new ();
1754 new->area = NULL;
1755 SET_FLAG (new->flags, OSPF_LSA_SELF|OSPF_LSA_APPROVED);
1756
1757 /* Copy LSA data to store, discard stream. */
1758 new->data = ospf_lsa_data_new (length);
1759 memcpy (new->data, lsah, length);
1760 stream_free (s);
1761
1762 return new;
1763}
1764
paul718e3742002-12-13 20:15:29 +00001765/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001766static void
paul68980082003-03-25 05:07:42 +00001767ospf_install_flood_nssa (struct ospf *ospf,
1768 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001769{
pauld4a53d52003-07-12 21:30:57 +00001770 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001771 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001772 struct ospf_area *area;
1773 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001774
pauld4a53d52003-07-12 21:30:57 +00001775 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1776 * which originated from an NSSA area. In which case it should not be
1777 * flooded back to NSSA areas.
1778 */
1779 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1780 return;
1781
paul718e3742002-12-13 20:15:29 +00001782 /* NSSA Originate or Refresh (If anyNSSA)
1783
1784 LSA is self-originated. And just installed as Type-5.
1785 Additionally, install as Type-7 LSDB for every attached NSSA.
1786
1787 P-Bit controls which ABR performs translation to outside world; If
1788 we are an ABR....do not set the P-bit, because we send the Type-5,
1789 not as the ABR Translator, but as the ASBR owner within the AS!
1790
1791 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1792 elected ABR Translator will see the P-bit, Translate, and re-flood.
1793
1794 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1795 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1796
paul1eb8ef22005-04-07 07:30:20 +00001797 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001798 {
hasso0c14ad82003-07-03 08:36:02 +00001799 /* Don't install Type-7 LSA's into nonNSSA area */
1800 if (area->external_routing != OSPF_AREA_NSSA)
1801 continue;
paul718e3742002-12-13 20:15:29 +00001802
paul68980082003-03-25 05:07:42 +00001803 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001804 new = ospf_lsa_dup (lsa);
1805 new->area = area;
1806 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001807
paul68980082003-03-25 05:07:42 +00001808 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001809 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001810 {
pauld4a53d52003-07-12 21:30:57 +00001811 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001812
1813 /* set non-zero FWD ADDR
1814
1815 draft-ietf-ospf-nssa-update-09.txt
1816
1817 if the network between the NSSA AS boundary router and the
1818 adjacent AS is advertised into OSPF as an internal OSPF route,
1819 the forwarding address should be the next op address as is cu
1820 currently done with type-5 LSAs. If the intervening network is
1821 not adversited into OSPF as an internal OSPF route and the
1822 type-7 LSA's P-bit is set a forwarding address should be
1823 selected from one of the router's active OSPF inteface addresses
1824 which belong to the NSSA. If no such addresses exist, then
1825 no type-7 LSA's with the P-bit set should originate from this
1826 router. */
1827
pauld4a53d52003-07-12 21:30:57 +00001828 /* kevinm: not updating lsa anymore, just new */
1829 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001830
1831 if (extlsa->e[0].fwd_addr.s_addr == 0)
1832 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001833
pauld7480322003-05-16 17:31:51 +00001834 if (extlsa->e[0].fwd_addr.s_addr == 0)
1835 {
1836 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001837 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001838 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001839 return;
1840 }
paulf2c80652002-12-13 21:44:27 +00001841 }
paul68980082003-03-25 05:07:42 +00001842 /* Re-calculate checksum. */
pauld4a53d52003-07-12 21:30:57 +00001843 ospf_lsa_checksum (new->data);
paul718e3742002-12-13 20:15:29 +00001844
paul68980082003-03-25 05:07:42 +00001845 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001846 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001847
1848 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001849 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001850 }
paul718e3742002-12-13 20:15:29 +00001851}
pauld4a53d52003-07-12 21:30:57 +00001852
paul4dadc292005-05-06 21:37:42 +00001853static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001854ospf_lsa_translated_nssa_new (struct ospf *ospf,
1855 struct ospf_lsa *type7)
1856{
1857
1858 struct ospf_lsa *new;
1859 struct as_external_lsa *ext, *extnew;
1860 struct external_info ei;
1861
1862 ext = (struct as_external_lsa *)(type7->data);
1863
1864 /* need external_info struct, fill in bare minimum */
1865 ei.p.family = AF_INET;
1866 ei.p.prefix = type7->data->id;
1867 ei.p.prefixlen = ip_masklen (ext->mask);
1868 ei.type = ZEBRA_ROUTE_OSPF;
1869 ei.nexthop = ext->header.adv_router;
1870 ei.route_map_set.metric = -1;
1871 ei.route_map_set.metric_type = -1;
1872 ei.tag = 0;
1873
1874 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1875 {
1876 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001877 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001878 "Translated Type-5 for %s",
1879 inet_ntoa (ei.p.prefix));
1880 return NULL;
1881 }
1882
1883 extnew = (struct as_external_lsa *)(new->data);
1884
1885 /* copy over Type-7 data to new */
1886 extnew->e[0].tos = ext->e[0].tos;
1887 extnew->e[0].route_tag = ext->e[0].route_tag;
1888 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1889 new->data->ls_seqnum = type7->data->ls_seqnum;
1890
1891 /* add translated flag, checksum and lock new lsa */
1892 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
1893 ospf_lsa_checksum (new->data);
1894 new = ospf_lsa_lock (new);
1895
1896 return new;
1897}
1898
1899/* compare type-5 to type-7
1900 * -1: err, 0: same, 1: different
1901 */
paul4dadc292005-05-06 21:37:42 +00001902static int
pauld4a53d52003-07-12 21:30:57 +00001903ospf_lsa_translated_nssa_compare (struct ospf_lsa *t7, struct ospf_lsa *t5)
1904{
1905
1906 struct as_external_lsa *e5 = (struct as_external_lsa *)t5,
1907 *e7 = (struct as_external_lsa *)t7;
1908
1909
1910 /* sanity checks */
1911 if (! ((t5->data->type == OSPF_AS_EXTERNAL_LSA)
1912 && (t7->data->type == OSPF_AS_NSSA_LSA)))
1913 return -1;
1914
1915 if (t5->data->id.s_addr != t7->data->id.s_addr)
1916 return -1;
1917
1918 if (t5->data->ls_seqnum != t7->data->ls_seqnum)
1919 return LSA_REFRESH_FORCE;
1920
1921 if (e5->mask.s_addr != e7->mask.s_addr)
1922 return LSA_REFRESH_FORCE;
1923
1924 if (e5->e[0].fwd_addr.s_addr != e7->e[0].fwd_addr.s_addr)
1925 return LSA_REFRESH_FORCE;
1926
1927 if (e5->e[0].route_tag != e7->e[0].route_tag)
1928 return LSA_REFRESH_FORCE;
1929
1930 if (GET_METRIC (e5->e[0].metric) != GET_METRIC (e7->e[0].metric))
1931 return LSA_REFRESH_FORCE;
1932
1933 return LSA_REFRESH_IF_CHANGED;
1934}
1935
1936/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1937struct ospf_lsa *
1938ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1939{
1940 struct ospf_lsa *new;
1941 struct as_external_lsa *extnew;
1942
1943 /* we cant use ospf_external_lsa_originate() as we need to set
1944 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1945 */
1946
1947 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1948 {
1949 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001950 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001951 "Type-7, Id %s, to Type-5",
1952 inet_ntoa (type7->data->id));
1953 return NULL;
1954 }
1955
1956 extnew = (struct as_external_lsa *)new;
1957
1958 if (IS_DEBUG_OSPF_NSSA)
1959 {
ajse588f212004-12-08 18:12:06 +00001960 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001961 "translated Type 7, installed:");
1962 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001963 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1964 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001965 }
1966
1967 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1968 {
1969 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001970 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001971 "Could not install LSA "
1972 "id %s", inet_ntoa (type7->data->id));
1973 return NULL;
1974 }
1975
1976 ospf->lsa_originate_count++;
1977 ospf_flood_through_as (ospf, NULL, new);
1978
1979 return new;
1980}
1981
1982/* Refresh Translated from NSSA AS-external-LSA. */
1983struct ospf_lsa *
1984ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1985 struct ospf_lsa *type5)
1986{
1987 struct ospf_lsa *new = NULL;
1988
1989 /* Sanity checks. */
1990 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00001991 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00001992 return NULL;
pauld4a53d52003-07-12 21:30:57 +00001993 if (type7)
1994 assert (type7->data);
1995 if (type5)
1996 assert (type5->data);
1997 assert (ospf->anyNSSA);
1998
1999 /* get required data according to what has been given */
2000 if (type7 && type5 == NULL)
2001 {
2002 /* find the translated Type-5 for this Type-7 */
2003 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
2004 struct prefix_ipv4 p =
2005 {
2006 .prefix = type7->data->id,
2007 .prefixlen = ip_masklen (ext->mask),
2008 .family = AF_INET,
2009 };
2010
2011 type5 = ospf_external_info_find_lsa (ospf, &p);
2012 }
2013 else if (type5 && type7 == NULL)
2014 {
2015 /* find the type-7 from which supplied type-5 was translated,
2016 * ie find first type-7 with same LSA Id.
2017 */
paul1eb8ef22005-04-07 07:30:20 +00002018 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00002019 struct route_node *rn;
2020 struct ospf_lsa *lsa;
2021 struct ospf_area *area;
2022
paul1eb8ef22005-04-07 07:30:20 +00002023 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00002024 {
2025 if (area->external_routing != OSPF_AREA_NSSA
2026 && !type7)
2027 continue;
2028
2029 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
2030 {
2031 if (lsa->data->id.s_addr == type5->data->id.s_addr)
2032 {
2033 type7 = lsa;
2034 break;
2035 }
2036 }
2037 }
2038 }
2039
2040 /* do we have type7? */
2041 if (!type7)
2042 {
2043 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002044 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00002045 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00002046 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00002047 return NULL;
2048 }
2049
2050 /* do we have valid translated type5? */
2051 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
2052 {
2053 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002054 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00002055 "found for Type-7 with Id %s",
2056 inet_ntoa (type7->data->id));
2057 return NULL;
2058 }
2059
2060 /* Delete LSA from neighbor retransmit-list. */
2061 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
2062
2063 /* create new translated LSA */
2064 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
2065 {
2066 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002067 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00002068 "Type-7 for %s to Type-5",
2069 inet_ntoa (type7->data->id));
2070 return NULL;
2071 }
2072
2073 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
2074 {
2075 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002076 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00002077 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00002078 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00002079 return NULL;
2080 }
2081
2082 /* Flood LSA through area. */
2083 ospf_flood_through_as (ospf, NULL, new);
2084
2085 return new;
2086}
paul718e3742002-12-13 20:15:29 +00002087
2088int
2089is_prefix_default (struct prefix_ipv4 *p)
2090{
2091 struct prefix_ipv4 q;
2092
2093 q.family = AF_INET;
2094 q.prefix.s_addr = 0;
2095 q.prefixlen = 0;
2096
2097 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
2098}
2099
2100/* Originate an AS-external-LSA, install and flood. */
2101struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002102ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00002103{
2104 struct ospf_lsa *new;
2105
2106 /* Added for NSSA project....
2107
2108 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2109 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2110 every area. The Type-7's are flooded to every IR and every ABR; We
2111 install the Type-5 LSDB so that the normal "refresh" code operates
2112 as usual, and flag them as not used during ASE calculations. The
2113 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2114 Address of non-zero.
2115
2116 If an ABR is the elected NSSA translator, following SPF and during
2117 the ABR task it will translate all the scanned Type-7's, with P-bit
2118 ON and not-self generated, and translate to Type-5's throughout the
2119 non-NSSA/STUB AS.
2120
2121 A difference in operation depends whether this ASBR is an ABR
2122 or not. If not an ABR, the P-bit is ON, to indicate that any
2123 elected NSSA-ABR can perform its translation.
2124
2125 If an ABR, the P-bit is OFF; No ABR will perform translation and
2126 this ASBR will flood the Type-5 LSA as usual.
2127
2128 For the case where this ASBR is not an ABR, the ASE calculations
2129 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2130 demonstrate to the user that there are LSA's that belong to any
2131 attached NSSA.
2132
2133 Finally, it just so happens that when the ABR is translating every
2134 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2135 approved Type-5 (translated from Type-7); at the end of translation
2136 if any Translated Type-5's remain unapproved, then they must be
2137 flushed from the AS.
2138
2139 */
2140
2141 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002142 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002143 return NULL;
2144
2145 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002146 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002147 {
2148 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002149 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002150 inet_ntoa (ei->p.prefix));
2151 return NULL;
2152 }
2153
2154 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002155 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002156
2157 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002158 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002159
2160 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002161 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002162
paul718e3742002-12-13 20:15:29 +00002163 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002164 if (ospf->anyNSSA &&
2165 /* stay away from translated LSAs! */
2166 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002167 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002168
2169 /* Debug logging. */
2170 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2171 {
ajse588f212004-12-08 18:12:06 +00002172 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002173 new->data->type, inet_ntoa (new->data->id), new);
2174 ospf_lsa_header_dump (new->data);
2175 }
2176
2177 return new;
2178}
2179
2180/* Originate AS-external-LSA from external info with initial flag. */
2181int
paul68980082003-03-25 05:07:42 +00002182ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002183{
paul68980082003-03-25 05:07:42 +00002184 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002185 struct route_node *rn;
2186 struct external_info *ei;
2187 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002188 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002189
paul68980082003-03-25 05:07:42 +00002190 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002191
2192 /* Originate As-external-LSA from all type of distribute source. */
2193 if ((rt = EXTERNAL_INFO (type)))
2194 for (rn = route_top (rt); rn; rn = route_next (rn))
2195 if ((ei = rn->info) != NULL)
2196 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002197 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002198 zlog_warn ("LSA: AS-external-LSA was not originated.");
2199
2200 return 0;
2201}
2202
paul4dadc292005-05-06 21:37:42 +00002203static struct external_info *
paul020709f2003-04-04 02:44:16 +00002204ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002205{
2206 int type;
2207 struct route_node *rn;
2208 struct prefix_ipv4 p;
2209
2210 p.family = AF_INET;
2211 p.prefix.s_addr = 0;
2212 p.prefixlen = 0;
2213
2214 /* First, lookup redistributed default route. */
2215 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2216 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2217 {
2218 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2219 if (rn != NULL)
2220 {
2221 route_unlock_node (rn);
2222 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002223 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002224 return rn->info;
2225 }
2226 }
2227
2228 return NULL;
2229}
2230
2231int
paul68980082003-03-25 05:07:42 +00002232ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002233{
paul718e3742002-12-13 20:15:29 +00002234 struct prefix_ipv4 p;
2235 struct in_addr nexthop;
2236 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002237 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002238
Paul Jakma4021b602006-05-12 22:55:41 +00002239 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002240
2241 p.family = AF_INET;
2242 p.prefix.s_addr = 0;
2243 p.prefixlen = 0;
2244
Paul Jakma4021b602006-05-12 22:55:41 +00002245 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002246 {
2247 /* If there is no default route via redistribute,
2248 then originate AS-external-LSA with nexthop 0 (self). */
2249 nexthop.s_addr = 0;
2250 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2251 }
2252
paul020709f2003-04-04 02:44:16 +00002253 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002254 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002255
2256 return 0;
2257}
2258
paul645878f2003-04-13 21:42:11 +00002259/* Flush any NSSA LSAs for given prefix */
2260void
2261ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2262{
paul1eb8ef22005-04-07 07:30:20 +00002263 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002264 struct ospf_lsa *lsa;
2265 struct ospf_area *area;
2266
paul1eb8ef22005-04-07 07:30:20 +00002267 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002268 {
paul1eb8ef22005-04-07 07:30:20 +00002269 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002270 {
2271 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2272 ospf->router_id)))
2273 {
2274 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002275 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002276 inet_ntoa (p->prefix), p->prefixlen);
2277 continue;
2278 }
2279 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2280 if (!IS_LSA_MAXAGE (lsa))
2281 {
2282 ospf_refresher_unregister_lsa (ospf, lsa);
2283 ospf_lsa_flush_area (lsa, area);
2284 }
2285 }
paul645878f2003-04-13 21:42:11 +00002286 }
2287}
paul645878f2003-04-13 21:42:11 +00002288
paul718e3742002-12-13 20:15:29 +00002289/* Flush an AS-external-LSA from LSDB and routing domain. */
2290void
paul68980082003-03-25 05:07:42 +00002291ospf_external_lsa_flush (struct ospf *ospf,
2292 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002293 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002294{
2295 struct ospf_lsa *lsa;
2296
2297 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002298 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002299 inet_ntoa (p->prefix), p->prefixlen);
2300
2301 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002302 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002303 {
2304 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002305 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002306 inet_ntoa (p->prefix), p->prefixlen);
2307 return;
2308 }
hassobeebba72004-06-20 21:00:27 +00002309
pauld4a53d52003-07-12 21:30:57 +00002310 /* If LSA is selforiginated, not a translated LSA, and there is
2311 * NSSA area, flush Type-7 LSA's at first.
2312 */
2313 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2314 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002315 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002316
2317 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002318 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002319
2320 /* There must be no self-originated LSA in rtrs_external. */
2321#if 0
2322 /* Remove External route from Zebra. */
2323 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2324#endif
2325
2326 if (!IS_LSA_MAXAGE (lsa))
2327 {
2328 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002329 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002330
2331 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002332 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002333 }
2334
2335 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002336 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002337}
2338
2339void
paul68980082003-03-25 05:07:42 +00002340ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002341{
2342 struct prefix_ipv4 p;
2343 struct external_info *ei;
2344 struct ospf_lsa *lsa;
2345
2346 p.family = AF_INET;
2347 p.prefixlen = 0;
2348 p.prefix.s_addr = 0;
2349
paul020709f2003-04-04 02:44:16 +00002350 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002351 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002352
2353 if (ei)
2354 {
2355 if (lsa)
2356 {
2357 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002358 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002359 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002360 }
2361 else
2362 {
2363 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002364 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002365 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002366 }
2367 }
2368 else
2369 {
2370 if (lsa)
2371 {
2372 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002373 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002374 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002375 }
2376 }
2377}
2378
2379void
paul68980082003-03-25 05:07:42 +00002380ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002381{
2382 struct route_node *rn;
2383 struct external_info *ei;
2384
2385 if (type != DEFAULT_ROUTE)
2386 if (EXTERNAL_INFO(type))
2387 /* Refresh each redistributed AS-external-LSAs. */
2388 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2389 if ((ei = rn->info))
2390 if (!is_prefix_default (&ei->p))
2391 {
2392 struct ospf_lsa *lsa;
2393
paul68980082003-03-25 05:07:42 +00002394 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2395 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002396 else
paul68980082003-03-25 05:07:42 +00002397 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002398 }
2399}
2400
2401/* Refresh AS-external-LSA. */
2402void
paul68980082003-03-25 05:07:42 +00002403ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002404 struct external_info *ei, int force)
2405{
2406 struct ospf_lsa *new;
2407 int changed;
2408
2409 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002410 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002411 {
pauld4a53d52003-07-12 21:30:57 +00002412 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002413 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002414 "redist check fail",
2415 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002416 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002417 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +00002418 return;
2419 }
2420
2421 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002422 {
2423 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002424 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002425 lsa->data->type, inet_ntoa (lsa->data->id));
2426 return;
2427 }
paul718e3742002-12-13 20:15:29 +00002428
2429 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002430 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002431
2432 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002433 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002434
paul68980082003-03-25 05:07:42 +00002435 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002436
2437 if (new == NULL)
2438 {
2439 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002440 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002441 inet_ntoa (lsa->data->id));
2442 return;
2443 }
2444
2445 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2446
paul718e3742002-12-13 20:15:29 +00002447 /* Re-calculate checksum. */
2448 ospf_lsa_checksum (new->data);
2449
paul68980082003-03-25 05:07:42 +00002450 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002451
2452 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002453 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002454
paul718e3742002-12-13 20:15:29 +00002455 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002456 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002457 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002458
pauld4a53d52003-07-12 21:30:57 +00002459 /* Register self-originated LSA to refresh queue.
2460 * Translated LSAs should not be registered, but refreshed upon
2461 * refresh of the Type-7
2462 */
2463 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2464 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002465
2466 /* Debug logging. */
2467 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2468 {
ajse588f212004-12-08 18:12:06 +00002469 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002470 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002471 ospf_lsa_header_dump (new->data);
2472 }
2473
2474 return;
2475}
2476
2477
2478/* LSA installation functions. */
2479
2480/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002481static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002482ospf_router_lsa_install (struct ospf *ospf,
2483 struct ospf_lsa *new, int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002484{
2485 struct ospf_area *area = new->area;
2486
2487 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2488 The entire routing table must be recalculated, starting with
2489 the shortest path calculations for each area (not just the
2490 area whose link-state database has changed).
2491 */
2492 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002493 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002494
2495 if (IS_LSA_SELF (new))
2496 {
2497 /* Set router-LSA refresh timer. */
2498 OSPF_TIMER_OFF (area->t_router_lsa_self);
2499 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
pauld4a53d52003-07-12 21:30:57 +00002500 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
paul718e3742002-12-13 20:15:29 +00002501
2502 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002503 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002504 area->router_lsa_self = ospf_lsa_lock (new);
2505
2506 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002507 zlog_debug("LSA[Type%d]: ID %s seq 0x%x is self-originated",
paul0c2be262004-05-31 14:16:54 +00002508 new->data->type, inet_ntoa (new->data->id),
2509 ntohl(new->data->ls_seqnum));
paul718e3742002-12-13 20:15:29 +00002510 }
2511
2512 return new;
2513}
2514
2515#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2516 if (!(T)) \
2517 (T) = thread_add_timer (master, (F), oi, (V))
2518
2519/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002520static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002521ospf_network_lsa_install (struct ospf *ospf,
2522 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002523 struct ospf_lsa *new,
2524 int rt_recalc)
2525{
2526
2527 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2528 The entire routing table must be recalculated, starting with
2529 the shortest path calculations for each area (not just the
2530 area whose link-state database has changed).
2531 */
2532 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002533 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002534
2535 /* We supposed that when LSA is originated by us, we pass the int
2536 for which it was originated. If LSA was received by flooding,
2537 the RECEIVED flag is set, so we do not link the LSA to the int. */
2538 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2539 {
2540 /* Set LSRefresh timer. */
2541 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2542
2543 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2544 ospf_network_lsa_refresh_timer,
2545 OSPF_LS_REFRESH_TIME);
2546
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002547 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002548 oi->network_lsa_self = ospf_lsa_lock (new);
2549 }
2550
2551 return new;
2552}
2553
2554/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002555static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002556ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2557 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002558{
paul718e3742002-12-13 20:15:29 +00002559 if (rt_recalc && !IS_LSA_SELF (new))
2560 {
2561 /* RFC 2328 Section 13.2 Summary-LSAs
2562 The best route to the destination described by the summary-
2563 LSA must be recalculated (see Section 16.5). If this
2564 destination is an AS boundary router, it may also be
2565 necessary to re-examine all the AS-external-LSAs.
2566 */
2567
2568#if 0
2569 /* This doesn't exist yet... */
2570 ospf_summary_incremental_update(new); */
2571#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002572 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002573#endif /* #if 0 */
2574
2575 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002576 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002577 }
2578
2579 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002580 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002581
2582 return new;
2583}
2584
2585/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002586static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002587ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2588 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002589{
2590 if (rt_recalc && !IS_LSA_SELF (new))
2591 {
2592 /* RFC 2328 Section 13.2 Summary-LSAs
2593 The best route to the destination described by the summary-
2594 LSA must be recalculated (see Section 16.5). If this
2595 destination is an AS boundary router, it may also be
2596 necessary to re-examine all the AS-external-LSAs.
2597 */
2598#if 0
2599 /* These don't exist yet... */
2600 ospf_summary_incremental_update(new);
2601 /* Isn't this done by the above call?
2602 - RFC 2328 Section 16.5 implies it should be */
2603 /* ospf_ase_calculate_schedule(); */
2604#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002605 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002606#endif /* #if 0 */
2607 }
2608
2609 /* register LSA to refresh-list. */
2610 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002611 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002612
2613 return new;
2614}
2615
2616/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002617static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002618ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2619 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002620{
paul68980082003-03-25 05:07:42 +00002621 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002622 /* If LSA is not self-originated, calculate an external route. */
2623 if (rt_recalc)
2624 {
2625 /* RFC 2328 Section 13.2 AS-external-LSAs
2626 The best route to the destination described by the AS-
2627 external-LSA must be recalculated (see Section 16.6).
2628 */
2629
2630 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002631 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002632 }
2633
pauld4a53d52003-07-12 21:30:57 +00002634 if (new->data->type == OSPF_AS_NSSA_LSA)
2635 {
2636 /* There is no point to register selforiginate Type-7 LSA for
2637 * refreshing. We rely on refreshing Type-5 LSA's
2638 */
2639 if (IS_LSA_SELF (new))
2640 return new;
2641 else
2642 {
2643 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2644 * New translations will be taken care of by the abr_task.
2645 */
2646 ospf_translated_nssa_refresh (ospf, new, NULL);
2647 }
2648 }
pauld7480322003-05-16 17:31:51 +00002649
pauld4a53d52003-07-12 21:30:57 +00002650 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002651 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002652 */
hassobeebba72004-06-20 21:00:27 +00002653 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002654 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002655
2656 return new;
2657}
2658
2659void
paul68980082003-03-25 05:07:42 +00002660ospf_discard_from_db (struct ospf *ospf,
2661 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002662{
2663 struct ospf_lsa *old;
2664
Paul Jakmaac904de2006-06-15 12:04:57 +00002665 if (!lsdb)
2666 {
2667 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2668 if (!lsa)
2669 zlog_warn ("%s: and NULL LSA!", __func__);
2670 else
2671 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2672 lsa->data->type, inet_ntoa (lsa->data->id));
2673 return;
2674 }
2675
paul718e3742002-12-13 20:15:29 +00002676 old = ospf_lsdb_lookup (lsdb, lsa);
2677
2678 if (!old)
2679 return;
2680
2681 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002682 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002683
2684 switch (old->data->type)
2685 {
2686 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002687 ospf_ase_unregister_external_lsa (old, ospf);
2688 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2689 break;
paul718e3742002-12-13 20:15:29 +00002690#ifdef HAVE_OPAQUE_LSA
2691 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002692 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002693 break;
paul69310a62005-05-11 18:09:59 +00002694#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002695 case OSPF_AS_NSSA_LSA:
2696 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2697 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002698 break;
paul718e3742002-12-13 20:15:29 +00002699 default:
paul68980082003-03-25 05:07:42 +00002700 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002701 break;
2702 }
2703
paul68980082003-03-25 05:07:42 +00002704 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002705 ospf_lsa_discard (old);
2706}
2707
paul718e3742002-12-13 20:15:29 +00002708struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002709ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2710 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002711{
2712 struct ospf_lsa *new = NULL;
2713 struct ospf_lsa *old = NULL;
2714 struct ospf_lsdb *lsdb = NULL;
2715 int rt_recalc;
2716
2717 /* Set LSDB. */
2718 switch (lsa->data->type)
2719 {
paulf2c80652002-12-13 21:44:27 +00002720 /* kevinm */
2721 case OSPF_AS_NSSA_LSA:
2722 if (lsa->area)
2723 lsdb = lsa->area->lsdb;
2724 else
paul68980082003-03-25 05:07:42 +00002725 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002726 break;
paul718e3742002-12-13 20:15:29 +00002727 case OSPF_AS_EXTERNAL_LSA:
2728#ifdef HAVE_OPAQUE_LSA
2729 case OSPF_OPAQUE_AS_LSA:
2730#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002731 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002732 break;
2733 default:
2734 lsdb = lsa->area->lsdb;
2735 break;
2736 }
2737
paul718e3742002-12-13 20:15:29 +00002738 assert (lsdb);
2739
2740 /* RFC 2328 13.2. Installing LSAs in the database
2741
2742 Installing a new LSA in the database, either as the result of
2743 flooding or a newly self-originated LSA, may cause the OSPF
2744 routing table structure to be recalculated. The contents of the
2745 new LSA should be compared to the old instance, if present. If
2746 there is no difference, there is no need to recalculate the
2747 routing table. When comparing an LSA to its previous instance,
2748 the following are all considered to be differences in contents:
2749
2750 o The LSA's Options field has changed.
2751
2752 o One of the LSA instances has LS age set to MaxAge, and
2753 the other does not.
2754
2755 o The length field in the LSA header has changed.
2756
2757 o The body of the LSA (i.e., anything outside the 20-byte
2758 LSA header) has changed. Note that this excludes changes
2759 in LS Sequence Number and LS Checksum.
2760
2761 */
2762 /* Look up old LSA and determine if any SPF calculation or incremental
2763 update is needed */
2764 old = ospf_lsdb_lookup (lsdb, lsa);
2765
2766 /* Do comparision and record if recalc needed. */
2767 rt_recalc = 0;
2768 if ( old == NULL || ospf_lsa_different(old, lsa))
2769 rt_recalc = 1;
2770
paul7ddf1d62003-10-13 09:06:46 +00002771 /*
2772 Sequence number check (Section 14.1 of rfc 2328)
2773 "Premature aging is used when it is time for a self-originated
2774 LSA's sequence number field to wrap. At this point, the current
2775 LSA instance (having LS sequence number MaxSequenceNumber) must
2776 be prematurely aged and flushed from the routing domain before a
2777 new instance with sequence number equal to InitialSequenceNumber
2778 can be originated. "
2779 */
2780
Paul Jakmac2b478d2006-03-30 14:16:11 +00002781 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002782 {
2783 if (ospf_lsa_is_self_originated(ospf, lsa))
2784 {
paul0c2be262004-05-31 14:16:54 +00002785 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2786
2787 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002788 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2789 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2790
2791 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2792 {
ajse588f212004-12-08 18:12:06 +00002793 zlog_debug ("ospf_lsa_install() Premature Aging "
paul7ddf1d62003-10-13 09:06:46 +00002794 "lsa 0x%lx", (u_long)lsa);
2795 ospf_lsa_header_dump (lsa->data);
2796 }
2797 }
2798 else
2799 {
2800 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2801 {
ajse588f212004-12-08 18:12:06 +00002802 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002803 "that was not self originated. Ignoring\n");
2804 ospf_lsa_header_dump (lsa->data);
2805 }
2806 return old;
2807 }
2808 }
2809
paul718e3742002-12-13 20:15:29 +00002810 /* discard old LSA from LSDB */
2811 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002812 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002813
paul718e3742002-12-13 20:15:29 +00002814 /* Calculate Checksum if self-originated?. */
2815 if (IS_LSA_SELF (lsa))
2816 ospf_lsa_checksum (lsa->data);
2817
hassofe71a972004-12-22 16:16:02 +00002818 /* Insert LSA to LSDB. */
2819 ospf_lsdb_add (lsdb, lsa);
2820 lsa->lsdb = lsdb;
2821
paul718e3742002-12-13 20:15:29 +00002822 /* Do LSA specific installation process. */
2823 switch (lsa->data->type)
2824 {
2825 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002826 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002827 break;
2828 case OSPF_NETWORK_LSA:
2829 assert (oi);
paul68980082003-03-25 05:07:42 +00002830 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002831 break;
2832 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002833 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002834 break;
2835 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002836 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002837 break;
2838 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002839 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002840 break;
2841#ifdef HAVE_OPAQUE_LSA
2842 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002843 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002844 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002845 else
paul68980082003-03-25 05:07:42 +00002846 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002847 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002848 case OSPF_OPAQUE_AREA_LSA:
2849 case OSPF_OPAQUE_AS_LSA:
2850 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2851 break;
2852#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002853 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002854 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002855 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002856 break;
2857 }
2858
2859 if (new == NULL)
2860 return new; /* Installation failed, cannot proceed further -- endo. */
2861
2862 /* Debug logs. */
2863 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2864 {
2865 char area_str[INET_ADDRSTRLEN];
2866
2867 switch (lsa->data->type)
2868 {
2869 case OSPF_AS_EXTERNAL_LSA:
2870#ifdef HAVE_OPAQUE_LSA
2871 case OSPF_OPAQUE_AS_LSA:
2872#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002873 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002874 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002875 dump_lsa_key (new),
2876 LOOKUP (ospf_lsa_type_msg, new->data->type));
2877 break;
2878 default:
2879 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002880 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002881 dump_lsa_key (new),
2882 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2883 break;
2884 }
2885 }
2886
paul7ddf1d62003-10-13 09:06:46 +00002887 /*
2888 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2889 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2890 */
2891 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2892 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002893 {
paul7ddf1d62003-10-13 09:06:46 +00002894 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002895 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002896 new->data->type,
2897 inet_ntoa (new->data->id),
2898 lsa);
paul68980082003-03-25 05:07:42 +00002899 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002900 }
2901
2902 return new;
2903}
2904
2905
paul4dadc292005-05-06 21:37:42 +00002906static int
paul68980082003-03-25 05:07:42 +00002907ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002908{
paul1eb8ef22005-04-07 07:30:20 +00002909 struct listnode *node, *nnode;
2910 struct ospf_interface *oi;
2911
2912 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002913 {
paul718e3742002-12-13 20:15:29 +00002914 struct route_node *rn;
2915 struct ospf_neighbor *nbr;
2916
2917 if (ospf_if_is_enable (oi))
2918 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2919 if ((nbr = rn->info) != NULL)
2920 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2921 {
2922 route_unlock_node (rn);
2923 return 0;
2924 }
2925 }
2926
2927 return 1;
2928}
2929
2930
2931#ifdef ORIGINAL_CODING
2932/* This function flood the maxaged LSA to DR. */
2933void
2934ospf_maxage_flood (struct ospf_lsa *lsa)
2935{
2936 switch (lsa->data->type)
2937 {
2938 case OSPF_ROUTER_LSA:
2939 case OSPF_NETWORK_LSA:
2940 case OSPF_SUMMARY_LSA:
2941 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00002942 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00002943#ifdef HAVE_OPAQUE_LSA
2944 case OSPF_OPAQUE_LINK_LSA:
2945 case OSPF_OPAQUE_AREA_LSA:
2946#endif /* HAVE_OPAQUE_LSA */
2947 ospf_flood_through_area (lsa->area, NULL, lsa);
2948 break;
2949 case OSPF_AS_EXTERNAL_LSA:
2950#ifdef HAVE_OPAQUE_LSA
2951 case OSPF_OPAQUE_AS_LSA:
2952#endif /* HAVE_OPAQUE_LSA */
2953 ospf_flood_through_as (NULL, lsa);
2954 break;
2955 default:
2956 break;
2957 }
2958}
2959#endif /* ORIGINAL_CODING */
2960
paul4dadc292005-05-06 21:37:42 +00002961static int
paul718e3742002-12-13 20:15:29 +00002962ospf_maxage_lsa_remover (struct thread *thread)
2963{
paul68980082003-03-25 05:07:42 +00002964 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002965 struct ospf_lsa *lsa;
2966 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002967 int reschedule = 0;
2968
paul68980082003-03-25 05:07:42 +00002969 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002970
2971 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002972 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002973
paul68980082003-03-25 05:07:42 +00002974 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002975
2976 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002977 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002978 {
paul718e3742002-12-13 20:15:29 +00002979 if (lsa->retransmit_counter > 0)
2980 {
2981 reschedule = 1;
2982 continue;
2983 }
2984
2985 /* Remove LSA from the LSDB */
2986 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
2987 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002988 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
paul7ddf1d62003-10-13 09:06:46 +00002989 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002990
2991 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002992 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002993 lsa->data->type, inet_ntoa (lsa->data->id));
2994
2995 /* Flood max age LSA. */
2996#ifdef ORIGINAL_CODING
2997 ospf_maxage_flood (lsa);
2998#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00002999 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00003000#endif /* ORIGINAL_CODING */
3001
paul7ddf1d62003-10-13 09:06:46 +00003002 if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
3003 {
3004 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003005 zlog_debug ("originating new router lsa for lsa 0x%lx \n",
paul7ddf1d62003-10-13 09:06:46 +00003006 (u_long)lsa);
3007 ospf_router_lsa_originate(lsa->area);
3008 }
3009
paul718e3742002-12-13 20:15:29 +00003010 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00003011 if (lsa->lsdb)
3012 {
3013 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
3014 ospf_lsdb_delete (lsa->lsdb, lsa);
3015 }
3016 else
3017 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
3018 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00003019 }
3020
3021 /* A MaxAge LSA must be removed immediately from the router's link
3022 state database as soon as both a) it is no longer contained on any
3023 neighbor Link state retransmission lists and b) none of the router's
3024 neighbors are in states Exchange or Loading. */
3025 if (reschedule)
paul68980082003-03-25 05:07:42 +00003026 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003027
3028 return 0;
3029}
3030
paul4dadc292005-05-06 21:37:42 +00003031static int
paul68980082003-03-25 05:07:42 +00003032ospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new)
paul718e3742002-12-13 20:15:29 +00003033{
hasso52dc7ee2004-09-23 19:18:23 +00003034 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003035 struct ospf_lsa *lsa;
3036
3037 for (ALL_LIST_ELEMENTS_RO (ospf->maxage_lsa, node, lsa))
3038 if (lsa == new)
paul718e3742002-12-13 20:15:29 +00003039 return 1;
3040
3041 return 0;
3042}
3043
3044void
paul68980082003-03-25 05:07:42 +00003045ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003046{
hasso52dc7ee2004-09-23 19:18:23 +00003047 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003048
paul68980082003-03-25 05:07:42 +00003049 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00003050 {
paul68980082003-03-25 05:07:42 +00003051 list_delete_node (ospf->maxage_lsa, n);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003052 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +00003053 }
3054}
3055
3056void
paul68980082003-03-25 05:07:42 +00003057ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003058{
3059 /* When we saw a MaxAge LSA flooded to us, we put it on the list
3060 and schedule the MaxAge LSA remover. */
paul68980082003-03-25 05:07:42 +00003061 if (ospf_lsa_maxage_exist (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003062 {
3063 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003064 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00003065 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
3066 return;
3067 }
3068
paul68980082003-03-25 05:07:42 +00003069 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00003070
3071 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003072 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003073
paul68980082003-03-25 05:07:42 +00003074 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003075}
3076
paul4dadc292005-05-06 21:37:42 +00003077static int
paul68980082003-03-25 05:07:42 +00003078ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003079{
paul718e3742002-12-13 20:15:29 +00003080 /* Stay away from any Local Translated Type-7 LSAs */
3081 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3082 return 0;
paul718e3742002-12-13 20:15:29 +00003083
3084 if (IS_LSA_MAXAGE (lsa))
3085 /* Self-originated LSAs should NOT time-out instead,
3086 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00003087 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003088 {
3089 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003090 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003091
3092 switch (lsa->data->type)
3093 {
paul718e3742002-12-13 20:15:29 +00003094#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00003095 case OSPF_OPAQUE_LINK_LSA:
3096 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003097 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003098 /*
3099 * As a general rule, whenever network topology has changed
3100 * (due to an LSA removal in this case), routing recalculation
3101 * should be triggered. However, this is not true for opaque
3102 * LSAs. Even if an opaque LSA instance is going to be removed
3103 * from the routing domain, it does not mean a change in network
3104 * topology, and thus, routing recalculation is not needed here.
3105 */
3106 break;
paul718e3742002-12-13 20:15:29 +00003107#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00003108 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003109 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003110 ospf_ase_incremental_update (ospf, lsa);
3111 break;
paul718e3742002-12-13 20:15:29 +00003112 default:
paul68980082003-03-25 05:07:42 +00003113 ospf_spf_calculate_schedule (ospf);
3114 break;
paul718e3742002-12-13 20:15:29 +00003115 }
paul68980082003-03-25 05:07:42 +00003116 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003117 }
3118
3119 return 0;
3120}
3121
3122/* Periodical check of MaxAge LSA. */
3123int
paul68980082003-03-25 05:07:42 +00003124ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003125{
paul68980082003-03-25 05:07:42 +00003126 struct ospf *ospf = THREAD_ARG (thread);
3127 struct route_node *rn;
3128 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003129 struct ospf_area *area;
3130 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003131
paul68980082003-03-25 05:07:42 +00003132 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003133
paul1eb8ef22005-04-07 07:30:20 +00003134 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003135 {
paul68980082003-03-25 05:07:42 +00003136 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3137 ospf_lsa_maxage_walker_remover (ospf, lsa);
3138 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3139 ospf_lsa_maxage_walker_remover (ospf, lsa);
3140 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3141 ospf_lsa_maxage_walker_remover (ospf, lsa);
3142 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3143 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003144#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003145 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3146 ospf_lsa_maxage_walker_remover (ospf, lsa);
3147 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3148 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003149#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003150 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3151 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003152 }
3153
paul4fb949e2003-05-10 20:06:51 +00003154 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003155 if (ospf->lsdb)
3156 {
3157 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3158 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003159#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003160 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3161 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003162#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003163 }
paul718e3742002-12-13 20:15:29 +00003164
paul68980082003-03-25 05:07:42 +00003165 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3166 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003167 return 0;
3168}
3169
paul68980082003-03-25 05:07:42 +00003170struct ospf_lsa *
3171ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3172 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003173{
paul68980082003-03-25 05:07:42 +00003174 struct ospf_lsa *lsa;
3175 struct in_addr mask, id;
3176 struct lsa_header_mask
3177 {
3178 struct lsa_header header;
3179 struct in_addr mask;
3180 } *hmask;
paul718e3742002-12-13 20:15:29 +00003181
paul68980082003-03-25 05:07:42 +00003182 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3183 if (lsa == NULL)
3184 return NULL;
paul718e3742002-12-13 20:15:29 +00003185
paul68980082003-03-25 05:07:42 +00003186 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003187
paul68980082003-03-25 05:07:42 +00003188 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003189
paul68980082003-03-25 05:07:42 +00003190 if (mask.s_addr != hmask->mask.s_addr)
3191 {
3192 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3193 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3194 if (!lsa)
3195 return NULL;
3196 }
paul718e3742002-12-13 20:15:29 +00003197
paul68980082003-03-25 05:07:42 +00003198 return lsa;
paul718e3742002-12-13 20:15:29 +00003199}
3200
3201struct ospf_lsa *
3202ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3203 struct in_addr id, struct in_addr adv_router)
3204{
paule05fba42003-04-13 20:20:53 +00003205 struct ospf *ospf = ospf_lookup();
3206 assert(ospf);
3207
paul718e3742002-12-13 20:15:29 +00003208 switch (type)
3209 {
3210 case OSPF_ROUTER_LSA:
3211 case OSPF_NETWORK_LSA:
3212 case OSPF_SUMMARY_LSA:
3213 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003214 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003215#ifdef HAVE_OPAQUE_LSA
3216 case OSPF_OPAQUE_LINK_LSA:
3217 case OSPF_OPAQUE_AREA_LSA:
3218#endif /* HAVE_OPAQUE_LSA */
3219 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003220 case OSPF_AS_EXTERNAL_LSA:
3221#ifdef HAVE_OPAQUE_LSA
3222 case OSPF_OPAQUE_AS_LSA:
3223#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003224 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003225 default:
3226 break;
3227 }
3228
3229 return NULL;
3230}
3231
3232struct ospf_lsa *
3233ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3234 struct in_addr id)
3235{
3236 struct ospf_lsa *lsa;
3237 struct route_node *rn;
3238
3239 switch (type)
3240 {
3241 case OSPF_ROUTER_LSA:
3242 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003243 case OSPF_NETWORK_LSA:
3244 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3245 if ((lsa = rn->info))
3246 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3247 {
3248 route_unlock_node (rn);
3249 return lsa;
3250 }
3251 break;
3252 case OSPF_SUMMARY_LSA:
3253 case OSPF_ASBR_SUMMARY_LSA:
3254 /* Currently not used. */
3255 assert (1);
3256 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003257 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003258 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003259#ifdef HAVE_OPAQUE_LSA
3260 case OSPF_OPAQUE_LINK_LSA:
3261 case OSPF_OPAQUE_AREA_LSA:
3262 case OSPF_OPAQUE_AS_LSA:
3263 /* Currently not used. */
3264 break;
3265#endif /* HAVE_OPAQUE_LSA */
3266 default:
3267 break;
3268 }
3269
3270 return NULL;
3271}
3272
3273struct ospf_lsa *
3274ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3275{
3276 struct ospf_lsa *match;
3277
3278#ifdef HAVE_OPAQUE_LSA
3279 /*
3280 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3281 * is redefined to have two subfields; opaque-type and opaque-id.
3282 * However, it is harmless to treat the two sub fields together, as if
3283 * they two were forming a unique LSA-ID.
3284 */
3285#endif /* HAVE_OPAQUE_LSA */
3286
3287 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3288
3289 if (match == NULL)
3290 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003291 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003292 lsah->type, inet_ntoa (lsah->id));
3293
3294 return match;
3295}
3296
3297/* return +n, l1 is more recent.
3298 return -n, l2 is more recent.
3299 return 0, l1 and l2 is identical. */
3300int
3301ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3302{
3303 int r;
3304 int x, y;
3305
3306 if (l1 == NULL && l2 == NULL)
3307 return 0;
3308 if (l1 == NULL)
3309 return -1;
3310 if (l2 == NULL)
3311 return 1;
3312
3313 /* compare LS sequence number. */
3314 x = (int) ntohl (l1->data->ls_seqnum);
3315 y = (int) ntohl (l2->data->ls_seqnum);
3316 if (x > y)
3317 return 1;
3318 if (x < y)
3319 return -1;
3320
3321 /* compare LS checksum. */
3322 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3323 if (r)
3324 return r;
3325
3326 /* compare LS age. */
3327 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3328 return 1;
3329 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3330 return -1;
3331
3332 /* compare LS age with MaxAgeDiff. */
3333 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3334 return -1;
3335 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3336 return 1;
3337
3338 /* LSAs are identical. */
3339 return 0;
3340}
3341
3342/* If two LSAs are different, return 1, otherwise return 0. */
3343int
3344ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3345{
3346 char *p1, *p2;
3347 assert (l1);
3348 assert (l2);
3349 assert (l1->data);
3350 assert (l2->data);
3351
3352 if (l1->data->options != l2->data->options)
3353 return 1;
3354
3355 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3356 return 1;
3357
3358 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3359 return 1;
3360
3361 if (l1->data->length != l2->data->length)
3362 return 1;
3363
3364 if (l1->data->length == 0)
3365 return 1;
3366
pauld1825832003-04-03 01:27:01 +00003367 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003368
3369 p1 = (char *) l1->data;
3370 p2 = (char *) l2->data;
3371
3372 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3373 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3374 return 1;
3375
3376 return 0;
3377}
3378
3379#ifdef ORIGINAL_CODING
3380void
3381ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3382 struct ospf_lsa *self,
3383 struct ospf_lsa *new)
3384{
3385 u_int32_t seqnum;
3386
3387 /* Adjust LS Sequence Number. */
3388 seqnum = ntohl (new->data->ls_seqnum) + 1;
3389 self->data->ls_seqnum = htonl (seqnum);
3390
3391 /* Recalculate LSA checksum. */
3392 ospf_lsa_checksum (self->data);
3393
3394 /* Reflooding LSA. */
3395 /* RFC2328 Section 13.3
3396 On non-broadcast networks, separate Link State Update
3397 packets must be sent, as unicasts, to each adjacent neighbor
3398 (i.e., those in state Exchange or greater). The destination
3399 IP addresses for these packets are the neighbors' IP
3400 addresses. */
3401 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3402 {
3403 struct route_node *rn;
3404 struct ospf_neighbor *onbr;
3405
3406 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3407 if ((onbr = rn->info) != NULL)
3408 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3409 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3410 }
3411 else
3412 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3413
3414 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003415 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003416 self->data->type, inet_ntoa (self->data->id));
3417}
3418#else /* ORIGINAL_CODING */
3419static int
paul68980082003-03-25 05:07:42 +00003420ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003421{
3422 if (lsa == NULL || !IS_LSA_SELF (lsa))
3423 return 0;
3424
3425 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003426 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00003427
3428 /* Force given lsa's age to MaxAge. */
3429 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3430
3431 switch (lsa->data->type)
3432 {
3433#ifdef HAVE_OPAQUE_LSA
3434 case OSPF_OPAQUE_LINK_LSA:
3435 case OSPF_OPAQUE_AREA_LSA:
3436 case OSPF_OPAQUE_AS_LSA:
3437 ospf_opaque_lsa_refresh (lsa);
3438 break;
3439#endif /* HAVE_OPAQUE_LSA */
3440 default:
paul68980082003-03-25 05:07:42 +00003441 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003442 break;
3443 }
3444
3445 return 0;
3446}
3447
3448void
paul68980082003-03-25 05:07:42 +00003449ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003450{
paul1eb8ef22005-04-07 07:30:20 +00003451 struct listnode *node, *nnode;
3452 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003453 struct ospf_area *area;
3454 struct ospf_interface *oi;
3455 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003456 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003457 int need_to_flush_ase = 0;
3458
paul1eb8ef22005-04-07 07:30:20 +00003459 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003460 {
paul718e3742002-12-13 20:15:29 +00003461 if ((lsa = area->router_lsa_self) != NULL)
3462 {
3463 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003464 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 +00003465
3466 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003467 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003468 area->router_lsa_self = NULL;
3469 OSPF_TIMER_OFF (area->t_router_lsa_self);
3470 }
3471
paul1eb8ef22005-04-07 07:30:20 +00003472 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003473 {
paul718e3742002-12-13 20:15:29 +00003474 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003475 && oi->state == ISM_DR
3476 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003477 {
3478 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003479 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 +00003480
3481 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003482 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003483 oi->network_lsa_self = NULL;
3484 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3485 }
3486
3487 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3488 && area->external_routing == OSPF_AREA_DEFAULT)
3489 need_to_flush_ase = 1;
3490 }
3491
paul68980082003-03-25 05:07:42 +00003492 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3493 ospf_lsa_flush_schedule (ospf, lsa);
3494 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3495 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003496#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003497 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3498 ospf_lsa_flush_schedule (ospf, lsa);
3499 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3500 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003501#endif /* HAVE_OPAQUE_LSA */
3502 }
3503
3504 if (need_to_flush_ase)
3505 {
paul68980082003-03-25 05:07:42 +00003506 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3507 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003508#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003509 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3510 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003511#endif /* HAVE_OPAQUE_LSA */
3512 }
3513
3514 /*
3515 * Make sure that the MaxAge LSA remover is executed immediately,
3516 * without conflicting to other threads.
3517 */
paul68980082003-03-25 05:07:42 +00003518 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003519 {
paul68980082003-03-25 05:07:42 +00003520 OSPF_TIMER_OFF (ospf->t_maxage);
3521 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003522 }
3523
3524 return;
3525}
3526#endif /* ORIGINAL_CODING */
3527
3528/* If there is self-originated LSA, then return 1, otherwise return 0. */
3529/* An interface-independent version of ospf_lsa_is_self_originated */
3530int
paul68980082003-03-25 05:07:42 +00003531ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003532{
hasso52dc7ee2004-09-23 19:18:23 +00003533 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003534 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003535
3536 /* This LSA is already checked. */
3537 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3538 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3539
3540 /* Make sure LSA is self-checked. */
3541 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3542
3543 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003544 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003545 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3546
3547 /* LSA is router-LSA. */
3548 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003549 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003550 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3551
3552 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3553 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003554 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003555 {
paul718e3742002-12-13 20:15:29 +00003556 /* Ignore virtual link. */
3557 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3558 if (oi->address->family == AF_INET)
3559 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3560 {
3561 /* to make it easier later */
3562 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3563 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3564 }
3565 }
3566
3567 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3568}
3569
3570/* Get unique Link State ID. */
3571struct in_addr
paul68980082003-03-25 05:07:42 +00003572ospf_lsa_unique_id (struct ospf *ospf,
3573 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003574{
3575 struct ospf_lsa *lsa;
3576 struct in_addr mask, id;
3577
3578 id = p->prefix;
3579
3580 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003581 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003582 if (lsa)
3583 {
3584 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3585 if (ip_masklen (al->mask) == p->prefixlen)
3586 {
3587 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003588 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003589 "Can't get Link State ID for %s/%d",
3590 inet_ntoa (p->prefix), p->prefixlen);
3591 /* id.s_addr = 0; */
3592 id.s_addr = 0xffffffff;
3593 return id;
3594 }
3595 /* Masklen differs, then apply wildcard mask to Link State ID. */
3596 else
3597 {
3598 masklen2ip (p->prefixlen, &mask);
3599
3600 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003601 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3602 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003603 if (lsa)
3604 {
3605 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003606 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003607 "Can't get Link State ID for %s/%d",
3608 inet_ntoa (p->prefix), p->prefixlen);
3609 /* id.s_addr = 0; */
3610 id.s_addr = 0xffffffff;
3611 return id;
3612 }
3613 }
3614 }
3615
3616 return id;
3617}
3618
3619
Paul Jakma70461d72006-05-12 22:57:57 +00003620#define LSA_ACTION_FLOOD_AREA 1
3621#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003622
3623struct lsa_action
3624{
3625 u_char action;
3626 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003627 struct ospf_lsa *lsa;
3628};
3629
paul4dadc292005-05-06 21:37:42 +00003630static int
paul718e3742002-12-13 20:15:29 +00003631ospf_lsa_action (struct thread *t)
3632{
3633 struct lsa_action *data;
3634
3635 data = THREAD_ARG (t);
3636
3637 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003638 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003639 data->action);
3640
3641 switch (data->action)
3642 {
paul718e3742002-12-13 20:15:29 +00003643 case LSA_ACTION_FLOOD_AREA:
3644 ospf_flood_through_area (data->area, NULL, data->lsa);
3645 break;
paul718e3742002-12-13 20:15:29 +00003646 case LSA_ACTION_FLUSH_AREA:
3647 ospf_lsa_flush_area (data->lsa, data->area);
3648 break;
paul718e3742002-12-13 20:15:29 +00003649 }
3650
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003651 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003652 XFREE (MTYPE_OSPF_MESSAGE, data);
3653 return 0;
3654}
3655
3656void
3657ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3658{
3659 struct lsa_action *data;
3660
3661 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3662 memset (data, 0, sizeof (struct lsa_action));
3663
3664 data->action = LSA_ACTION_FLOOD_AREA;
3665 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003666 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003667
3668 thread_add_event (master, ospf_lsa_action, data, 0);
3669}
3670
3671void
3672ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3673{
3674 struct lsa_action *data;
3675
3676 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3677 memset (data, 0, sizeof (struct lsa_action));
3678
3679 data->action = LSA_ACTION_FLUSH_AREA;
3680 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003681 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003682
3683 thread_add_event (master, ospf_lsa_action, data, 0);
3684}
3685
3686
3687/* LSA Refreshment functions. */
paul4dadc292005-05-06 21:37:42 +00003688static void
paul68980082003-03-25 05:07:42 +00003689ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003690{
3691 struct external_info *ei;
3692 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3693
3694 switch (lsa->data->type)
3695 {
3696 /* Router and Network LSAs are processed differently. */
3697 case OSPF_ROUTER_LSA:
3698 case OSPF_NETWORK_LSA:
3699 break;
3700 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003701 ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003702 break;
3703 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003704 ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003705 break;
3706 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003707 /* Translated from NSSA Type-5s are refreshed when
3708 * from refresh of Type-7 - do not refresh these directly.
3709 */
3710 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3711 break;
paul718e3742002-12-13 20:15:29 +00003712 ei = ospf_external_info_check (lsa);
3713 if (ei)
pauld4a53d52003-07-12 21:30:57 +00003714 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003715 else
pauld4a53d52003-07-12 21:30:57 +00003716 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003717 break;
3718#ifdef HAVE_OPAQUE_LSA
3719 case OSPF_OPAQUE_LINK_LSA:
3720 case OSPF_OPAQUE_AREA_LSA:
3721 case OSPF_OPAQUE_AS_LSA:
3722 ospf_opaque_lsa_refresh (lsa);
3723 break;
pauld7480322003-05-16 17:31:51 +00003724#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003725 default:
3726 break;
paul718e3742002-12-13 20:15:29 +00003727 }
3728}
3729
3730void
paul68980082003-03-25 05:07:42 +00003731ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003732{
3733 u_int16_t index, current_index;
3734
3735 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3736
3737 if (lsa->refresh_list < 0)
3738 {
3739 int delay;
3740
3741 if (LS_AGE (lsa) == 0 &&
3742 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3743 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3744 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3745 else
3746 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3747 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3748 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3749
3750 if (delay < 0)
3751 delay = 0;
3752
paul68980082003-03-25 05:07:42 +00003753 current_index = ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003754 (quagga_time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003755
3756 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3757 % (OSPF_LSA_REFRESHER_SLOTS);
3758
3759 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003760 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003761 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003762 if (!ospf->lsa_refresh_queue.qs[index])
3763 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003764 listnode_add (ospf->lsa_refresh_queue.qs[index],
3765 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003766 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003767 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003768 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003769 "setting refresh_list on lsa %p (slod %d)",
3770 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003771 }
3772}
3773
3774void
paul68980082003-03-25 05:07:42 +00003775ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003776{
3777 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3778 if (lsa->refresh_list >= 0)
3779 {
hasso52dc7ee2004-09-23 19:18:23 +00003780 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003781 listnode_delete (refresh_list, lsa);
3782 if (!listcount (refresh_list))
3783 {
3784 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003785 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003786 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003787 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003788 lsa->refresh_list = -1;
3789 }
3790}
3791
3792int
3793ospf_lsa_refresh_walker (struct thread *t)
3794{
hasso52dc7ee2004-09-23 19:18:23 +00003795 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003796 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003797 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003798 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003799 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003800 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003801
3802 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003803 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003804
3805
paul68980082003-03-25 05:07:42 +00003806 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003807
ajs9dbc7972005-03-13 19:27:22 +00003808 /* Note: if clock has jumped backwards, then time change could be negative,
3809 so we are careful to cast the expression to unsigned before taking
3810 modulus. */
paul68980082003-03-25 05:07:42 +00003811 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003812 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003813 (quagga_time (NULL) - ospf->lsa_refresher_started) /
ajs9dbc7972005-03-13 19:27:22 +00003814 OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003815
3816 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003817 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003818 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003819
paul68980082003-03-25 05:07:42 +00003820 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003821 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3822 {
3823 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003824 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003825 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003826
paul68980082003-03-25 05:07:42 +00003827 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003828
paul68980082003-03-25 05:07:42 +00003829 ospf->lsa_refresh_queue.qs [i] = NULL;
3830
paul718e3742002-12-13 20:15:29 +00003831 if (refresh_list)
3832 {
paul1eb8ef22005-04-07 07:30:20 +00003833 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003834 {
paul718e3742002-12-13 20:15:29 +00003835 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003836 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003837 "refresh lsa %p (slot %d)",
3838 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003839
3840 list_delete_node (refresh_list, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003841 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003842 lsa->refresh_list = -1;
3843 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003844 }
3845 list_free (refresh_list);
3846 }
3847 }
3848
paul68980082003-03-25 05:07:42 +00003849 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3850 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003851 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003852
paul1eb8ef22005-04-07 07:30:20 +00003853 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
3854 ospf_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003855
3856 list_delete (lsa_to_refresh);
3857
3858 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003859 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003860
3861 return 0;
3862}
3863