blob: 05eed35ebeb6c3bf98ea47c8fdce480e86035f02 [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
546/* Describe Point-to-Point link. */
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
hasso3fb9cd62004-10-19 19:44:43 +0000567 if (CONNECTED_DEST_HOST(oi->connected))
paul718e3742002-12-13 20:15:29 +0000568 {
569 /* Option 1:
570 link_type = LSA_LINK_TYPE_STUB;
571 link_id = nbr->address.u.prefix4;
572 link_data.s_addr = 0xffffffff;
573 link_cost = o->output_cost; */
574
575 id.s_addr = oi->connected->destination->u.prefix4.s_addr;
576 mask.s_addr = 0xffffffff;
paul779adb02006-01-18 15:07:38 +0000577 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
578 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000579 }
580 else
581 {
582 /* Option 2: We need to include link to a stub
583 network regardless of the state of the neighbor */
584 masklen2ip (oi->address->prefixlen, &mask);
585 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000586 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
587 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000588 }
paul718e3742002-12-13 20:15:29 +0000589 return links;
590}
591
592/* Describe Broadcast Link. */
paul4dadc292005-05-06 21:37:42 +0000593static int
paul718e3742002-12-13 20:15:29 +0000594lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
595{
596 struct ospf_neighbor *dr;
597 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000598 u_int16_t cost = ospf_link_cost (oi);
599
paul718e3742002-12-13 20:15:29 +0000600 /* Describe Type 3 Link. */
601 if (oi->state == ISM_Waiting)
602 {
603 masklen2ip (oi->address->prefixlen, &mask);
604 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000605 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
606 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000607 }
608
609 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
610 /* Describe Type 2 link. */
611 if (dr && (dr->state == NSM_Full ||
612 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000613 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000614 {
paul779adb02006-01-18 15:07:38 +0000615 return link_info_set (s, DR (oi), oi->address->u.prefix4,
616 LSA_LINK_TYPE_TRANSIT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000617 }
618 /* Describe type 3 link. */
619 else
620 {
621 masklen2ip (oi->address->prefixlen, &mask);
622 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000623 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
624 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000625 }
paul718e3742002-12-13 20:15:29 +0000626}
627
paul4dadc292005-05-06 21:37:42 +0000628static int
paul718e3742002-12-13 20:15:29 +0000629lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
630{
631 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000632
paul718e3742002-12-13 20:15:29 +0000633 /* Describe Type 3 Link. */
634 if (oi->state != ISM_Loopback)
635 return 0;
636
637 mask.s_addr = 0xffffffff;
638 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000639 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000640}
641
642/* Describe Virtual Link. */
paul4dadc292005-05-06 21:37:42 +0000643static int
paul718e3742002-12-13 20:15:29 +0000644lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
645{
646 struct ospf_neighbor *nbr;
paul88d6cf32005-10-29 12:50:09 +0000647 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000648
paul718e3742002-12-13 20:15:29 +0000649 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000650 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000651 if (nbr->state == NSM_Full)
652 {
paul779adb02006-01-18 15:07:38 +0000653 return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
654 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
paul718e3742002-12-13 20:15:29 +0000655 }
656
657 return 0;
658}
659
660#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
661
paul7afa08d2002-12-13 20:59:45 +0000662/* this function add for support point-to-multipoint ,see rfc2328
66312.4.1.4.*/
664/* from "edward rrr" <edward_rrr@hotmail.com>
665 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul4dadc292005-05-06 21:37:42 +0000666static int
paul68980082003-03-25 05:07:42 +0000667lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000668{
669 int links = 0;
670 struct route_node *rn;
671 struct ospf_neighbor *nbr = NULL;
672 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000673 u_int16_t cost = ospf_link_cost (oi);
paul7afa08d2002-12-13 20:59:45 +0000674
675 mask.s_addr = 0xffffffff;
676 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000677 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
paul7afa08d2002-12-13 20:59:45 +0000678
paul1cc8f762003-04-05 19:34:32 +0000679 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000680 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000681
682 /* Search neighbor, */
683 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
684 if ((nbr = rn->info) != NULL)
685 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000686 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000687 if (nbr->state == NSM_Full)
688
689 {
paul779adb02006-01-18 15:07:38 +0000690 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
691 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul1cc8f762003-04-05 19:34:32 +0000692 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000693 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000694 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000695 }
696
697 return links;
paul7afa08d2002-12-13 20:59:45 +0000698}
699
paul718e3742002-12-13 20:15:29 +0000700/* Set router-LSA link information. */
paul4dadc292005-05-06 21:37:42 +0000701static int
paul718e3742002-12-13 20:15:29 +0000702router_lsa_link_set (struct stream *s, struct ospf_area *area)
703{
hasso52dc7ee2004-09-23 19:18:23 +0000704 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000705 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000706 int links = 0;
707
paul1eb8ef22005-04-07 07:30:20 +0000708 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +0000709 {
paul718e3742002-12-13 20:15:29 +0000710 struct interface *ifp = oi->ifp;
711
712 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000713 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000714 {
715 if (oi->state != ISM_Down)
716 {
717 /* Describe each link. */
718 switch (oi->type)
719 {
720 case OSPF_IFTYPE_POINTOPOINT:
721 links += lsa_link_ptop_set (s, oi);
722 break;
723 case OSPF_IFTYPE_BROADCAST:
724 links += lsa_link_broadcast_set (s, oi);
725 break;
726 case OSPF_IFTYPE_NBMA:
727 links += lsa_link_nbma_set (s, oi);
728 break;
729 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000730 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000731 break;
732 case OSPF_IFTYPE_VIRTUALLINK:
733 links += lsa_link_virtuallink_set (s, oi);
734 break;
735 case OSPF_IFTYPE_LOOPBACK:
736 links += lsa_link_loopback_set (s, oi);
737 }
738 }
739 }
740 }
741
742 return links;
743}
744
745/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000746static void
paul718e3742002-12-13 20:15:29 +0000747ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
748{
749 unsigned long putp;
750 u_int16_t cnt;
751
752 /* Set flags. */
753 stream_putc (s, router_lsa_flags (area));
754
755 /* Set Zero fields. */
756 stream_putc (s, 0);
757
758 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000759 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000760
761 /* Forward word */
762 stream_putw(s, 0);
763
764 /* Set all link information. */
765 cnt = router_lsa_link_set (s, area);
766
767 /* Set # of links here. */
768 stream_putw_at (s, putp, cnt);
769}
paul88d6cf32005-10-29 12:50:09 +0000770
771static int
772ospf_stub_router_timer (struct thread *t)
773{
774 struct ospf_area *area = THREAD_ARG (t);
775
776 area->t_stub_router = NULL;
777
778 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
779
780 /* clear stub route state and generate router-lsa refresh, don't
781 * clobber an administratively set stub-router state though.
782 */
783 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
784 return 0;
785
786 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
787
788 ospf_router_lsa_timer_add (area);
789
790 return 0;
791}
paul718e3742002-12-13 20:15:29 +0000792
paul88d6cf32005-10-29 12:50:09 +0000793inline static void
794ospf_stub_router_check (struct ospf_area *area)
795{
796 /* area must either be administratively configured to be stub
797 * or startup-time stub-router must be configured and we must in a pre-stub
798 * state.
799 */
800 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
801 {
802 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
803 return;
804 }
805
806 /* not admin-stubbed, check whether startup stubbing is configured and
807 * whether it's not been done yet
808 */
809 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
810 return;
811
812 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
813 {
814 /* stub-router is hence done forever for this area, even if someone
815 * tries configure it (take effect next restart).
816 */
817 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
818 return;
819 }
820
821 /* startup stub-router configured and not yet done */
822 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
823
824 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
825 area->ospf->stub_router_startup_time);
826}
827
paul718e3742002-12-13 20:15:29 +0000828/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000829static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000830ospf_router_lsa_new (struct ospf_area *area)
831{
paul68980082003-03-25 05:07:42 +0000832 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000833 struct stream *s;
834 struct lsa_header *lsah;
835 struct ospf_lsa *new;
836 int length;
837
838 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000839 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000840
paul88d6cf32005-10-29 12:50:09 +0000841 /* check whether stub-router is desired, and if this is the first
842 * router LSA.
843 */
844 ospf_stub_router_check (area);
845
paul718e3742002-12-13 20:15:29 +0000846 /* Create a stream for LSA. */
847 s = stream_new (OSPF_MAX_LSA_SIZE);
paul718e3742002-12-13 20:15:29 +0000848 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000849 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000850 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000851
852 /* Set router-LSA body fields. */
853 ospf_router_lsa_body_set (s, area);
854
855 /* Set length. */
856 length = stream_get_endp (s);
paul779adb02006-01-18 15:07:38 +0000857 lsah = (struct lsa_header *) STREAM_DATA (s);
paul718e3742002-12-13 20:15:29 +0000858 lsah->length = htons (length);
859
860 /* Now, create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000861 if ( (new = ospf_lsa_new ()) == NULL)
862 {
863 zlog_err ("%s: Unable to create new lsa", __func__);
864 return NULL;
865 }
866
paul718e3742002-12-13 20:15:29 +0000867 new->area = area;
868 SET_FLAG (new->flags, OSPF_LSA_SELF);
869
870 /* Copy LSA data to store, discard stream. */
871 new->data = ospf_lsa_data_new (length);
872 memcpy (new->data, lsah, length);
873 stream_free (s);
874
875 return new;
876}
877
878/* Originate Router-LSA. */
paul88d6cf32005-10-29 12:50:09 +0000879static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000880ospf_router_lsa_originate (struct ospf_area *area)
881{
882 struct ospf_lsa *new;
paul88d6cf32005-10-29 12:50:09 +0000883
paul718e3742002-12-13 20:15:29 +0000884 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000885 if ( (new = ospf_router_lsa_new (area)) == NULL)
886 {
887 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
888 return NULL;
889 }
paul718e3742002-12-13 20:15:29 +0000890
891 /* Sanity check. */
892 if (new->data->adv_router.s_addr == 0)
893 {
894 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000895 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000896 ospf_lsa_discard (new);
897 return NULL;
898 }
899
900 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000901 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000902
903 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000904 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000905
906 /* Flooding new LSA through area. */
907 ospf_flood_through_area (area, NULL, new);
908
909 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
910 {
ajse588f212004-12-08 18:12:06 +0000911 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
paul718e3742002-12-13 20:15:29 +0000912 new->data->type, inet_ntoa (new->data->id), new);
913 ospf_lsa_header_dump (new->data);
914 }
915
916 return new;
917}
918
919/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000920static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000921ospf_router_lsa_refresh (struct ospf_lsa *lsa)
922{
923 struct ospf_area *area = lsa->area;
924 struct ospf_lsa *new;
925
926 /* Sanity check. */
927 assert (lsa->data);
928
929 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000930 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000931
932 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000933 if ( (new = ospf_router_lsa_new (area)) == NULL)
934 {
935 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
936 return NULL;
937 }
938
paul718e3742002-12-13 20:15:29 +0000939 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
940
paul68980082003-03-25 05:07:42 +0000941 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000942
943 /* Flood LSA through area. */
944 ospf_flood_through_area (area, NULL, new);
945
946 /* Debug logging. */
947 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
948 {
ajse588f212004-12-08 18:12:06 +0000949 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000950 new->data->type, inet_ntoa (new->data->id));
951 ospf_lsa_header_dump (new->data);
952 }
953
954 return NULL;
955}
956
paul4dadc292005-05-06 21:37:42 +0000957static int
paul718e3742002-12-13 20:15:29 +0000958ospf_router_lsa_timer (struct thread *t)
959{
960 struct ospf_area *area;
961
962 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000963 zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
paul718e3742002-12-13 20:15:29 +0000964
965 area = THREAD_ARG (t);
966 area->t_router_lsa_self = NULL;
967
968 /* Now refresh router-LSA. */
969 if (area->router_lsa_self)
970 ospf_router_lsa_refresh (area->router_lsa_self);
971 /* Newly originate router-LSA. */
972 else
973 ospf_router_lsa_originate (area);
974
975 return 0;
976}
977
978void
979ospf_router_lsa_timer_add (struct ospf_area *area)
980{
981 /* Keep area's self-originated router-LSA. */
982 struct ospf_lsa *lsa = area->router_lsa_self;
983
984 /* Cancel previously scheduled router-LSA timer. */
985 if (area->t_router_lsa_self)
986 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000987 zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
paul718e3742002-12-13 20:15:29 +0000988
989 OSPF_TIMER_OFF (area->t_router_lsa_self);
990
991 /* If router-LSA is originated previously, check the interval time. */
992 if (lsa)
993 {
994 int delay;
995 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
996 {
997 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
998 ospf_router_lsa_timer, delay);
999 return;
1000 }
1001 }
1002
1003 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001004 zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
paul718e3742002-12-13 20:15:29 +00001005
1006 /* Immediately refresh router-LSA. */
1007 OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
1008}
1009
1010int
paul68980082003-03-25 05:07:42 +00001011ospf_router_lsa_update_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00001012{
paul68980082003-03-25 05:07:42 +00001013 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00001014 struct listnode *node, *nnode;
1015 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00001016
1017 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001018 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +00001019
paul68980082003-03-25 05:07:42 +00001020 ospf->t_router_lsa_update = NULL;
paul718e3742002-12-13 20:15:29 +00001021
paul1eb8ef22005-04-07 07:30:20 +00001022 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00001023 {
paul718e3742002-12-13 20:15:29 +00001024 struct ospf_lsa *lsa = area->router_lsa_self;
1025 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +00001026 const char *area_str;
paul718e3742002-12-13 20:15:29 +00001027
1028 /* Keep Area ID string. */
1029 area_str = AREA_NAME (area);
1030
1031 /* If LSA not exist in this Area, originate new. */
1032 if (lsa == NULL)
1033 {
1034 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001035 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +00001036
1037 ospf_router_lsa_originate (area);
1038 }
1039 /* If router-ID is changed, Link ID must change.
1040 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +00001041 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001042 {
1043 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001044 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +00001045 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
1046 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001047 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00001048 area->router_lsa_self = NULL;
1049
1050 /* Refresh router-LSA, (not install) and flood through area. */
1051 ospf_router_lsa_timer_add (area);
1052 }
1053 else
1054 {
1055 rl = (struct router_lsa *) lsa->data;
1056 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +00001057 if (rl->flags != ospf->flags)
paul718e3742002-12-13 20:15:29 +00001058 ospf_router_lsa_timer_add (area);
1059 }
1060 }
1061
1062 return 0;
1063}
1064
1065
1066/* network-LSA related functions. */
1067/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001068static void
paul718e3742002-12-13 20:15:29 +00001069ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1070{
1071 struct in_addr mask;
1072 struct route_node *rn;
1073 struct ospf_neighbor *nbr;
1074
1075 masklen2ip (oi->address->prefixlen, &mask);
1076 stream_put_ipv4 (s, mask.s_addr);
1077
1078 /* The network-LSA lists those routers that are fully adjacent to
1079 the Designated Router; each fully adjacent router is identified by
1080 its OSPF Router ID. The Designated Router includes itself in this
1081 list. RFC2328, Section 12.4.2 */
1082
1083 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1084 if ((nbr = rn->info) != NULL)
1085 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1086 stream_put_ipv4 (s, nbr->router_id.s_addr);
1087}
1088
paul4dadc292005-05-06 21:37:42 +00001089static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001090ospf_network_lsa_new (struct ospf_interface *oi)
1091{
1092 struct stream *s;
1093 struct ospf_lsa *new;
1094 struct lsa_header *lsah;
1095 int length;
1096
1097 /* If there are no neighbours on this network (the net is stub),
1098 the router does not originate network-LSA (see RFC 12.4.2) */
1099 if (oi->full_nbrs == 0)
1100 return NULL;
1101
1102 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001103 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001104
1105 /* Create new stream for LSA. */
1106 s = stream_new (OSPF_MAX_LSA_SIZE);
1107 lsah = (struct lsa_header *) STREAM_DATA (s);
1108
1109 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001110 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001111
1112 /* Set network-LSA body fields. */
1113 ospf_network_lsa_body_set (s, oi);
1114
1115 /* Set length. */
1116 length = stream_get_endp (s);
1117 lsah->length = htons (length);
1118
1119 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001120 if ( (new = ospf_lsa_new ()) == NULL)
1121 {
1122 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1123 return NULL;
1124 }
1125
paul718e3742002-12-13 20:15:29 +00001126 new->area = oi->area;
1127 SET_FLAG (new->flags, OSPF_LSA_SELF);
1128
1129 /* Copy LSA to store. */
1130 new->data = ospf_lsa_data_new (length);
1131 memcpy (new->data, lsah, length);
1132 stream_free (s);
1133
1134 return new;
1135}
1136
1137/* Originate network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001138static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001139ospf_network_lsa_originate (struct ospf_interface *oi)
1140{
1141 struct ospf_lsa *new;
1142
1143 /* Create new network-LSA instance. */
1144 new = ospf_network_lsa_new (oi);
1145 if (new == NULL)
1146 return NULL;
1147
1148 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001149 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001150
1151 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001152 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001153
1154 /* Flooding new LSA through area. */
1155 ospf_flood_through_area (oi->area, NULL, new);
1156
1157 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1158 {
ajse588f212004-12-08 18:12:06 +00001159 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001160 new->data->type, inet_ntoa (new->data->id), new);
1161 ospf_lsa_header_dump (new->data);
1162 }
1163
1164 return new;
1165}
1166
1167int
1168ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1169{
1170 struct ospf_area *area = lsa->area;
1171 struct ospf_lsa *new;
1172
1173 assert (lsa->data);
1174
1175 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001176 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001177
1178 /* Create new network-LSA instance. */
1179 new = ospf_network_lsa_new (oi);
1180 if (new == NULL)
1181 return -1;
1182 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1183
paul68980082003-03-25 05:07:42 +00001184 ospf_lsa_install (area->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001185
1186 /* Flood LSA through aera. */
1187 ospf_flood_through_area (area, NULL, new);
1188
1189 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1190 {
ajse588f212004-12-08 18:12:06 +00001191 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001192 new->data->type, inet_ntoa (new->data->id));
1193 ospf_lsa_header_dump (new->data);
1194 }
1195
1196 return 0;
1197}
1198
paul4dadc292005-05-06 21:37:42 +00001199static int
paul718e3742002-12-13 20:15:29 +00001200ospf_network_lsa_refresh_timer (struct thread *t)
1201{
1202 struct ospf_interface *oi;
1203
1204 oi = THREAD_ARG (t);
1205 oi->t_network_lsa_self = NULL;
1206
1207 if (oi->network_lsa_self)
1208 /* Now refresh network-LSA. */
1209 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1210 else
1211 /* Newly create network-LSA. */
1212 ospf_network_lsa_originate (oi);
1213
1214 return 0;
1215}
1216
1217void
1218ospf_network_lsa_timer_add (struct ospf_interface *oi)
1219{
1220 /* Keep interface's self-originated network-LSA. */
1221 struct ospf_lsa *lsa = oi->network_lsa_self;
1222
1223 /* Cancel previously schedules network-LSA timer. */
1224 if (oi->t_network_lsa_self)
1225 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001226 zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
paul718e3742002-12-13 20:15:29 +00001227 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1228
1229 /* If network-LSA is originated previously, check the interval time. */
1230 if (lsa)
1231 {
1232 int delay;
1233 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1234 {
1235 oi->t_network_lsa_self =
1236 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1237 oi, delay);
1238 return;
1239 }
1240 }
1241
1242 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001243 zlog_debug ("Scheduling network-LSA origination right away");
paul718e3742002-12-13 20:15:29 +00001244
1245 /* Immediately refresh network-LSA. */
1246 oi->t_network_lsa_self =
1247 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1248}
1249
1250
paul4dadc292005-05-06 21:37:42 +00001251static void
paul718e3742002-12-13 20:15:29 +00001252stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1253{
1254 u_int32_t metric;
1255 char *mp;
1256
1257 /* Put 0 metric. TOS metric is not supported. */
1258 metric = htonl (metric_value);
1259 mp = (char *) &metric;
1260 mp++;
1261 stream_put (s, mp, 3);
1262}
1263
1264/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001265static void
paul718e3742002-12-13 20:15:29 +00001266ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1267 u_int32_t metric)
1268{
1269 struct in_addr mask;
1270
1271 masklen2ip (p->prefixlen, &mask);
1272
1273 /* Put Network Mask. */
1274 stream_put_ipv4 (s, mask.s_addr);
1275
1276 /* Set # TOS. */
1277 stream_putc (s, (u_char) 0);
1278
1279 /* Set metric. */
1280 stream_put_ospf_metric (s, metric);
1281}
1282
paul4dadc292005-05-06 21:37:42 +00001283static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001284ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1285 u_int32_t metric, struct in_addr id)
1286{
1287 struct stream *s;
1288 struct ospf_lsa *new;
1289 struct lsa_header *lsah;
1290 int length;
1291
paulc24d6022005-11-20 14:54:12 +00001292 if (id.s_addr == 0xffffffff)
1293 {
1294 /* Maybe Link State ID not available. */
1295 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1296 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1297 OSPF_SUMMARY_LSA);
1298 return NULL;
1299 }
1300
paul718e3742002-12-13 20:15:29 +00001301 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001302 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001303
1304 /* Create new stream for LSA. */
1305 s = stream_new (OSPF_MAX_LSA_SIZE);
1306 lsah = (struct lsa_header *) STREAM_DATA (s);
1307
paul68980082003-03-25 05:07:42 +00001308 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1309 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001310
1311 /* Set summary-LSA body fields. */
1312 ospf_summary_lsa_body_set (s, p, metric);
1313
1314 /* Set length. */
1315 length = stream_get_endp (s);
1316 lsah->length = htons (length);
1317
1318 /* Create OSPF LSA instance. */
1319 new = ospf_lsa_new ();
1320 new->area = area;
1321 SET_FLAG (new->flags, OSPF_LSA_SELF);
1322
1323 /* Copy LSA to store. */
1324 new->data = ospf_lsa_data_new (length);
1325 memcpy (new->data, lsah, length);
1326 stream_free (s);
1327
1328 return new;
1329}
1330
1331/* Originate Summary-LSA. */
1332struct ospf_lsa *
1333ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1334 struct ospf_area *area)
1335{
1336 struct ospf_lsa *new;
1337 struct in_addr id;
1338
paul68980082003-03-25 05:07:42 +00001339 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001340
paulc24d6022005-11-20 14:54:12 +00001341 if (id.s_addr == 0xffffffff)
1342 {
1343 /* Maybe Link State ID not available. */
1344 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1345 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1346 OSPF_SUMMARY_LSA);
1347 return NULL;
1348 }
1349
paul718e3742002-12-13 20:15:29 +00001350 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001351 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1352 return NULL;
paul718e3742002-12-13 20:15:29 +00001353
1354 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001355 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001356
1357 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001358 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001359
1360 /* Flooding new LSA through area. */
1361 ospf_flood_through_area (area, NULL, new);
1362
1363 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1364 {
ajse588f212004-12-08 18:12:06 +00001365 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001366 new->data->type, inet_ntoa (new->data->id), new);
1367 ospf_lsa_header_dump (new->data);
1368 }
1369
1370 return new;
1371}
1372
1373struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001374ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001375{
1376 struct ospf_lsa *new;
1377 struct summary_lsa *sl;
1378 struct prefix p;
1379
1380 /* Sanity check. */
1381 assert (lsa->data);
1382
1383 sl = (struct summary_lsa *)lsa->data;
1384 p.prefixlen = ip_masklen (sl->mask);
1385 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1386 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001387
1388 if (!new)
1389 return NULL;
1390
paul718e3742002-12-13 20:15:29 +00001391 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1392
1393 /* Re-calculate checksum. */
1394 ospf_lsa_checksum (new->data);
1395
paul68980082003-03-25 05:07:42 +00001396 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001397
1398 /* Flood LSA through AS. */
1399 ospf_flood_through_area (new->area, NULL, new);
1400
1401 /* Debug logging. */
1402 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1403 {
ajse588f212004-12-08 18:12:06 +00001404 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001405 new->data->type, inet_ntoa (new->data->id));
1406 ospf_lsa_header_dump (new->data);
1407 }
1408
1409 return new;
1410}
1411
1412
1413/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001414static void
paul718e3742002-12-13 20:15:29 +00001415ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1416 u_int32_t metric)
1417{
1418 struct in_addr mask;
1419
1420 masklen2ip (p->prefixlen, &mask);
1421
1422 /* Put Network Mask. */
1423 stream_put_ipv4 (s, mask.s_addr);
1424
1425 /* Set # TOS. */
1426 stream_putc (s, (u_char) 0);
1427
1428 /* Set metric. */
1429 stream_put_ospf_metric (s, metric);
1430}
1431
paul4dadc292005-05-06 21:37:42 +00001432static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001433ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1434 u_int32_t metric, struct in_addr id)
1435{
1436 struct stream *s;
1437 struct ospf_lsa *new;
1438 struct lsa_header *lsah;
1439 int length;
1440
paulc24d6022005-11-20 14:54:12 +00001441 if (id.s_addr == 0xffffffff)
1442 {
1443 /* Maybe Link State ID not available. */
1444 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1445 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1446 OSPF_ASBR_SUMMARY_LSA);
1447 return NULL;
1448 }
1449
paul718e3742002-12-13 20:15:29 +00001450 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001451 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001452
1453 /* Create new stream for LSA. */
1454 s = stream_new (OSPF_MAX_LSA_SIZE);
1455 lsah = (struct lsa_header *) STREAM_DATA (s);
1456
paul68980082003-03-25 05:07:42 +00001457 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1458 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001459
1460 /* Set summary-LSA body fields. */
1461 ospf_summary_asbr_lsa_body_set (s, p, metric);
1462
1463 /* Set length. */
1464 length = stream_get_endp (s);
1465 lsah->length = htons (length);
1466
1467 /* Create OSPF LSA instance. */
1468 new = ospf_lsa_new ();
1469 new->area = area;
1470 SET_FLAG (new->flags, OSPF_LSA_SELF);
1471
1472 /* Copy LSA to store. */
1473 new->data = ospf_lsa_data_new (length);
1474 memcpy (new->data, lsah, length);
1475 stream_free (s);
1476
1477 return new;
1478}
1479
1480/* Originate summary-ASBR-LSA. */
1481struct ospf_lsa *
1482ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1483 struct ospf_area *area)
1484{
1485 struct ospf_lsa *new;
1486 struct in_addr id;
1487
paul68980082003-03-25 05:07:42 +00001488 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001489
paulc24d6022005-11-20 14:54:12 +00001490 if (id.s_addr == 0xffffffff)
1491 {
1492 /* Maybe Link State ID not available. */
1493 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1494 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1495 OSPF_ASBR_SUMMARY_LSA);
1496 return NULL;
1497 }
1498
paul718e3742002-12-13 20:15:29 +00001499 /* Create new summary-LSA instance. */
1500 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001501 if (!new)
1502 return NULL;
paul718e3742002-12-13 20:15:29 +00001503
1504 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001505 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001506
1507 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001508 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001509
1510 /* Flooding new LSA through area. */
1511 ospf_flood_through_area (area, NULL, new);
1512
1513 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1514 {
ajse588f212004-12-08 18:12:06 +00001515 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001516 new->data->type, inet_ntoa (new->data->id), new);
1517 ospf_lsa_header_dump (new->data);
1518 }
1519
1520 return new;
1521}
1522
1523struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001524ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001525{
1526 struct ospf_lsa *new;
1527 struct summary_lsa *sl;
1528 struct prefix p;
1529
1530 /* Sanity check. */
1531 assert (lsa->data);
1532
1533 sl = (struct summary_lsa *)lsa->data;
1534 p.prefixlen = ip_masklen (sl->mask);
1535 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1536 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001537 if (!new)
1538 return NULL;
paul718e3742002-12-13 20:15:29 +00001539
1540 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1541
1542 /* Re-calculate checksum. */
1543 ospf_lsa_checksum (new->data);
1544
paul68980082003-03-25 05:07:42 +00001545 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001546
1547 /* Flood LSA through area. */
1548 ospf_flood_through_area (new->area, NULL, new);
1549
1550 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1551 {
ajse588f212004-12-08 18:12:06 +00001552 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001553 new->data->type, inet_ntoa (new->data->id));
1554 ospf_lsa_header_dump (new->data);
1555 }
1556
1557 return new;
1558}
1559
1560/* AS-external-LSA related functions. */
1561
1562/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1563 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001564static struct in_addr
paul68980082003-03-25 05:07:42 +00001565ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001566{
1567 struct in_addr fwd;
1568 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001569 struct listnode *node;
1570 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001571
1572 fwd.s_addr = 0;
1573
1574 if (!nexthop.s_addr)
1575 return fwd;
1576
1577 /* Check whether nexthop is covered by OSPF network. */
1578 nh.family = AF_INET;
1579 nh.u.prefix4 = nexthop;
1580 nh.prefixlen = IPV4_MAX_BITLEN;
1581
paul1eb8ef22005-04-07 07:30:20 +00001582 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1583 if (if_is_operative (oi->ifp))
1584 if (oi->address->family == AF_INET)
1585 if (prefix_match (oi->address, &nh))
1586 return nexthop;
paul718e3742002-12-13 20:15:29 +00001587
1588 return fwd;
1589}
1590
paul718e3742002-12-13 20:15:29 +00001591/* NSSA-external-LSA related functions. */
1592
1593/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001594
paul718e3742002-12-13 20:15:29 +00001595struct in_addr
1596ospf_get_ip_from_ifp (struct ospf_interface *oi)
1597{
1598 struct in_addr fwd;
1599
1600 fwd.s_addr = 0;
1601
paul2e3b2e42002-12-13 21:03:13 +00001602 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001603 return oi->address->u.prefix4;
1604
1605 return fwd;
1606}
1607
1608/* Get 1st IP connection for Forward Addr */
1609struct in_addr
paulf2c80652002-12-13 21:44:27 +00001610ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001611{
1612 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001613 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001614 struct listnode *node;
1615 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001616
1617 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001618 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001619
paul1eb8ef22005-04-07 07:30:20 +00001620 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001621 {
paul2e3b2e42002-12-13 21:03:13 +00001622 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001623 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001624 if (oi->address && oi->address->family == AF_INET)
1625 {
1626 if (best_default.s_addr == 0)
1627 best_default = oi->address->u.prefix4;
1628 if (oi->area == area)
1629 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001630 }
paul718e3742002-12-13 20:15:29 +00001631 }
paulf2c80652002-12-13 21:44:27 +00001632 if (best_default.s_addr != 0)
1633 return best_default;
paul718e3742002-12-13 20:15:29 +00001634
paul68980082003-03-25 05:07:42 +00001635 if (best_default.s_addr != 0)
1636 return best_default;
1637
paul718e3742002-12-13 20:15:29 +00001638 return fwd;
1639}
hassobeebba72004-06-20 21:00:27 +00001640
paul718e3742002-12-13 20:15:29 +00001641#define DEFAULT_DEFAULT_METRIC 20
1642#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1643#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1644
1645#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1646
1647int
paul68980082003-03-25 05:07:42 +00001648metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001649{
paul68980082003-03-25 05:07:42 +00001650 return (ospf->dmetric[src].type < 0 ?
1651 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001652}
1653
1654int
paul68980082003-03-25 05:07:42 +00001655metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001656{
paul68980082003-03-25 05:07:42 +00001657 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001658 {
1659 if (src == DEFAULT_ROUTE)
1660 {
paul68980082003-03-25 05:07:42 +00001661 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001662 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1663 else
1664 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1665 }
paul68980082003-03-25 05:07:42 +00001666 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001667 return DEFAULT_DEFAULT_METRIC;
1668 else
paul68980082003-03-25 05:07:42 +00001669 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001670 }
1671
paul68980082003-03-25 05:07:42 +00001672 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001673}
1674
1675/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001676static void
paul68980082003-03-25 05:07:42 +00001677ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1678 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001679{
1680 struct prefix_ipv4 *p = &ei->p;
1681 struct in_addr mask, fwd_addr;
1682 u_int32_t mvalue;
1683 int mtype;
1684 int type;
1685
1686 /* Put Network Mask. */
1687 masklen2ip (p->prefixlen, &mask);
1688 stream_put_ipv4 (s, mask.s_addr);
1689
1690 /* If prefix is default, specify DEFAULT_ROUTE. */
1691 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1692
1693 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001694 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001695
1696 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001697 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001698
1699 /* Put type of external metric. */
1700 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1701
1702 /* Put 0 metric. TOS metric is not supported. */
1703 stream_put_ospf_metric (s, mvalue);
1704
1705 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001706 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001707
1708 /* Put forwarding address. */
1709 stream_put_ipv4 (s, fwd_addr.s_addr);
1710
1711 /* Put route tag -- This value should be introduced from configuration. */
1712 stream_putl (s, 0);
1713}
1714
1715/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001716static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001717ospf_external_lsa_new (struct ospf *ospf,
1718 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001719{
1720 struct stream *s;
1721 struct lsa_header *lsah;
1722 struct ospf_lsa *new;
1723 struct in_addr id;
1724 int length;
1725
1726 if (ei == NULL)
1727 {
1728 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001729 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
paul718e3742002-12-13 20:15:29 +00001730 return NULL;
1731 }
1732
1733 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001734 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001735
1736 /* If old Link State ID is specified, refresh LSA with same ID. */
1737 if (old_id)
1738 id = *old_id;
1739 /* Get Link State with unique ID. */
1740 else
1741 {
paul68980082003-03-25 05:07:42 +00001742 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001743 if (id.s_addr == 0xffffffff)
1744 {
1745 /* Maybe Link State ID not available. */
1746 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001747 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001748 return NULL;
1749 }
1750 }
1751
1752 /* Create new stream for LSA. */
1753 s = stream_new (OSPF_MAX_LSA_SIZE);
1754 lsah = (struct lsa_header *) STREAM_DATA (s);
1755
1756 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001757 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1758 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001759
1760 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001761 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001762
1763 /* Set length. */
1764 length = stream_get_endp (s);
1765 lsah->length = htons (length);
1766
1767 /* Now, create OSPF LSA instance. */
1768 new = ospf_lsa_new ();
1769 new->area = NULL;
1770 SET_FLAG (new->flags, OSPF_LSA_SELF|OSPF_LSA_APPROVED);
1771
1772 /* Copy LSA data to store, discard stream. */
1773 new->data = ospf_lsa_data_new (length);
1774 memcpy (new->data, lsah, length);
1775 stream_free (s);
1776
1777 return new;
1778}
1779
paul718e3742002-12-13 20:15:29 +00001780/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001781static void
paul68980082003-03-25 05:07:42 +00001782ospf_install_flood_nssa (struct ospf *ospf,
1783 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001784{
pauld4a53d52003-07-12 21:30:57 +00001785 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001786 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001787 struct ospf_area *area;
1788 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001789
pauld4a53d52003-07-12 21:30:57 +00001790 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1791 * which originated from an NSSA area. In which case it should not be
1792 * flooded back to NSSA areas.
1793 */
1794 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1795 return;
1796
paul718e3742002-12-13 20:15:29 +00001797 /* NSSA Originate or Refresh (If anyNSSA)
1798
1799 LSA is self-originated. And just installed as Type-5.
1800 Additionally, install as Type-7 LSDB for every attached NSSA.
1801
1802 P-Bit controls which ABR performs translation to outside world; If
1803 we are an ABR....do not set the P-bit, because we send the Type-5,
1804 not as the ABR Translator, but as the ASBR owner within the AS!
1805
1806 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1807 elected ABR Translator will see the P-bit, Translate, and re-flood.
1808
1809 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1810 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1811
paul1eb8ef22005-04-07 07:30:20 +00001812 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001813 {
hasso0c14ad82003-07-03 08:36:02 +00001814 /* Don't install Type-7 LSA's into nonNSSA area */
1815 if (area->external_routing != OSPF_AREA_NSSA)
1816 continue;
paul718e3742002-12-13 20:15:29 +00001817
paul68980082003-03-25 05:07:42 +00001818 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001819 new = ospf_lsa_dup (lsa);
1820 new->area = area;
1821 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001822
paul68980082003-03-25 05:07:42 +00001823 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001824 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001825 {
pauld4a53d52003-07-12 21:30:57 +00001826 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001827
1828 /* set non-zero FWD ADDR
1829
1830 draft-ietf-ospf-nssa-update-09.txt
1831
1832 if the network between the NSSA AS boundary router and the
1833 adjacent AS is advertised into OSPF as an internal OSPF route,
1834 the forwarding address should be the next op address as is cu
1835 currently done with type-5 LSAs. If the intervening network is
1836 not adversited into OSPF as an internal OSPF route and the
1837 type-7 LSA's P-bit is set a forwarding address should be
1838 selected from one of the router's active OSPF inteface addresses
1839 which belong to the NSSA. If no such addresses exist, then
1840 no type-7 LSA's with the P-bit set should originate from this
1841 router. */
1842
pauld4a53d52003-07-12 21:30:57 +00001843 /* kevinm: not updating lsa anymore, just new */
1844 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001845
1846 if (extlsa->e[0].fwd_addr.s_addr == 0)
1847 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001848
pauld7480322003-05-16 17:31:51 +00001849 if (extlsa->e[0].fwd_addr.s_addr == 0)
1850 {
1851 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001852 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001853 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001854 return;
1855 }
paulf2c80652002-12-13 21:44:27 +00001856 }
paul68980082003-03-25 05:07:42 +00001857 /* Re-calculate checksum. */
pauld4a53d52003-07-12 21:30:57 +00001858 ospf_lsa_checksum (new->data);
paul718e3742002-12-13 20:15:29 +00001859
paul68980082003-03-25 05:07:42 +00001860 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001861 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001862
1863 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001864 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001865 }
paul718e3742002-12-13 20:15:29 +00001866}
pauld4a53d52003-07-12 21:30:57 +00001867
paul4dadc292005-05-06 21:37:42 +00001868static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001869ospf_lsa_translated_nssa_new (struct ospf *ospf,
1870 struct ospf_lsa *type7)
1871{
1872
1873 struct ospf_lsa *new;
1874 struct as_external_lsa *ext, *extnew;
1875 struct external_info ei;
1876
1877 ext = (struct as_external_lsa *)(type7->data);
1878
1879 /* need external_info struct, fill in bare minimum */
1880 ei.p.family = AF_INET;
1881 ei.p.prefix = type7->data->id;
1882 ei.p.prefixlen = ip_masklen (ext->mask);
1883 ei.type = ZEBRA_ROUTE_OSPF;
1884 ei.nexthop = ext->header.adv_router;
1885 ei.route_map_set.metric = -1;
1886 ei.route_map_set.metric_type = -1;
1887 ei.tag = 0;
1888
1889 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1890 {
1891 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001892 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001893 "Translated Type-5 for %s",
1894 inet_ntoa (ei.p.prefix));
1895 return NULL;
1896 }
1897
1898 extnew = (struct as_external_lsa *)(new->data);
1899
1900 /* copy over Type-7 data to new */
1901 extnew->e[0].tos = ext->e[0].tos;
1902 extnew->e[0].route_tag = ext->e[0].route_tag;
1903 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1904 new->data->ls_seqnum = type7->data->ls_seqnum;
1905
1906 /* add translated flag, checksum and lock new lsa */
1907 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
1908 ospf_lsa_checksum (new->data);
1909 new = ospf_lsa_lock (new);
1910
1911 return new;
1912}
1913
1914/* compare type-5 to type-7
1915 * -1: err, 0: same, 1: different
1916 */
paul4dadc292005-05-06 21:37:42 +00001917static int
pauld4a53d52003-07-12 21:30:57 +00001918ospf_lsa_translated_nssa_compare (struct ospf_lsa *t7, struct ospf_lsa *t5)
1919{
1920
1921 struct as_external_lsa *e5 = (struct as_external_lsa *)t5,
1922 *e7 = (struct as_external_lsa *)t7;
1923
1924
1925 /* sanity checks */
1926 if (! ((t5->data->type == OSPF_AS_EXTERNAL_LSA)
1927 && (t7->data->type == OSPF_AS_NSSA_LSA)))
1928 return -1;
1929
1930 if (t5->data->id.s_addr != t7->data->id.s_addr)
1931 return -1;
1932
1933 if (t5->data->ls_seqnum != t7->data->ls_seqnum)
1934 return LSA_REFRESH_FORCE;
1935
1936 if (e5->mask.s_addr != e7->mask.s_addr)
1937 return LSA_REFRESH_FORCE;
1938
1939 if (e5->e[0].fwd_addr.s_addr != e7->e[0].fwd_addr.s_addr)
1940 return LSA_REFRESH_FORCE;
1941
1942 if (e5->e[0].route_tag != e7->e[0].route_tag)
1943 return LSA_REFRESH_FORCE;
1944
1945 if (GET_METRIC (e5->e[0].metric) != GET_METRIC (e7->e[0].metric))
1946 return LSA_REFRESH_FORCE;
1947
1948 return LSA_REFRESH_IF_CHANGED;
1949}
1950
1951/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1952struct ospf_lsa *
1953ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1954{
1955 struct ospf_lsa *new;
1956 struct as_external_lsa *extnew;
1957
1958 /* we cant use ospf_external_lsa_originate() as we need to set
1959 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1960 */
1961
1962 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1963 {
1964 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001965 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001966 "Type-7, Id %s, to Type-5",
1967 inet_ntoa (type7->data->id));
1968 return NULL;
1969 }
1970
1971 extnew = (struct as_external_lsa *)new;
1972
1973 if (IS_DEBUG_OSPF_NSSA)
1974 {
ajse588f212004-12-08 18:12:06 +00001975 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001976 "translated Type 7, installed:");
1977 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001978 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1979 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001980 }
1981
1982 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1983 {
1984 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001985 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001986 "Could not install LSA "
1987 "id %s", inet_ntoa (type7->data->id));
1988 return NULL;
1989 }
1990
1991 ospf->lsa_originate_count++;
1992 ospf_flood_through_as (ospf, NULL, new);
1993
1994 return new;
1995}
1996
1997/* Refresh Translated from NSSA AS-external-LSA. */
1998struct ospf_lsa *
1999ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
2000 struct ospf_lsa *type5)
2001{
2002 struct ospf_lsa *new = NULL;
2003
2004 /* Sanity checks. */
2005 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00002006 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00002007 return NULL;
pauld4a53d52003-07-12 21:30:57 +00002008 if (type7)
2009 assert (type7->data);
2010 if (type5)
2011 assert (type5->data);
2012 assert (ospf->anyNSSA);
2013
2014 /* get required data according to what has been given */
2015 if (type7 && type5 == NULL)
2016 {
2017 /* find the translated Type-5 for this Type-7 */
2018 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
2019 struct prefix_ipv4 p =
2020 {
2021 .prefix = type7->data->id,
2022 .prefixlen = ip_masklen (ext->mask),
2023 .family = AF_INET,
2024 };
2025
2026 type5 = ospf_external_info_find_lsa (ospf, &p);
2027 }
2028 else if (type5 && type7 == NULL)
2029 {
2030 /* find the type-7 from which supplied type-5 was translated,
2031 * ie find first type-7 with same LSA Id.
2032 */
paul1eb8ef22005-04-07 07:30:20 +00002033 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00002034 struct route_node *rn;
2035 struct ospf_lsa *lsa;
2036 struct ospf_area *area;
2037
paul1eb8ef22005-04-07 07:30:20 +00002038 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00002039 {
2040 if (area->external_routing != OSPF_AREA_NSSA
2041 && !type7)
2042 continue;
2043
2044 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
2045 {
2046 if (lsa->data->id.s_addr == type5->data->id.s_addr)
2047 {
2048 type7 = lsa;
2049 break;
2050 }
2051 }
2052 }
2053 }
2054
2055 /* do we have type7? */
2056 if (!type7)
2057 {
2058 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002059 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00002060 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00002061 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00002062 return NULL;
2063 }
2064
2065 /* do we have valid translated type5? */
2066 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
2067 {
2068 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002069 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00002070 "found for Type-7 with Id %s",
2071 inet_ntoa (type7->data->id));
2072 return NULL;
2073 }
2074
2075 /* Delete LSA from neighbor retransmit-list. */
2076 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
2077
2078 /* create new translated LSA */
2079 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
2080 {
2081 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002082 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00002083 "Type-7 for %s to Type-5",
2084 inet_ntoa (type7->data->id));
2085 return NULL;
2086 }
2087
2088 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
2089 {
2090 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002091 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00002092 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00002093 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00002094 return NULL;
2095 }
2096
2097 /* Flood LSA through area. */
2098 ospf_flood_through_as (ospf, NULL, new);
2099
2100 return new;
2101}
paul718e3742002-12-13 20:15:29 +00002102
2103int
2104is_prefix_default (struct prefix_ipv4 *p)
2105{
2106 struct prefix_ipv4 q;
2107
2108 q.family = AF_INET;
2109 q.prefix.s_addr = 0;
2110 q.prefixlen = 0;
2111
2112 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
2113}
2114
2115/* Originate an AS-external-LSA, install and flood. */
2116struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002117ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00002118{
2119 struct ospf_lsa *new;
2120
2121 /* Added for NSSA project....
2122
2123 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2124 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2125 every area. The Type-7's are flooded to every IR and every ABR; We
2126 install the Type-5 LSDB so that the normal "refresh" code operates
2127 as usual, and flag them as not used during ASE calculations. The
2128 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2129 Address of non-zero.
2130
2131 If an ABR is the elected NSSA translator, following SPF and during
2132 the ABR task it will translate all the scanned Type-7's, with P-bit
2133 ON and not-self generated, and translate to Type-5's throughout the
2134 non-NSSA/STUB AS.
2135
2136 A difference in operation depends whether this ASBR is an ABR
2137 or not. If not an ABR, the P-bit is ON, to indicate that any
2138 elected NSSA-ABR can perform its translation.
2139
2140 If an ABR, the P-bit is OFF; No ABR will perform translation and
2141 this ASBR will flood the Type-5 LSA as usual.
2142
2143 For the case where this ASBR is not an ABR, the ASE calculations
2144 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2145 demonstrate to the user that there are LSA's that belong to any
2146 attached NSSA.
2147
2148 Finally, it just so happens that when the ABR is translating every
2149 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2150 approved Type-5 (translated from Type-7); at the end of translation
2151 if any Translated Type-5's remain unapproved, then they must be
2152 flushed from the AS.
2153
2154 */
2155
2156 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002157 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002158 return NULL;
2159
2160 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002161 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002162 {
2163 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002164 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002165 inet_ntoa (ei->p.prefix));
2166 return NULL;
2167 }
2168
2169 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002170 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002171
2172 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002173 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002174
2175 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002176 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002177
paul718e3742002-12-13 20:15:29 +00002178 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002179 if (ospf->anyNSSA &&
2180 /* stay away from translated LSAs! */
2181 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002182 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002183
2184 /* Debug logging. */
2185 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2186 {
ajse588f212004-12-08 18:12:06 +00002187 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002188 new->data->type, inet_ntoa (new->data->id), new);
2189 ospf_lsa_header_dump (new->data);
2190 }
2191
2192 return new;
2193}
2194
2195/* Originate AS-external-LSA from external info with initial flag. */
2196int
paul68980082003-03-25 05:07:42 +00002197ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002198{
paul68980082003-03-25 05:07:42 +00002199 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002200 struct route_node *rn;
2201 struct external_info *ei;
2202 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002203 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002204
paul68980082003-03-25 05:07:42 +00002205 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002206
2207 /* Originate As-external-LSA from all type of distribute source. */
2208 if ((rt = EXTERNAL_INFO (type)))
2209 for (rn = route_top (rt); rn; rn = route_next (rn))
2210 if ((ei = rn->info) != NULL)
2211 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002212 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002213 zlog_warn ("LSA: AS-external-LSA was not originated.");
2214
2215 return 0;
2216}
2217
paul4dadc292005-05-06 21:37:42 +00002218static struct external_info *
paul020709f2003-04-04 02:44:16 +00002219ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002220{
2221 int type;
2222 struct route_node *rn;
2223 struct prefix_ipv4 p;
2224
2225 p.family = AF_INET;
2226 p.prefix.s_addr = 0;
2227 p.prefixlen = 0;
2228
2229 /* First, lookup redistributed default route. */
2230 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2231 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2232 {
2233 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2234 if (rn != NULL)
2235 {
2236 route_unlock_node (rn);
2237 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002238 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002239 return rn->info;
2240 }
2241 }
2242
2243 return NULL;
2244}
2245
2246int
paul68980082003-03-25 05:07:42 +00002247ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002248{
paul718e3742002-12-13 20:15:29 +00002249 struct prefix_ipv4 p;
2250 struct in_addr nexthop;
2251 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002252 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002253
Paul Jakma4021b602006-05-12 22:55:41 +00002254 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002255
2256 p.family = AF_INET;
2257 p.prefix.s_addr = 0;
2258 p.prefixlen = 0;
2259
Paul Jakma4021b602006-05-12 22:55:41 +00002260 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002261 {
2262 /* If there is no default route via redistribute,
2263 then originate AS-external-LSA with nexthop 0 (self). */
2264 nexthop.s_addr = 0;
2265 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2266 }
2267
paul020709f2003-04-04 02:44:16 +00002268 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002269 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002270
2271 return 0;
2272}
2273
paul645878f2003-04-13 21:42:11 +00002274/* Flush any NSSA LSAs for given prefix */
2275void
2276ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2277{
paul1eb8ef22005-04-07 07:30:20 +00002278 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002279 struct ospf_lsa *lsa;
2280 struct ospf_area *area;
2281
paul1eb8ef22005-04-07 07:30:20 +00002282 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002283 {
paul1eb8ef22005-04-07 07:30:20 +00002284 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002285 {
2286 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2287 ospf->router_id)))
2288 {
2289 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002290 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002291 inet_ntoa (p->prefix), p->prefixlen);
2292 continue;
2293 }
2294 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2295 if (!IS_LSA_MAXAGE (lsa))
2296 {
2297 ospf_refresher_unregister_lsa (ospf, lsa);
2298 ospf_lsa_flush_area (lsa, area);
2299 }
2300 }
paul645878f2003-04-13 21:42:11 +00002301 }
2302}
paul645878f2003-04-13 21:42:11 +00002303
paul718e3742002-12-13 20:15:29 +00002304/* Flush an AS-external-LSA from LSDB and routing domain. */
2305void
paul68980082003-03-25 05:07:42 +00002306ospf_external_lsa_flush (struct ospf *ospf,
2307 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002308 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002309{
2310 struct ospf_lsa *lsa;
2311
2312 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002313 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002314 inet_ntoa (p->prefix), p->prefixlen);
2315
2316 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002317 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002318 {
2319 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002320 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002321 inet_ntoa (p->prefix), p->prefixlen);
2322 return;
2323 }
hassobeebba72004-06-20 21:00:27 +00002324
pauld4a53d52003-07-12 21:30:57 +00002325 /* If LSA is selforiginated, not a translated LSA, and there is
2326 * NSSA area, flush Type-7 LSA's at first.
2327 */
2328 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2329 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002330 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002331
2332 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002333 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002334
2335 /* There must be no self-originated LSA in rtrs_external. */
2336#if 0
2337 /* Remove External route from Zebra. */
2338 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2339#endif
2340
2341 if (!IS_LSA_MAXAGE (lsa))
2342 {
2343 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002344 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002345
2346 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002347 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002348 }
2349
2350 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002351 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002352}
2353
2354void
paul68980082003-03-25 05:07:42 +00002355ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002356{
2357 struct prefix_ipv4 p;
2358 struct external_info *ei;
2359 struct ospf_lsa *lsa;
2360
2361 p.family = AF_INET;
2362 p.prefixlen = 0;
2363 p.prefix.s_addr = 0;
2364
paul020709f2003-04-04 02:44:16 +00002365 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002366 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002367
2368 if (ei)
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]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002374 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002375 }
2376 else
2377 {
2378 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002379 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002380 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002381 }
2382 }
2383 else
2384 {
2385 if (lsa)
2386 {
2387 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002388 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002389 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002390 }
2391 }
2392}
2393
2394void
paul68980082003-03-25 05:07:42 +00002395ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002396{
2397 struct route_node *rn;
2398 struct external_info *ei;
2399
2400 if (type != DEFAULT_ROUTE)
2401 if (EXTERNAL_INFO(type))
2402 /* Refresh each redistributed AS-external-LSAs. */
2403 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2404 if ((ei = rn->info))
2405 if (!is_prefix_default (&ei->p))
2406 {
2407 struct ospf_lsa *lsa;
2408
paul68980082003-03-25 05:07:42 +00002409 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2410 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002411 else
paul68980082003-03-25 05:07:42 +00002412 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002413 }
2414}
2415
2416/* Refresh AS-external-LSA. */
2417void
paul68980082003-03-25 05:07:42 +00002418ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002419 struct external_info *ei, int force)
2420{
2421 struct ospf_lsa *new;
2422 int changed;
2423
2424 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002425 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002426 {
pauld4a53d52003-07-12 21:30:57 +00002427 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002428 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002429 "redist check fail",
2430 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002431 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002432 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +00002433 return;
2434 }
2435
2436 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002437 {
2438 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002439 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002440 lsa->data->type, inet_ntoa (lsa->data->id));
2441 return;
2442 }
paul718e3742002-12-13 20:15:29 +00002443
2444 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002445 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002446
2447 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002448 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002449
paul68980082003-03-25 05:07:42 +00002450 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002451
2452 if (new == NULL)
2453 {
2454 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002455 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002456 inet_ntoa (lsa->data->id));
2457 return;
2458 }
2459
2460 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2461
paul718e3742002-12-13 20:15:29 +00002462 /* Re-calculate checksum. */
2463 ospf_lsa_checksum (new->data);
2464
paul68980082003-03-25 05:07:42 +00002465 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002466
2467 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002468 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002469
paul718e3742002-12-13 20:15:29 +00002470 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002471 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002472 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002473
pauld4a53d52003-07-12 21:30:57 +00002474 /* Register self-originated LSA to refresh queue.
2475 * Translated LSAs should not be registered, but refreshed upon
2476 * refresh of the Type-7
2477 */
2478 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2479 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002480
2481 /* Debug logging. */
2482 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2483 {
ajse588f212004-12-08 18:12:06 +00002484 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002485 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002486 ospf_lsa_header_dump (new->data);
2487 }
2488
2489 return;
2490}
2491
2492
2493/* LSA installation functions. */
2494
2495/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002496static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002497ospf_router_lsa_install (struct ospf *ospf,
2498 struct ospf_lsa *new, int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002499{
2500 struct ospf_area *area = new->area;
2501
2502 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2503 The entire routing table must be recalculated, starting with
2504 the shortest path calculations for each area (not just the
2505 area whose link-state database has changed).
2506 */
2507 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002508 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002509
2510 if (IS_LSA_SELF (new))
2511 {
2512 /* Set router-LSA refresh timer. */
2513 OSPF_TIMER_OFF (area->t_router_lsa_self);
2514 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
pauld4a53d52003-07-12 21:30:57 +00002515 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
paul718e3742002-12-13 20:15:29 +00002516
2517 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002518 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002519 area->router_lsa_self = ospf_lsa_lock (new);
2520
2521 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002522 zlog_debug("LSA[Type%d]: ID %s seq 0x%x is self-originated",
paul0c2be262004-05-31 14:16:54 +00002523 new->data->type, inet_ntoa (new->data->id),
2524 ntohl(new->data->ls_seqnum));
paul718e3742002-12-13 20:15:29 +00002525 }
2526
2527 return new;
2528}
2529
2530#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2531 if (!(T)) \
2532 (T) = thread_add_timer (master, (F), oi, (V))
2533
2534/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002535static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002536ospf_network_lsa_install (struct ospf *ospf,
2537 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002538 struct ospf_lsa *new,
2539 int rt_recalc)
2540{
2541
2542 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2543 The entire routing table must be recalculated, starting with
2544 the shortest path calculations for each area (not just the
2545 area whose link-state database has changed).
2546 */
2547 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002548 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002549
2550 /* We supposed that when LSA is originated by us, we pass the int
2551 for which it was originated. If LSA was received by flooding,
2552 the RECEIVED flag is set, so we do not link the LSA to the int. */
2553 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2554 {
2555 /* Set LSRefresh timer. */
2556 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2557
2558 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2559 ospf_network_lsa_refresh_timer,
2560 OSPF_LS_REFRESH_TIME);
2561
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002562 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002563 oi->network_lsa_self = ospf_lsa_lock (new);
2564 }
2565
2566 return new;
2567}
2568
2569/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002570static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002571ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2572 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002573{
paul718e3742002-12-13 20:15:29 +00002574 if (rt_recalc && !IS_LSA_SELF (new))
2575 {
2576 /* RFC 2328 Section 13.2 Summary-LSAs
2577 The best route to the destination described by the summary-
2578 LSA must be recalculated (see Section 16.5). If this
2579 destination is an AS boundary router, it may also be
2580 necessary to re-examine all the AS-external-LSAs.
2581 */
2582
2583#if 0
2584 /* This doesn't exist yet... */
2585 ospf_summary_incremental_update(new); */
2586#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002587 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002588#endif /* #if 0 */
2589
2590 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002591 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002592 }
2593
2594 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002595 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002596
2597 return new;
2598}
2599
2600/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002601static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002602ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2603 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002604{
2605 if (rt_recalc && !IS_LSA_SELF (new))
2606 {
2607 /* RFC 2328 Section 13.2 Summary-LSAs
2608 The best route to the destination described by the summary-
2609 LSA must be recalculated (see Section 16.5). If this
2610 destination is an AS boundary router, it may also be
2611 necessary to re-examine all the AS-external-LSAs.
2612 */
2613#if 0
2614 /* These don't exist yet... */
2615 ospf_summary_incremental_update(new);
2616 /* Isn't this done by the above call?
2617 - RFC 2328 Section 16.5 implies it should be */
2618 /* ospf_ase_calculate_schedule(); */
2619#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002620 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002621#endif /* #if 0 */
2622 }
2623
2624 /* register LSA to refresh-list. */
2625 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002626 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002627
2628 return new;
2629}
2630
2631/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002632static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002633ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2634 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002635{
paul68980082003-03-25 05:07:42 +00002636 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002637 /* If LSA is not self-originated, calculate an external route. */
2638 if (rt_recalc)
2639 {
2640 /* RFC 2328 Section 13.2 AS-external-LSAs
2641 The best route to the destination described by the AS-
2642 external-LSA must be recalculated (see Section 16.6).
2643 */
2644
2645 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002646 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002647 }
2648
pauld4a53d52003-07-12 21:30:57 +00002649 if (new->data->type == OSPF_AS_NSSA_LSA)
2650 {
2651 /* There is no point to register selforiginate Type-7 LSA for
2652 * refreshing. We rely on refreshing Type-5 LSA's
2653 */
2654 if (IS_LSA_SELF (new))
2655 return new;
2656 else
2657 {
2658 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2659 * New translations will be taken care of by the abr_task.
2660 */
2661 ospf_translated_nssa_refresh (ospf, new, NULL);
2662 }
2663 }
pauld7480322003-05-16 17:31:51 +00002664
pauld4a53d52003-07-12 21:30:57 +00002665 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002666 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002667 */
hassobeebba72004-06-20 21:00:27 +00002668 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002669 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002670
2671 return new;
2672}
2673
2674void
paul68980082003-03-25 05:07:42 +00002675ospf_discard_from_db (struct ospf *ospf,
2676 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002677{
2678 struct ospf_lsa *old;
2679
Paul Jakmaac904de2006-06-15 12:04:57 +00002680 if (!lsdb)
2681 {
2682 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2683 if (!lsa)
2684 zlog_warn ("%s: and NULL LSA!", __func__);
2685 else
2686 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2687 lsa->data->type, inet_ntoa (lsa->data->id));
2688 return;
2689 }
2690
paul718e3742002-12-13 20:15:29 +00002691 old = ospf_lsdb_lookup (lsdb, lsa);
2692
2693 if (!old)
2694 return;
2695
2696 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002697 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002698
2699 switch (old->data->type)
2700 {
2701 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002702 ospf_ase_unregister_external_lsa (old, ospf);
2703 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2704 break;
paul718e3742002-12-13 20:15:29 +00002705#ifdef HAVE_OPAQUE_LSA
2706 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002707 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002708 break;
paul69310a62005-05-11 18:09:59 +00002709#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002710 case OSPF_AS_NSSA_LSA:
2711 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2712 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002713 break;
paul718e3742002-12-13 20:15:29 +00002714 default:
paul68980082003-03-25 05:07:42 +00002715 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002716 break;
2717 }
2718
paul68980082003-03-25 05:07:42 +00002719 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002720 ospf_lsa_discard (old);
2721}
2722
paul718e3742002-12-13 20:15:29 +00002723struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002724ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2725 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002726{
2727 struct ospf_lsa *new = NULL;
2728 struct ospf_lsa *old = NULL;
2729 struct ospf_lsdb *lsdb = NULL;
2730 int rt_recalc;
2731
2732 /* Set LSDB. */
2733 switch (lsa->data->type)
2734 {
paulf2c80652002-12-13 21:44:27 +00002735 /* kevinm */
2736 case OSPF_AS_NSSA_LSA:
2737 if (lsa->area)
2738 lsdb = lsa->area->lsdb;
2739 else
paul68980082003-03-25 05:07:42 +00002740 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002741 break;
paul718e3742002-12-13 20:15:29 +00002742 case OSPF_AS_EXTERNAL_LSA:
2743#ifdef HAVE_OPAQUE_LSA
2744 case OSPF_OPAQUE_AS_LSA:
2745#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002746 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002747 break;
2748 default:
2749 lsdb = lsa->area->lsdb;
2750 break;
2751 }
2752
paul718e3742002-12-13 20:15:29 +00002753 assert (lsdb);
2754
2755 /* RFC 2328 13.2. Installing LSAs in the database
2756
2757 Installing a new LSA in the database, either as the result of
2758 flooding or a newly self-originated LSA, may cause the OSPF
2759 routing table structure to be recalculated. The contents of the
2760 new LSA should be compared to the old instance, if present. If
2761 there is no difference, there is no need to recalculate the
2762 routing table. When comparing an LSA to its previous instance,
2763 the following are all considered to be differences in contents:
2764
2765 o The LSA's Options field has changed.
2766
2767 o One of the LSA instances has LS age set to MaxAge, and
2768 the other does not.
2769
2770 o The length field in the LSA header has changed.
2771
2772 o The body of the LSA (i.e., anything outside the 20-byte
2773 LSA header) has changed. Note that this excludes changes
2774 in LS Sequence Number and LS Checksum.
2775
2776 */
2777 /* Look up old LSA and determine if any SPF calculation or incremental
2778 update is needed */
2779 old = ospf_lsdb_lookup (lsdb, lsa);
2780
2781 /* Do comparision and record if recalc needed. */
2782 rt_recalc = 0;
2783 if ( old == NULL || ospf_lsa_different(old, lsa))
2784 rt_recalc = 1;
2785
paul7ddf1d62003-10-13 09:06:46 +00002786 /*
2787 Sequence number check (Section 14.1 of rfc 2328)
2788 "Premature aging is used when it is time for a self-originated
2789 LSA's sequence number field to wrap. At this point, the current
2790 LSA instance (having LS sequence number MaxSequenceNumber) must
2791 be prematurely aged and flushed from the routing domain before a
2792 new instance with sequence number equal to InitialSequenceNumber
2793 can be originated. "
2794 */
2795
Paul Jakmac2b478d2006-03-30 14:16:11 +00002796 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002797 {
2798 if (ospf_lsa_is_self_originated(ospf, lsa))
2799 {
paul0c2be262004-05-31 14:16:54 +00002800 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2801
2802 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002803 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2804 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2805
2806 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2807 {
ajse588f212004-12-08 18:12:06 +00002808 zlog_debug ("ospf_lsa_install() Premature Aging "
paul7ddf1d62003-10-13 09:06:46 +00002809 "lsa 0x%lx", (u_long)lsa);
2810 ospf_lsa_header_dump (lsa->data);
2811 }
2812 }
2813 else
2814 {
2815 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2816 {
ajse588f212004-12-08 18:12:06 +00002817 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002818 "that was not self originated. Ignoring\n");
2819 ospf_lsa_header_dump (lsa->data);
2820 }
2821 return old;
2822 }
2823 }
2824
paul718e3742002-12-13 20:15:29 +00002825 /* discard old LSA from LSDB */
2826 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002827 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002828
paul718e3742002-12-13 20:15:29 +00002829 /* Calculate Checksum if self-originated?. */
2830 if (IS_LSA_SELF (lsa))
2831 ospf_lsa_checksum (lsa->data);
2832
hassofe71a972004-12-22 16:16:02 +00002833 /* Insert LSA to LSDB. */
2834 ospf_lsdb_add (lsdb, lsa);
2835 lsa->lsdb = lsdb;
2836
paul718e3742002-12-13 20:15:29 +00002837 /* Do LSA specific installation process. */
2838 switch (lsa->data->type)
2839 {
2840 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002841 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002842 break;
2843 case OSPF_NETWORK_LSA:
2844 assert (oi);
paul68980082003-03-25 05:07:42 +00002845 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002846 break;
2847 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002848 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002849 break;
2850 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002851 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002852 break;
2853 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002854 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002855 break;
2856#ifdef HAVE_OPAQUE_LSA
2857 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002858 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002859 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002860 else
paul68980082003-03-25 05:07:42 +00002861 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002862 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002863 case OSPF_OPAQUE_AREA_LSA:
2864 case OSPF_OPAQUE_AS_LSA:
2865 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2866 break;
2867#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002868 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002869 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002870 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002871 break;
2872 }
2873
2874 if (new == NULL)
2875 return new; /* Installation failed, cannot proceed further -- endo. */
2876
2877 /* Debug logs. */
2878 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2879 {
2880 char area_str[INET_ADDRSTRLEN];
2881
2882 switch (lsa->data->type)
2883 {
2884 case OSPF_AS_EXTERNAL_LSA:
2885#ifdef HAVE_OPAQUE_LSA
2886 case OSPF_OPAQUE_AS_LSA:
2887#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002888 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002889 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002890 dump_lsa_key (new),
2891 LOOKUP (ospf_lsa_type_msg, new->data->type));
2892 break;
2893 default:
2894 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002895 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002896 dump_lsa_key (new),
2897 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2898 break;
2899 }
2900 }
2901
paul7ddf1d62003-10-13 09:06:46 +00002902 /*
2903 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2904 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2905 */
2906 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2907 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002908 {
paul7ddf1d62003-10-13 09:06:46 +00002909 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002910 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002911 new->data->type,
2912 inet_ntoa (new->data->id),
2913 lsa);
paul68980082003-03-25 05:07:42 +00002914 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002915 }
2916
2917 return new;
2918}
2919
2920
paul4dadc292005-05-06 21:37:42 +00002921static int
paul68980082003-03-25 05:07:42 +00002922ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002923{
paul1eb8ef22005-04-07 07:30:20 +00002924 struct listnode *node, *nnode;
2925 struct ospf_interface *oi;
2926
2927 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002928 {
paul718e3742002-12-13 20:15:29 +00002929 struct route_node *rn;
2930 struct ospf_neighbor *nbr;
2931
2932 if (ospf_if_is_enable (oi))
2933 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2934 if ((nbr = rn->info) != NULL)
2935 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2936 {
2937 route_unlock_node (rn);
2938 return 0;
2939 }
2940 }
2941
2942 return 1;
2943}
2944
2945
2946#ifdef ORIGINAL_CODING
2947/* This function flood the maxaged LSA to DR. */
2948void
2949ospf_maxage_flood (struct ospf_lsa *lsa)
2950{
2951 switch (lsa->data->type)
2952 {
2953 case OSPF_ROUTER_LSA:
2954 case OSPF_NETWORK_LSA:
2955 case OSPF_SUMMARY_LSA:
2956 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00002957 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00002958#ifdef HAVE_OPAQUE_LSA
2959 case OSPF_OPAQUE_LINK_LSA:
2960 case OSPF_OPAQUE_AREA_LSA:
2961#endif /* HAVE_OPAQUE_LSA */
2962 ospf_flood_through_area (lsa->area, NULL, lsa);
2963 break;
2964 case OSPF_AS_EXTERNAL_LSA:
2965#ifdef HAVE_OPAQUE_LSA
2966 case OSPF_OPAQUE_AS_LSA:
2967#endif /* HAVE_OPAQUE_LSA */
2968 ospf_flood_through_as (NULL, lsa);
2969 break;
2970 default:
2971 break;
2972 }
2973}
2974#endif /* ORIGINAL_CODING */
2975
paul4dadc292005-05-06 21:37:42 +00002976static int
paul718e3742002-12-13 20:15:29 +00002977ospf_maxage_lsa_remover (struct thread *thread)
2978{
paul68980082003-03-25 05:07:42 +00002979 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002980 struct ospf_lsa *lsa;
2981 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002982 int reschedule = 0;
2983
paul68980082003-03-25 05:07:42 +00002984 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002985
2986 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002987 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002988
paul68980082003-03-25 05:07:42 +00002989 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002990
2991 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002992 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002993 {
paul718e3742002-12-13 20:15:29 +00002994 if (lsa->retransmit_counter > 0)
2995 {
2996 reschedule = 1;
2997 continue;
2998 }
2999
3000 /* Remove LSA from the LSDB */
3001 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
3002 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003003 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
paul7ddf1d62003-10-13 09:06:46 +00003004 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00003005
3006 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003007 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00003008 lsa->data->type, inet_ntoa (lsa->data->id));
3009
3010 /* Flood max age LSA. */
3011#ifdef ORIGINAL_CODING
3012 ospf_maxage_flood (lsa);
3013#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00003014 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00003015#endif /* ORIGINAL_CODING */
3016
paul7ddf1d62003-10-13 09:06:46 +00003017 if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
3018 {
3019 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003020 zlog_debug ("originating new router lsa for lsa 0x%lx \n",
paul7ddf1d62003-10-13 09:06:46 +00003021 (u_long)lsa);
3022 ospf_router_lsa_originate(lsa->area);
3023 }
3024
paul718e3742002-12-13 20:15:29 +00003025 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00003026 if (lsa->lsdb)
3027 {
3028 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
3029 ospf_lsdb_delete (lsa->lsdb, lsa);
3030 }
3031 else
3032 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
3033 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00003034 }
3035
3036 /* A MaxAge LSA must be removed immediately from the router's link
3037 state database as soon as both a) it is no longer contained on any
3038 neighbor Link state retransmission lists and b) none of the router's
3039 neighbors are in states Exchange or Loading. */
3040 if (reschedule)
paul68980082003-03-25 05:07:42 +00003041 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003042
3043 return 0;
3044}
3045
paul4dadc292005-05-06 21:37:42 +00003046static int
paul68980082003-03-25 05:07:42 +00003047ospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new)
paul718e3742002-12-13 20:15:29 +00003048{
hasso52dc7ee2004-09-23 19:18:23 +00003049 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003050 struct ospf_lsa *lsa;
3051
3052 for (ALL_LIST_ELEMENTS_RO (ospf->maxage_lsa, node, lsa))
3053 if (lsa == new)
paul718e3742002-12-13 20:15:29 +00003054 return 1;
3055
3056 return 0;
3057}
3058
3059void
paul68980082003-03-25 05:07:42 +00003060ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003061{
hasso52dc7ee2004-09-23 19:18:23 +00003062 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003063
paul68980082003-03-25 05:07:42 +00003064 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00003065 {
paul68980082003-03-25 05:07:42 +00003066 list_delete_node (ospf->maxage_lsa, n);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003067 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +00003068 }
3069}
3070
3071void
paul68980082003-03-25 05:07:42 +00003072ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003073{
3074 /* When we saw a MaxAge LSA flooded to us, we put it on the list
3075 and schedule the MaxAge LSA remover. */
paul68980082003-03-25 05:07:42 +00003076 if (ospf_lsa_maxage_exist (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003077 {
3078 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003079 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00003080 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
3081 return;
3082 }
3083
paul68980082003-03-25 05:07:42 +00003084 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00003085
3086 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003087 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003088
paul68980082003-03-25 05:07:42 +00003089 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003090}
3091
paul4dadc292005-05-06 21:37:42 +00003092static int
paul68980082003-03-25 05:07:42 +00003093ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003094{
paul718e3742002-12-13 20:15:29 +00003095 /* Stay away from any Local Translated Type-7 LSAs */
3096 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3097 return 0;
paul718e3742002-12-13 20:15:29 +00003098
3099 if (IS_LSA_MAXAGE (lsa))
3100 /* Self-originated LSAs should NOT time-out instead,
3101 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00003102 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003103 {
3104 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003105 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003106
3107 switch (lsa->data->type)
3108 {
paul718e3742002-12-13 20:15:29 +00003109#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00003110 case OSPF_OPAQUE_LINK_LSA:
3111 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003112 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003113 /*
3114 * As a general rule, whenever network topology has changed
3115 * (due to an LSA removal in this case), routing recalculation
3116 * should be triggered. However, this is not true for opaque
3117 * LSAs. Even if an opaque LSA instance is going to be removed
3118 * from the routing domain, it does not mean a change in network
3119 * topology, and thus, routing recalculation is not needed here.
3120 */
3121 break;
paul718e3742002-12-13 20:15:29 +00003122#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00003123 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003124 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003125 ospf_ase_incremental_update (ospf, lsa);
3126 break;
paul718e3742002-12-13 20:15:29 +00003127 default:
paul68980082003-03-25 05:07:42 +00003128 ospf_spf_calculate_schedule (ospf);
3129 break;
paul718e3742002-12-13 20:15:29 +00003130 }
paul68980082003-03-25 05:07:42 +00003131 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003132 }
3133
3134 return 0;
3135}
3136
3137/* Periodical check of MaxAge LSA. */
3138int
paul68980082003-03-25 05:07:42 +00003139ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003140{
paul68980082003-03-25 05:07:42 +00003141 struct ospf *ospf = THREAD_ARG (thread);
3142 struct route_node *rn;
3143 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003144 struct ospf_area *area;
3145 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003146
paul68980082003-03-25 05:07:42 +00003147 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003148
paul1eb8ef22005-04-07 07:30:20 +00003149 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003150 {
paul68980082003-03-25 05:07:42 +00003151 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3152 ospf_lsa_maxage_walker_remover (ospf, lsa);
3153 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3154 ospf_lsa_maxage_walker_remover (ospf, lsa);
3155 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3156 ospf_lsa_maxage_walker_remover (ospf, lsa);
3157 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), 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_AREA_LSDB (area), rn, lsa)
3161 ospf_lsa_maxage_walker_remover (ospf, lsa);
3162 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3163 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003164#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003165 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3166 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003167 }
3168
paul4fb949e2003-05-10 20:06:51 +00003169 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003170 if (ospf->lsdb)
3171 {
3172 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3173 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003174#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003175 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3176 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003177#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003178 }
paul718e3742002-12-13 20:15:29 +00003179
paul68980082003-03-25 05:07:42 +00003180 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3181 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003182 return 0;
3183}
3184
paul68980082003-03-25 05:07:42 +00003185struct ospf_lsa *
3186ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3187 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003188{
paul68980082003-03-25 05:07:42 +00003189 struct ospf_lsa *lsa;
3190 struct in_addr mask, id;
3191 struct lsa_header_mask
3192 {
3193 struct lsa_header header;
3194 struct in_addr mask;
3195 } *hmask;
paul718e3742002-12-13 20:15:29 +00003196
paul68980082003-03-25 05:07:42 +00003197 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3198 if (lsa == NULL)
3199 return NULL;
paul718e3742002-12-13 20:15:29 +00003200
paul68980082003-03-25 05:07:42 +00003201 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003202
paul68980082003-03-25 05:07:42 +00003203 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003204
paul68980082003-03-25 05:07:42 +00003205 if (mask.s_addr != hmask->mask.s_addr)
3206 {
3207 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3208 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3209 if (!lsa)
3210 return NULL;
3211 }
paul718e3742002-12-13 20:15:29 +00003212
paul68980082003-03-25 05:07:42 +00003213 return lsa;
paul718e3742002-12-13 20:15:29 +00003214}
3215
3216struct ospf_lsa *
3217ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3218 struct in_addr id, struct in_addr adv_router)
3219{
paule05fba42003-04-13 20:20:53 +00003220 struct ospf *ospf = ospf_lookup();
3221 assert(ospf);
3222
paul718e3742002-12-13 20:15:29 +00003223 switch (type)
3224 {
3225 case OSPF_ROUTER_LSA:
3226 case OSPF_NETWORK_LSA:
3227 case OSPF_SUMMARY_LSA:
3228 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003229 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003230#ifdef HAVE_OPAQUE_LSA
3231 case OSPF_OPAQUE_LINK_LSA:
3232 case OSPF_OPAQUE_AREA_LSA:
3233#endif /* HAVE_OPAQUE_LSA */
3234 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003235 case OSPF_AS_EXTERNAL_LSA:
3236#ifdef HAVE_OPAQUE_LSA
3237 case OSPF_OPAQUE_AS_LSA:
3238#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003239 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003240 default:
3241 break;
3242 }
3243
3244 return NULL;
3245}
3246
3247struct ospf_lsa *
3248ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3249 struct in_addr id)
3250{
3251 struct ospf_lsa *lsa;
3252 struct route_node *rn;
3253
3254 switch (type)
3255 {
3256 case OSPF_ROUTER_LSA:
3257 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003258 case OSPF_NETWORK_LSA:
3259 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3260 if ((lsa = rn->info))
3261 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3262 {
3263 route_unlock_node (rn);
3264 return lsa;
3265 }
3266 break;
3267 case OSPF_SUMMARY_LSA:
3268 case OSPF_ASBR_SUMMARY_LSA:
3269 /* Currently not used. */
3270 assert (1);
3271 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003272 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003273 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003274#ifdef HAVE_OPAQUE_LSA
3275 case OSPF_OPAQUE_LINK_LSA:
3276 case OSPF_OPAQUE_AREA_LSA:
3277 case OSPF_OPAQUE_AS_LSA:
3278 /* Currently not used. */
3279 break;
3280#endif /* HAVE_OPAQUE_LSA */
3281 default:
3282 break;
3283 }
3284
3285 return NULL;
3286}
3287
3288struct ospf_lsa *
3289ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3290{
3291 struct ospf_lsa *match;
3292
3293#ifdef HAVE_OPAQUE_LSA
3294 /*
3295 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3296 * is redefined to have two subfields; opaque-type and opaque-id.
3297 * However, it is harmless to treat the two sub fields together, as if
3298 * they two were forming a unique LSA-ID.
3299 */
3300#endif /* HAVE_OPAQUE_LSA */
3301
3302 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3303
3304 if (match == NULL)
3305 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003306 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003307 lsah->type, inet_ntoa (lsah->id));
3308
3309 return match;
3310}
3311
3312/* return +n, l1 is more recent.
3313 return -n, l2 is more recent.
3314 return 0, l1 and l2 is identical. */
3315int
3316ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3317{
3318 int r;
3319 int x, y;
3320
3321 if (l1 == NULL && l2 == NULL)
3322 return 0;
3323 if (l1 == NULL)
3324 return -1;
3325 if (l2 == NULL)
3326 return 1;
3327
3328 /* compare LS sequence number. */
3329 x = (int) ntohl (l1->data->ls_seqnum);
3330 y = (int) ntohl (l2->data->ls_seqnum);
3331 if (x > y)
3332 return 1;
3333 if (x < y)
3334 return -1;
3335
3336 /* compare LS checksum. */
3337 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3338 if (r)
3339 return r;
3340
3341 /* compare LS age. */
3342 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3343 return 1;
3344 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3345 return -1;
3346
3347 /* compare LS age with MaxAgeDiff. */
3348 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3349 return -1;
3350 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3351 return 1;
3352
3353 /* LSAs are identical. */
3354 return 0;
3355}
3356
3357/* If two LSAs are different, return 1, otherwise return 0. */
3358int
3359ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3360{
3361 char *p1, *p2;
3362 assert (l1);
3363 assert (l2);
3364 assert (l1->data);
3365 assert (l2->data);
3366
3367 if (l1->data->options != l2->data->options)
3368 return 1;
3369
3370 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3371 return 1;
3372
3373 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3374 return 1;
3375
3376 if (l1->data->length != l2->data->length)
3377 return 1;
3378
3379 if (l1->data->length == 0)
3380 return 1;
3381
pauld1825832003-04-03 01:27:01 +00003382 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003383
3384 p1 = (char *) l1->data;
3385 p2 = (char *) l2->data;
3386
3387 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3388 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3389 return 1;
3390
3391 return 0;
3392}
3393
3394#ifdef ORIGINAL_CODING
3395void
3396ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3397 struct ospf_lsa *self,
3398 struct ospf_lsa *new)
3399{
3400 u_int32_t seqnum;
3401
3402 /* Adjust LS Sequence Number. */
3403 seqnum = ntohl (new->data->ls_seqnum) + 1;
3404 self->data->ls_seqnum = htonl (seqnum);
3405
3406 /* Recalculate LSA checksum. */
3407 ospf_lsa_checksum (self->data);
3408
3409 /* Reflooding LSA. */
3410 /* RFC2328 Section 13.3
3411 On non-broadcast networks, separate Link State Update
3412 packets must be sent, as unicasts, to each adjacent neighbor
3413 (i.e., those in state Exchange or greater). The destination
3414 IP addresses for these packets are the neighbors' IP
3415 addresses. */
3416 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3417 {
3418 struct route_node *rn;
3419 struct ospf_neighbor *onbr;
3420
3421 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3422 if ((onbr = rn->info) != NULL)
3423 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3424 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3425 }
3426 else
3427 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3428
3429 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003430 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003431 self->data->type, inet_ntoa (self->data->id));
3432}
3433#else /* ORIGINAL_CODING */
3434static int
paul68980082003-03-25 05:07:42 +00003435ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003436{
3437 if (lsa == NULL || !IS_LSA_SELF (lsa))
3438 return 0;
3439
3440 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003441 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 +00003442
3443 /* Force given lsa's age to MaxAge. */
3444 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3445
3446 switch (lsa->data->type)
3447 {
3448#ifdef HAVE_OPAQUE_LSA
3449 case OSPF_OPAQUE_LINK_LSA:
3450 case OSPF_OPAQUE_AREA_LSA:
3451 case OSPF_OPAQUE_AS_LSA:
3452 ospf_opaque_lsa_refresh (lsa);
3453 break;
3454#endif /* HAVE_OPAQUE_LSA */
3455 default:
paul68980082003-03-25 05:07:42 +00003456 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003457 break;
3458 }
3459
3460 return 0;
3461}
3462
3463void
paul68980082003-03-25 05:07:42 +00003464ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003465{
paul1eb8ef22005-04-07 07:30:20 +00003466 struct listnode *node, *nnode;
3467 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003468 struct ospf_area *area;
3469 struct ospf_interface *oi;
3470 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003471 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003472 int need_to_flush_ase = 0;
3473
paul1eb8ef22005-04-07 07:30:20 +00003474 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003475 {
paul718e3742002-12-13 20:15:29 +00003476 if ((lsa = area->router_lsa_self) != NULL)
3477 {
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 (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003482 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003483 area->router_lsa_self = NULL;
3484 OSPF_TIMER_OFF (area->t_router_lsa_self);
3485 }
3486
paul1eb8ef22005-04-07 07:30:20 +00003487 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003488 {
paul718e3742002-12-13 20:15:29 +00003489 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003490 && oi->state == ISM_DR
3491 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003492 {
3493 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003494 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 +00003495
3496 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003497 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003498 oi->network_lsa_self = NULL;
3499 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3500 }
3501
3502 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3503 && area->external_routing == OSPF_AREA_DEFAULT)
3504 need_to_flush_ase = 1;
3505 }
3506
paul68980082003-03-25 05:07:42 +00003507 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3508 ospf_lsa_flush_schedule (ospf, lsa);
3509 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3510 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003511#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003512 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3513 ospf_lsa_flush_schedule (ospf, lsa);
3514 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3515 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003516#endif /* HAVE_OPAQUE_LSA */
3517 }
3518
3519 if (need_to_flush_ase)
3520 {
paul68980082003-03-25 05:07:42 +00003521 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3522 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003523#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003524 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3525 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003526#endif /* HAVE_OPAQUE_LSA */
3527 }
3528
3529 /*
3530 * Make sure that the MaxAge LSA remover is executed immediately,
3531 * without conflicting to other threads.
3532 */
paul68980082003-03-25 05:07:42 +00003533 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003534 {
paul68980082003-03-25 05:07:42 +00003535 OSPF_TIMER_OFF (ospf->t_maxage);
3536 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003537 }
3538
3539 return;
3540}
3541#endif /* ORIGINAL_CODING */
3542
3543/* If there is self-originated LSA, then return 1, otherwise return 0. */
3544/* An interface-independent version of ospf_lsa_is_self_originated */
3545int
paul68980082003-03-25 05:07:42 +00003546ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003547{
hasso52dc7ee2004-09-23 19:18:23 +00003548 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003549 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003550
3551 /* This LSA is already checked. */
3552 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3553 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3554
3555 /* Make sure LSA is self-checked. */
3556 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3557
3558 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003559 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003560 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3561
3562 /* LSA is router-LSA. */
3563 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003564 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003565 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3566
3567 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3568 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003569 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003570 {
paul718e3742002-12-13 20:15:29 +00003571 /* Ignore virtual link. */
3572 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3573 if (oi->address->family == AF_INET)
3574 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3575 {
3576 /* to make it easier later */
3577 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3578 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3579 }
3580 }
3581
3582 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3583}
3584
3585/* Get unique Link State ID. */
3586struct in_addr
paul68980082003-03-25 05:07:42 +00003587ospf_lsa_unique_id (struct ospf *ospf,
3588 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003589{
3590 struct ospf_lsa *lsa;
3591 struct in_addr mask, id;
3592
3593 id = p->prefix;
3594
3595 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003596 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003597 if (lsa)
3598 {
3599 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3600 if (ip_masklen (al->mask) == p->prefixlen)
3601 {
3602 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003603 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003604 "Can't get Link State ID for %s/%d",
3605 inet_ntoa (p->prefix), p->prefixlen);
3606 /* id.s_addr = 0; */
3607 id.s_addr = 0xffffffff;
3608 return id;
3609 }
3610 /* Masklen differs, then apply wildcard mask to Link State ID. */
3611 else
3612 {
3613 masklen2ip (p->prefixlen, &mask);
3614
3615 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003616 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3617 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003618 if (lsa)
3619 {
3620 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003621 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003622 "Can't get Link State ID for %s/%d",
3623 inet_ntoa (p->prefix), p->prefixlen);
3624 /* id.s_addr = 0; */
3625 id.s_addr = 0xffffffff;
3626 return id;
3627 }
3628 }
3629 }
3630
3631 return id;
3632}
3633
3634
Paul Jakma70461d72006-05-12 22:57:57 +00003635#define LSA_ACTION_FLOOD_AREA 1
3636#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003637
3638struct lsa_action
3639{
3640 u_char action;
3641 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003642 struct ospf_lsa *lsa;
3643};
3644
paul4dadc292005-05-06 21:37:42 +00003645static int
paul718e3742002-12-13 20:15:29 +00003646ospf_lsa_action (struct thread *t)
3647{
3648 struct lsa_action *data;
3649
3650 data = THREAD_ARG (t);
3651
3652 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003653 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003654 data->action);
3655
3656 switch (data->action)
3657 {
paul718e3742002-12-13 20:15:29 +00003658 case LSA_ACTION_FLOOD_AREA:
3659 ospf_flood_through_area (data->area, NULL, data->lsa);
3660 break;
paul718e3742002-12-13 20:15:29 +00003661 case LSA_ACTION_FLUSH_AREA:
3662 ospf_lsa_flush_area (data->lsa, data->area);
3663 break;
paul718e3742002-12-13 20:15:29 +00003664 }
3665
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003666 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003667 XFREE (MTYPE_OSPF_MESSAGE, data);
3668 return 0;
3669}
3670
3671void
3672ospf_schedule_lsa_flood_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_FLOOD_AREA;
3680 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003681 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003682
3683 thread_add_event (master, ospf_lsa_action, data, 0);
3684}
3685
3686void
3687ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3688{
3689 struct lsa_action *data;
3690
3691 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3692 memset (data, 0, sizeof (struct lsa_action));
3693
3694 data->action = LSA_ACTION_FLUSH_AREA;
3695 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003696 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003697
3698 thread_add_event (master, ospf_lsa_action, data, 0);
3699}
3700
3701
3702/* LSA Refreshment functions. */
paul4dadc292005-05-06 21:37:42 +00003703static void
paul68980082003-03-25 05:07:42 +00003704ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003705{
3706 struct external_info *ei;
3707 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3708
3709 switch (lsa->data->type)
3710 {
3711 /* Router and Network LSAs are processed differently. */
3712 case OSPF_ROUTER_LSA:
3713 case OSPF_NETWORK_LSA:
3714 break;
3715 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003716 ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003717 break;
3718 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003719 ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003720 break;
3721 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003722 /* Translated from NSSA Type-5s are refreshed when
3723 * from refresh of Type-7 - do not refresh these directly.
3724 */
3725 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3726 break;
paul718e3742002-12-13 20:15:29 +00003727 ei = ospf_external_info_check (lsa);
3728 if (ei)
pauld4a53d52003-07-12 21:30:57 +00003729 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003730 else
pauld4a53d52003-07-12 21:30:57 +00003731 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003732 break;
3733#ifdef HAVE_OPAQUE_LSA
3734 case OSPF_OPAQUE_LINK_LSA:
3735 case OSPF_OPAQUE_AREA_LSA:
3736 case OSPF_OPAQUE_AS_LSA:
3737 ospf_opaque_lsa_refresh (lsa);
3738 break;
pauld7480322003-05-16 17:31:51 +00003739#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003740 default:
3741 break;
paul718e3742002-12-13 20:15:29 +00003742 }
3743}
3744
3745void
paul68980082003-03-25 05:07:42 +00003746ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003747{
3748 u_int16_t index, current_index;
3749
3750 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3751
3752 if (lsa->refresh_list < 0)
3753 {
3754 int delay;
3755
3756 if (LS_AGE (lsa) == 0 &&
3757 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3758 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3759 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3760 else
3761 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3762 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3763 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3764
3765 if (delay < 0)
3766 delay = 0;
3767
paul68980082003-03-25 05:07:42 +00003768 current_index = ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003769 (quagga_time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003770
3771 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3772 % (OSPF_LSA_REFRESHER_SLOTS);
3773
3774 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003775 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003776 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003777 if (!ospf->lsa_refresh_queue.qs[index])
3778 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003779 listnode_add (ospf->lsa_refresh_queue.qs[index],
3780 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003781 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003782 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003783 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003784 "setting refresh_list on lsa %p (slod %d)",
3785 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003786 }
3787}
3788
3789void
paul68980082003-03-25 05:07:42 +00003790ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003791{
3792 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3793 if (lsa->refresh_list >= 0)
3794 {
hasso52dc7ee2004-09-23 19:18:23 +00003795 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003796 listnode_delete (refresh_list, lsa);
3797 if (!listcount (refresh_list))
3798 {
3799 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003800 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003801 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003802 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003803 lsa->refresh_list = -1;
3804 }
3805}
3806
3807int
3808ospf_lsa_refresh_walker (struct thread *t)
3809{
hasso52dc7ee2004-09-23 19:18:23 +00003810 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003811 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003812 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003813 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003814 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003815 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003816
3817 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003818 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003819
3820
paul68980082003-03-25 05:07:42 +00003821 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003822
ajs9dbc7972005-03-13 19:27:22 +00003823 /* Note: if clock has jumped backwards, then time change could be negative,
3824 so we are careful to cast the expression to unsigned before taking
3825 modulus. */
paul68980082003-03-25 05:07:42 +00003826 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003827 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakma2518efd2006-08-27 06:49:29 +00003828 (quagga_time (NULL) - ospf->lsa_refresher_started) /
ajs9dbc7972005-03-13 19:27:22 +00003829 OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003830
3831 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003832 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003833 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003834
paul68980082003-03-25 05:07:42 +00003835 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003836 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3837 {
3838 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003839 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003840 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003841
paul68980082003-03-25 05:07:42 +00003842 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003843
paul68980082003-03-25 05:07:42 +00003844 ospf->lsa_refresh_queue.qs [i] = NULL;
3845
paul718e3742002-12-13 20:15:29 +00003846 if (refresh_list)
3847 {
paul1eb8ef22005-04-07 07:30:20 +00003848 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003849 {
paul718e3742002-12-13 20:15:29 +00003850 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003851 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003852 "refresh lsa %p (slot %d)",
3853 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003854
3855 list_delete_node (refresh_list, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003856 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003857 lsa->refresh_list = -1;
3858 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003859 }
3860 list_free (refresh_list);
3861 }
3862 }
3863
paul68980082003-03-25 05:07:42 +00003864 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3865 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003866 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003867
paul1eb8ef22005-04-07 07:30:20 +00003868 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
3869 ospf_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003870
3871 list_delete (lsa_to_refresh);
3872
3873 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003874 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003875
3876 return 0;
3877}
3878