blob: b99b931c13bd5e962cf8d25dbaf3b7dd7258c5d7 [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
144 gettimeofday (&now, NULL);
145 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;
166 struct timeval now;
167
168 gettimeofday (&now, NULL);
169 age = ntohs (lsa->data->ls_age) + tv_floor (tv_sub (now, lsa->tv_recv));
170
171 return age;
172}
173
174
175/* Fletcher Checksum -- Refer to RFC1008. */
176#define MODX 4102
177#define LSA_CHECKSUM_OFFSET 15
178
179u_int16_t
180ospf_lsa_checksum (struct lsa_header *lsa)
181{
182 u_char *sp, *ep, *p, *q;
183 int c0 = 0, c1 = 0;
184 int x, y;
185 u_int16_t length;
186
187 lsa->checksum = 0;
188 length = ntohs (lsa->length) - 2;
hassoc9e52be2004-09-26 16:09:34 +0000189 sp = (u_char *) &lsa->options;
paul718e3742002-12-13 20:15:29 +0000190
191 for (ep = sp + length; sp < ep; sp = q)
192 {
193 q = sp + MODX;
194 if (q > ep)
195 q = ep;
196 for (p = sp; p < q; p++)
197 {
198 c0 += *p;
199 c1 += c0;
200 }
201 c0 %= 255;
202 c1 %= 255;
203 }
204
Paul Jakma075c2012006-03-30 14:34:31 +0000205 x = (((int)length - LSA_CHECKSUM_OFFSET) * c0 - c1) % 255;
paul718e3742002-12-13 20:15:29 +0000206 if (x <= 0)
207 x += 255;
208 y = 510 - c0 - x;
209 if (y > 255)
210 y -= 255;
211
212 /* take care endian issue. */
213 lsa->checksum = htons ((x << 8) + y);
214
215 return (lsa->checksum);
216}
217
218
219
220/* Create OSPF LSA. */
221struct ospf_lsa *
222ospf_lsa_new ()
223{
224 struct ospf_lsa *new;
225
226 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
227 memset (new, 0, sizeof (struct ospf_lsa));
228
229 new->flags = 0;
230 new->lock = 1;
231 new->retransmit_counter = 0;
232 gettimeofday (&new->tv_recv, NULL);
233 new->tv_orig = new->tv_recv;
234 new->refresh_list = -1;
235
236 return new;
237}
238
239/* Duplicate OSPF LSA. */
240struct ospf_lsa *
241ospf_lsa_dup (struct ospf_lsa *lsa)
242{
243 struct ospf_lsa *new;
244
245 if (lsa == NULL)
246 return NULL;
247
248 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
249
250 memcpy (new, lsa, sizeof (struct ospf_lsa));
251 UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
252 new->lock = 1;
253 new->retransmit_counter = 0;
254 new->data = ospf_lsa_data_dup (lsa->data);
255
paulf2c80652002-12-13 21:44:27 +0000256 /* kevinm: Clear the refresh_list, otherwise there are going
257 to be problems when we try to remove the LSA from the
258 queue (which it's not a member of.)
259 XXX: Should we add the LSA to the refresh_list queue? */
260 new->refresh_list = -1;
261
262 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000263 zlog_debug ("LSA: duplicated %p (new: %p)", lsa, new);
paulf2c80652002-12-13 21:44:27 +0000264
paul718e3742002-12-13 20:15:29 +0000265 return new;
266}
267
268/* Free OSPF LSA. */
269void
270ospf_lsa_free (struct ospf_lsa *lsa)
271{
272 assert (lsa->lock == 0);
273
274 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000275 zlog_debug ("LSA: freed %p", lsa);
paul718e3742002-12-13 20:15:29 +0000276
277 /* Delete LSA data. */
278 if (lsa->data != NULL)
279 ospf_lsa_data_free (lsa->data);
280
281 assert (lsa->refresh_list < 0);
282
283 memset (lsa, 0, sizeof (struct ospf_lsa));
284 XFREE (MTYPE_OSPF_LSA, lsa);
285}
286
287/* Lock LSA. */
288struct ospf_lsa *
289ospf_lsa_lock (struct ospf_lsa *lsa)
290{
291 lsa->lock++;
292 return lsa;
293}
294
295/* Unlock LSA. */
296void
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000297ospf_lsa_unlock (struct ospf_lsa **lsa)
paul718e3742002-12-13 20:15:29 +0000298{
299 /* This is sanity check. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000300 if (!lsa || !*lsa)
paul718e3742002-12-13 20:15:29 +0000301 return;
302
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000303 (*lsa)->lock--;
paul718e3742002-12-13 20:15:29 +0000304
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000305 assert ((*lsa)->lock >= 0);
paul718e3742002-12-13 20:15:29 +0000306
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000307 if ((*lsa)->lock == 0)
paul718e3742002-12-13 20:15:29 +0000308 {
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000309 assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
310 ospf_lsa_free (*lsa);
311 *lsa = NULL;
paul718e3742002-12-13 20:15:29 +0000312 }
313}
314
315/* Check discard flag. */
316void
317ospf_lsa_discard (struct ospf_lsa *lsa)
318{
319 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
320 {
321 SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000322 ospf_lsa_unlock (&lsa);
paul718e3742002-12-13 20:15:29 +0000323 }
324}
325
326/* Create LSA data. */
327struct lsa_header *
328ospf_lsa_data_new (size_t size)
329{
330 struct lsa_header *new;
331
332 new = (struct lsa_header *) XMALLOC (MTYPE_OSPF_LSA_DATA, size);
333 memset (new, 0, size);
334
335 return new;
336}
337
338/* Duplicate LSA data. */
339struct lsa_header *
340ospf_lsa_data_dup (struct lsa_header *lsah)
341{
342 struct lsa_header *new;
343
344 new = ospf_lsa_data_new (ntohs (lsah->length));
345 memcpy (new, lsah, ntohs (lsah->length));
346
347 return new;
348}
349
350/* Free LSA data. */
351void
352ospf_lsa_data_free (struct lsa_header *lsah)
353{
354 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000355 zlog_debug ("LSA[Type%d:%s]: data freed %p",
paul718e3742002-12-13 20:15:29 +0000356 lsah->type, inet_ntoa (lsah->id), lsah);
357
358 XFREE (MTYPE_OSPF_LSA_DATA, lsah);
359}
360
361
362/* LSA general functions. */
363
364const char *
365dump_lsa_key (struct ospf_lsa *lsa)
366{
367 static char buf[] = {
hasso52dc7ee2004-09-23 19:18:23 +0000368 "Type255,id(255.255.255.255),ar(255.255.255.255)"
paul718e3742002-12-13 20:15:29 +0000369 };
370 struct lsa_header *lsah;
371
372 if (lsa != NULL && (lsah = lsa->data) != NULL)
373 {
374 char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
375 strcpy (id, inet_ntoa (lsah->id));
376 strcpy (ar, inet_ntoa (lsah->adv_router));
377
378 sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
379 }
380 else
381 strcpy (buf, "NULL");
382
383 return buf;
384}
385
386u_int32_t
387lsa_seqnum_increment (struct ospf_lsa *lsa)
388{
389 u_int32_t seqnum;
390
391 seqnum = ntohl (lsa->data->ls_seqnum) + 1;
392
393 return htonl (seqnum);
394}
395
396void
397lsa_header_set (struct stream *s, u_char options,
paul68980082003-03-25 05:07:42 +0000398 u_char type, struct in_addr id, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +0000399{
400 struct lsa_header *lsah;
401
402 lsah = (struct lsa_header *) STREAM_DATA (s);
403
404 lsah->ls_age = htons (0);
405 lsah->options = options;
406 lsah->type = type;
407 lsah->id = id;
paul68980082003-03-25 05:07:42 +0000408 lsah->adv_router = router_id;
paul718e3742002-12-13 20:15:29 +0000409 lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
410
paul9985f832005-02-09 15:51:56 +0000411 stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000412}
413
paul68980082003-03-25 05:07:42 +0000414
paul718e3742002-12-13 20:15:29 +0000415/* router-LSA related functions. */
416/* Get router-LSA flags. */
paul4dadc292005-05-06 21:37:42 +0000417static u_char
paul718e3742002-12-13 20:15:29 +0000418router_lsa_flags (struct ospf_area *area)
419{
420 u_char flags;
421
paul68980082003-03-25 05:07:42 +0000422 flags = area->ospf->flags;
paul718e3742002-12-13 20:15:29 +0000423
424 /* Set virtual link flag. */
425 if (ospf_full_virtual_nbrs (area))
426 SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
427 else
428 /* Just sanity check */
429 UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);
430
431 /* Set Shortcut ABR behabiour flag. */
432 UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
paul68980082003-03-25 05:07:42 +0000433 if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
paul718e3742002-12-13 20:15:29 +0000434 if (!OSPF_IS_AREA_BACKBONE (area))
435 if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
paul68980082003-03-25 05:07:42 +0000436 area->ospf->backbone == NULL) ||
paul718e3742002-12-13 20:15:29 +0000437 area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
438 SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
439
440 /* ASBR can't exit in stub area. */
Paul Jakma9560fa82006-06-26 12:50:06 +0000441 if (area->external_routing == OSPF_AREA_STUB
442 || area->external_routing == OSPF_AREA_NSSA)
paul942b6c12003-06-22 08:22:18 +0000443 UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
444 /* If ASBR set External flag */
445 else if (IS_OSPF_ASBR (area->ospf))
446 SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
447
448 /* Set ABR dependent flags */
449 if (IS_OSPF_ABR (area->ospf))
450 {
451 SET_FLAG (flags, ROUTER_LSA_BORDER);
paul942b6c12003-06-22 08:22:18 +0000452 /* If Area is NSSA and we are both ABR and unconditional translator,
pauld4a53d52003-07-12 21:30:57 +0000453 * set Nt bit to inform other routers.
paul942b6c12003-06-22 08:22:18 +0000454 */
pauld4a53d52003-07-12 21:30:57 +0000455 if ( (area->external_routing == OSPF_AREA_NSSA)
456 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
457 SET_FLAG (flags, ROUTER_LSA_NT);
paul942b6c12003-06-22 08:22:18 +0000458 }
paul718e3742002-12-13 20:15:29 +0000459 return flags;
460}
461
462/* Lookup neighbor other than myself.
463 And check neighbor count,
464 Point-to-Point link must have only 1 neighbor. */
465struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +0000466ospf_nbr_lookup_ptop (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +0000467{
paul718e3742002-12-13 20:15:29 +0000468 struct ospf_neighbor *nbr = NULL;
paul68980082003-03-25 05:07:42 +0000469 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000470
471 /* Search neighbor, there must be one of two nbrs. */
paul68980082003-03-25 05:07:42 +0000472 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
473 if ((nbr = rn->info))
474 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000475 if (nbr->state == NSM_Full)
paul68980082003-03-25 05:07:42 +0000476 {
477 route_unlock_node (rn);
478 break;
479 }
paul718e3742002-12-13 20:15:29 +0000480
481 /* PtoP link must have only 1 neighbor. */
paul68980082003-03-25 05:07:42 +0000482 if (ospf_nbr_count (oi, 0) > 1)
paul718e3742002-12-13 20:15:29 +0000483 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
484
485 return nbr;
486}
487
paul88d6cf32005-10-29 12:50:09 +0000488/* Determine cost of link, taking RFC3137 stub-router support into
489 * consideration
490 */
491static u_int16_t
492ospf_link_cost (struct ospf_interface *oi)
493{
494 /* RFC3137 stub router support */
495 if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
496 return oi->output_cost;
497 else
498 return OSPF_OUTPUT_COST_INFINITE;
499}
500
paul718e3742002-12-13 20:15:29 +0000501/* Set a link information. */
paul779adb02006-01-18 15:07:38 +0000502static char
paul718e3742002-12-13 20:15:29 +0000503link_info_set (struct stream *s, struct in_addr id,
504 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
505{
paul779adb02006-01-18 15:07:38 +0000506 /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
507 * vast majority of cases. Some rare routers with lots of links need more.
508 * we try accomodate those here.
509 */
510 if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
511 {
512 size_t ret = OSPF_MAX_LSA_SIZE;
513
514 /* Can we enlarge the stream still? */
515 if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
516 {
517 /* we futz the size here for simplicity, really we need to account
518 * for just:
519 * IP Header - (sizeof (struct ip))
520 * OSPF Header - OSPF_HEADER_SIZE
521 * LSA Header - OSPF_LSA_HEADER_SIZE
522 * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
523 *
524 * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
525 */
526 ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
527 }
528
529 if (ret == OSPF_MAX_LSA_SIZE)
530 {
531 zlog_warn ("%s: Out of space in LSA stream, left %ld, size %ld",
532 __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
533 return 0;
534 }
535 }
536
paul718e3742002-12-13 20:15:29 +0000537 /* TOS based routing is not supported. */
538 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
539 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
540 stream_putc (s, type); /* Link Type. */
541 stream_putc (s, tos); /* TOS = 0. */
542 stream_putw (s, cost); /* Link Cost. */
paul779adb02006-01-18 15:07:38 +0000543
544 return 1;
paul718e3742002-12-13 20:15:29 +0000545}
546
547/* Describe Point-to-Point link. */
paul4dadc292005-05-06 21:37:42 +0000548static int
paul718e3742002-12-13 20:15:29 +0000549lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
550{
551 int links = 0;
552 struct ospf_neighbor *nbr;
553 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000554 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000555
556 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000557 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
paul718e3742002-12-13 20:15:29 +0000558
paul68980082003-03-25 05:07:42 +0000559 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000560 if (nbr->state == NSM_Full)
561 {
562 /* For unnumbered point-to-point networks, the Link Data field
563 should specify the interface's MIB-II ifIndex value. */
paul779adb02006-01-18 15:07:38 +0000564 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
565 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000566 }
567
hasso3fb9cd62004-10-19 19:44:43 +0000568 if (CONNECTED_DEST_HOST(oi->connected))
paul718e3742002-12-13 20:15:29 +0000569 {
570 /* Option 1:
571 link_type = LSA_LINK_TYPE_STUB;
572 link_id = nbr->address.u.prefix4;
573 link_data.s_addr = 0xffffffff;
574 link_cost = o->output_cost; */
575
576 id.s_addr = oi->connected->destination->u.prefix4.s_addr;
577 mask.s_addr = 0xffffffff;
paul779adb02006-01-18 15:07:38 +0000578 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
579 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000580 }
581 else
582 {
583 /* Option 2: We need to include link to a stub
584 network regardless of the state of the neighbor */
585 masklen2ip (oi->address->prefixlen, &mask);
586 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000587 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
588 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000589 }
paul718e3742002-12-13 20:15:29 +0000590 return links;
591}
592
593/* Describe Broadcast Link. */
paul4dadc292005-05-06 21:37:42 +0000594static int
paul718e3742002-12-13 20:15:29 +0000595lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
596{
597 struct ospf_neighbor *dr;
598 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000599 u_int16_t cost = ospf_link_cost (oi);
600
paul718e3742002-12-13 20:15:29 +0000601 /* Describe Type 3 Link. */
602 if (oi->state == ISM_Waiting)
603 {
604 masklen2ip (oi->address->prefixlen, &mask);
605 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000606 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
607 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000608 }
609
610 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
611 /* Describe Type 2 link. */
612 if (dr && (dr->state == NSM_Full ||
613 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000614 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000615 {
paul779adb02006-01-18 15:07:38 +0000616 return link_info_set (s, DR (oi), oi->address->u.prefix4,
617 LSA_LINK_TYPE_TRANSIT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000618 }
619 /* Describe type 3 link. */
620 else
621 {
622 masklen2ip (oi->address->prefixlen, &mask);
623 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000624 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
625 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000626 }
paul718e3742002-12-13 20:15:29 +0000627}
628
paul4dadc292005-05-06 21:37:42 +0000629static int
paul718e3742002-12-13 20:15:29 +0000630lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
631{
632 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000633
paul718e3742002-12-13 20:15:29 +0000634 /* Describe Type 3 Link. */
635 if (oi->state != ISM_Loopback)
636 return 0;
637
638 mask.s_addr = 0xffffffff;
639 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000640 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000641}
642
643/* Describe Virtual Link. */
paul4dadc292005-05-06 21:37:42 +0000644static int
paul718e3742002-12-13 20:15:29 +0000645lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
646{
647 struct ospf_neighbor *nbr;
paul88d6cf32005-10-29 12:50:09 +0000648 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000649
paul718e3742002-12-13 20:15:29 +0000650 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000651 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000652 if (nbr->state == NSM_Full)
653 {
paul779adb02006-01-18 15:07:38 +0000654 return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
655 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
paul718e3742002-12-13 20:15:29 +0000656 }
657
658 return 0;
659}
660
661#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
662
paul7afa08d2002-12-13 20:59:45 +0000663/* this function add for support point-to-multipoint ,see rfc2328
66412.4.1.4.*/
665/* from "edward rrr" <edward_rrr@hotmail.com>
666 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul4dadc292005-05-06 21:37:42 +0000667static int
paul68980082003-03-25 05:07:42 +0000668lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000669{
670 int links = 0;
671 struct route_node *rn;
672 struct ospf_neighbor *nbr = NULL;
673 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000674 u_int16_t cost = ospf_link_cost (oi);
paul7afa08d2002-12-13 20:59:45 +0000675
676 mask.s_addr = 0xffffffff;
677 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000678 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
paul7afa08d2002-12-13 20:59:45 +0000679
paul1cc8f762003-04-05 19:34:32 +0000680 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000681 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000682
683 /* Search neighbor, */
684 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
685 if ((nbr = rn->info) != NULL)
686 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000687 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000688 if (nbr->state == NSM_Full)
689
690 {
paul779adb02006-01-18 15:07:38 +0000691 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
692 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul1cc8f762003-04-05 19:34:32 +0000693 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000694 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000695 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000696 }
697
698 return links;
paul7afa08d2002-12-13 20:59:45 +0000699}
700
paul718e3742002-12-13 20:15:29 +0000701/* Set router-LSA link information. */
paul4dadc292005-05-06 21:37:42 +0000702static int
paul718e3742002-12-13 20:15:29 +0000703router_lsa_link_set (struct stream *s, struct ospf_area *area)
704{
hasso52dc7ee2004-09-23 19:18:23 +0000705 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000706 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000707 int links = 0;
708
paul1eb8ef22005-04-07 07:30:20 +0000709 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +0000710 {
paul718e3742002-12-13 20:15:29 +0000711 struct interface *ifp = oi->ifp;
712
713 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000714 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000715 {
716 if (oi->state != ISM_Down)
717 {
718 /* Describe each link. */
719 switch (oi->type)
720 {
721 case OSPF_IFTYPE_POINTOPOINT:
722 links += lsa_link_ptop_set (s, oi);
723 break;
724 case OSPF_IFTYPE_BROADCAST:
725 links += lsa_link_broadcast_set (s, oi);
726 break;
727 case OSPF_IFTYPE_NBMA:
728 links += lsa_link_nbma_set (s, oi);
729 break;
730 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000731 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000732 break;
733 case OSPF_IFTYPE_VIRTUALLINK:
734 links += lsa_link_virtuallink_set (s, oi);
735 break;
736 case OSPF_IFTYPE_LOOPBACK:
737 links += lsa_link_loopback_set (s, oi);
738 }
739 }
740 }
741 }
742
743 return links;
744}
745
746/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000747static void
paul718e3742002-12-13 20:15:29 +0000748ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
749{
750 unsigned long putp;
751 u_int16_t cnt;
752
753 /* Set flags. */
754 stream_putc (s, router_lsa_flags (area));
755
756 /* Set Zero fields. */
757 stream_putc (s, 0);
758
759 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000760 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000761
762 /* Forward word */
763 stream_putw(s, 0);
764
765 /* Set all link information. */
766 cnt = router_lsa_link_set (s, area);
767
768 /* Set # of links here. */
769 stream_putw_at (s, putp, cnt);
770}
paul88d6cf32005-10-29 12:50:09 +0000771
772static int
773ospf_stub_router_timer (struct thread *t)
774{
775 struct ospf_area *area = THREAD_ARG (t);
776
777 area->t_stub_router = NULL;
778
779 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
780
781 /* clear stub route state and generate router-lsa refresh, don't
782 * clobber an administratively set stub-router state though.
783 */
784 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
785 return 0;
786
787 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
788
789 ospf_router_lsa_timer_add (area);
790
791 return 0;
792}
paul718e3742002-12-13 20:15:29 +0000793
paul88d6cf32005-10-29 12:50:09 +0000794inline static void
795ospf_stub_router_check (struct ospf_area *area)
796{
797 /* area must either be administratively configured to be stub
798 * or startup-time stub-router must be configured and we must in a pre-stub
799 * state.
800 */
801 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
802 {
803 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
804 return;
805 }
806
807 /* not admin-stubbed, check whether startup stubbing is configured and
808 * whether it's not been done yet
809 */
810 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
811 return;
812
813 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
814 {
815 /* stub-router is hence done forever for this area, even if someone
816 * tries configure it (take effect next restart).
817 */
818 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
819 return;
820 }
821
822 /* startup stub-router configured and not yet done */
823 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
824
825 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
826 area->ospf->stub_router_startup_time);
827}
828
paul718e3742002-12-13 20:15:29 +0000829/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000830static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000831ospf_router_lsa_new (struct ospf_area *area)
832{
paul68980082003-03-25 05:07:42 +0000833 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000834 struct stream *s;
835 struct lsa_header *lsah;
836 struct ospf_lsa *new;
837 int length;
838
839 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000840 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000841
paul88d6cf32005-10-29 12:50:09 +0000842 /* check whether stub-router is desired, and if this is the first
843 * router LSA.
844 */
845 ospf_stub_router_check (area);
846
paul718e3742002-12-13 20:15:29 +0000847 /* Create a stream for LSA. */
848 s = stream_new (OSPF_MAX_LSA_SIZE);
paul718e3742002-12-13 20:15:29 +0000849 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000850 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000851 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000852
853 /* Set router-LSA body fields. */
854 ospf_router_lsa_body_set (s, area);
855
856 /* Set length. */
857 length = stream_get_endp (s);
paul779adb02006-01-18 15:07:38 +0000858 lsah = (struct lsa_header *) STREAM_DATA (s);
paul718e3742002-12-13 20:15:29 +0000859 lsah->length = htons (length);
860
861 /* Now, create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000862 if ( (new = ospf_lsa_new ()) == NULL)
863 {
864 zlog_err ("%s: Unable to create new lsa", __func__);
865 return NULL;
866 }
867
paul718e3742002-12-13 20:15:29 +0000868 new->area = area;
869 SET_FLAG (new->flags, OSPF_LSA_SELF);
870
871 /* Copy LSA data to store, discard stream. */
872 new->data = ospf_lsa_data_new (length);
873 memcpy (new->data, lsah, length);
874 stream_free (s);
875
876 return new;
877}
878
879/* Originate Router-LSA. */
paul88d6cf32005-10-29 12:50:09 +0000880static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000881ospf_router_lsa_originate (struct ospf_area *area)
882{
883 struct ospf_lsa *new;
paul88d6cf32005-10-29 12:50:09 +0000884
paul718e3742002-12-13 20:15:29 +0000885 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000886 if ( (new = ospf_router_lsa_new (area)) == NULL)
887 {
888 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
889 return NULL;
890 }
paul718e3742002-12-13 20:15:29 +0000891
892 /* Sanity check. */
893 if (new->data->adv_router.s_addr == 0)
894 {
895 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000896 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000897 ospf_lsa_discard (new);
898 return NULL;
899 }
900
901 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000902 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000903
904 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000905 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000906
907 /* Flooding new LSA through area. */
908 ospf_flood_through_area (area, NULL, new);
909
910 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
911 {
ajse588f212004-12-08 18:12:06 +0000912 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
paul718e3742002-12-13 20:15:29 +0000913 new->data->type, inet_ntoa (new->data->id), new);
914 ospf_lsa_header_dump (new->data);
915 }
916
917 return new;
918}
919
920/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000921static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000922ospf_router_lsa_refresh (struct ospf_lsa *lsa)
923{
924 struct ospf_area *area = lsa->area;
925 struct ospf_lsa *new;
926
927 /* Sanity check. */
928 assert (lsa->data);
929
930 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000931 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000932
933 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000934 if ( (new = ospf_router_lsa_new (area)) == NULL)
935 {
936 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
937 return NULL;
938 }
939
paul718e3742002-12-13 20:15:29 +0000940 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
941
paul68980082003-03-25 05:07:42 +0000942 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000943
944 /* Flood LSA through area. */
945 ospf_flood_through_area (area, NULL, new);
946
947 /* Debug logging. */
948 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
949 {
ajse588f212004-12-08 18:12:06 +0000950 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000951 new->data->type, inet_ntoa (new->data->id));
952 ospf_lsa_header_dump (new->data);
953 }
954
955 return NULL;
956}
957
paul4dadc292005-05-06 21:37:42 +0000958static int
paul718e3742002-12-13 20:15:29 +0000959ospf_router_lsa_timer (struct thread *t)
960{
961 struct ospf_area *area;
962
963 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000964 zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
paul718e3742002-12-13 20:15:29 +0000965
966 area = THREAD_ARG (t);
967 area->t_router_lsa_self = NULL;
968
969 /* Now refresh router-LSA. */
970 if (area->router_lsa_self)
971 ospf_router_lsa_refresh (area->router_lsa_self);
972 /* Newly originate router-LSA. */
973 else
974 ospf_router_lsa_originate (area);
975
976 return 0;
977}
978
979void
980ospf_router_lsa_timer_add (struct ospf_area *area)
981{
982 /* Keep area's self-originated router-LSA. */
983 struct ospf_lsa *lsa = area->router_lsa_self;
984
985 /* Cancel previously scheduled router-LSA timer. */
986 if (area->t_router_lsa_self)
987 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000988 zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
paul718e3742002-12-13 20:15:29 +0000989
990 OSPF_TIMER_OFF (area->t_router_lsa_self);
991
992 /* If router-LSA is originated previously, check the interval time. */
993 if (lsa)
994 {
995 int delay;
996 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
997 {
998 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
999 ospf_router_lsa_timer, delay);
1000 return;
1001 }
1002 }
1003
1004 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001005 zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
paul718e3742002-12-13 20:15:29 +00001006
1007 /* Immediately refresh router-LSA. */
1008 OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
1009}
1010
1011int
paul68980082003-03-25 05:07:42 +00001012ospf_router_lsa_update_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00001013{
paul68980082003-03-25 05:07:42 +00001014 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00001015 struct listnode *node, *nnode;
1016 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00001017
1018 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001019 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +00001020
paul68980082003-03-25 05:07:42 +00001021 ospf->t_router_lsa_update = NULL;
paul718e3742002-12-13 20:15:29 +00001022
paul1eb8ef22005-04-07 07:30:20 +00001023 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00001024 {
paul718e3742002-12-13 20:15:29 +00001025 struct ospf_lsa *lsa = area->router_lsa_self;
1026 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +00001027 const char *area_str;
paul718e3742002-12-13 20:15:29 +00001028
1029 /* Keep Area ID string. */
1030 area_str = AREA_NAME (area);
1031
1032 /* If LSA not exist in this Area, originate new. */
1033 if (lsa == NULL)
1034 {
1035 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001036 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +00001037
1038 ospf_router_lsa_originate (area);
1039 }
1040 /* If router-ID is changed, Link ID must change.
1041 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +00001042 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00001043 {
1044 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001045 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +00001046 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
1047 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001048 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00001049 area->router_lsa_self = NULL;
1050
1051 /* Refresh router-LSA, (not install) and flood through area. */
1052 ospf_router_lsa_timer_add (area);
1053 }
1054 else
1055 {
1056 rl = (struct router_lsa *) lsa->data;
1057 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +00001058 if (rl->flags != ospf->flags)
paul718e3742002-12-13 20:15:29 +00001059 ospf_router_lsa_timer_add (area);
1060 }
1061 }
1062
1063 return 0;
1064}
1065
1066
1067/* network-LSA related functions. */
1068/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001069static void
paul718e3742002-12-13 20:15:29 +00001070ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1071{
1072 struct in_addr mask;
1073 struct route_node *rn;
1074 struct ospf_neighbor *nbr;
1075
1076 masklen2ip (oi->address->prefixlen, &mask);
1077 stream_put_ipv4 (s, mask.s_addr);
1078
1079 /* The network-LSA lists those routers that are fully adjacent to
1080 the Designated Router; each fully adjacent router is identified by
1081 its OSPF Router ID. The Designated Router includes itself in this
1082 list. RFC2328, Section 12.4.2 */
1083
1084 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1085 if ((nbr = rn->info) != NULL)
1086 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1087 stream_put_ipv4 (s, nbr->router_id.s_addr);
1088}
1089
paul4dadc292005-05-06 21:37:42 +00001090static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001091ospf_network_lsa_new (struct ospf_interface *oi)
1092{
1093 struct stream *s;
1094 struct ospf_lsa *new;
1095 struct lsa_header *lsah;
1096 int length;
1097
1098 /* If there are no neighbours on this network (the net is stub),
1099 the router does not originate network-LSA (see RFC 12.4.2) */
1100 if (oi->full_nbrs == 0)
1101 return NULL;
1102
1103 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001104 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001105
1106 /* Create new stream for LSA. */
1107 s = stream_new (OSPF_MAX_LSA_SIZE);
1108 lsah = (struct lsa_header *) STREAM_DATA (s);
1109
1110 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001111 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001112
1113 /* Set network-LSA body fields. */
1114 ospf_network_lsa_body_set (s, oi);
1115
1116 /* Set length. */
1117 length = stream_get_endp (s);
1118 lsah->length = htons (length);
1119
1120 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001121 if ( (new = ospf_lsa_new ()) == NULL)
1122 {
1123 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1124 return NULL;
1125 }
1126
paul718e3742002-12-13 20:15:29 +00001127 new->area = oi->area;
1128 SET_FLAG (new->flags, OSPF_LSA_SELF);
1129
1130 /* Copy LSA to store. */
1131 new->data = ospf_lsa_data_new (length);
1132 memcpy (new->data, lsah, length);
1133 stream_free (s);
1134
1135 return new;
1136}
1137
1138/* Originate network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001139static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001140ospf_network_lsa_originate (struct ospf_interface *oi)
1141{
1142 struct ospf_lsa *new;
1143
1144 /* Create new network-LSA instance. */
1145 new = ospf_network_lsa_new (oi);
1146 if (new == NULL)
1147 return NULL;
1148
1149 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001150 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001151
1152 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001153 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001154
1155 /* Flooding new LSA through area. */
1156 ospf_flood_through_area (oi->area, NULL, new);
1157
1158 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1159 {
ajse588f212004-12-08 18:12:06 +00001160 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001161 new->data->type, inet_ntoa (new->data->id), new);
1162 ospf_lsa_header_dump (new->data);
1163 }
1164
1165 return new;
1166}
1167
1168int
1169ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1170{
1171 struct ospf_area *area = lsa->area;
1172 struct ospf_lsa *new;
1173
1174 assert (lsa->data);
1175
1176 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001177 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001178
1179 /* Create new network-LSA instance. */
1180 new = ospf_network_lsa_new (oi);
1181 if (new == NULL)
1182 return -1;
1183 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1184
paul68980082003-03-25 05:07:42 +00001185 ospf_lsa_install (area->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001186
1187 /* Flood LSA through aera. */
1188 ospf_flood_through_area (area, NULL, new);
1189
1190 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1191 {
ajse588f212004-12-08 18:12:06 +00001192 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001193 new->data->type, inet_ntoa (new->data->id));
1194 ospf_lsa_header_dump (new->data);
1195 }
1196
1197 return 0;
1198}
1199
paul4dadc292005-05-06 21:37:42 +00001200static int
paul718e3742002-12-13 20:15:29 +00001201ospf_network_lsa_refresh_timer (struct thread *t)
1202{
1203 struct ospf_interface *oi;
1204
1205 oi = THREAD_ARG (t);
1206 oi->t_network_lsa_self = NULL;
1207
1208 if (oi->network_lsa_self)
1209 /* Now refresh network-LSA. */
1210 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1211 else
1212 /* Newly create network-LSA. */
1213 ospf_network_lsa_originate (oi);
1214
1215 return 0;
1216}
1217
1218void
1219ospf_network_lsa_timer_add (struct ospf_interface *oi)
1220{
1221 /* Keep interface's self-originated network-LSA. */
1222 struct ospf_lsa *lsa = oi->network_lsa_self;
1223
1224 /* Cancel previously schedules network-LSA timer. */
1225 if (oi->t_network_lsa_self)
1226 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001227 zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
paul718e3742002-12-13 20:15:29 +00001228 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1229
1230 /* If network-LSA is originated previously, check the interval time. */
1231 if (lsa)
1232 {
1233 int delay;
1234 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1235 {
1236 oi->t_network_lsa_self =
1237 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1238 oi, delay);
1239 return;
1240 }
1241 }
1242
1243 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001244 zlog_debug ("Scheduling network-LSA origination right away");
paul718e3742002-12-13 20:15:29 +00001245
1246 /* Immediately refresh network-LSA. */
1247 oi->t_network_lsa_self =
1248 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1249}
1250
1251
paul4dadc292005-05-06 21:37:42 +00001252static void
paul718e3742002-12-13 20:15:29 +00001253stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1254{
1255 u_int32_t metric;
1256 char *mp;
1257
1258 /* Put 0 metric. TOS metric is not supported. */
1259 metric = htonl (metric_value);
1260 mp = (char *) &metric;
1261 mp++;
1262 stream_put (s, mp, 3);
1263}
1264
1265/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001266static void
paul718e3742002-12-13 20:15:29 +00001267ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1268 u_int32_t metric)
1269{
1270 struct in_addr mask;
1271
1272 masklen2ip (p->prefixlen, &mask);
1273
1274 /* Put Network Mask. */
1275 stream_put_ipv4 (s, mask.s_addr);
1276
1277 /* Set # TOS. */
1278 stream_putc (s, (u_char) 0);
1279
1280 /* Set metric. */
1281 stream_put_ospf_metric (s, metric);
1282}
1283
paul4dadc292005-05-06 21:37:42 +00001284static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001285ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1286 u_int32_t metric, struct in_addr id)
1287{
1288 struct stream *s;
1289 struct ospf_lsa *new;
1290 struct lsa_header *lsah;
1291 int length;
1292
paulc24d6022005-11-20 14:54:12 +00001293 if (id.s_addr == 0xffffffff)
1294 {
1295 /* Maybe Link State ID not available. */
1296 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1297 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1298 OSPF_SUMMARY_LSA);
1299 return NULL;
1300 }
1301
paul718e3742002-12-13 20:15:29 +00001302 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001303 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001304
1305 /* Create new stream for LSA. */
1306 s = stream_new (OSPF_MAX_LSA_SIZE);
1307 lsah = (struct lsa_header *) STREAM_DATA (s);
1308
paul68980082003-03-25 05:07:42 +00001309 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1310 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001311
1312 /* Set summary-LSA body fields. */
1313 ospf_summary_lsa_body_set (s, p, metric);
1314
1315 /* Set length. */
1316 length = stream_get_endp (s);
1317 lsah->length = htons (length);
1318
1319 /* Create OSPF LSA instance. */
1320 new = ospf_lsa_new ();
1321 new->area = area;
1322 SET_FLAG (new->flags, OSPF_LSA_SELF);
1323
1324 /* Copy LSA to store. */
1325 new->data = ospf_lsa_data_new (length);
1326 memcpy (new->data, lsah, length);
1327 stream_free (s);
1328
1329 return new;
1330}
1331
1332/* Originate Summary-LSA. */
1333struct ospf_lsa *
1334ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1335 struct ospf_area *area)
1336{
1337 struct ospf_lsa *new;
1338 struct in_addr id;
1339
paul68980082003-03-25 05:07:42 +00001340 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001341
paulc24d6022005-11-20 14:54:12 +00001342 if (id.s_addr == 0xffffffff)
1343 {
1344 /* Maybe Link State ID not available. */
1345 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1346 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1347 OSPF_SUMMARY_LSA);
1348 return NULL;
1349 }
1350
paul718e3742002-12-13 20:15:29 +00001351 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001352 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1353 return NULL;
paul718e3742002-12-13 20:15:29 +00001354
1355 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001356 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001357
1358 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001359 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001360
1361 /* Flooding new LSA through area. */
1362 ospf_flood_through_area (area, NULL, new);
1363
1364 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1365 {
ajse588f212004-12-08 18:12:06 +00001366 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001367 new->data->type, inet_ntoa (new->data->id), new);
1368 ospf_lsa_header_dump (new->data);
1369 }
1370
1371 return new;
1372}
1373
1374struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001375ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001376{
1377 struct ospf_lsa *new;
1378 struct summary_lsa *sl;
1379 struct prefix p;
1380
1381 /* Sanity check. */
1382 assert (lsa->data);
1383
1384 sl = (struct summary_lsa *)lsa->data;
1385 p.prefixlen = ip_masklen (sl->mask);
1386 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1387 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001388
1389 if (!new)
1390 return NULL;
1391
paul718e3742002-12-13 20:15:29 +00001392 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1393
1394 /* Re-calculate checksum. */
1395 ospf_lsa_checksum (new->data);
1396
paul68980082003-03-25 05:07:42 +00001397 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001398
1399 /* Flood LSA through AS. */
1400 ospf_flood_through_area (new->area, NULL, new);
1401
1402 /* Debug logging. */
1403 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1404 {
ajse588f212004-12-08 18:12:06 +00001405 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001406 new->data->type, inet_ntoa (new->data->id));
1407 ospf_lsa_header_dump (new->data);
1408 }
1409
1410 return new;
1411}
1412
1413
1414/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001415static void
paul718e3742002-12-13 20:15:29 +00001416ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1417 u_int32_t metric)
1418{
1419 struct in_addr mask;
1420
1421 masklen2ip (p->prefixlen, &mask);
1422
1423 /* Put Network Mask. */
1424 stream_put_ipv4 (s, mask.s_addr);
1425
1426 /* Set # TOS. */
1427 stream_putc (s, (u_char) 0);
1428
1429 /* Set metric. */
1430 stream_put_ospf_metric (s, metric);
1431}
1432
paul4dadc292005-05-06 21:37:42 +00001433static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001434ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1435 u_int32_t metric, struct in_addr id)
1436{
1437 struct stream *s;
1438 struct ospf_lsa *new;
1439 struct lsa_header *lsah;
1440 int length;
1441
paulc24d6022005-11-20 14:54:12 +00001442 if (id.s_addr == 0xffffffff)
1443 {
1444 /* Maybe Link State ID not available. */
1445 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1446 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1447 OSPF_ASBR_SUMMARY_LSA);
1448 return NULL;
1449 }
1450
paul718e3742002-12-13 20:15:29 +00001451 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001452 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001453
1454 /* Create new stream for LSA. */
1455 s = stream_new (OSPF_MAX_LSA_SIZE);
1456 lsah = (struct lsa_header *) STREAM_DATA (s);
1457
paul68980082003-03-25 05:07:42 +00001458 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1459 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001460
1461 /* Set summary-LSA body fields. */
1462 ospf_summary_asbr_lsa_body_set (s, p, metric);
1463
1464 /* Set length. */
1465 length = stream_get_endp (s);
1466 lsah->length = htons (length);
1467
1468 /* Create OSPF LSA instance. */
1469 new = ospf_lsa_new ();
1470 new->area = area;
1471 SET_FLAG (new->flags, OSPF_LSA_SELF);
1472
1473 /* Copy LSA to store. */
1474 new->data = ospf_lsa_data_new (length);
1475 memcpy (new->data, lsah, length);
1476 stream_free (s);
1477
1478 return new;
1479}
1480
1481/* Originate summary-ASBR-LSA. */
1482struct ospf_lsa *
1483ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1484 struct ospf_area *area)
1485{
1486 struct ospf_lsa *new;
1487 struct in_addr id;
1488
paul68980082003-03-25 05:07:42 +00001489 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001490
paulc24d6022005-11-20 14:54:12 +00001491 if (id.s_addr == 0xffffffff)
1492 {
1493 /* Maybe Link State ID not available. */
1494 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1495 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1496 OSPF_ASBR_SUMMARY_LSA);
1497 return NULL;
1498 }
1499
paul718e3742002-12-13 20:15:29 +00001500 /* Create new summary-LSA instance. */
1501 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001502 if (!new)
1503 return NULL;
paul718e3742002-12-13 20:15:29 +00001504
1505 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001506 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001507
1508 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001509 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001510
1511 /* Flooding new LSA through area. */
1512 ospf_flood_through_area (area, NULL, new);
1513
1514 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1515 {
ajse588f212004-12-08 18:12:06 +00001516 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001517 new->data->type, inet_ntoa (new->data->id), new);
1518 ospf_lsa_header_dump (new->data);
1519 }
1520
1521 return new;
1522}
1523
1524struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001525ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001526{
1527 struct ospf_lsa *new;
1528 struct summary_lsa *sl;
1529 struct prefix p;
1530
1531 /* Sanity check. */
1532 assert (lsa->data);
1533
1534 sl = (struct summary_lsa *)lsa->data;
1535 p.prefixlen = ip_masklen (sl->mask);
1536 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1537 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001538 if (!new)
1539 return NULL;
paul718e3742002-12-13 20:15:29 +00001540
1541 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1542
1543 /* Re-calculate checksum. */
1544 ospf_lsa_checksum (new->data);
1545
paul68980082003-03-25 05:07:42 +00001546 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001547
1548 /* Flood LSA through area. */
1549 ospf_flood_through_area (new->area, NULL, new);
1550
1551 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1552 {
ajse588f212004-12-08 18:12:06 +00001553 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001554 new->data->type, inet_ntoa (new->data->id));
1555 ospf_lsa_header_dump (new->data);
1556 }
1557
1558 return new;
1559}
1560
1561/* AS-external-LSA related functions. */
1562
1563/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1564 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001565static struct in_addr
paul68980082003-03-25 05:07:42 +00001566ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001567{
1568 struct in_addr fwd;
1569 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001570 struct listnode *node;
1571 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001572
1573 fwd.s_addr = 0;
1574
1575 if (!nexthop.s_addr)
1576 return fwd;
1577
1578 /* Check whether nexthop is covered by OSPF network. */
1579 nh.family = AF_INET;
1580 nh.u.prefix4 = nexthop;
1581 nh.prefixlen = IPV4_MAX_BITLEN;
1582
paul1eb8ef22005-04-07 07:30:20 +00001583 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1584 if (if_is_operative (oi->ifp))
1585 if (oi->address->family == AF_INET)
1586 if (prefix_match (oi->address, &nh))
1587 return nexthop;
paul718e3742002-12-13 20:15:29 +00001588
1589 return fwd;
1590}
1591
paul718e3742002-12-13 20:15:29 +00001592/* NSSA-external-LSA related functions. */
1593
1594/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001595
paul718e3742002-12-13 20:15:29 +00001596struct in_addr
1597ospf_get_ip_from_ifp (struct ospf_interface *oi)
1598{
1599 struct in_addr fwd;
1600
1601 fwd.s_addr = 0;
1602
paul2e3b2e42002-12-13 21:03:13 +00001603 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001604 return oi->address->u.prefix4;
1605
1606 return fwd;
1607}
1608
1609/* Get 1st IP connection for Forward Addr */
1610struct in_addr
paulf2c80652002-12-13 21:44:27 +00001611ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001612{
1613 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001614 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001615 struct listnode *node;
1616 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001617
1618 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001619 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001620
paul1eb8ef22005-04-07 07:30:20 +00001621 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001622 {
paul2e3b2e42002-12-13 21:03:13 +00001623 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001624 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001625 if (oi->address && oi->address->family == AF_INET)
1626 {
1627 if (best_default.s_addr == 0)
1628 best_default = oi->address->u.prefix4;
1629 if (oi->area == area)
1630 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001631 }
paul718e3742002-12-13 20:15:29 +00001632 }
paulf2c80652002-12-13 21:44:27 +00001633 if (best_default.s_addr != 0)
1634 return best_default;
paul718e3742002-12-13 20:15:29 +00001635
paul68980082003-03-25 05:07:42 +00001636 if (best_default.s_addr != 0)
1637 return best_default;
1638
paul718e3742002-12-13 20:15:29 +00001639 return fwd;
1640}
hassobeebba72004-06-20 21:00:27 +00001641
paul718e3742002-12-13 20:15:29 +00001642#define DEFAULT_DEFAULT_METRIC 20
1643#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1644#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1645
1646#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1647
1648int
paul68980082003-03-25 05:07:42 +00001649metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001650{
paul68980082003-03-25 05:07:42 +00001651 return (ospf->dmetric[src].type < 0 ?
1652 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001653}
1654
1655int
paul68980082003-03-25 05:07:42 +00001656metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001657{
paul68980082003-03-25 05:07:42 +00001658 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001659 {
1660 if (src == DEFAULT_ROUTE)
1661 {
paul68980082003-03-25 05:07:42 +00001662 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001663 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1664 else
1665 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1666 }
paul68980082003-03-25 05:07:42 +00001667 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001668 return DEFAULT_DEFAULT_METRIC;
1669 else
paul68980082003-03-25 05:07:42 +00001670 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001671 }
1672
paul68980082003-03-25 05:07:42 +00001673 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001674}
1675
1676/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001677static void
paul68980082003-03-25 05:07:42 +00001678ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1679 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001680{
1681 struct prefix_ipv4 *p = &ei->p;
1682 struct in_addr mask, fwd_addr;
1683 u_int32_t mvalue;
1684 int mtype;
1685 int type;
1686
1687 /* Put Network Mask. */
1688 masklen2ip (p->prefixlen, &mask);
1689 stream_put_ipv4 (s, mask.s_addr);
1690
1691 /* If prefix is default, specify DEFAULT_ROUTE. */
1692 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1693
1694 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001695 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001696
1697 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001698 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001699
1700 /* Put type of external metric. */
1701 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1702
1703 /* Put 0 metric. TOS metric is not supported. */
1704 stream_put_ospf_metric (s, mvalue);
1705
1706 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001707 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001708
1709 /* Put forwarding address. */
1710 stream_put_ipv4 (s, fwd_addr.s_addr);
1711
1712 /* Put route tag -- This value should be introduced from configuration. */
1713 stream_putl (s, 0);
1714}
1715
1716/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001717static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001718ospf_external_lsa_new (struct ospf *ospf,
1719 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001720{
1721 struct stream *s;
1722 struct lsa_header *lsah;
1723 struct ospf_lsa *new;
1724 struct in_addr id;
1725 int length;
1726
1727 if (ei == NULL)
1728 {
1729 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001730 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
paul718e3742002-12-13 20:15:29 +00001731 return NULL;
1732 }
1733
1734 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001735 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001736
1737 /* If old Link State ID is specified, refresh LSA with same ID. */
1738 if (old_id)
1739 id = *old_id;
1740 /* Get Link State with unique ID. */
1741 else
1742 {
paul68980082003-03-25 05:07:42 +00001743 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001744 if (id.s_addr == 0xffffffff)
1745 {
1746 /* Maybe Link State ID not available. */
1747 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001748 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001749 return NULL;
1750 }
1751 }
1752
1753 /* Create new stream for LSA. */
1754 s = stream_new (OSPF_MAX_LSA_SIZE);
1755 lsah = (struct lsa_header *) STREAM_DATA (s);
1756
1757 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001758 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1759 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001760
1761 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001762 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001763
1764 /* Set length. */
1765 length = stream_get_endp (s);
1766 lsah->length = htons (length);
1767
1768 /* Now, create OSPF LSA instance. */
1769 new = ospf_lsa_new ();
1770 new->area = NULL;
1771 SET_FLAG (new->flags, OSPF_LSA_SELF|OSPF_LSA_APPROVED);
1772
1773 /* Copy LSA data to store, discard stream. */
1774 new->data = ospf_lsa_data_new (length);
1775 memcpy (new->data, lsah, length);
1776 stream_free (s);
1777
1778 return new;
1779}
1780
paul718e3742002-12-13 20:15:29 +00001781/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001782static void
paul68980082003-03-25 05:07:42 +00001783ospf_install_flood_nssa (struct ospf *ospf,
1784 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001785{
pauld4a53d52003-07-12 21:30:57 +00001786 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001787 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001788 struct ospf_area *area;
1789 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001790
pauld4a53d52003-07-12 21:30:57 +00001791 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1792 * which originated from an NSSA area. In which case it should not be
1793 * flooded back to NSSA areas.
1794 */
1795 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1796 return;
1797
paul718e3742002-12-13 20:15:29 +00001798 /* NSSA Originate or Refresh (If anyNSSA)
1799
1800 LSA is self-originated. And just installed as Type-5.
1801 Additionally, install as Type-7 LSDB for every attached NSSA.
1802
1803 P-Bit controls which ABR performs translation to outside world; If
1804 we are an ABR....do not set the P-bit, because we send the Type-5,
1805 not as the ABR Translator, but as the ASBR owner within the AS!
1806
1807 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1808 elected ABR Translator will see the P-bit, Translate, and re-flood.
1809
1810 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1811 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1812
paul1eb8ef22005-04-07 07:30:20 +00001813 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001814 {
hasso0c14ad82003-07-03 08:36:02 +00001815 /* Don't install Type-7 LSA's into nonNSSA area */
1816 if (area->external_routing != OSPF_AREA_NSSA)
1817 continue;
paul718e3742002-12-13 20:15:29 +00001818
paul68980082003-03-25 05:07:42 +00001819 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001820 new = ospf_lsa_dup (lsa);
1821 new->area = area;
1822 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001823
paul68980082003-03-25 05:07:42 +00001824 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001825 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001826 {
pauld4a53d52003-07-12 21:30:57 +00001827 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001828
1829 /* set non-zero FWD ADDR
1830
1831 draft-ietf-ospf-nssa-update-09.txt
1832
1833 if the network between the NSSA AS boundary router and the
1834 adjacent AS is advertised into OSPF as an internal OSPF route,
1835 the forwarding address should be the next op address as is cu
1836 currently done with type-5 LSAs. If the intervening network is
1837 not adversited into OSPF as an internal OSPF route and the
1838 type-7 LSA's P-bit is set a forwarding address should be
1839 selected from one of the router's active OSPF inteface addresses
1840 which belong to the NSSA. If no such addresses exist, then
1841 no type-7 LSA's with the P-bit set should originate from this
1842 router. */
1843
pauld4a53d52003-07-12 21:30:57 +00001844 /* kevinm: not updating lsa anymore, just new */
1845 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001846
1847 if (extlsa->e[0].fwd_addr.s_addr == 0)
1848 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001849
pauld7480322003-05-16 17:31:51 +00001850 if (extlsa->e[0].fwd_addr.s_addr == 0)
1851 {
1852 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001853 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001854 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001855 return;
1856 }
paulf2c80652002-12-13 21:44:27 +00001857 }
paul68980082003-03-25 05:07:42 +00001858 /* Re-calculate checksum. */
pauld4a53d52003-07-12 21:30:57 +00001859 ospf_lsa_checksum (new->data);
paul718e3742002-12-13 20:15:29 +00001860
paul68980082003-03-25 05:07:42 +00001861 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001862 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001863
1864 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001865 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001866 }
paul718e3742002-12-13 20:15:29 +00001867}
pauld4a53d52003-07-12 21:30:57 +00001868
paul4dadc292005-05-06 21:37:42 +00001869static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001870ospf_lsa_translated_nssa_new (struct ospf *ospf,
1871 struct ospf_lsa *type7)
1872{
1873
1874 struct ospf_lsa *new;
1875 struct as_external_lsa *ext, *extnew;
1876 struct external_info ei;
1877
1878 ext = (struct as_external_lsa *)(type7->data);
1879
1880 /* need external_info struct, fill in bare minimum */
1881 ei.p.family = AF_INET;
1882 ei.p.prefix = type7->data->id;
1883 ei.p.prefixlen = ip_masklen (ext->mask);
1884 ei.type = ZEBRA_ROUTE_OSPF;
1885 ei.nexthop = ext->header.adv_router;
1886 ei.route_map_set.metric = -1;
1887 ei.route_map_set.metric_type = -1;
1888 ei.tag = 0;
1889
1890 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1891 {
1892 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001893 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001894 "Translated Type-5 for %s",
1895 inet_ntoa (ei.p.prefix));
1896 return NULL;
1897 }
1898
1899 extnew = (struct as_external_lsa *)(new->data);
1900
1901 /* copy over Type-7 data to new */
1902 extnew->e[0].tos = ext->e[0].tos;
1903 extnew->e[0].route_tag = ext->e[0].route_tag;
1904 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1905 new->data->ls_seqnum = type7->data->ls_seqnum;
1906
1907 /* add translated flag, checksum and lock new lsa */
1908 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
1909 ospf_lsa_checksum (new->data);
1910 new = ospf_lsa_lock (new);
1911
1912 return new;
1913}
1914
1915/* compare type-5 to type-7
1916 * -1: err, 0: same, 1: different
1917 */
paul4dadc292005-05-06 21:37:42 +00001918static int
pauld4a53d52003-07-12 21:30:57 +00001919ospf_lsa_translated_nssa_compare (struct ospf_lsa *t7, struct ospf_lsa *t5)
1920{
1921
1922 struct as_external_lsa *e5 = (struct as_external_lsa *)t5,
1923 *e7 = (struct as_external_lsa *)t7;
1924
1925
1926 /* sanity checks */
1927 if (! ((t5->data->type == OSPF_AS_EXTERNAL_LSA)
1928 && (t7->data->type == OSPF_AS_NSSA_LSA)))
1929 return -1;
1930
1931 if (t5->data->id.s_addr != t7->data->id.s_addr)
1932 return -1;
1933
1934 if (t5->data->ls_seqnum != t7->data->ls_seqnum)
1935 return LSA_REFRESH_FORCE;
1936
1937 if (e5->mask.s_addr != e7->mask.s_addr)
1938 return LSA_REFRESH_FORCE;
1939
1940 if (e5->e[0].fwd_addr.s_addr != e7->e[0].fwd_addr.s_addr)
1941 return LSA_REFRESH_FORCE;
1942
1943 if (e5->e[0].route_tag != e7->e[0].route_tag)
1944 return LSA_REFRESH_FORCE;
1945
1946 if (GET_METRIC (e5->e[0].metric) != GET_METRIC (e7->e[0].metric))
1947 return LSA_REFRESH_FORCE;
1948
1949 return LSA_REFRESH_IF_CHANGED;
1950}
1951
1952/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1953struct ospf_lsa *
1954ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1955{
1956 struct ospf_lsa *new;
1957 struct as_external_lsa *extnew;
1958
1959 /* we cant use ospf_external_lsa_originate() as we need to set
1960 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1961 */
1962
1963 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1964 {
1965 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001966 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001967 "Type-7, Id %s, to Type-5",
1968 inet_ntoa (type7->data->id));
1969 return NULL;
1970 }
1971
1972 extnew = (struct as_external_lsa *)new;
1973
1974 if (IS_DEBUG_OSPF_NSSA)
1975 {
ajse588f212004-12-08 18:12:06 +00001976 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001977 "translated Type 7, installed:");
1978 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001979 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1980 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001981 }
1982
1983 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1984 {
1985 if (IS_DEBUG_OSPF_NSSA);
ajse588f212004-12-08 18:12:06 +00001986 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001987 "Could not install LSA "
1988 "id %s", inet_ntoa (type7->data->id));
1989 return NULL;
1990 }
1991
1992 ospf->lsa_originate_count++;
1993 ospf_flood_through_as (ospf, NULL, new);
1994
1995 return new;
1996}
1997
1998/* Refresh Translated from NSSA AS-external-LSA. */
1999struct ospf_lsa *
2000ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
2001 struct ospf_lsa *type5)
2002{
2003 struct ospf_lsa *new = NULL;
2004
2005 /* Sanity checks. */
2006 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00002007 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00002008 return NULL;
pauld4a53d52003-07-12 21:30:57 +00002009 if (type7)
2010 assert (type7->data);
2011 if (type5)
2012 assert (type5->data);
2013 assert (ospf->anyNSSA);
2014
2015 /* get required data according to what has been given */
2016 if (type7 && type5 == NULL)
2017 {
2018 /* find the translated Type-5 for this Type-7 */
2019 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
2020 struct prefix_ipv4 p =
2021 {
2022 .prefix = type7->data->id,
2023 .prefixlen = ip_masklen (ext->mask),
2024 .family = AF_INET,
2025 };
2026
2027 type5 = ospf_external_info_find_lsa (ospf, &p);
2028 }
2029 else if (type5 && type7 == NULL)
2030 {
2031 /* find the type-7 from which supplied type-5 was translated,
2032 * ie find first type-7 with same LSA Id.
2033 */
paul1eb8ef22005-04-07 07:30:20 +00002034 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00002035 struct route_node *rn;
2036 struct ospf_lsa *lsa;
2037 struct ospf_area *area;
2038
paul1eb8ef22005-04-07 07:30:20 +00002039 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00002040 {
2041 if (area->external_routing != OSPF_AREA_NSSA
2042 && !type7)
2043 continue;
2044
2045 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
2046 {
2047 if (lsa->data->id.s_addr == type5->data->id.s_addr)
2048 {
2049 type7 = lsa;
2050 break;
2051 }
2052 }
2053 }
2054 }
2055
2056 /* do we have type7? */
2057 if (!type7)
2058 {
2059 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002060 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00002061 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00002062 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00002063 return NULL;
2064 }
2065
2066 /* do we have valid translated type5? */
2067 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
2068 {
2069 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002070 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00002071 "found for Type-7 with Id %s",
2072 inet_ntoa (type7->data->id));
2073 return NULL;
2074 }
2075
2076 /* Delete LSA from neighbor retransmit-list. */
2077 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
2078
2079 /* create new translated LSA */
2080 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
2081 {
2082 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002083 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00002084 "Type-7 for %s to Type-5",
2085 inet_ntoa (type7->data->id));
2086 return NULL;
2087 }
2088
2089 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
2090 {
2091 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00002092 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00002093 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00002094 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00002095 return NULL;
2096 }
2097
2098 /* Flood LSA through area. */
2099 ospf_flood_through_as (ospf, NULL, new);
2100
2101 return new;
2102}
paul718e3742002-12-13 20:15:29 +00002103
2104int
2105is_prefix_default (struct prefix_ipv4 *p)
2106{
2107 struct prefix_ipv4 q;
2108
2109 q.family = AF_INET;
2110 q.prefix.s_addr = 0;
2111 q.prefixlen = 0;
2112
2113 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
2114}
2115
2116/* Originate an AS-external-LSA, install and flood. */
2117struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002118ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00002119{
2120 struct ospf_lsa *new;
2121
2122 /* Added for NSSA project....
2123
2124 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2125 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2126 every area. The Type-7's are flooded to every IR and every ABR; We
2127 install the Type-5 LSDB so that the normal "refresh" code operates
2128 as usual, and flag them as not used during ASE calculations. The
2129 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2130 Address of non-zero.
2131
2132 If an ABR is the elected NSSA translator, following SPF and during
2133 the ABR task it will translate all the scanned Type-7's, with P-bit
2134 ON and not-self generated, and translate to Type-5's throughout the
2135 non-NSSA/STUB AS.
2136
2137 A difference in operation depends whether this ASBR is an ABR
2138 or not. If not an ABR, the P-bit is ON, to indicate that any
2139 elected NSSA-ABR can perform its translation.
2140
2141 If an ABR, the P-bit is OFF; No ABR will perform translation and
2142 this ASBR will flood the Type-5 LSA as usual.
2143
2144 For the case where this ASBR is not an ABR, the ASE calculations
2145 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2146 demonstrate to the user that there are LSA's that belong to any
2147 attached NSSA.
2148
2149 Finally, it just so happens that when the ABR is translating every
2150 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2151 approved Type-5 (translated from Type-7); at the end of translation
2152 if any Translated Type-5's remain unapproved, then they must be
2153 flushed from the AS.
2154
2155 */
2156
2157 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002158 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002159 return NULL;
2160
2161 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002162 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002163 {
2164 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002165 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002166 inet_ntoa (ei->p.prefix));
2167 return NULL;
2168 }
2169
2170 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002171 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002172
2173 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002174 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002175
2176 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002177 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002178
paul718e3742002-12-13 20:15:29 +00002179 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002180 if (ospf->anyNSSA &&
2181 /* stay away from translated LSAs! */
2182 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002183 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002184
2185 /* Debug logging. */
2186 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2187 {
ajse588f212004-12-08 18:12:06 +00002188 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002189 new->data->type, inet_ntoa (new->data->id), new);
2190 ospf_lsa_header_dump (new->data);
2191 }
2192
2193 return new;
2194}
2195
2196/* Originate AS-external-LSA from external info with initial flag. */
2197int
paul68980082003-03-25 05:07:42 +00002198ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002199{
paul68980082003-03-25 05:07:42 +00002200 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002201 struct route_node *rn;
2202 struct external_info *ei;
2203 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002204 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002205
paul68980082003-03-25 05:07:42 +00002206 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002207
2208 /* Originate As-external-LSA from all type of distribute source. */
2209 if ((rt = EXTERNAL_INFO (type)))
2210 for (rn = route_top (rt); rn; rn = route_next (rn))
2211 if ((ei = rn->info) != NULL)
2212 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002213 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002214 zlog_warn ("LSA: AS-external-LSA was not originated.");
2215
2216 return 0;
2217}
2218
paul4dadc292005-05-06 21:37:42 +00002219static struct external_info *
paul020709f2003-04-04 02:44:16 +00002220ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002221{
2222 int type;
2223 struct route_node *rn;
2224 struct prefix_ipv4 p;
2225
2226 p.family = AF_INET;
2227 p.prefix.s_addr = 0;
2228 p.prefixlen = 0;
2229
2230 /* First, lookup redistributed default route. */
2231 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2232 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2233 {
2234 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2235 if (rn != NULL)
2236 {
2237 route_unlock_node (rn);
2238 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002239 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002240 return rn->info;
2241 }
2242 }
2243
2244 return NULL;
2245}
2246
2247int
paul68980082003-03-25 05:07:42 +00002248ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002249{
paul718e3742002-12-13 20:15:29 +00002250 struct prefix_ipv4 p;
2251 struct in_addr nexthop;
2252 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002253 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002254
Paul Jakma4021b602006-05-12 22:55:41 +00002255 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002256
2257 p.family = AF_INET;
2258 p.prefix.s_addr = 0;
2259 p.prefixlen = 0;
2260
Paul Jakma4021b602006-05-12 22:55:41 +00002261 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002262 {
2263 /* If there is no default route via redistribute,
2264 then originate AS-external-LSA with nexthop 0 (self). */
2265 nexthop.s_addr = 0;
2266 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2267 }
2268
paul020709f2003-04-04 02:44:16 +00002269 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002270 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002271
2272 return 0;
2273}
2274
paul645878f2003-04-13 21:42:11 +00002275/* Flush any NSSA LSAs for given prefix */
2276void
2277ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2278{
paul1eb8ef22005-04-07 07:30:20 +00002279 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002280 struct ospf_lsa *lsa;
2281 struct ospf_area *area;
2282
paul1eb8ef22005-04-07 07:30:20 +00002283 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002284 {
paul1eb8ef22005-04-07 07:30:20 +00002285 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002286 {
2287 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2288 ospf->router_id)))
2289 {
2290 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002291 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002292 inet_ntoa (p->prefix), p->prefixlen);
2293 continue;
2294 }
2295 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2296 if (!IS_LSA_MAXAGE (lsa))
2297 {
2298 ospf_refresher_unregister_lsa (ospf, lsa);
2299 ospf_lsa_flush_area (lsa, area);
2300 }
2301 }
paul645878f2003-04-13 21:42:11 +00002302 }
2303}
paul645878f2003-04-13 21:42:11 +00002304
paul718e3742002-12-13 20:15:29 +00002305/* Flush an AS-external-LSA from LSDB and routing domain. */
2306void
paul68980082003-03-25 05:07:42 +00002307ospf_external_lsa_flush (struct ospf *ospf,
2308 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002309 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002310{
2311 struct ospf_lsa *lsa;
2312
2313 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002314 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002315 inet_ntoa (p->prefix), p->prefixlen);
2316
2317 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002318 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002319 {
2320 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002321 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002322 inet_ntoa (p->prefix), p->prefixlen);
2323 return;
2324 }
hassobeebba72004-06-20 21:00:27 +00002325
pauld4a53d52003-07-12 21:30:57 +00002326 /* If LSA is selforiginated, not a translated LSA, and there is
2327 * NSSA area, flush Type-7 LSA's at first.
2328 */
2329 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2330 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002331 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002332
2333 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002334 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002335
2336 /* There must be no self-originated LSA in rtrs_external. */
2337#if 0
2338 /* Remove External route from Zebra. */
2339 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2340#endif
2341
2342 if (!IS_LSA_MAXAGE (lsa))
2343 {
2344 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002345 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002346
2347 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002348 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002349 }
2350
2351 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002352 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002353}
2354
2355void
paul68980082003-03-25 05:07:42 +00002356ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002357{
2358 struct prefix_ipv4 p;
2359 struct external_info *ei;
2360 struct ospf_lsa *lsa;
2361
2362 p.family = AF_INET;
2363 p.prefixlen = 0;
2364 p.prefix.s_addr = 0;
2365
paul020709f2003-04-04 02:44:16 +00002366 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002367 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002368
2369 if (ei)
2370 {
2371 if (lsa)
2372 {
2373 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002374 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002375 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002376 }
2377 else
2378 {
2379 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002380 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002381 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002382 }
2383 }
2384 else
2385 {
2386 if (lsa)
2387 {
2388 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002389 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002390 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002391 }
2392 }
2393}
2394
2395void
paul68980082003-03-25 05:07:42 +00002396ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002397{
2398 struct route_node *rn;
2399 struct external_info *ei;
2400
2401 if (type != DEFAULT_ROUTE)
2402 if (EXTERNAL_INFO(type))
2403 /* Refresh each redistributed AS-external-LSAs. */
2404 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2405 if ((ei = rn->info))
2406 if (!is_prefix_default (&ei->p))
2407 {
2408 struct ospf_lsa *lsa;
2409
paul68980082003-03-25 05:07:42 +00002410 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2411 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002412 else
paul68980082003-03-25 05:07:42 +00002413 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002414 }
2415}
2416
2417/* Refresh AS-external-LSA. */
2418void
paul68980082003-03-25 05:07:42 +00002419ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002420 struct external_info *ei, int force)
2421{
2422 struct ospf_lsa *new;
2423 int changed;
2424
2425 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002426 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002427 {
pauld4a53d52003-07-12 21:30:57 +00002428 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002429 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002430 "redist check fail",
2431 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002432 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002433 ei->ifindex /*, ei->nexthop */);
paul718e3742002-12-13 20:15:29 +00002434 return;
2435 }
2436
2437 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002438 {
2439 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002440 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002441 lsa->data->type, inet_ntoa (lsa->data->id));
2442 return;
2443 }
paul718e3742002-12-13 20:15:29 +00002444
2445 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002446 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002447
2448 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002449 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002450
paul68980082003-03-25 05:07:42 +00002451 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002452
2453 if (new == NULL)
2454 {
2455 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002456 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002457 inet_ntoa (lsa->data->id));
2458 return;
2459 }
2460
2461 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2462
2463 /* Record timestamp. */
2464 gettimeofday (&new->tv_orig, NULL);
2465
2466 /* Re-calculate checksum. */
2467 ospf_lsa_checksum (new->data);
2468
paul68980082003-03-25 05:07:42 +00002469 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002470
2471 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002472 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002473
paul718e3742002-12-13 20:15:29 +00002474 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002475 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002476 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002477
pauld4a53d52003-07-12 21:30:57 +00002478 /* Register self-originated LSA to refresh queue.
2479 * Translated LSAs should not be registered, but refreshed upon
2480 * refresh of the Type-7
2481 */
2482 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2483 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002484
2485 /* Debug logging. */
2486 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2487 {
ajse588f212004-12-08 18:12:06 +00002488 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002489 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002490 ospf_lsa_header_dump (new->data);
2491 }
2492
2493 return;
2494}
2495
2496
2497/* LSA installation functions. */
2498
2499/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002500static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002501ospf_router_lsa_install (struct ospf *ospf,
2502 struct ospf_lsa *new, int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002503{
2504 struct ospf_area *area = new->area;
2505
2506 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2507 The entire routing table must be recalculated, starting with
2508 the shortest path calculations for each area (not just the
2509 area whose link-state database has changed).
2510 */
2511 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002512 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002513
2514 if (IS_LSA_SELF (new))
2515 {
2516 /* Set router-LSA refresh timer. */
2517 OSPF_TIMER_OFF (area->t_router_lsa_self);
2518 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
pauld4a53d52003-07-12 21:30:57 +00002519 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
paul718e3742002-12-13 20:15:29 +00002520
2521 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002522 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002523 area->router_lsa_self = ospf_lsa_lock (new);
2524
2525 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002526 zlog_debug("LSA[Type%d]: ID %s seq 0x%x is self-originated",
paul0c2be262004-05-31 14:16:54 +00002527 new->data->type, inet_ntoa (new->data->id),
2528 ntohl(new->data->ls_seqnum));
paul718e3742002-12-13 20:15:29 +00002529 }
2530
2531 return new;
2532}
2533
2534#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2535 if (!(T)) \
2536 (T) = thread_add_timer (master, (F), oi, (V))
2537
2538/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002539static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002540ospf_network_lsa_install (struct ospf *ospf,
2541 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002542 struct ospf_lsa *new,
2543 int rt_recalc)
2544{
2545
2546 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2547 The entire routing table must be recalculated, starting with
2548 the shortest path calculations for each area (not just the
2549 area whose link-state database has changed).
2550 */
2551 if (rt_recalc)
paul68980082003-03-25 05:07:42 +00002552 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002553
2554 /* We supposed that when LSA is originated by us, we pass the int
2555 for which it was originated. If LSA was received by flooding,
2556 the RECEIVED flag is set, so we do not link the LSA to the int. */
2557 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2558 {
2559 /* Set LSRefresh timer. */
2560 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2561
2562 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2563 ospf_network_lsa_refresh_timer,
2564 OSPF_LS_REFRESH_TIME);
2565
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002566 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002567 oi->network_lsa_self = ospf_lsa_lock (new);
2568 }
2569
2570 return new;
2571}
2572
2573/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002574static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002575ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2576 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002577{
paul718e3742002-12-13 20:15:29 +00002578 if (rt_recalc && !IS_LSA_SELF (new))
2579 {
2580 /* RFC 2328 Section 13.2 Summary-LSAs
2581 The best route to the destination described by the summary-
2582 LSA must be recalculated (see Section 16.5). If this
2583 destination is an AS boundary router, it may also be
2584 necessary to re-examine all the AS-external-LSAs.
2585 */
2586
2587#if 0
2588 /* This doesn't exist yet... */
2589 ospf_summary_incremental_update(new); */
2590#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002591 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002592#endif /* #if 0 */
2593
2594 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002595 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002596 }
2597
2598 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002599 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002600
2601 return new;
2602}
2603
2604/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002605static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002606ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2607 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002608{
2609 if (rt_recalc && !IS_LSA_SELF (new))
2610 {
2611 /* RFC 2328 Section 13.2 Summary-LSAs
2612 The best route to the destination described by the summary-
2613 LSA must be recalculated (see Section 16.5). If this
2614 destination is an AS boundary router, it may also be
2615 necessary to re-examine all the AS-external-LSAs.
2616 */
2617#if 0
2618 /* These don't exist yet... */
2619 ospf_summary_incremental_update(new);
2620 /* Isn't this done by the above call?
2621 - RFC 2328 Section 16.5 implies it should be */
2622 /* ospf_ase_calculate_schedule(); */
2623#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002624 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002625#endif /* #if 0 */
2626 }
2627
2628 /* register LSA to refresh-list. */
2629 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002630 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002631
2632 return new;
2633}
2634
2635/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002636static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002637ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2638 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002639{
paul68980082003-03-25 05:07:42 +00002640 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002641 /* If LSA is not self-originated, calculate an external route. */
2642 if (rt_recalc)
2643 {
2644 /* RFC 2328 Section 13.2 AS-external-LSAs
2645 The best route to the destination described by the AS-
2646 external-LSA must be recalculated (see Section 16.6).
2647 */
2648
2649 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002650 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002651 }
2652
pauld4a53d52003-07-12 21:30:57 +00002653 if (new->data->type == OSPF_AS_NSSA_LSA)
2654 {
2655 /* There is no point to register selforiginate Type-7 LSA for
2656 * refreshing. We rely on refreshing Type-5 LSA's
2657 */
2658 if (IS_LSA_SELF (new))
2659 return new;
2660 else
2661 {
2662 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2663 * New translations will be taken care of by the abr_task.
2664 */
2665 ospf_translated_nssa_refresh (ospf, new, NULL);
2666 }
2667 }
pauld7480322003-05-16 17:31:51 +00002668
pauld4a53d52003-07-12 21:30:57 +00002669 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002670 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002671 */
hassobeebba72004-06-20 21:00:27 +00002672 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002673 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002674
2675 return new;
2676}
2677
2678void
paul68980082003-03-25 05:07:42 +00002679ospf_discard_from_db (struct ospf *ospf,
2680 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002681{
2682 struct ospf_lsa *old;
2683
Paul Jakmaac904de2006-06-15 12:04:57 +00002684 if (!lsdb)
2685 {
2686 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2687 if (!lsa)
2688 zlog_warn ("%s: and NULL LSA!", __func__);
2689 else
2690 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2691 lsa->data->type, inet_ntoa (lsa->data->id));
2692 return;
2693 }
2694
paul718e3742002-12-13 20:15:29 +00002695 old = ospf_lsdb_lookup (lsdb, lsa);
2696
2697 if (!old)
2698 return;
2699
2700 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002701 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002702
2703 switch (old->data->type)
2704 {
2705 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002706 ospf_ase_unregister_external_lsa (old, ospf);
2707 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2708 break;
paul718e3742002-12-13 20:15:29 +00002709#ifdef HAVE_OPAQUE_LSA
2710 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002711 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002712 break;
paul69310a62005-05-11 18:09:59 +00002713#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002714 case OSPF_AS_NSSA_LSA:
2715 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2716 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002717 break;
paul718e3742002-12-13 20:15:29 +00002718 default:
paul68980082003-03-25 05:07:42 +00002719 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002720 break;
2721 }
2722
paul68980082003-03-25 05:07:42 +00002723 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002724 ospf_lsa_discard (old);
2725}
2726
paul718e3742002-12-13 20:15:29 +00002727struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002728ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2729 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002730{
2731 struct ospf_lsa *new = NULL;
2732 struct ospf_lsa *old = NULL;
2733 struct ospf_lsdb *lsdb = NULL;
2734 int rt_recalc;
2735
2736 /* Set LSDB. */
2737 switch (lsa->data->type)
2738 {
paulf2c80652002-12-13 21:44:27 +00002739 /* kevinm */
2740 case OSPF_AS_NSSA_LSA:
2741 if (lsa->area)
2742 lsdb = lsa->area->lsdb;
2743 else
paul68980082003-03-25 05:07:42 +00002744 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002745 break;
paul718e3742002-12-13 20:15:29 +00002746 case OSPF_AS_EXTERNAL_LSA:
2747#ifdef HAVE_OPAQUE_LSA
2748 case OSPF_OPAQUE_AS_LSA:
2749#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002750 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002751 break;
2752 default:
2753 lsdb = lsa->area->lsdb;
2754 break;
2755 }
2756
paul718e3742002-12-13 20:15:29 +00002757 assert (lsdb);
2758
2759 /* RFC 2328 13.2. Installing LSAs in the database
2760
2761 Installing a new LSA in the database, either as the result of
2762 flooding or a newly self-originated LSA, may cause the OSPF
2763 routing table structure to be recalculated. The contents of the
2764 new LSA should be compared to the old instance, if present. If
2765 there is no difference, there is no need to recalculate the
2766 routing table. When comparing an LSA to its previous instance,
2767 the following are all considered to be differences in contents:
2768
2769 o The LSA's Options field has changed.
2770
2771 o One of the LSA instances has LS age set to MaxAge, and
2772 the other does not.
2773
2774 o The length field in the LSA header has changed.
2775
2776 o The body of the LSA (i.e., anything outside the 20-byte
2777 LSA header) has changed. Note that this excludes changes
2778 in LS Sequence Number and LS Checksum.
2779
2780 */
2781 /* Look up old LSA and determine if any SPF calculation or incremental
2782 update is needed */
2783 old = ospf_lsdb_lookup (lsdb, lsa);
2784
2785 /* Do comparision and record if recalc needed. */
2786 rt_recalc = 0;
2787 if ( old == NULL || ospf_lsa_different(old, lsa))
2788 rt_recalc = 1;
2789
paul7ddf1d62003-10-13 09:06:46 +00002790 /*
2791 Sequence number check (Section 14.1 of rfc 2328)
2792 "Premature aging is used when it is time for a self-originated
2793 LSA's sequence number field to wrap. At this point, the current
2794 LSA instance (having LS sequence number MaxSequenceNumber) must
2795 be prematurely aged and flushed from the routing domain before a
2796 new instance with sequence number equal to InitialSequenceNumber
2797 can be originated. "
2798 */
2799
Paul Jakmac2b478d2006-03-30 14:16:11 +00002800 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002801 {
2802 if (ospf_lsa_is_self_originated(ospf, lsa))
2803 {
paul0c2be262004-05-31 14:16:54 +00002804 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2805
2806 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002807 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2808 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2809
2810 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2811 {
ajse588f212004-12-08 18:12:06 +00002812 zlog_debug ("ospf_lsa_install() Premature Aging "
paul7ddf1d62003-10-13 09:06:46 +00002813 "lsa 0x%lx", (u_long)lsa);
2814 ospf_lsa_header_dump (lsa->data);
2815 }
2816 }
2817 else
2818 {
2819 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2820 {
ajse588f212004-12-08 18:12:06 +00002821 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002822 "that was not self originated. Ignoring\n");
2823 ospf_lsa_header_dump (lsa->data);
2824 }
2825 return old;
2826 }
2827 }
2828
paul718e3742002-12-13 20:15:29 +00002829 /* discard old LSA from LSDB */
2830 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002831 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002832
paul718e3742002-12-13 20:15:29 +00002833 /* Calculate Checksum if self-originated?. */
2834 if (IS_LSA_SELF (lsa))
2835 ospf_lsa_checksum (lsa->data);
2836
hassofe71a972004-12-22 16:16:02 +00002837 /* Insert LSA to LSDB. */
2838 ospf_lsdb_add (lsdb, lsa);
2839 lsa->lsdb = lsdb;
2840
paul718e3742002-12-13 20:15:29 +00002841 /* Do LSA specific installation process. */
2842 switch (lsa->data->type)
2843 {
2844 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002845 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002846 break;
2847 case OSPF_NETWORK_LSA:
2848 assert (oi);
paul68980082003-03-25 05:07:42 +00002849 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002850 break;
2851 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002852 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002853 break;
2854 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002855 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002856 break;
2857 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002858 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002859 break;
2860#ifdef HAVE_OPAQUE_LSA
2861 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002862 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002863 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002864 else
paul68980082003-03-25 05:07:42 +00002865 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002866 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002867 case OSPF_OPAQUE_AREA_LSA:
2868 case OSPF_OPAQUE_AS_LSA:
2869 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2870 break;
2871#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002872 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002873 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002874 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002875 break;
2876 }
2877
2878 if (new == NULL)
2879 return new; /* Installation failed, cannot proceed further -- endo. */
2880
2881 /* Debug logs. */
2882 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2883 {
2884 char area_str[INET_ADDRSTRLEN];
2885
2886 switch (lsa->data->type)
2887 {
2888 case OSPF_AS_EXTERNAL_LSA:
2889#ifdef HAVE_OPAQUE_LSA
2890 case OSPF_OPAQUE_AS_LSA:
2891#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002892 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002893 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002894 dump_lsa_key (new),
2895 LOOKUP (ospf_lsa_type_msg, new->data->type));
2896 break;
2897 default:
2898 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002899 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002900 dump_lsa_key (new),
2901 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2902 break;
2903 }
2904 }
2905
paul7ddf1d62003-10-13 09:06:46 +00002906 /*
2907 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2908 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2909 */
2910 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2911 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002912 {
paul7ddf1d62003-10-13 09:06:46 +00002913 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002914 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002915 new->data->type,
2916 inet_ntoa (new->data->id),
2917 lsa);
paul68980082003-03-25 05:07:42 +00002918 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002919 }
2920
2921 return new;
2922}
2923
2924
paul4dadc292005-05-06 21:37:42 +00002925static int
paul68980082003-03-25 05:07:42 +00002926ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002927{
paul1eb8ef22005-04-07 07:30:20 +00002928 struct listnode *node, *nnode;
2929 struct ospf_interface *oi;
2930
2931 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002932 {
paul718e3742002-12-13 20:15:29 +00002933 struct route_node *rn;
2934 struct ospf_neighbor *nbr;
2935
2936 if (ospf_if_is_enable (oi))
2937 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2938 if ((nbr = rn->info) != NULL)
2939 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2940 {
2941 route_unlock_node (rn);
2942 return 0;
2943 }
2944 }
2945
2946 return 1;
2947}
2948
2949
2950#ifdef ORIGINAL_CODING
2951/* This function flood the maxaged LSA to DR. */
2952void
2953ospf_maxage_flood (struct ospf_lsa *lsa)
2954{
2955 switch (lsa->data->type)
2956 {
2957 case OSPF_ROUTER_LSA:
2958 case OSPF_NETWORK_LSA:
2959 case OSPF_SUMMARY_LSA:
2960 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00002961 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00002962#ifdef HAVE_OPAQUE_LSA
2963 case OSPF_OPAQUE_LINK_LSA:
2964 case OSPF_OPAQUE_AREA_LSA:
2965#endif /* HAVE_OPAQUE_LSA */
2966 ospf_flood_through_area (lsa->area, NULL, lsa);
2967 break;
2968 case OSPF_AS_EXTERNAL_LSA:
2969#ifdef HAVE_OPAQUE_LSA
2970 case OSPF_OPAQUE_AS_LSA:
2971#endif /* HAVE_OPAQUE_LSA */
2972 ospf_flood_through_as (NULL, lsa);
2973 break;
2974 default:
2975 break;
2976 }
2977}
2978#endif /* ORIGINAL_CODING */
2979
paul4dadc292005-05-06 21:37:42 +00002980static int
paul718e3742002-12-13 20:15:29 +00002981ospf_maxage_lsa_remover (struct thread *thread)
2982{
paul68980082003-03-25 05:07:42 +00002983 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002984 struct ospf_lsa *lsa;
2985 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002986 int reschedule = 0;
2987
paul68980082003-03-25 05:07:42 +00002988 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002989
2990 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002991 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002992
paul68980082003-03-25 05:07:42 +00002993 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002994
2995 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002996 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002997 {
paul718e3742002-12-13 20:15:29 +00002998 if (lsa->retransmit_counter > 0)
2999 {
3000 reschedule = 1;
3001 continue;
3002 }
3003
3004 /* Remove LSA from the LSDB */
3005 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF))
3006 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003007 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
paul7ddf1d62003-10-13 09:06:46 +00003008 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00003009
3010 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003011 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00003012 lsa->data->type, inet_ntoa (lsa->data->id));
3013
3014 /* Flood max age LSA. */
3015#ifdef ORIGINAL_CODING
3016 ospf_maxage_flood (lsa);
3017#else /* ORIGINAL_CODING */
paul68980082003-03-25 05:07:42 +00003018 ospf_flood_through (ospf, NULL, lsa);
paul718e3742002-12-13 20:15:29 +00003019#endif /* ORIGINAL_CODING */
3020
paul7ddf1d62003-10-13 09:06:46 +00003021 if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
3022 {
3023 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003024 zlog_debug ("originating new router lsa for lsa 0x%lx \n",
paul7ddf1d62003-10-13 09:06:46 +00003025 (u_long)lsa);
3026 ospf_router_lsa_originate(lsa->area);
3027 }
3028
paul718e3742002-12-13 20:15:29 +00003029 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00003030 if (lsa->lsdb)
3031 {
3032 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
3033 ospf_lsdb_delete (lsa->lsdb, lsa);
3034 }
3035 else
3036 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
3037 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00003038 }
3039
3040 /* A MaxAge LSA must be removed immediately from the router's link
3041 state database as soon as both a) it is no longer contained on any
3042 neighbor Link state retransmission lists and b) none of the router's
3043 neighbors are in states Exchange or Loading. */
3044 if (reschedule)
paul68980082003-03-25 05:07:42 +00003045 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003046
3047 return 0;
3048}
3049
paul4dadc292005-05-06 21:37:42 +00003050static int
paul68980082003-03-25 05:07:42 +00003051ospf_lsa_maxage_exist (struct ospf *ospf, struct ospf_lsa *new)
paul718e3742002-12-13 20:15:29 +00003052{
hasso52dc7ee2004-09-23 19:18:23 +00003053 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003054 struct ospf_lsa *lsa;
3055
3056 for (ALL_LIST_ELEMENTS_RO (ospf->maxage_lsa, node, lsa))
3057 if (lsa == new)
paul718e3742002-12-13 20:15:29 +00003058 return 1;
3059
3060 return 0;
3061}
3062
3063void
paul68980082003-03-25 05:07:42 +00003064ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003065{
hasso52dc7ee2004-09-23 19:18:23 +00003066 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00003067
paul68980082003-03-25 05:07:42 +00003068 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00003069 {
paul68980082003-03-25 05:07:42 +00003070 list_delete_node (ospf->maxage_lsa, n);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003071 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +00003072 }
3073}
3074
3075void
paul68980082003-03-25 05:07:42 +00003076ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003077{
3078 /* When we saw a MaxAge LSA flooded to us, we put it on the list
3079 and schedule the MaxAge LSA remover. */
paul68980082003-03-25 05:07:42 +00003080 if (ospf_lsa_maxage_exist (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003081 {
3082 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003083 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00003084 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
3085 return;
3086 }
3087
paul68980082003-03-25 05:07:42 +00003088 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
paul718e3742002-12-13 20:15:29 +00003089
3090 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003091 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003092
paul68980082003-03-25 05:07:42 +00003093 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
paul718e3742002-12-13 20:15:29 +00003094}
3095
paul4dadc292005-05-06 21:37:42 +00003096static int
paul68980082003-03-25 05:07:42 +00003097ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003098{
paul718e3742002-12-13 20:15:29 +00003099 /* Stay away from any Local Translated Type-7 LSAs */
3100 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3101 return 0;
paul718e3742002-12-13 20:15:29 +00003102
3103 if (IS_LSA_MAXAGE (lsa))
3104 /* Self-originated LSAs should NOT time-out instead,
3105 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00003106 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003107 {
3108 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003109 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003110
3111 switch (lsa->data->type)
3112 {
paul718e3742002-12-13 20:15:29 +00003113#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00003114 case OSPF_OPAQUE_LINK_LSA:
3115 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003116 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003117 /*
3118 * As a general rule, whenever network topology has changed
3119 * (due to an LSA removal in this case), routing recalculation
3120 * should be triggered. However, this is not true for opaque
3121 * LSAs. Even if an opaque LSA instance is going to be removed
3122 * from the routing domain, it does not mean a change in network
3123 * topology, and thus, routing recalculation is not needed here.
3124 */
3125 break;
paul718e3742002-12-13 20:15:29 +00003126#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00003127 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003128 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003129 ospf_ase_incremental_update (ospf, lsa);
3130 break;
paul718e3742002-12-13 20:15:29 +00003131 default:
paul68980082003-03-25 05:07:42 +00003132 ospf_spf_calculate_schedule (ospf);
3133 break;
paul718e3742002-12-13 20:15:29 +00003134 }
paul68980082003-03-25 05:07:42 +00003135 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003136 }
3137
3138 return 0;
3139}
3140
3141/* Periodical check of MaxAge LSA. */
3142int
paul68980082003-03-25 05:07:42 +00003143ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003144{
paul68980082003-03-25 05:07:42 +00003145 struct ospf *ospf = THREAD_ARG (thread);
3146 struct route_node *rn;
3147 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003148 struct ospf_area *area;
3149 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003150
paul68980082003-03-25 05:07:42 +00003151 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003152
paul1eb8ef22005-04-07 07:30:20 +00003153 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003154 {
paul68980082003-03-25 05:07:42 +00003155 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3156 ospf_lsa_maxage_walker_remover (ospf, lsa);
3157 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3158 ospf_lsa_maxage_walker_remover (ospf, lsa);
3159 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3160 ospf_lsa_maxage_walker_remover (ospf, lsa);
3161 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3162 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003163#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003164 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3165 ospf_lsa_maxage_walker_remover (ospf, lsa);
3166 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3167 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003168#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003169 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3170 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003171 }
3172
paul4fb949e2003-05-10 20:06:51 +00003173 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003174 if (ospf->lsdb)
3175 {
3176 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3177 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003178#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003179 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3180 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003181#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003182 }
paul718e3742002-12-13 20:15:29 +00003183
paul68980082003-03-25 05:07:42 +00003184 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3185 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003186 return 0;
3187}
3188
paul68980082003-03-25 05:07:42 +00003189struct ospf_lsa *
3190ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3191 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003192{
paul68980082003-03-25 05:07:42 +00003193 struct ospf_lsa *lsa;
3194 struct in_addr mask, id;
3195 struct lsa_header_mask
3196 {
3197 struct lsa_header header;
3198 struct in_addr mask;
3199 } *hmask;
paul718e3742002-12-13 20:15:29 +00003200
paul68980082003-03-25 05:07:42 +00003201 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3202 if (lsa == NULL)
3203 return NULL;
paul718e3742002-12-13 20:15:29 +00003204
paul68980082003-03-25 05:07:42 +00003205 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003206
paul68980082003-03-25 05:07:42 +00003207 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003208
paul68980082003-03-25 05:07:42 +00003209 if (mask.s_addr != hmask->mask.s_addr)
3210 {
3211 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3212 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3213 if (!lsa)
3214 return NULL;
3215 }
paul718e3742002-12-13 20:15:29 +00003216
paul68980082003-03-25 05:07:42 +00003217 return lsa;
paul718e3742002-12-13 20:15:29 +00003218}
3219
3220struct ospf_lsa *
3221ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3222 struct in_addr id, struct in_addr adv_router)
3223{
paule05fba42003-04-13 20:20:53 +00003224 struct ospf *ospf = ospf_lookup();
3225 assert(ospf);
3226
paul718e3742002-12-13 20:15:29 +00003227 switch (type)
3228 {
3229 case OSPF_ROUTER_LSA:
3230 case OSPF_NETWORK_LSA:
3231 case OSPF_SUMMARY_LSA:
3232 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003233 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003234#ifdef HAVE_OPAQUE_LSA
3235 case OSPF_OPAQUE_LINK_LSA:
3236 case OSPF_OPAQUE_AREA_LSA:
3237#endif /* HAVE_OPAQUE_LSA */
3238 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003239 case OSPF_AS_EXTERNAL_LSA:
3240#ifdef HAVE_OPAQUE_LSA
3241 case OSPF_OPAQUE_AS_LSA:
3242#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003243 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003244 default:
3245 break;
3246 }
3247
3248 return NULL;
3249}
3250
3251struct ospf_lsa *
3252ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3253 struct in_addr id)
3254{
3255 struct ospf_lsa *lsa;
3256 struct route_node *rn;
3257
3258 switch (type)
3259 {
3260 case OSPF_ROUTER_LSA:
3261 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003262 case OSPF_NETWORK_LSA:
3263 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3264 if ((lsa = rn->info))
3265 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3266 {
3267 route_unlock_node (rn);
3268 return lsa;
3269 }
3270 break;
3271 case OSPF_SUMMARY_LSA:
3272 case OSPF_ASBR_SUMMARY_LSA:
3273 /* Currently not used. */
3274 assert (1);
3275 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003276 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003277 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003278#ifdef HAVE_OPAQUE_LSA
3279 case OSPF_OPAQUE_LINK_LSA:
3280 case OSPF_OPAQUE_AREA_LSA:
3281 case OSPF_OPAQUE_AS_LSA:
3282 /* Currently not used. */
3283 break;
3284#endif /* HAVE_OPAQUE_LSA */
3285 default:
3286 break;
3287 }
3288
3289 return NULL;
3290}
3291
3292struct ospf_lsa *
3293ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3294{
3295 struct ospf_lsa *match;
3296
3297#ifdef HAVE_OPAQUE_LSA
3298 /*
3299 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3300 * is redefined to have two subfields; opaque-type and opaque-id.
3301 * However, it is harmless to treat the two sub fields together, as if
3302 * they two were forming a unique LSA-ID.
3303 */
3304#endif /* HAVE_OPAQUE_LSA */
3305
3306 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3307
3308 if (match == NULL)
3309 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003310 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003311 lsah->type, inet_ntoa (lsah->id));
3312
3313 return match;
3314}
3315
3316/* return +n, l1 is more recent.
3317 return -n, l2 is more recent.
3318 return 0, l1 and l2 is identical. */
3319int
3320ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3321{
3322 int r;
3323 int x, y;
3324
3325 if (l1 == NULL && l2 == NULL)
3326 return 0;
3327 if (l1 == NULL)
3328 return -1;
3329 if (l2 == NULL)
3330 return 1;
3331
3332 /* compare LS sequence number. */
3333 x = (int) ntohl (l1->data->ls_seqnum);
3334 y = (int) ntohl (l2->data->ls_seqnum);
3335 if (x > y)
3336 return 1;
3337 if (x < y)
3338 return -1;
3339
3340 /* compare LS checksum. */
3341 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3342 if (r)
3343 return r;
3344
3345 /* compare LS age. */
3346 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3347 return 1;
3348 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3349 return -1;
3350
3351 /* compare LS age with MaxAgeDiff. */
3352 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3353 return -1;
3354 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3355 return 1;
3356
3357 /* LSAs are identical. */
3358 return 0;
3359}
3360
3361/* If two LSAs are different, return 1, otherwise return 0. */
3362int
3363ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3364{
3365 char *p1, *p2;
3366 assert (l1);
3367 assert (l2);
3368 assert (l1->data);
3369 assert (l2->data);
3370
3371 if (l1->data->options != l2->data->options)
3372 return 1;
3373
3374 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3375 return 1;
3376
3377 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3378 return 1;
3379
3380 if (l1->data->length != l2->data->length)
3381 return 1;
3382
3383 if (l1->data->length == 0)
3384 return 1;
3385
pauld1825832003-04-03 01:27:01 +00003386 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003387
3388 p1 = (char *) l1->data;
3389 p2 = (char *) l2->data;
3390
3391 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3392 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3393 return 1;
3394
3395 return 0;
3396}
3397
3398#ifdef ORIGINAL_CODING
3399void
3400ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3401 struct ospf_lsa *self,
3402 struct ospf_lsa *new)
3403{
3404 u_int32_t seqnum;
3405
3406 /* Adjust LS Sequence Number. */
3407 seqnum = ntohl (new->data->ls_seqnum) + 1;
3408 self->data->ls_seqnum = htonl (seqnum);
3409
3410 /* Recalculate LSA checksum. */
3411 ospf_lsa_checksum (self->data);
3412
3413 /* Reflooding LSA. */
3414 /* RFC2328 Section 13.3
3415 On non-broadcast networks, separate Link State Update
3416 packets must be sent, as unicasts, to each adjacent neighbor
3417 (i.e., those in state Exchange or greater). The destination
3418 IP addresses for these packets are the neighbors' IP
3419 addresses. */
3420 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3421 {
3422 struct route_node *rn;
3423 struct ospf_neighbor *onbr;
3424
3425 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3426 if ((onbr = rn->info) != NULL)
3427 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3428 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3429 }
3430 else
3431 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3432
3433 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003434 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003435 self->data->type, inet_ntoa (self->data->id));
3436}
3437#else /* ORIGINAL_CODING */
3438static int
paul68980082003-03-25 05:07:42 +00003439ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003440{
3441 if (lsa == NULL || !IS_LSA_SELF (lsa))
3442 return 0;
3443
3444 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003445 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 +00003446
3447 /* Force given lsa's age to MaxAge. */
3448 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3449
3450 switch (lsa->data->type)
3451 {
3452#ifdef HAVE_OPAQUE_LSA
3453 case OSPF_OPAQUE_LINK_LSA:
3454 case OSPF_OPAQUE_AREA_LSA:
3455 case OSPF_OPAQUE_AS_LSA:
3456 ospf_opaque_lsa_refresh (lsa);
3457 break;
3458#endif /* HAVE_OPAQUE_LSA */
3459 default:
paul68980082003-03-25 05:07:42 +00003460 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003461 break;
3462 }
3463
3464 return 0;
3465}
3466
3467void
paul68980082003-03-25 05:07:42 +00003468ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003469{
paul1eb8ef22005-04-07 07:30:20 +00003470 struct listnode *node, *nnode;
3471 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003472 struct ospf_area *area;
3473 struct ospf_interface *oi;
3474 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003475 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003476 int need_to_flush_ase = 0;
3477
paul1eb8ef22005-04-07 07:30:20 +00003478 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003479 {
paul718e3742002-12-13 20:15:29 +00003480 if ((lsa = area->router_lsa_self) != NULL)
3481 {
3482 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003483 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 +00003484
3485 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003486 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003487 area->router_lsa_self = NULL;
3488 OSPF_TIMER_OFF (area->t_router_lsa_self);
3489 }
3490
paul1eb8ef22005-04-07 07:30:20 +00003491 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003492 {
paul718e3742002-12-13 20:15:29 +00003493 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003494 && oi->state == ISM_DR
3495 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003496 {
3497 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003498 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 +00003499
3500 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003501 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003502 oi->network_lsa_self = NULL;
3503 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3504 }
3505
3506 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3507 && area->external_routing == OSPF_AREA_DEFAULT)
3508 need_to_flush_ase = 1;
3509 }
3510
paul68980082003-03-25 05:07:42 +00003511 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3512 ospf_lsa_flush_schedule (ospf, lsa);
3513 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3514 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003515#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003516 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3517 ospf_lsa_flush_schedule (ospf, lsa);
3518 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3519 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003520#endif /* HAVE_OPAQUE_LSA */
3521 }
3522
3523 if (need_to_flush_ase)
3524 {
paul68980082003-03-25 05:07:42 +00003525 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3526 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003527#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003528 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3529 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003530#endif /* HAVE_OPAQUE_LSA */
3531 }
3532
3533 /*
3534 * Make sure that the MaxAge LSA remover is executed immediately,
3535 * without conflicting to other threads.
3536 */
paul68980082003-03-25 05:07:42 +00003537 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003538 {
paul68980082003-03-25 05:07:42 +00003539 OSPF_TIMER_OFF (ospf->t_maxage);
3540 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003541 }
3542
3543 return;
3544}
3545#endif /* ORIGINAL_CODING */
3546
3547/* If there is self-originated LSA, then return 1, otherwise return 0. */
3548/* An interface-independent version of ospf_lsa_is_self_originated */
3549int
paul68980082003-03-25 05:07:42 +00003550ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003551{
hasso52dc7ee2004-09-23 19:18:23 +00003552 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003553 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003554
3555 /* This LSA is already checked. */
3556 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
3557 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3558
3559 /* Make sure LSA is self-checked. */
3560 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3561
3562 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003563 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003564 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3565
3566 /* LSA is router-LSA. */
3567 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003568 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003569 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3570
3571 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3572 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003573 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003574 {
paul718e3742002-12-13 20:15:29 +00003575 /* Ignore virtual link. */
3576 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3577 if (oi->address->family == AF_INET)
3578 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3579 {
3580 /* to make it easier later */
3581 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3582 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3583 }
3584 }
3585
3586 return CHECK_FLAG (lsa->flags, OSPF_LSA_SELF);
3587}
3588
3589/* Get unique Link State ID. */
3590struct in_addr
paul68980082003-03-25 05:07:42 +00003591ospf_lsa_unique_id (struct ospf *ospf,
3592 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003593{
3594 struct ospf_lsa *lsa;
3595 struct in_addr mask, id;
3596
3597 id = p->prefix;
3598
3599 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003600 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003601 if (lsa)
3602 {
3603 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3604 if (ip_masklen (al->mask) == p->prefixlen)
3605 {
3606 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003607 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003608 "Can't get Link State ID for %s/%d",
3609 inet_ntoa (p->prefix), p->prefixlen);
3610 /* id.s_addr = 0; */
3611 id.s_addr = 0xffffffff;
3612 return id;
3613 }
3614 /* Masklen differs, then apply wildcard mask to Link State ID. */
3615 else
3616 {
3617 masklen2ip (p->prefixlen, &mask);
3618
3619 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003620 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3621 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003622 if (lsa)
3623 {
3624 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003625 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003626 "Can't get Link State ID for %s/%d",
3627 inet_ntoa (p->prefix), p->prefixlen);
3628 /* id.s_addr = 0; */
3629 id.s_addr = 0xffffffff;
3630 return id;
3631 }
3632 }
3633 }
3634
3635 return id;
3636}
3637
3638
Paul Jakma70461d72006-05-12 22:57:57 +00003639#define LSA_ACTION_FLOOD_AREA 1
3640#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003641
3642struct lsa_action
3643{
3644 u_char action;
3645 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003646 struct ospf_lsa *lsa;
3647};
3648
paul4dadc292005-05-06 21:37:42 +00003649static int
paul718e3742002-12-13 20:15:29 +00003650ospf_lsa_action (struct thread *t)
3651{
3652 struct lsa_action *data;
3653
3654 data = THREAD_ARG (t);
3655
3656 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003657 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003658 data->action);
3659
3660 switch (data->action)
3661 {
paul718e3742002-12-13 20:15:29 +00003662 case LSA_ACTION_FLOOD_AREA:
3663 ospf_flood_through_area (data->area, NULL, data->lsa);
3664 break;
paul718e3742002-12-13 20:15:29 +00003665 case LSA_ACTION_FLUSH_AREA:
3666 ospf_lsa_flush_area (data->lsa, data->area);
3667 break;
paul718e3742002-12-13 20:15:29 +00003668 }
3669
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003670 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003671 XFREE (MTYPE_OSPF_MESSAGE, data);
3672 return 0;
3673}
3674
3675void
3676ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3677{
3678 struct lsa_action *data;
3679
3680 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3681 memset (data, 0, sizeof (struct lsa_action));
3682
3683 data->action = LSA_ACTION_FLOOD_AREA;
3684 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003685 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003686
3687 thread_add_event (master, ospf_lsa_action, data, 0);
3688}
3689
3690void
3691ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3692{
3693 struct lsa_action *data;
3694
3695 data = XMALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
3696 memset (data, 0, sizeof (struct lsa_action));
3697
3698 data->action = LSA_ACTION_FLUSH_AREA;
3699 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003700 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003701
3702 thread_add_event (master, ospf_lsa_action, data, 0);
3703}
3704
3705
3706/* LSA Refreshment functions. */
paul4dadc292005-05-06 21:37:42 +00003707static void
paul68980082003-03-25 05:07:42 +00003708ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003709{
3710 struct external_info *ei;
3711 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3712
3713 switch (lsa->data->type)
3714 {
3715 /* Router and Network LSAs are processed differently. */
3716 case OSPF_ROUTER_LSA:
3717 case OSPF_NETWORK_LSA:
3718 break;
3719 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003720 ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003721 break;
3722 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00003723 ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003724 break;
3725 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003726 /* Translated from NSSA Type-5s are refreshed when
3727 * from refresh of Type-7 - do not refresh these directly.
3728 */
3729 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3730 break;
paul718e3742002-12-13 20:15:29 +00003731 ei = ospf_external_info_check (lsa);
3732 if (ei)
pauld4a53d52003-07-12 21:30:57 +00003733 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003734 else
pauld4a53d52003-07-12 21:30:57 +00003735 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003736 break;
3737#ifdef HAVE_OPAQUE_LSA
3738 case OSPF_OPAQUE_LINK_LSA:
3739 case OSPF_OPAQUE_AREA_LSA:
3740 case OSPF_OPAQUE_AS_LSA:
3741 ospf_opaque_lsa_refresh (lsa);
3742 break;
pauld7480322003-05-16 17:31:51 +00003743#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003744 default:
3745 break;
paul718e3742002-12-13 20:15:29 +00003746 }
3747}
3748
3749void
paul68980082003-03-25 05:07:42 +00003750ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003751{
3752 u_int16_t index, current_index;
3753
3754 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3755
3756 if (lsa->refresh_list < 0)
3757 {
3758 int delay;
3759
3760 if (LS_AGE (lsa) == 0 &&
3761 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3762 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3763 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3764 else
3765 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3766 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3767 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3768
3769 if (delay < 0)
3770 delay = 0;
3771
paul68980082003-03-25 05:07:42 +00003772 current_index = ospf->lsa_refresh_queue.index +
3773 (time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003774
3775 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3776 % (OSPF_LSA_REFRESHER_SLOTS);
3777
3778 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003779 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003780 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003781 if (!ospf->lsa_refresh_queue.qs[index])
3782 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003783 listnode_add (ospf->lsa_refresh_queue.qs[index],
3784 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003785 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003786 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003787 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003788 "setting refresh_list on lsa %p (slod %d)",
3789 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003790 }
3791}
3792
3793void
paul68980082003-03-25 05:07:42 +00003794ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003795{
3796 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
3797 if (lsa->refresh_list >= 0)
3798 {
hasso52dc7ee2004-09-23 19:18:23 +00003799 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003800 listnode_delete (refresh_list, lsa);
3801 if (!listcount (refresh_list))
3802 {
3803 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003804 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003805 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003806 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003807 lsa->refresh_list = -1;
3808 }
3809}
3810
3811int
3812ospf_lsa_refresh_walker (struct thread *t)
3813{
hasso52dc7ee2004-09-23 19:18:23 +00003814 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003815 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003816 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003817 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003818 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003819 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003820
3821 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003822 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003823
3824
paul68980082003-03-25 05:07:42 +00003825 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003826
ajs9dbc7972005-03-13 19:27:22 +00003827 /* Note: if clock has jumped backwards, then time change could be negative,
3828 so we are careful to cast the expression to unsigned before taking
3829 modulus. */
paul68980082003-03-25 05:07:42 +00003830 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003831 ((unsigned long)(ospf->lsa_refresh_queue.index +
3832 (time (NULL) - ospf->lsa_refresher_started) /
3833 OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003834
3835 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003836 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003837 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003838
paul68980082003-03-25 05:07:42 +00003839 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003840 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3841 {
3842 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003843 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003844 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003845
paul68980082003-03-25 05:07:42 +00003846 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003847
paul68980082003-03-25 05:07:42 +00003848 ospf->lsa_refresh_queue.qs [i] = NULL;
3849
paul718e3742002-12-13 20:15:29 +00003850 if (refresh_list)
3851 {
paul1eb8ef22005-04-07 07:30:20 +00003852 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003853 {
paul718e3742002-12-13 20:15:29 +00003854 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003855 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003856 "refresh lsa %p (slot %d)",
3857 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003858
3859 list_delete_node (refresh_list, node);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003860 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003861 lsa->refresh_list = -1;
3862 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003863 }
3864 list_free (refresh_list);
3865 }
3866 }
3867
paul68980082003-03-25 05:07:42 +00003868 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3869 ospf, ospf->lsa_refresh_interval);
3870 ospf->lsa_refresher_started = time (NULL);
paul718e3742002-12-13 20:15:29 +00003871
paul1eb8ef22005-04-07 07:30:20 +00003872 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
3873 ospf_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003874
3875 list_delete (lsa_to_refresh);
3876
3877 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003878 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003879
3880 return 0;
3881}
3882