blob: e778251caace226ba47668818e9043a671957bc1 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
2 * OSPF Link State Advertisement
3 * Copyright (C) 1999, 2000 Toshiaki Takada
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "linklist.h"
26#include "prefix.h"
27#include "if.h"
28#include "table.h"
29#include "memory.h"
30#include "stream.h"
31#include "log.h"
32#include "thread.h"
33#include "hash.h"
34#include "sockunion.h" /* for inet_aton() */
Jingjing Duan6a270cd2008-08-13 19:09:10 +010035#include "checksum.h"
paul718e3742002-12-13 20:15:29 +000036
37#include "ospfd/ospfd.h"
38#include "ospfd/ospf_interface.h"
39#include "ospfd/ospf_ism.h"
40#include "ospfd/ospf_asbr.h"
41#include "ospfd/ospf_lsa.h"
42#include "ospfd/ospf_lsdb.h"
43#include "ospfd/ospf_neighbor.h"
44#include "ospfd/ospf_nsm.h"
45#include "ospfd/ospf_flood.h"
46#include "ospfd/ospf_packet.h"
47#include "ospfd/ospf_spf.h"
48#include "ospfd/ospf_dump.h"
49#include "ospfd/ospf_route.h"
50#include "ospfd/ospf_ase.h"
51#include "ospfd/ospf_zebra.h"
52
53
54u_int32_t
55get_metric (u_char *metric)
56{
57 u_int32_t m;
58 m = metric[0];
59 m = (m << 8) + metric[1];
60 m = (m << 8) + metric[2];
61 return m;
62}
63
64
65struct timeval
66tv_adjust (struct timeval a)
67{
68 while (a.tv_usec >= 1000000)
69 {
70 a.tv_usec -= 1000000;
71 a.tv_sec++;
72 }
73
74 while (a.tv_usec < 0)
75 {
76 a.tv_usec += 1000000;
77 a.tv_sec--;
78 }
79
80 return a;
81}
82
83int
84tv_ceil (struct timeval a)
85{
86 a = tv_adjust (a);
87
88 return (a.tv_usec ? a.tv_sec + 1 : a.tv_sec);
89}
90
91int
92tv_floor (struct timeval a)
93{
94 a = tv_adjust (a);
95
96 return a.tv_sec;
97}
98
99struct timeval
100int2tv (int a)
101{
102 struct timeval ret;
103
104 ret.tv_sec = a;
105 ret.tv_usec = 0;
106
107 return ret;
108}
109
110struct timeval
111tv_add (struct timeval a, struct timeval b)
112{
113 struct timeval ret;
114
115 ret.tv_sec = a.tv_sec + b.tv_sec;
116 ret.tv_usec = a.tv_usec + b.tv_usec;
117
118 return tv_adjust (ret);
119}
120
121struct timeval
122tv_sub (struct timeval a, struct timeval b)
123{
124 struct timeval ret;
125
126 ret.tv_sec = a.tv_sec - b.tv_sec;
127 ret.tv_usec = a.tv_usec - b.tv_usec;
128
129 return tv_adjust (ret);
130}
131
132int
133tv_cmp (struct timeval a, struct timeval b)
134{
135 return (a.tv_sec == b.tv_sec ?
136 a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
137}
138
139int
140ospf_lsa_refresh_delay (struct ospf_lsa *lsa)
141{
142 struct timeval delta, now;
143 int delay = 0;
144
Paul Jakma2518efd2006-08-27 06:49:29 +0000145 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +0000146 delta = tv_sub (now, lsa->tv_orig);
147
148 if (tv_cmp (delta, int2tv (OSPF_MIN_LS_INTERVAL)) < 0)
149 {
150 delay = tv_ceil (tv_sub (int2tv (OSPF_MIN_LS_INTERVAL), delta));
151
152 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000153 zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
paul718e3742002-12-13 20:15:29 +0000154 lsa->data->type, inet_ntoa (lsa->data->id), delay);
155
156 assert (delay > 0);
157 }
158
159 return delay;
160}
161
162
163int
164get_age (struct ospf_lsa *lsa)
165{
166 int age;
paul718e3742002-12-13 20:15:29 +0000167
Paul Jakma2518efd2006-08-27 06:49:29 +0000168 age = ntohs (lsa->data->ls_age)
169 + tv_floor (tv_sub (recent_relative_time (), lsa->tv_recv));
paul718e3742002-12-13 20:15:29 +0000170
171 return age;
172}
173
174
175/* Fletcher Checksum -- Refer to RFC1008. */
paul718e3742002-12-13 20:15:29 +0000176
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100177/* All the offsets are zero-based. The offsets in the RFC1008 are
178 one-based. */
paul718e3742002-12-13 20:15:29 +0000179u_int16_t
180ospf_lsa_checksum (struct lsa_header *lsa)
181{
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100182 u_char *buffer = (u_char *) &lsa->options;
183 int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */
paul718e3742002-12-13 20:15:29 +0000184
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100185 /* Skip the AGE field */
186 u_int16_t len = ntohs(lsa->length) - options_offset;
paul718e3742002-12-13 20:15:29 +0000187
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100188 /* Checksum offset starts from "options" field, not the beginning of the
189 lsa_header struct. The offset is 14, rather than 16. */
190 int checksum_offset = (u_char *) &lsa->checksum - buffer;
paul718e3742002-12-13 20:15:29 +0000191
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100192 return fletcher_checksum(buffer, len, checksum_offset);
paul718e3742002-12-13 20:15:29 +0000193}
194
JR Riversd8a4e422012-09-13 17:17:36 +0000195int
196ospf_lsa_checksum_valid (struct lsa_header *lsa)
197{
198 u_char *buffer = (u_char *) &lsa->options;
199 int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */
200
201 /* Skip the AGE field */
202 u_int16_t len = ntohs(lsa->length) - options_offset;
203
204 return(fletcher_checksum(buffer, len, FLETCHER_CHECKSUM_VALIDATE) == 0);
205}
206
paul718e3742002-12-13 20:15:29 +0000207
208
209/* Create OSPF LSA. */
210struct ospf_lsa *
211ospf_lsa_new ()
212{
213 struct ospf_lsa *new;
214
215 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
paul718e3742002-12-13 20:15:29 +0000216
217 new->flags = 0;
218 new->lock = 1;
219 new->retransmit_counter = 0;
Paul Jakma2518efd2006-08-27 06:49:29 +0000220 new->tv_recv = recent_relative_time ();
paul718e3742002-12-13 20:15:29 +0000221 new->tv_orig = new->tv_recv;
222 new->refresh_list = -1;
223
224 return new;
225}
226
227/* Duplicate OSPF LSA. */
228struct ospf_lsa *
229ospf_lsa_dup (struct ospf_lsa *lsa)
230{
231 struct ospf_lsa *new;
232
233 if (lsa == NULL)
234 return NULL;
235
236 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
237
238 memcpy (new, lsa, sizeof (struct ospf_lsa));
239 UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
240 new->lock = 1;
241 new->retransmit_counter = 0;
242 new->data = ospf_lsa_data_dup (lsa->data);
243
paulf2c80652002-12-13 21:44:27 +0000244 /* kevinm: Clear the refresh_list, otherwise there are going
245 to be problems when we try to remove the LSA from the
246 queue (which it's not a member of.)
247 XXX: Should we add the LSA to the refresh_list queue? */
248 new->refresh_list = -1;
249
250 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000251 zlog_debug ("LSA: duplicated %p (new: %p)", lsa, new);
paulf2c80652002-12-13 21:44:27 +0000252
paul718e3742002-12-13 20:15:29 +0000253 return new;
254}
255
256/* Free OSPF LSA. */
257void
258ospf_lsa_free (struct ospf_lsa *lsa)
259{
260 assert (lsa->lock == 0);
261
262 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000263 zlog_debug ("LSA: freed %p", lsa);
paul718e3742002-12-13 20:15:29 +0000264
265 /* Delete LSA data. */
266 if (lsa->data != NULL)
267 ospf_lsa_data_free (lsa->data);
268
269 assert (lsa->refresh_list < 0);
270
271 memset (lsa, 0, sizeof (struct ospf_lsa));
272 XFREE (MTYPE_OSPF_LSA, lsa);
273}
274
275/* Lock LSA. */
276struct ospf_lsa *
277ospf_lsa_lock (struct ospf_lsa *lsa)
278{
279 lsa->lock++;
280 return lsa;
281}
282
283/* Unlock LSA. */
284void
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000285ospf_lsa_unlock (struct ospf_lsa **lsa)
paul718e3742002-12-13 20:15:29 +0000286{
287 /* This is sanity check. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000288 if (!lsa || !*lsa)
paul718e3742002-12-13 20:15:29 +0000289 return;
290
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000291 (*lsa)->lock--;
paul718e3742002-12-13 20:15:29 +0000292
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000293 assert ((*lsa)->lock >= 0);
paul718e3742002-12-13 20:15:29 +0000294
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000295 if ((*lsa)->lock == 0)
paul718e3742002-12-13 20:15:29 +0000296 {
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000297 assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
298 ospf_lsa_free (*lsa);
299 *lsa = NULL;
paul718e3742002-12-13 20:15:29 +0000300 }
301}
302
303/* Check discard flag. */
304void
305ospf_lsa_discard (struct ospf_lsa *lsa)
306{
307 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
308 {
309 SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000310 ospf_lsa_unlock (&lsa);
paul718e3742002-12-13 20:15:29 +0000311 }
312}
313
314/* Create LSA data. */
315struct lsa_header *
316ospf_lsa_data_new (size_t size)
317{
Stephen Hemminger393deb92008-08-18 14:13:29 -0700318 return XCALLOC (MTYPE_OSPF_LSA_DATA, size);
paul718e3742002-12-13 20:15:29 +0000319}
320
321/* Duplicate LSA data. */
322struct lsa_header *
323ospf_lsa_data_dup (struct lsa_header *lsah)
324{
325 struct lsa_header *new;
326
327 new = ospf_lsa_data_new (ntohs (lsah->length));
328 memcpy (new, lsah, ntohs (lsah->length));
329
330 return new;
331}
332
333/* Free LSA data. */
334void
335ospf_lsa_data_free (struct lsa_header *lsah)
336{
337 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000338 zlog_debug ("LSA[Type%d:%s]: data freed %p",
paul718e3742002-12-13 20:15:29 +0000339 lsah->type, inet_ntoa (lsah->id), lsah);
340
341 XFREE (MTYPE_OSPF_LSA_DATA, lsah);
342}
343
344
345/* LSA general functions. */
346
347const char *
348dump_lsa_key (struct ospf_lsa *lsa)
349{
350 static char buf[] = {
hasso52dc7ee2004-09-23 19:18:23 +0000351 "Type255,id(255.255.255.255),ar(255.255.255.255)"
paul718e3742002-12-13 20:15:29 +0000352 };
353 struct lsa_header *lsah;
354
355 if (lsa != NULL && (lsah = lsa->data) != NULL)
356 {
357 char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
358 strcpy (id, inet_ntoa (lsah->id));
359 strcpy (ar, inet_ntoa (lsah->adv_router));
360
361 sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
362 }
363 else
364 strcpy (buf, "NULL");
365
366 return buf;
367}
368
369u_int32_t
370lsa_seqnum_increment (struct ospf_lsa *lsa)
371{
372 u_int32_t seqnum;
373
374 seqnum = ntohl (lsa->data->ls_seqnum) + 1;
375
376 return htonl (seqnum);
377}
378
379void
380lsa_header_set (struct stream *s, u_char options,
paul68980082003-03-25 05:07:42 +0000381 u_char type, struct in_addr id, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +0000382{
383 struct lsa_header *lsah;
384
385 lsah = (struct lsa_header *) STREAM_DATA (s);
386
Paul Jakma02d942c2010-01-24 23:36:20 +0000387 lsah->ls_age = htons (OSPF_LSA_INITIAL_AGE);
paul718e3742002-12-13 20:15:29 +0000388 lsah->options = options;
389 lsah->type = type;
390 lsah->id = id;
paul68980082003-03-25 05:07:42 +0000391 lsah->adv_router = router_id;
paul718e3742002-12-13 20:15:29 +0000392 lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
393
paul9985f832005-02-09 15:51:56 +0000394 stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000395}
396
paul68980082003-03-25 05:07:42 +0000397
paul718e3742002-12-13 20:15:29 +0000398/* router-LSA related functions. */
399/* Get router-LSA flags. */
paul4dadc292005-05-06 21:37:42 +0000400static u_char
paul718e3742002-12-13 20:15:29 +0000401router_lsa_flags (struct ospf_area *area)
402{
403 u_char flags;
404
paul68980082003-03-25 05:07:42 +0000405 flags = area->ospf->flags;
paul718e3742002-12-13 20:15:29 +0000406
407 /* Set virtual link flag. */
408 if (ospf_full_virtual_nbrs (area))
409 SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
410 else
411 /* Just sanity check */
412 UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);
413
414 /* Set Shortcut ABR behabiour flag. */
415 UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
paul68980082003-03-25 05:07:42 +0000416 if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
paul718e3742002-12-13 20:15:29 +0000417 if (!OSPF_IS_AREA_BACKBONE (area))
418 if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
paul68980082003-03-25 05:07:42 +0000419 area->ospf->backbone == NULL) ||
paul718e3742002-12-13 20:15:29 +0000420 area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
421 SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
422
423 /* ASBR can't exit in stub area. */
Greg Troxelfc787e82007-08-06 15:50:20 +0000424 if (area->external_routing == OSPF_AREA_STUB)
paul942b6c12003-06-22 08:22:18 +0000425 UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
426 /* If ASBR set External flag */
427 else if (IS_OSPF_ASBR (area->ospf))
428 SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
429
430 /* Set ABR dependent flags */
431 if (IS_OSPF_ABR (area->ospf))
432 {
433 SET_FLAG (flags, ROUTER_LSA_BORDER);
paul942b6c12003-06-22 08:22:18 +0000434 /* If Area is NSSA and we are both ABR and unconditional translator,
pauld4a53d52003-07-12 21:30:57 +0000435 * set Nt bit to inform other routers.
paul942b6c12003-06-22 08:22:18 +0000436 */
pauld4a53d52003-07-12 21:30:57 +0000437 if ( (area->external_routing == OSPF_AREA_NSSA)
438 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
439 SET_FLAG (flags, ROUTER_LSA_NT);
paul942b6c12003-06-22 08:22:18 +0000440 }
paul718e3742002-12-13 20:15:29 +0000441 return flags;
442}
443
444/* Lookup neighbor other than myself.
445 And check neighbor count,
446 Point-to-Point link must have only 1 neighbor. */
447struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +0000448ospf_nbr_lookup_ptop (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +0000449{
paul718e3742002-12-13 20:15:29 +0000450 struct ospf_neighbor *nbr = NULL;
paul68980082003-03-25 05:07:42 +0000451 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000452
453 /* Search neighbor, there must be one of two nbrs. */
paul68980082003-03-25 05:07:42 +0000454 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
455 if ((nbr = rn->info))
456 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000457 if (nbr->state == NSM_Full)
paul68980082003-03-25 05:07:42 +0000458 {
459 route_unlock_node (rn);
460 break;
461 }
paul718e3742002-12-13 20:15:29 +0000462
463 /* PtoP link must have only 1 neighbor. */
paul68980082003-03-25 05:07:42 +0000464 if (ospf_nbr_count (oi, 0) > 1)
paul718e3742002-12-13 20:15:29 +0000465 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
466
467 return nbr;
468}
469
paul88d6cf32005-10-29 12:50:09 +0000470/* Determine cost of link, taking RFC3137 stub-router support into
471 * consideration
472 */
473static u_int16_t
474ospf_link_cost (struct ospf_interface *oi)
475{
476 /* RFC3137 stub router support */
477 if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
478 return oi->output_cost;
479 else
480 return OSPF_OUTPUT_COST_INFINITE;
481}
482
paul718e3742002-12-13 20:15:29 +0000483/* Set a link information. */
paul779adb02006-01-18 15:07:38 +0000484static char
paul718e3742002-12-13 20:15:29 +0000485link_info_set (struct stream *s, struct in_addr id,
486 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
487{
paul779adb02006-01-18 15:07:38 +0000488 /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
489 * vast majority of cases. Some rare routers with lots of links need more.
490 * we try accomodate those here.
491 */
492 if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
493 {
494 size_t ret = OSPF_MAX_LSA_SIZE;
495
496 /* Can we enlarge the stream still? */
497 if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
498 {
499 /* we futz the size here for simplicity, really we need to account
500 * for just:
501 * IP Header - (sizeof (struct ip))
502 * OSPF Header - OSPF_HEADER_SIZE
503 * LSA Header - OSPF_LSA_HEADER_SIZE
504 * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
505 *
506 * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
507 */
508 ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
509 }
510
511 if (ret == OSPF_MAX_LSA_SIZE)
512 {
Paul Jakma53725102009-08-03 16:34:16 +0100513 zlog_warn ("%s: Out of space in LSA stream, left %zd, size %zd",
paul779adb02006-01-18 15:07:38 +0000514 __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
515 return 0;
516 }
517 }
518
paul718e3742002-12-13 20:15:29 +0000519 /* TOS based routing is not supported. */
520 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
521 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
522 stream_putc (s, type); /* Link Type. */
523 stream_putc (s, tos); /* TOS = 0. */
524 stream_putw (s, cost); /* Link Cost. */
paul779adb02006-01-18 15:07:38 +0000525
526 return 1;
paul718e3742002-12-13 20:15:29 +0000527}
528
Andrew J. Schorre4529632006-12-12 19:18:21 +0000529/* Describe Point-to-Point link (Section 12.4.1.1). */
paul4dadc292005-05-06 21:37:42 +0000530static int
paul718e3742002-12-13 20:15:29 +0000531lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
532{
533 int links = 0;
534 struct ospf_neighbor *nbr;
535 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000536 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000537
538 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000539 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
paul718e3742002-12-13 20:15:29 +0000540
paul68980082003-03-25 05:07:42 +0000541 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000542 if (nbr->state == NSM_Full)
543 {
544 /* For unnumbered point-to-point networks, the Link Data field
545 should specify the interface's MIB-II ifIndex value. */
paul779adb02006-01-18 15:07:38 +0000546 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
547 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000548 }
549
Andrew J. Schorre4529632006-12-12 19:18:21 +0000550 /* Regardless of the state of the neighboring router, we must
551 add a Type 3 link (stub network).
552 N.B. Options 1 & 2 share basically the same logic. */
553 masklen2ip (oi->address->prefixlen, &mask);
554 id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
555 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
556 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000557 return links;
558}
559
560/* Describe Broadcast Link. */
paul4dadc292005-05-06 21:37:42 +0000561static int
paul718e3742002-12-13 20:15:29 +0000562lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
563{
564 struct ospf_neighbor *dr;
565 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000566 u_int16_t cost = ospf_link_cost (oi);
567
paul718e3742002-12-13 20:15:29 +0000568 /* Describe Type 3 Link. */
569 if (oi->state == ISM_Waiting)
570 {
571 masklen2ip (oi->address->prefixlen, &mask);
572 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000573 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
574 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000575 }
576
577 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
578 /* Describe Type 2 link. */
579 if (dr && (dr->state == NSM_Full ||
580 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000581 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000582 {
paul779adb02006-01-18 15:07:38 +0000583 return link_info_set (s, DR (oi), oi->address->u.prefix4,
584 LSA_LINK_TYPE_TRANSIT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000585 }
586 /* Describe type 3 link. */
587 else
588 {
589 masklen2ip (oi->address->prefixlen, &mask);
590 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000591 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
592 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000593 }
paul718e3742002-12-13 20:15:29 +0000594}
595
paul4dadc292005-05-06 21:37:42 +0000596static int
paul718e3742002-12-13 20:15:29 +0000597lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
598{
599 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000600
paul718e3742002-12-13 20:15:29 +0000601 /* Describe Type 3 Link. */
602 if (oi->state != ISM_Loopback)
603 return 0;
604
605 mask.s_addr = 0xffffffff;
606 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000607 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000608}
609
610/* Describe Virtual Link. */
paul4dadc292005-05-06 21:37:42 +0000611static int
paul718e3742002-12-13 20:15:29 +0000612lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
613{
614 struct ospf_neighbor *nbr;
paul88d6cf32005-10-29 12:50:09 +0000615 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000616
paul718e3742002-12-13 20:15:29 +0000617 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000618 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000619 if (nbr->state == NSM_Full)
620 {
paul779adb02006-01-18 15:07:38 +0000621 return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
622 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
paul718e3742002-12-13 20:15:29 +0000623 }
624
625 return 0;
626}
627
628#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
629
paul7afa08d2002-12-13 20:59:45 +0000630/* this function add for support point-to-multipoint ,see rfc2328
63112.4.1.4.*/
632/* from "edward rrr" <edward_rrr@hotmail.com>
633 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul4dadc292005-05-06 21:37:42 +0000634static int
paul68980082003-03-25 05:07:42 +0000635lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000636{
637 int links = 0;
638 struct route_node *rn;
639 struct ospf_neighbor *nbr = NULL;
640 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000641 u_int16_t cost = ospf_link_cost (oi);
paul7afa08d2002-12-13 20:59:45 +0000642
643 mask.s_addr = 0xffffffff;
644 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000645 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
paul7afa08d2002-12-13 20:59:45 +0000646
paul1cc8f762003-04-05 19:34:32 +0000647 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000648 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000649
650 /* Search neighbor, */
651 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
652 if ((nbr = rn->info) != NULL)
653 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000654 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000655 if (nbr->state == NSM_Full)
656
657 {
paul779adb02006-01-18 15:07:38 +0000658 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
659 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul1cc8f762003-04-05 19:34:32 +0000660 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000661 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000662 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000663 }
664
665 return links;
paul7afa08d2002-12-13 20:59:45 +0000666}
667
paul718e3742002-12-13 20:15:29 +0000668/* Set router-LSA link information. */
paul4dadc292005-05-06 21:37:42 +0000669static int
paul718e3742002-12-13 20:15:29 +0000670router_lsa_link_set (struct stream *s, struct ospf_area *area)
671{
hasso52dc7ee2004-09-23 19:18:23 +0000672 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000673 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000674 int links = 0;
675
paul1eb8ef22005-04-07 07:30:20 +0000676 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +0000677 {
paul718e3742002-12-13 20:15:29 +0000678 struct interface *ifp = oi->ifp;
679
680 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000681 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000682 {
683 if (oi->state != ISM_Down)
684 {
Joakim Tjernlundc81ee5c2012-07-07 17:06:11 +0200685 oi->lsa_pos_beg = links;
paul718e3742002-12-13 20:15:29 +0000686 /* Describe each link. */
687 switch (oi->type)
688 {
689 case OSPF_IFTYPE_POINTOPOINT:
690 links += lsa_link_ptop_set (s, oi);
691 break;
692 case OSPF_IFTYPE_BROADCAST:
693 links += lsa_link_broadcast_set (s, oi);
694 break;
695 case OSPF_IFTYPE_NBMA:
696 links += lsa_link_nbma_set (s, oi);
697 break;
698 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000699 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000700 break;
701 case OSPF_IFTYPE_VIRTUALLINK:
702 links += lsa_link_virtuallink_set (s, oi);
703 break;
704 case OSPF_IFTYPE_LOOPBACK:
705 links += lsa_link_loopback_set (s, oi);
706 }
Joakim Tjernlundc81ee5c2012-07-07 17:06:11 +0200707 oi->lsa_pos_end = links;
paul718e3742002-12-13 20:15:29 +0000708 }
709 }
710 }
711
712 return links;
713}
714
715/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000716static void
paul718e3742002-12-13 20:15:29 +0000717ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
718{
719 unsigned long putp;
720 u_int16_t cnt;
721
722 /* Set flags. */
723 stream_putc (s, router_lsa_flags (area));
724
725 /* Set Zero fields. */
726 stream_putc (s, 0);
727
728 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000729 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000730
731 /* Forward word */
732 stream_putw(s, 0);
733
734 /* Set all link information. */
735 cnt = router_lsa_link_set (s, area);
736
737 /* Set # of links here. */
738 stream_putw_at (s, putp, cnt);
739}
paul88d6cf32005-10-29 12:50:09 +0000740
741static int
742ospf_stub_router_timer (struct thread *t)
743{
744 struct ospf_area *area = THREAD_ARG (t);
745
746 area->t_stub_router = NULL;
747
748 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
749
750 /* clear stub route state and generate router-lsa refresh, don't
751 * clobber an administratively set stub-router state though.
752 */
753 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
754 return 0;
755
756 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
757
Paul Jakmac363d382010-01-24 22:42:13 +0000758 ospf_router_lsa_update_area (area);
paul88d6cf32005-10-29 12:50:09 +0000759
760 return 0;
761}
paul718e3742002-12-13 20:15:29 +0000762
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100763static void
paul88d6cf32005-10-29 12:50:09 +0000764ospf_stub_router_check (struct ospf_area *area)
765{
766 /* area must either be administratively configured to be stub
767 * or startup-time stub-router must be configured and we must in a pre-stub
768 * state.
769 */
770 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
771 {
772 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
773 return;
774 }
775
776 /* not admin-stubbed, check whether startup stubbing is configured and
777 * whether it's not been done yet
778 */
779 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
780 return;
781
782 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
783 {
784 /* stub-router is hence done forever for this area, even if someone
785 * tries configure it (take effect next restart).
786 */
787 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
788 return;
789 }
790
791 /* startup stub-router configured and not yet done */
792 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
793
794 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
795 area->ospf->stub_router_startup_time);
796}
797
paul718e3742002-12-13 20:15:29 +0000798/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000799static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000800ospf_router_lsa_new (struct ospf_area *area)
801{
paul68980082003-03-25 05:07:42 +0000802 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000803 struct stream *s;
804 struct lsa_header *lsah;
805 struct ospf_lsa *new;
806 int length;
807
808 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000809 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000810
paul88d6cf32005-10-29 12:50:09 +0000811 /* check whether stub-router is desired, and if this is the first
812 * router LSA.
813 */
814 ospf_stub_router_check (area);
815
paul718e3742002-12-13 20:15:29 +0000816 /* Create a stream for LSA. */
817 s = stream_new (OSPF_MAX_LSA_SIZE);
paul718e3742002-12-13 20:15:29 +0000818 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000819 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000820 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000821
822 /* Set router-LSA body fields. */
823 ospf_router_lsa_body_set (s, area);
824
825 /* Set length. */
826 length = stream_get_endp (s);
paul779adb02006-01-18 15:07:38 +0000827 lsah = (struct lsa_header *) STREAM_DATA (s);
paul718e3742002-12-13 20:15:29 +0000828 lsah->length = htons (length);
829
830 /* Now, create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000831 if ( (new = ospf_lsa_new ()) == NULL)
832 {
833 zlog_err ("%s: Unable to create new lsa", __func__);
834 return NULL;
835 }
836
paul718e3742002-12-13 20:15:29 +0000837 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +0000838 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +0000839
840 /* Copy LSA data to store, discard stream. */
841 new->data = ospf_lsa_data_new (length);
842 memcpy (new->data, lsah, length);
843 stream_free (s);
844
845 return new;
846}
847
848/* Originate Router-LSA. */
paul88d6cf32005-10-29 12:50:09 +0000849static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000850ospf_router_lsa_originate (struct ospf_area *area)
851{
852 struct ospf_lsa *new;
paul88d6cf32005-10-29 12:50:09 +0000853
paul718e3742002-12-13 20:15:29 +0000854 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000855 if ( (new = ospf_router_lsa_new (area)) == NULL)
856 {
857 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
858 return NULL;
859 }
paul718e3742002-12-13 20:15:29 +0000860
861 /* Sanity check. */
862 if (new->data->adv_router.s_addr == 0)
863 {
864 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000865 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000866 ospf_lsa_discard (new);
867 return NULL;
868 }
869
870 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000871 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000872
873 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000874 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000875
876 /* Flooding new LSA through area. */
877 ospf_flood_through_area (area, NULL, new);
878
879 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
880 {
ajse588f212004-12-08 18:12:06 +0000881 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
paul718e3742002-12-13 20:15:29 +0000882 new->data->type, inet_ntoa (new->data->id), new);
883 ospf_lsa_header_dump (new->data);
884 }
885
886 return new;
887}
888
889/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000890static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000891ospf_router_lsa_refresh (struct ospf_lsa *lsa)
892{
893 struct ospf_area *area = lsa->area;
894 struct ospf_lsa *new;
895
896 /* Sanity check. */
897 assert (lsa->data);
898
899 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000900 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000901
Paul Jakmac363d382010-01-24 22:42:13 +0000902 /* Unregister LSA from refresh-list */
903 ospf_refresher_unregister_lsa (area->ospf, lsa);
904
paul718e3742002-12-13 20:15:29 +0000905 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000906 if ( (new = ospf_router_lsa_new (area)) == NULL)
907 {
908 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
909 return NULL;
910 }
911
paul718e3742002-12-13 20:15:29 +0000912 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
913
paul68980082003-03-25 05:07:42 +0000914 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000915
916 /* Flood LSA through area. */
917 ospf_flood_through_area (area, NULL, new);
918
919 /* Debug logging. */
920 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
921 {
ajse588f212004-12-08 18:12:06 +0000922 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000923 new->data->type, inet_ntoa (new->data->id));
924 ospf_lsa_header_dump (new->data);
925 }
926
927 return NULL;
928}
929
Paul Jakmac363d382010-01-24 22:42:13 +0000930int
931ospf_router_lsa_update_area (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000932{
paul718e3742002-12-13 20:15:29 +0000933 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmac363d382010-01-24 22:42:13 +0000934 zlog_debug ("[router-LSA]: (router-LSA area update)");
paul718e3742002-12-13 20:15:29 +0000935
936 /* Now refresh router-LSA. */
937 if (area->router_lsa_self)
Paul Jakmac363d382010-01-24 22:42:13 +0000938 ospf_lsa_refresh (area->ospf, area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000939 /* Newly originate router-LSA. */
940 else
941 ospf_router_lsa_originate (area);
942
943 return 0;
944}
945
paul718e3742002-12-13 20:15:29 +0000946int
Paul Jakmac363d382010-01-24 22:42:13 +0000947ospf_router_lsa_update (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000948{
paul1eb8ef22005-04-07 07:30:20 +0000949 struct listnode *node, *nnode;
950 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +0000951
952 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000953 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +0000954
paul1eb8ef22005-04-07 07:30:20 +0000955 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000956 {
paul718e3742002-12-13 20:15:29 +0000957 struct ospf_lsa *lsa = area->router_lsa_self;
958 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +0000959 const char *area_str;
paul718e3742002-12-13 20:15:29 +0000960
961 /* Keep Area ID string. */
962 area_str = AREA_NAME (area);
963
964 /* If LSA not exist in this Area, originate new. */
965 if (lsa == NULL)
966 {
967 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000968 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +0000969
970 ospf_router_lsa_originate (area);
971 }
972 /* If router-ID is changed, Link ID must change.
973 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +0000974 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000975 {
976 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000977 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +0000978 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
Paul Jakmadfbd5172010-04-14 10:32:12 +0100979 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +0000980 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000981 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000982 area->router_lsa_self = NULL;
983
984 /* Refresh router-LSA, (not install) and flood through area. */
Paul Jakmac363d382010-01-24 22:42:13 +0000985 ospf_router_lsa_update_area (area);
paul718e3742002-12-13 20:15:29 +0000986 }
987 else
988 {
989 rl = (struct router_lsa *) lsa->data;
990 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +0000991 if (rl->flags != ospf->flags)
Paul Jakmac363d382010-01-24 22:42:13 +0000992 ospf_router_lsa_update_area (area);
paul718e3742002-12-13 20:15:29 +0000993 }
994 }
995
996 return 0;
997}
998
999
1000/* network-LSA related functions. */
1001/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001002static void
paul718e3742002-12-13 20:15:29 +00001003ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1004{
1005 struct in_addr mask;
1006 struct route_node *rn;
1007 struct ospf_neighbor *nbr;
1008
1009 masklen2ip (oi->address->prefixlen, &mask);
1010 stream_put_ipv4 (s, mask.s_addr);
1011
1012 /* The network-LSA lists those routers that are fully adjacent to
1013 the Designated Router; each fully adjacent router is identified by
1014 its OSPF Router ID. The Designated Router includes itself in this
1015 list. RFC2328, Section 12.4.2 */
1016
1017 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1018 if ((nbr = rn->info) != NULL)
1019 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1020 stream_put_ipv4 (s, nbr->router_id.s_addr);
1021}
1022
paul4dadc292005-05-06 21:37:42 +00001023static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001024ospf_network_lsa_new (struct ospf_interface *oi)
1025{
1026 struct stream *s;
1027 struct ospf_lsa *new;
1028 struct lsa_header *lsah;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001029 struct ospf_if_params *oip;
paul718e3742002-12-13 20:15:29 +00001030 int length;
1031
1032 /* If there are no neighbours on this network (the net is stub),
1033 the router does not originate network-LSA (see RFC 12.4.2) */
1034 if (oi->full_nbrs == 0)
1035 return NULL;
1036
1037 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001038 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001039
1040 /* Create new stream for LSA. */
1041 s = stream_new (OSPF_MAX_LSA_SIZE);
1042 lsah = (struct lsa_header *) STREAM_DATA (s);
1043
1044 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001045 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001046
1047 /* Set network-LSA body fields. */
1048 ospf_network_lsa_body_set (s, oi);
1049
1050 /* Set length. */
1051 length = stream_get_endp (s);
1052 lsah->length = htons (length);
1053
1054 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001055 if ( (new = ospf_lsa_new ()) == NULL)
1056 {
1057 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1058 return NULL;
1059 }
1060
paul718e3742002-12-13 20:15:29 +00001061 new->area = oi->area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001062 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001063
1064 /* Copy LSA to store. */
1065 new->data = ospf_lsa_data_new (length);
1066 memcpy (new->data, lsah, length);
1067 stream_free (s);
Paul Jakma7eb5b472009-10-13 16:13:13 +01001068
1069 /* Remember prior network LSA sequence numbers, even if we stop
1070 * originating one for this oi, to try avoid re-originating LSAs with a
1071 * prior sequence number, and thus speed up adjency forming & convergence.
1072 */
1073 if ((oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4)))
1074 {
1075 new->data->ls_seqnum = oip->network_lsa_seqnum;
1076 new->data->ls_seqnum = lsa_seqnum_increment (new);
1077 }
1078 else
1079 {
1080 oip = ospf_get_if_params (oi->ifp, oi->address->u.prefix4);
1081 ospf_if_update_params (oi->ifp, oi->address->u.prefix4);
1082 }
1083 oip->network_lsa_seqnum = new->data->ls_seqnum;
1084
paul718e3742002-12-13 20:15:29 +00001085 return new;
1086}
1087
1088/* Originate network-LSA. */
Paul Jakmac363d382010-01-24 22:42:13 +00001089void
1090ospf_network_lsa_update (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001091{
1092 struct ospf_lsa *new;
Paul Jakmac363d382010-01-24 22:42:13 +00001093
1094 if (oi->network_lsa_self != NULL)
1095 {
1096 ospf_lsa_refresh (oi->ospf, oi->network_lsa_self);
1097 return;
1098 }
1099
paul718e3742002-12-13 20:15:29 +00001100 /* Create new network-LSA instance. */
1101 new = ospf_network_lsa_new (oi);
1102 if (new == NULL)
Paul Jakmac363d382010-01-24 22:42:13 +00001103 return;
paul718e3742002-12-13 20:15:29 +00001104
1105 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001106 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001107
1108 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001109 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001110
1111 /* Flooding new LSA through area. */
1112 ospf_flood_through_area (oi->area, NULL, new);
1113
1114 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1115 {
ajse588f212004-12-08 18:12:06 +00001116 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
paul718e3742002-12-13 20:15:29 +00001117 new->data->type, inet_ntoa (new->data->id), new);
1118 ospf_lsa_header_dump (new->data);
1119 }
1120
Paul Jakmac363d382010-01-24 22:42:13 +00001121 return;
paul718e3742002-12-13 20:15:29 +00001122}
1123
Paul Jakmac363d382010-01-24 22:42:13 +00001124static struct ospf_lsa *
1125ospf_network_lsa_refresh (struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001126{
1127 struct ospf_area *area = lsa->area;
Paul Jakmac363d382010-01-24 22:42:13 +00001128 struct ospf_lsa *new, *new2;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001129 struct ospf_if_params *oip;
Paul Jakma4dd87df2010-04-15 08:11:51 +01001130 struct ospf_interface *oi;
Paul Jakmac363d382010-01-24 22:42:13 +00001131
paul718e3742002-12-13 20:15:29 +00001132 assert (lsa->data);
Paul Jakma4dd87df2010-04-15 08:11:51 +01001133
1134 /* Retrieve the oi for the network LSA */
1135 oi = ospf_if_lookup_by_local_addr (area->ospf, NULL, lsa->data->id);
1136 if (oi == NULL)
1137 {
1138 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1139 {
1140 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh: "
1141 "no oi found, ick, ignoring.",
1142 lsa->data->type, inet_ntoa (lsa->data->id));
1143 ospf_lsa_header_dump (lsa->data);
1144 }
1145 return NULL;
1146 }
paul718e3742002-12-13 20:15:29 +00001147 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001148 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001149
Paul Jakmac363d382010-01-24 22:42:13 +00001150 /* Unregister LSA from refresh-list */
1151 ospf_refresher_unregister_lsa (area->ospf, lsa);
1152
paul718e3742002-12-13 20:15:29 +00001153 /* Create new network-LSA instance. */
1154 new = ospf_network_lsa_new (oi);
1155 if (new == NULL)
Paul Jakmac363d382010-01-24 22:42:13 +00001156 return NULL;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001157
1158 oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4);
1159 assert (oip != NULL);
1160 oip->network_lsa_seqnum = new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001161
Paul Jakmac363d382010-01-24 22:42:13 +00001162 new2 = ospf_lsa_install (area->ospf, oi, new);
1163
1164 assert (new2 == new);
1165
paul718e3742002-12-13 20:15:29 +00001166 /* Flood LSA through aera. */
1167 ospf_flood_through_area (area, NULL, new);
1168
1169 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1170 {
ajse588f212004-12-08 18:12:06 +00001171 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001172 new->data->type, inet_ntoa (new->data->id));
1173 ospf_lsa_header_dump (new->data);
1174 }
1175
Paul Jakmac363d382010-01-24 22:42:13 +00001176 return new;
paul718e3742002-12-13 20:15:29 +00001177}
paul718e3742002-12-13 20:15:29 +00001178
paul4dadc292005-05-06 21:37:42 +00001179static void
paul718e3742002-12-13 20:15:29 +00001180stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1181{
1182 u_int32_t metric;
1183 char *mp;
1184
1185 /* Put 0 metric. TOS metric is not supported. */
1186 metric = htonl (metric_value);
1187 mp = (char *) &metric;
1188 mp++;
1189 stream_put (s, mp, 3);
1190}
1191
1192/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001193static void
paul718e3742002-12-13 20:15:29 +00001194ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1195 u_int32_t metric)
1196{
1197 struct in_addr mask;
1198
1199 masklen2ip (p->prefixlen, &mask);
1200
1201 /* Put Network Mask. */
1202 stream_put_ipv4 (s, mask.s_addr);
1203
1204 /* Set # TOS. */
1205 stream_putc (s, (u_char) 0);
1206
1207 /* Set metric. */
1208 stream_put_ospf_metric (s, metric);
1209}
1210
paul4dadc292005-05-06 21:37:42 +00001211static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001212ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1213 u_int32_t metric, struct in_addr id)
1214{
1215 struct stream *s;
1216 struct ospf_lsa *new;
1217 struct lsa_header *lsah;
1218 int length;
1219
paulc24d6022005-11-20 14:54:12 +00001220 if (id.s_addr == 0xffffffff)
1221 {
1222 /* Maybe Link State ID not available. */
1223 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1224 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1225 OSPF_SUMMARY_LSA);
1226 return NULL;
1227 }
1228
paul718e3742002-12-13 20:15:29 +00001229 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001230 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001231
1232 /* Create new stream for LSA. */
1233 s = stream_new (OSPF_MAX_LSA_SIZE);
1234 lsah = (struct lsa_header *) STREAM_DATA (s);
1235
paul68980082003-03-25 05:07:42 +00001236 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1237 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001238
1239 /* Set summary-LSA body fields. */
1240 ospf_summary_lsa_body_set (s, p, metric);
1241
1242 /* Set length. */
1243 length = stream_get_endp (s);
1244 lsah->length = htons (length);
1245
1246 /* Create OSPF LSA instance. */
1247 new = ospf_lsa_new ();
1248 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001249 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001250
1251 /* Copy LSA to store. */
1252 new->data = ospf_lsa_data_new (length);
1253 memcpy (new->data, lsah, length);
1254 stream_free (s);
1255
1256 return new;
1257}
1258
1259/* Originate Summary-LSA. */
1260struct ospf_lsa *
1261ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1262 struct ospf_area *area)
1263{
1264 struct ospf_lsa *new;
1265 struct in_addr id;
1266
paul68980082003-03-25 05:07:42 +00001267 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001268
paulc24d6022005-11-20 14:54:12 +00001269 if (id.s_addr == 0xffffffff)
1270 {
1271 /* Maybe Link State ID not available. */
1272 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1273 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1274 OSPF_SUMMARY_LSA);
1275 return NULL;
1276 }
1277
paul718e3742002-12-13 20:15:29 +00001278 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001279 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1280 return NULL;
paul718e3742002-12-13 20:15:29 +00001281
1282 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001283 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001284
1285 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001286 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001287
1288 /* Flooding new LSA through area. */
1289 ospf_flood_through_area (area, NULL, new);
1290
1291 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1292 {
ajse588f212004-12-08 18:12:06 +00001293 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
paul718e3742002-12-13 20:15:29 +00001294 new->data->type, inet_ntoa (new->data->id), new);
1295 ospf_lsa_header_dump (new->data);
1296 }
1297
1298 return new;
1299}
1300
Paul Jakmac363d382010-01-24 22:42:13 +00001301static struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001302ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001303{
1304 struct ospf_lsa *new;
1305 struct summary_lsa *sl;
1306 struct prefix p;
1307
1308 /* Sanity check. */
1309 assert (lsa->data);
1310
1311 sl = (struct summary_lsa *)lsa->data;
1312 p.prefixlen = ip_masklen (sl->mask);
1313 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1314 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001315
1316 if (!new)
1317 return NULL;
1318
paul718e3742002-12-13 20:15:29 +00001319 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001320
paul68980082003-03-25 05:07:42 +00001321 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001322
1323 /* Flood LSA through AS. */
1324 ospf_flood_through_area (new->area, NULL, new);
1325
1326 /* Debug logging. */
1327 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1328 {
ajse588f212004-12-08 18:12:06 +00001329 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001330 new->data->type, inet_ntoa (new->data->id));
1331 ospf_lsa_header_dump (new->data);
1332 }
1333
1334 return new;
1335}
1336
1337
1338/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001339static void
paul718e3742002-12-13 20:15:29 +00001340ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1341 u_int32_t metric)
1342{
1343 struct in_addr mask;
1344
1345 masklen2ip (p->prefixlen, &mask);
1346
1347 /* Put Network Mask. */
1348 stream_put_ipv4 (s, mask.s_addr);
1349
1350 /* Set # TOS. */
1351 stream_putc (s, (u_char) 0);
1352
1353 /* Set metric. */
1354 stream_put_ospf_metric (s, metric);
1355}
1356
paul4dadc292005-05-06 21:37:42 +00001357static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001358ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1359 u_int32_t metric, struct in_addr id)
1360{
1361 struct stream *s;
1362 struct ospf_lsa *new;
1363 struct lsa_header *lsah;
1364 int length;
1365
paulc24d6022005-11-20 14:54:12 +00001366 if (id.s_addr == 0xffffffff)
1367 {
1368 /* Maybe Link State ID not available. */
1369 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1370 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1371 OSPF_ASBR_SUMMARY_LSA);
1372 return NULL;
1373 }
1374
paul718e3742002-12-13 20:15:29 +00001375 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001376 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001377
1378 /* Create new stream for LSA. */
1379 s = stream_new (OSPF_MAX_LSA_SIZE);
1380 lsah = (struct lsa_header *) STREAM_DATA (s);
1381
paul68980082003-03-25 05:07:42 +00001382 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1383 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001384
1385 /* Set summary-LSA body fields. */
1386 ospf_summary_asbr_lsa_body_set (s, p, metric);
1387
1388 /* Set length. */
1389 length = stream_get_endp (s);
1390 lsah->length = htons (length);
1391
1392 /* Create OSPF LSA instance. */
1393 new = ospf_lsa_new ();
1394 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001395 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001396
1397 /* Copy LSA to store. */
1398 new->data = ospf_lsa_data_new (length);
1399 memcpy (new->data, lsah, length);
1400 stream_free (s);
1401
1402 return new;
1403}
1404
1405/* Originate summary-ASBR-LSA. */
1406struct ospf_lsa *
1407ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1408 struct ospf_area *area)
1409{
1410 struct ospf_lsa *new;
1411 struct in_addr id;
1412
paul68980082003-03-25 05:07:42 +00001413 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001414
paulc24d6022005-11-20 14:54:12 +00001415 if (id.s_addr == 0xffffffff)
1416 {
1417 /* Maybe Link State ID not available. */
1418 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1419 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1420 OSPF_ASBR_SUMMARY_LSA);
1421 return NULL;
1422 }
1423
paul718e3742002-12-13 20:15:29 +00001424 /* Create new summary-LSA instance. */
1425 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001426 if (!new)
1427 return NULL;
paul718e3742002-12-13 20:15:29 +00001428
1429 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001430 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001431
1432 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001433 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001434
1435 /* Flooding new LSA through area. */
1436 ospf_flood_through_area (area, NULL, new);
1437
1438 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1439 {
ajse588f212004-12-08 18:12:06 +00001440 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001441 new->data->type, inet_ntoa (new->data->id), new);
1442 ospf_lsa_header_dump (new->data);
1443 }
1444
1445 return new;
1446}
1447
Paul Jakmac363d382010-01-24 22:42:13 +00001448static struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001449ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001450{
1451 struct ospf_lsa *new;
1452 struct summary_lsa *sl;
1453 struct prefix p;
1454
1455 /* Sanity check. */
1456 assert (lsa->data);
1457
1458 sl = (struct summary_lsa *)lsa->data;
1459 p.prefixlen = ip_masklen (sl->mask);
1460 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1461 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001462 if (!new)
1463 return NULL;
paul718e3742002-12-13 20:15:29 +00001464
1465 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001466
paul68980082003-03-25 05:07:42 +00001467 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001468
1469 /* Flood LSA through area. */
1470 ospf_flood_through_area (new->area, NULL, new);
1471
1472 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1473 {
ajse588f212004-12-08 18:12:06 +00001474 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001475 new->data->type, inet_ntoa (new->data->id));
1476 ospf_lsa_header_dump (new->data);
1477 }
1478
1479 return new;
1480}
1481
1482/* AS-external-LSA related functions. */
1483
1484/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1485 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001486static struct in_addr
paul68980082003-03-25 05:07:42 +00001487ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001488{
1489 struct in_addr fwd;
1490 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001491 struct listnode *node;
1492 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001493
1494 fwd.s_addr = 0;
1495
1496 if (!nexthop.s_addr)
1497 return fwd;
1498
1499 /* Check whether nexthop is covered by OSPF network. */
1500 nh.family = AF_INET;
1501 nh.u.prefix4 = nexthop;
1502 nh.prefixlen = IPV4_MAX_BITLEN;
Paul Jakma4ca15d42009-08-03 15:16:41 +01001503
1504 /* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be
1505 * better to make use of the per-ifp table of ois.
1506 */
paul1eb8ef22005-04-07 07:30:20 +00001507 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1508 if (if_is_operative (oi->ifp))
1509 if (oi->address->family == AF_INET)
1510 if (prefix_match (oi->address, &nh))
1511 return nexthop;
paul718e3742002-12-13 20:15:29 +00001512
1513 return fwd;
1514}
1515
paul718e3742002-12-13 20:15:29 +00001516/* NSSA-external-LSA related functions. */
1517
1518/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001519
paul718e3742002-12-13 20:15:29 +00001520struct in_addr
1521ospf_get_ip_from_ifp (struct ospf_interface *oi)
1522{
1523 struct in_addr fwd;
1524
1525 fwd.s_addr = 0;
1526
paul2e3b2e42002-12-13 21:03:13 +00001527 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001528 return oi->address->u.prefix4;
1529
1530 return fwd;
1531}
1532
1533/* Get 1st IP connection for Forward Addr */
1534struct in_addr
paulf2c80652002-12-13 21:44:27 +00001535ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001536{
1537 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001538 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001539 struct listnode *node;
1540 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001541
1542 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001543 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001544
paul1eb8ef22005-04-07 07:30:20 +00001545 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001546 {
paul2e3b2e42002-12-13 21:03:13 +00001547 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001548 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001549 if (oi->address && oi->address->family == AF_INET)
1550 {
1551 if (best_default.s_addr == 0)
1552 best_default = oi->address->u.prefix4;
1553 if (oi->area == area)
1554 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001555 }
paul718e3742002-12-13 20:15:29 +00001556 }
paulf2c80652002-12-13 21:44:27 +00001557 if (best_default.s_addr != 0)
1558 return best_default;
paul718e3742002-12-13 20:15:29 +00001559
paul68980082003-03-25 05:07:42 +00001560 if (best_default.s_addr != 0)
1561 return best_default;
1562
paul718e3742002-12-13 20:15:29 +00001563 return fwd;
1564}
hassobeebba72004-06-20 21:00:27 +00001565
paul718e3742002-12-13 20:15:29 +00001566#define DEFAULT_DEFAULT_METRIC 20
1567#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1568#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1569
1570#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1571
1572int
paul68980082003-03-25 05:07:42 +00001573metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001574{
paul68980082003-03-25 05:07:42 +00001575 return (ospf->dmetric[src].type < 0 ?
1576 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001577}
1578
1579int
paul68980082003-03-25 05:07:42 +00001580metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001581{
paul68980082003-03-25 05:07:42 +00001582 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001583 {
1584 if (src == DEFAULT_ROUTE)
1585 {
paul68980082003-03-25 05:07:42 +00001586 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001587 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1588 else
1589 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1590 }
paul68980082003-03-25 05:07:42 +00001591 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001592 return DEFAULT_DEFAULT_METRIC;
1593 else
paul68980082003-03-25 05:07:42 +00001594 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001595 }
1596
paul68980082003-03-25 05:07:42 +00001597 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001598}
1599
1600/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001601static void
paul68980082003-03-25 05:07:42 +00001602ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1603 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001604{
1605 struct prefix_ipv4 *p = &ei->p;
1606 struct in_addr mask, fwd_addr;
1607 u_int32_t mvalue;
1608 int mtype;
1609 int type;
1610
1611 /* Put Network Mask. */
1612 masklen2ip (p->prefixlen, &mask);
1613 stream_put_ipv4 (s, mask.s_addr);
1614
1615 /* If prefix is default, specify DEFAULT_ROUTE. */
1616 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1617
1618 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001619 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001620
1621 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001622 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001623
1624 /* Put type of external metric. */
1625 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1626
1627 /* Put 0 metric. TOS metric is not supported. */
1628 stream_put_ospf_metric (s, mvalue);
1629
1630 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001631 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001632
1633 /* Put forwarding address. */
1634 stream_put_ipv4 (s, fwd_addr.s_addr);
1635
1636 /* Put route tag -- This value should be introduced from configuration. */
1637 stream_putl (s, 0);
1638}
1639
1640/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001641static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001642ospf_external_lsa_new (struct ospf *ospf,
1643 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001644{
1645 struct stream *s;
1646 struct lsa_header *lsah;
1647 struct ospf_lsa *new;
1648 struct in_addr id;
1649 int length;
1650
1651 if (ei == NULL)
1652 {
1653 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
Denis Ovsienkoad8d4802011-12-02 20:02:40 +04001654 zlog_debug ("LSA[Type5]: External info is NULL, can't originate");
paul718e3742002-12-13 20:15:29 +00001655 return NULL;
1656 }
1657
1658 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001659 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001660
1661 /* If old Link State ID is specified, refresh LSA with same ID. */
1662 if (old_id)
1663 id = *old_id;
1664 /* Get Link State with unique ID. */
1665 else
1666 {
paul68980082003-03-25 05:07:42 +00001667 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001668 if (id.s_addr == 0xffffffff)
1669 {
1670 /* Maybe Link State ID not available. */
1671 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001672 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001673 return NULL;
1674 }
1675 }
1676
1677 /* Create new stream for LSA. */
1678 s = stream_new (OSPF_MAX_LSA_SIZE);
1679 lsah = (struct lsa_header *) STREAM_DATA (s);
1680
1681 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001682 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1683 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001684
1685 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001686 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001687
1688 /* Set length. */
1689 length = stream_get_endp (s);
1690 lsah->length = htons (length);
1691
1692 /* Now, create OSPF LSA instance. */
1693 new = ospf_lsa_new ();
1694 new->area = NULL;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001695 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001696
1697 /* Copy LSA data to store, discard stream. */
1698 new->data = ospf_lsa_data_new (length);
1699 memcpy (new->data, lsah, length);
1700 stream_free (s);
1701
1702 return new;
1703}
1704
paul718e3742002-12-13 20:15:29 +00001705/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001706static void
paul68980082003-03-25 05:07:42 +00001707ospf_install_flood_nssa (struct ospf *ospf,
1708 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001709{
pauld4a53d52003-07-12 21:30:57 +00001710 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001711 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001712 struct ospf_area *area;
1713 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001714
pauld4a53d52003-07-12 21:30:57 +00001715 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1716 * which originated from an NSSA area. In which case it should not be
1717 * flooded back to NSSA areas.
1718 */
1719 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1720 return;
1721
paul718e3742002-12-13 20:15:29 +00001722 /* NSSA Originate or Refresh (If anyNSSA)
1723
1724 LSA is self-originated. And just installed as Type-5.
1725 Additionally, install as Type-7 LSDB for every attached NSSA.
1726
1727 P-Bit controls which ABR performs translation to outside world; If
1728 we are an ABR....do not set the P-bit, because we send the Type-5,
1729 not as the ABR Translator, but as the ASBR owner within the AS!
1730
1731 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1732 elected ABR Translator will see the P-bit, Translate, and re-flood.
1733
1734 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1735 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1736
paul1eb8ef22005-04-07 07:30:20 +00001737 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001738 {
hasso0c14ad82003-07-03 08:36:02 +00001739 /* Don't install Type-7 LSA's into nonNSSA area */
1740 if (area->external_routing != OSPF_AREA_NSSA)
1741 continue;
paul718e3742002-12-13 20:15:29 +00001742
paul68980082003-03-25 05:07:42 +00001743 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001744 new = ospf_lsa_dup (lsa);
1745 new->area = area;
1746 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001747
paul68980082003-03-25 05:07:42 +00001748 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001749 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001750 {
pauld4a53d52003-07-12 21:30:57 +00001751 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001752
1753 /* set non-zero FWD ADDR
1754
1755 draft-ietf-ospf-nssa-update-09.txt
1756
1757 if the network between the NSSA AS boundary router and the
1758 adjacent AS is advertised into OSPF as an internal OSPF route,
1759 the forwarding address should be the next op address as is cu
1760 currently done with type-5 LSAs. If the intervening network is
1761 not adversited into OSPF as an internal OSPF route and the
1762 type-7 LSA's P-bit is set a forwarding address should be
1763 selected from one of the router's active OSPF inteface addresses
1764 which belong to the NSSA. If no such addresses exist, then
1765 no type-7 LSA's with the P-bit set should originate from this
1766 router. */
1767
pauld4a53d52003-07-12 21:30:57 +00001768 /* kevinm: not updating lsa anymore, just new */
1769 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001770
1771 if (extlsa->e[0].fwd_addr.s_addr == 0)
1772 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001773
pauld7480322003-05-16 17:31:51 +00001774 if (extlsa->e[0].fwd_addr.s_addr == 0)
1775 {
1776 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001777 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001778 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001779 return;
1780 }
paulf2c80652002-12-13 21:44:27 +00001781 }
paul718e3742002-12-13 20:15:29 +00001782
paul68980082003-03-25 05:07:42 +00001783 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001784 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001785
1786 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001787 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001788 }
paul718e3742002-12-13 20:15:29 +00001789}
pauld4a53d52003-07-12 21:30:57 +00001790
paul4dadc292005-05-06 21:37:42 +00001791static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001792ospf_lsa_translated_nssa_new (struct ospf *ospf,
1793 struct ospf_lsa *type7)
1794{
1795
1796 struct ospf_lsa *new;
1797 struct as_external_lsa *ext, *extnew;
1798 struct external_info ei;
1799
1800 ext = (struct as_external_lsa *)(type7->data);
1801
1802 /* need external_info struct, fill in bare minimum */
1803 ei.p.family = AF_INET;
1804 ei.p.prefix = type7->data->id;
1805 ei.p.prefixlen = ip_masklen (ext->mask);
1806 ei.type = ZEBRA_ROUTE_OSPF;
1807 ei.nexthop = ext->header.adv_router;
1808 ei.route_map_set.metric = -1;
1809 ei.route_map_set.metric_type = -1;
1810 ei.tag = 0;
1811
1812 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1813 {
1814 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001815 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001816 "Translated Type-5 for %s",
1817 inet_ntoa (ei.p.prefix));
1818 return NULL;
1819 }
1820
1821 extnew = (struct as_external_lsa *)(new->data);
1822
1823 /* copy over Type-7 data to new */
1824 extnew->e[0].tos = ext->e[0].tos;
1825 extnew->e[0].route_tag = ext->e[0].route_tag;
1826 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1827 new->data->ls_seqnum = type7->data->ls_seqnum;
1828
1829 /* add translated flag, checksum and lock new lsa */
1830 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
pauld4a53d52003-07-12 21:30:57 +00001831 new = ospf_lsa_lock (new);
1832
1833 return new;
1834}
1835
pauld4a53d52003-07-12 21:30:57 +00001836/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1837struct ospf_lsa *
1838ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1839{
1840 struct ospf_lsa *new;
1841 struct as_external_lsa *extnew;
1842
1843 /* we cant use ospf_external_lsa_originate() as we need to set
1844 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1845 */
1846
1847 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1848 {
1849 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001850 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001851 "Type-7, Id %s, to Type-5",
1852 inet_ntoa (type7->data->id));
1853 return NULL;
1854 }
1855
1856 extnew = (struct as_external_lsa *)new;
1857
1858 if (IS_DEBUG_OSPF_NSSA)
1859 {
ajse588f212004-12-08 18:12:06 +00001860 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001861 "translated Type 7, installed:");
1862 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001863 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1864 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001865 }
1866
1867 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1868 {
Hasso Tepper8c9ed272012-10-11 11:15:18 +00001869 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001870 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001871 "Could not install LSA "
1872 "id %s", inet_ntoa (type7->data->id));
1873 return NULL;
1874 }
1875
1876 ospf->lsa_originate_count++;
1877 ospf_flood_through_as (ospf, NULL, new);
1878
1879 return new;
1880}
1881
1882/* Refresh Translated from NSSA AS-external-LSA. */
1883struct ospf_lsa *
1884ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1885 struct ospf_lsa *type5)
1886{
1887 struct ospf_lsa *new = NULL;
1888
1889 /* Sanity checks. */
1890 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00001891 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00001892 return NULL;
pauld4a53d52003-07-12 21:30:57 +00001893 if (type7)
1894 assert (type7->data);
1895 if (type5)
1896 assert (type5->data);
1897 assert (ospf->anyNSSA);
1898
1899 /* get required data according to what has been given */
1900 if (type7 && type5 == NULL)
1901 {
1902 /* find the translated Type-5 for this Type-7 */
1903 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1904 struct prefix_ipv4 p =
1905 {
1906 .prefix = type7->data->id,
1907 .prefixlen = ip_masklen (ext->mask),
1908 .family = AF_INET,
1909 };
1910
1911 type5 = ospf_external_info_find_lsa (ospf, &p);
1912 }
1913 else if (type5 && type7 == NULL)
1914 {
1915 /* find the type-7 from which supplied type-5 was translated,
1916 * ie find first type-7 with same LSA Id.
1917 */
paul1eb8ef22005-04-07 07:30:20 +00001918 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00001919 struct route_node *rn;
1920 struct ospf_lsa *lsa;
1921 struct ospf_area *area;
1922
paul1eb8ef22005-04-07 07:30:20 +00001923 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00001924 {
1925 if (area->external_routing != OSPF_AREA_NSSA
1926 && !type7)
1927 continue;
1928
1929 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
1930 {
1931 if (lsa->data->id.s_addr == type5->data->id.s_addr)
1932 {
1933 type7 = lsa;
1934 break;
1935 }
1936 }
1937 }
1938 }
1939
1940 /* do we have type7? */
1941 if (!type7)
1942 {
1943 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001944 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00001945 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00001946 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00001947 return NULL;
1948 }
1949
1950 /* do we have valid translated type5? */
1951 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
1952 {
1953 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001954 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00001955 "found for Type-7 with Id %s",
1956 inet_ntoa (type7->data->id));
1957 return NULL;
1958 }
1959
1960 /* Delete LSA from neighbor retransmit-list. */
1961 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
1962
1963 /* create new translated LSA */
1964 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1965 {
1966 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001967 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001968 "Type-7 for %s to Type-5",
1969 inet_ntoa (type7->data->id));
1970 return NULL;
1971 }
1972
1973 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
1974 {
1975 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001976 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00001977 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00001978 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00001979 return NULL;
1980 }
1981
1982 /* Flood LSA through area. */
1983 ospf_flood_through_as (ospf, NULL, new);
1984
1985 return new;
1986}
paul718e3742002-12-13 20:15:29 +00001987
1988int
1989is_prefix_default (struct prefix_ipv4 *p)
1990{
1991 struct prefix_ipv4 q;
1992
1993 q.family = AF_INET;
1994 q.prefix.s_addr = 0;
1995 q.prefixlen = 0;
1996
1997 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
1998}
1999
2000/* Originate an AS-external-LSA, install and flood. */
2001struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002002ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00002003{
2004 struct ospf_lsa *new;
2005
2006 /* Added for NSSA project....
2007
2008 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2009 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2010 every area. The Type-7's are flooded to every IR and every ABR; We
2011 install the Type-5 LSDB so that the normal "refresh" code operates
2012 as usual, and flag them as not used during ASE calculations. The
2013 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2014 Address of non-zero.
2015
2016 If an ABR is the elected NSSA translator, following SPF and during
2017 the ABR task it will translate all the scanned Type-7's, with P-bit
2018 ON and not-self generated, and translate to Type-5's throughout the
2019 non-NSSA/STUB AS.
2020
2021 A difference in operation depends whether this ASBR is an ABR
2022 or not. If not an ABR, the P-bit is ON, to indicate that any
2023 elected NSSA-ABR can perform its translation.
2024
2025 If an ABR, the P-bit is OFF; No ABR will perform translation and
2026 this ASBR will flood the Type-5 LSA as usual.
2027
2028 For the case where this ASBR is not an ABR, the ASE calculations
2029 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2030 demonstrate to the user that there are LSA's that belong to any
2031 attached NSSA.
2032
2033 Finally, it just so happens that when the ABR is translating every
2034 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2035 approved Type-5 (translated from Type-7); at the end of translation
2036 if any Translated Type-5's remain unapproved, then they must be
2037 flushed from the AS.
2038
2039 */
2040
2041 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002042 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002043 return NULL;
2044
2045 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002046 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002047 {
2048 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002049 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002050 inet_ntoa (ei->p.prefix));
2051 return NULL;
2052 }
2053
2054 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002055 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002056
2057 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002058 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002059
2060 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002061 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002062
paul718e3742002-12-13 20:15:29 +00002063 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002064 if (ospf->anyNSSA &&
2065 /* stay away from translated LSAs! */
2066 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002067 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002068
2069 /* Debug logging. */
2070 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2071 {
ajse588f212004-12-08 18:12:06 +00002072 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002073 new->data->type, inet_ntoa (new->data->id), new);
2074 ospf_lsa_header_dump (new->data);
2075 }
2076
2077 return new;
2078}
2079
2080/* Originate AS-external-LSA from external info with initial flag. */
2081int
paul68980082003-03-25 05:07:42 +00002082ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002083{
paul68980082003-03-25 05:07:42 +00002084 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002085 struct route_node *rn;
2086 struct external_info *ei;
2087 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002088 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002089
paul68980082003-03-25 05:07:42 +00002090 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002091
2092 /* Originate As-external-LSA from all type of distribute source. */
2093 if ((rt = EXTERNAL_INFO (type)))
2094 for (rn = route_top (rt); rn; rn = route_next (rn))
2095 if ((ei = rn->info) != NULL)
2096 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002097 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002098 zlog_warn ("LSA: AS-external-LSA was not originated.");
2099
2100 return 0;
2101}
2102
paul4dadc292005-05-06 21:37:42 +00002103static struct external_info *
paul020709f2003-04-04 02:44:16 +00002104ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002105{
2106 int type;
2107 struct route_node *rn;
2108 struct prefix_ipv4 p;
2109
2110 p.family = AF_INET;
2111 p.prefix.s_addr = 0;
2112 p.prefixlen = 0;
2113
2114 /* First, lookup redistributed default route. */
2115 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2116 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2117 {
2118 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2119 if (rn != NULL)
2120 {
2121 route_unlock_node (rn);
2122 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002123 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002124 return rn->info;
2125 }
2126 }
2127
2128 return NULL;
2129}
2130
2131int
paul68980082003-03-25 05:07:42 +00002132ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002133{
paul718e3742002-12-13 20:15:29 +00002134 struct prefix_ipv4 p;
2135 struct in_addr nexthop;
2136 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002137 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002138
Paul Jakma4021b602006-05-12 22:55:41 +00002139 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002140
2141 p.family = AF_INET;
2142 p.prefix.s_addr = 0;
2143 p.prefixlen = 0;
2144
Paul Jakma4021b602006-05-12 22:55:41 +00002145 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002146 {
2147 /* If there is no default route via redistribute,
2148 then originate AS-external-LSA with nexthop 0 (self). */
2149 nexthop.s_addr = 0;
2150 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2151 }
2152
paul020709f2003-04-04 02:44:16 +00002153 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002154 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002155
2156 return 0;
2157}
2158
paul645878f2003-04-13 21:42:11 +00002159/* Flush any NSSA LSAs for given prefix */
2160void
2161ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2162{
paul1eb8ef22005-04-07 07:30:20 +00002163 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002164 struct ospf_lsa *lsa;
2165 struct ospf_area *area;
2166
paul1eb8ef22005-04-07 07:30:20 +00002167 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002168 {
paul1eb8ef22005-04-07 07:30:20 +00002169 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002170 {
2171 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2172 ospf->router_id)))
2173 {
2174 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002175 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002176 inet_ntoa (p->prefix), p->prefixlen);
2177 continue;
2178 }
2179 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2180 if (!IS_LSA_MAXAGE (lsa))
2181 {
2182 ospf_refresher_unregister_lsa (ospf, lsa);
2183 ospf_lsa_flush_area (lsa, area);
2184 }
2185 }
paul645878f2003-04-13 21:42:11 +00002186 }
2187}
paul645878f2003-04-13 21:42:11 +00002188
paul718e3742002-12-13 20:15:29 +00002189/* Flush an AS-external-LSA from LSDB and routing domain. */
2190void
paul68980082003-03-25 05:07:42 +00002191ospf_external_lsa_flush (struct ospf *ospf,
2192 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002193 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002194{
2195 struct ospf_lsa *lsa;
2196
2197 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002198 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002199 inet_ntoa (p->prefix), p->prefixlen);
2200
2201 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002202 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002203 {
2204 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002205 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002206 inet_ntoa (p->prefix), p->prefixlen);
2207 return;
2208 }
hassobeebba72004-06-20 21:00:27 +00002209
pauld4a53d52003-07-12 21:30:57 +00002210 /* If LSA is selforiginated, not a translated LSA, and there is
2211 * NSSA area, flush Type-7 LSA's at first.
2212 */
2213 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2214 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002215 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002216
2217 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002218 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002219
2220 /* There must be no self-originated LSA in rtrs_external. */
2221#if 0
2222 /* Remove External route from Zebra. */
2223 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2224#endif
2225
2226 if (!IS_LSA_MAXAGE (lsa))
2227 {
2228 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002229 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002230
2231 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002232 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002233 }
2234
2235 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002236 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002237}
2238
2239void
paul68980082003-03-25 05:07:42 +00002240ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002241{
2242 struct prefix_ipv4 p;
2243 struct external_info *ei;
2244 struct ospf_lsa *lsa;
2245
2246 p.family = AF_INET;
2247 p.prefixlen = 0;
2248 p.prefix.s_addr = 0;
2249
paul020709f2003-04-04 02:44:16 +00002250 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002251 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002252
2253 if (ei)
2254 {
2255 if (lsa)
2256 {
2257 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002258 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002259 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002260 }
2261 else
2262 {
2263 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002264 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002265 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002266 }
2267 }
2268 else
2269 {
2270 if (lsa)
2271 {
2272 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002273 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
Paul Jakmadfbd5172010-04-14 10:32:12 +01002274 ospf_refresher_unregister_lsa (ospf, lsa);
paul68980082003-03-25 05:07:42 +00002275 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002276 }
2277 }
2278}
2279
2280void
paul68980082003-03-25 05:07:42 +00002281ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002282{
2283 struct route_node *rn;
2284 struct external_info *ei;
2285
2286 if (type != DEFAULT_ROUTE)
2287 if (EXTERNAL_INFO(type))
2288 /* Refresh each redistributed AS-external-LSAs. */
2289 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2290 if ((ei = rn->info))
2291 if (!is_prefix_default (&ei->p))
2292 {
2293 struct ospf_lsa *lsa;
2294
paul68980082003-03-25 05:07:42 +00002295 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2296 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002297 else
paul68980082003-03-25 05:07:42 +00002298 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002299 }
2300}
2301
2302/* Refresh AS-external-LSA. */
Paul Jakmac363d382010-01-24 22:42:13 +00002303struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002304ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002305 struct external_info *ei, int force)
2306{
2307 struct ospf_lsa *new;
2308 int changed;
2309
2310 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002311 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002312 {
pauld4a53d52003-07-12 21:30:57 +00002313 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002314 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002315 "redist check fail",
2316 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002317 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002318 ei->ifindex /*, ei->nexthop */);
Paul Jakmac363d382010-01-24 22:42:13 +00002319 return NULL;
paul718e3742002-12-13 20:15:29 +00002320 }
2321
2322 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002323 {
2324 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002325 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002326 lsa->data->type, inet_ntoa (lsa->data->id));
Paul Jakmac363d382010-01-24 22:42:13 +00002327 return NULL;
pauld4a53d52003-07-12 21:30:57 +00002328 }
paul718e3742002-12-13 20:15:29 +00002329
2330 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002331 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002332
2333 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002334 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002335
paul68980082003-03-25 05:07:42 +00002336 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002337
2338 if (new == NULL)
2339 {
2340 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002341 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002342 inet_ntoa (lsa->data->id));
Paul Jakmac363d382010-01-24 22:42:13 +00002343 return NULL;
paul718e3742002-12-13 20:15:29 +00002344 }
2345
2346 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2347
paul68980082003-03-25 05:07:42 +00002348 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002349
2350 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002351 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002352
paul718e3742002-12-13 20:15:29 +00002353 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002354 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002355 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002356
pauld4a53d52003-07-12 21:30:57 +00002357 /* Register self-originated LSA to refresh queue.
2358 * Translated LSAs should not be registered, but refreshed upon
2359 * refresh of the Type-7
2360 */
2361 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2362 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002363
2364 /* Debug logging. */
2365 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2366 {
ajse588f212004-12-08 18:12:06 +00002367 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002368 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002369 ospf_lsa_header_dump (new->data);
2370 }
2371
Paul Jakmac363d382010-01-24 22:42:13 +00002372 return new;
paul718e3742002-12-13 20:15:29 +00002373}
2374
2375
2376/* LSA installation functions. */
2377
2378/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002379static struct ospf_lsa *
Paul Jakmac363d382010-01-24 22:42:13 +00002380ospf_router_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2381 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002382{
2383 struct ospf_area *area = new->area;
2384
2385 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2386 The entire routing table must be recalculated, starting with
2387 the shortest path calculations for each area (not just the
2388 area whose link-state database has changed).
2389 */
paul718e3742002-12-13 20:15:29 +00002390
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002391 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002392 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002393
2394 /* Only install LSA if it is originated/refreshed by us.
2395 * If LSA was received by flooding, the RECEIVED flag is set so do
2396 * not link the LSA */
2397 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2398 return new; /* ignore stale LSA */
2399
paul718e3742002-12-13 20:15:29 +00002400 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002401 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002402 area->router_lsa_self = ospf_lsa_lock (new);
2403
Paul Jakmac363d382010-01-24 22:42:13 +00002404 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002405 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002406 if (rt_recalc)
2407 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002408
2409 return new;
2410}
2411
2412#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2413 if (!(T)) \
2414 (T) = thread_add_timer (master, (F), oi, (V))
2415
2416/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002417static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002418ospf_network_lsa_install (struct ospf *ospf,
2419 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002420 struct ospf_lsa *new,
2421 int rt_recalc)
2422{
2423
2424 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2425 The entire routing table must be recalculated, starting with
2426 the shortest path calculations for each area (not just the
2427 area whose link-state database has changed).
2428 */
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002429 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002430 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002431 /* We supposed that when LSA is originated by us, we pass the int
2432 for which it was originated. If LSA was received by flooding,
2433 the RECEIVED flag is set, so we do not link the LSA to the int. */
2434 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2435 return new; /* ignore stale LSA */
2436
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002437 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002438 oi->network_lsa_self = ospf_lsa_lock (new);
Paul Jakmac363d382010-01-24 22:42:13 +00002439 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002440 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002441 if (rt_recalc)
2442 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002443
2444 return new;
2445}
2446
2447/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002448static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002449ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2450 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002451{
paul718e3742002-12-13 20:15:29 +00002452 if (rt_recalc && !IS_LSA_SELF (new))
2453 {
2454 /* RFC 2328 Section 13.2 Summary-LSAs
2455 The best route to the destination described by the summary-
2456 LSA must be recalculated (see Section 16.5). If this
2457 destination is an AS boundary router, it may also be
2458 necessary to re-examine all the AS-external-LSAs.
2459 */
2460
2461#if 0
2462 /* This doesn't exist yet... */
2463 ospf_summary_incremental_update(new); */
2464#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002465 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002466#endif /* #if 0 */
2467
2468 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002469 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002470 }
2471
2472 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002473 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002474
2475 return new;
2476}
2477
2478/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002479static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002480ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2481 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002482{
2483 if (rt_recalc && !IS_LSA_SELF (new))
2484 {
2485 /* RFC 2328 Section 13.2 Summary-LSAs
2486 The best route to the destination described by the summary-
2487 LSA must be recalculated (see Section 16.5). If this
2488 destination is an AS boundary router, it may also be
2489 necessary to re-examine all the AS-external-LSAs.
2490 */
2491#if 0
2492 /* These don't exist yet... */
2493 ospf_summary_incremental_update(new);
2494 /* Isn't this done by the above call?
2495 - RFC 2328 Section 16.5 implies it should be */
2496 /* ospf_ase_calculate_schedule(); */
2497#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002498 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002499#endif /* #if 0 */
2500 }
2501
2502 /* register LSA to refresh-list. */
2503 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002504 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002505
2506 return new;
2507}
2508
2509/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002510static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002511ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2512 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002513{
paul68980082003-03-25 05:07:42 +00002514 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002515 /* If LSA is not self-originated, calculate an external route. */
2516 if (rt_recalc)
2517 {
2518 /* RFC 2328 Section 13.2 AS-external-LSAs
2519 The best route to the destination described by the AS-
2520 external-LSA must be recalculated (see Section 16.6).
2521 */
2522
2523 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002524 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002525 }
2526
pauld4a53d52003-07-12 21:30:57 +00002527 if (new->data->type == OSPF_AS_NSSA_LSA)
2528 {
2529 /* There is no point to register selforiginate Type-7 LSA for
2530 * refreshing. We rely on refreshing Type-5 LSA's
2531 */
2532 if (IS_LSA_SELF (new))
2533 return new;
2534 else
2535 {
2536 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2537 * New translations will be taken care of by the abr_task.
2538 */
2539 ospf_translated_nssa_refresh (ospf, new, NULL);
2540 }
2541 }
pauld7480322003-05-16 17:31:51 +00002542
pauld4a53d52003-07-12 21:30:57 +00002543 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002544 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002545 */
hassobeebba72004-06-20 21:00:27 +00002546 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002547 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002548
2549 return new;
2550}
2551
2552void
paul68980082003-03-25 05:07:42 +00002553ospf_discard_from_db (struct ospf *ospf,
2554 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002555{
2556 struct ospf_lsa *old;
2557
Paul Jakmaac904de2006-06-15 12:04:57 +00002558 if (!lsdb)
2559 {
2560 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2561 if (!lsa)
2562 zlog_warn ("%s: and NULL LSA!", __func__);
2563 else
2564 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2565 lsa->data->type, inet_ntoa (lsa->data->id));
2566 return;
2567 }
2568
paul718e3742002-12-13 20:15:29 +00002569 old = ospf_lsdb_lookup (lsdb, lsa);
2570
2571 if (!old)
2572 return;
2573
2574 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002575 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002576
2577 switch (old->data->type)
2578 {
2579 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002580 ospf_ase_unregister_external_lsa (old, ospf);
2581 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2582 break;
paul718e3742002-12-13 20:15:29 +00002583#ifdef HAVE_OPAQUE_LSA
2584 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002585 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002586 break;
paul69310a62005-05-11 18:09:59 +00002587#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002588 case OSPF_AS_NSSA_LSA:
2589 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2590 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002591 break;
paul718e3742002-12-13 20:15:29 +00002592 default:
paul68980082003-03-25 05:07:42 +00002593 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002594 break;
2595 }
2596
paul68980082003-03-25 05:07:42 +00002597 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002598 ospf_lsa_discard (old);
2599}
2600
paul718e3742002-12-13 20:15:29 +00002601struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002602ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2603 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002604{
2605 struct ospf_lsa *new = NULL;
2606 struct ospf_lsa *old = NULL;
2607 struct ospf_lsdb *lsdb = NULL;
2608 int rt_recalc;
2609
2610 /* Set LSDB. */
2611 switch (lsa->data->type)
2612 {
paulf2c80652002-12-13 21:44:27 +00002613 /* kevinm */
2614 case OSPF_AS_NSSA_LSA:
2615 if (lsa->area)
2616 lsdb = lsa->area->lsdb;
2617 else
paul68980082003-03-25 05:07:42 +00002618 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002619 break;
paul718e3742002-12-13 20:15:29 +00002620 case OSPF_AS_EXTERNAL_LSA:
2621#ifdef HAVE_OPAQUE_LSA
2622 case OSPF_OPAQUE_AS_LSA:
2623#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002624 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002625 break;
2626 default:
2627 lsdb = lsa->area->lsdb;
2628 break;
2629 }
2630
paul718e3742002-12-13 20:15:29 +00002631 assert (lsdb);
2632
2633 /* RFC 2328 13.2. Installing LSAs in the database
2634
2635 Installing a new LSA in the database, either as the result of
2636 flooding or a newly self-originated LSA, may cause the OSPF
2637 routing table structure to be recalculated. The contents of the
2638 new LSA should be compared to the old instance, if present. If
2639 there is no difference, there is no need to recalculate the
2640 routing table. When comparing an LSA to its previous instance,
2641 the following are all considered to be differences in contents:
2642
2643 o The LSA's Options field has changed.
2644
2645 o One of the LSA instances has LS age set to MaxAge, and
2646 the other does not.
2647
2648 o The length field in the LSA header has changed.
2649
2650 o The body of the LSA (i.e., anything outside the 20-byte
2651 LSA header) has changed. Note that this excludes changes
2652 in LS Sequence Number and LS Checksum.
2653
2654 */
2655 /* Look up old LSA and determine if any SPF calculation or incremental
2656 update is needed */
2657 old = ospf_lsdb_lookup (lsdb, lsa);
2658
2659 /* Do comparision and record if recalc needed. */
2660 rt_recalc = 0;
2661 if ( old == NULL || ospf_lsa_different(old, lsa))
2662 rt_recalc = 1;
2663
paul7ddf1d62003-10-13 09:06:46 +00002664 /*
2665 Sequence number check (Section 14.1 of rfc 2328)
2666 "Premature aging is used when it is time for a self-originated
2667 LSA's sequence number field to wrap. At this point, the current
2668 LSA instance (having LS sequence number MaxSequenceNumber) must
2669 be prematurely aged and flushed from the routing domain before a
2670 new instance with sequence number equal to InitialSequenceNumber
2671 can be originated. "
2672 */
2673
Paul Jakmac2b478d2006-03-30 14:16:11 +00002674 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002675 {
2676 if (ospf_lsa_is_self_originated(ospf, lsa))
2677 {
paul0c2be262004-05-31 14:16:54 +00002678 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2679
2680 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002681 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2682 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2683
2684 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2685 {
ajse588f212004-12-08 18:12:06 +00002686 zlog_debug ("ospf_lsa_install() Premature Aging "
Paul Jakmac363d382010-01-24 22:42:13 +00002687 "lsa 0x%p, seqnum 0x%x",
2688 lsa, ntohl(lsa->data->ls_seqnum));
paul7ddf1d62003-10-13 09:06:46 +00002689 ospf_lsa_header_dump (lsa->data);
2690 }
2691 }
2692 else
2693 {
2694 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2695 {
ajse588f212004-12-08 18:12:06 +00002696 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002697 "that was not self originated. Ignoring\n");
2698 ospf_lsa_header_dump (lsa->data);
2699 }
2700 return old;
2701 }
2702 }
2703
paul718e3742002-12-13 20:15:29 +00002704 /* discard old LSA from LSDB */
2705 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002706 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002707
paul718e3742002-12-13 20:15:29 +00002708 /* Calculate Checksum if self-originated?. */
2709 if (IS_LSA_SELF (lsa))
2710 ospf_lsa_checksum (lsa->data);
2711
hassofe71a972004-12-22 16:16:02 +00002712 /* Insert LSA to LSDB. */
2713 ospf_lsdb_add (lsdb, lsa);
2714 lsa->lsdb = lsdb;
2715
paul718e3742002-12-13 20:15:29 +00002716 /* Do LSA specific installation process. */
2717 switch (lsa->data->type)
2718 {
2719 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002720 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002721 break;
2722 case OSPF_NETWORK_LSA:
2723 assert (oi);
paul68980082003-03-25 05:07:42 +00002724 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002725 break;
2726 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002727 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002728 break;
2729 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002730 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002731 break;
2732 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002733 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002734 break;
2735#ifdef HAVE_OPAQUE_LSA
2736 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002737 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002738 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002739 else
paul68980082003-03-25 05:07:42 +00002740 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
paul09e4efd2003-01-18 00:12:02 +00002741 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002742 case OSPF_OPAQUE_AREA_LSA:
2743 case OSPF_OPAQUE_AS_LSA:
2744 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2745 break;
2746#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002747 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002748 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002749 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002750 break;
2751 }
2752
2753 if (new == NULL)
2754 return new; /* Installation failed, cannot proceed further -- endo. */
2755
2756 /* Debug logs. */
2757 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2758 {
2759 char area_str[INET_ADDRSTRLEN];
2760
2761 switch (lsa->data->type)
2762 {
2763 case OSPF_AS_EXTERNAL_LSA:
2764#ifdef HAVE_OPAQUE_LSA
2765 case OSPF_OPAQUE_AS_LSA:
2766#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002767 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002768 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002769 dump_lsa_key (new),
2770 LOOKUP (ospf_lsa_type_msg, new->data->type));
2771 break;
2772 default:
2773 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002774 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002775 dump_lsa_key (new),
2776 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2777 break;
2778 }
2779 }
2780
paul7ddf1d62003-10-13 09:06:46 +00002781 /*
2782 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2783 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2784 */
2785 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2786 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
paul718e3742002-12-13 20:15:29 +00002787 {
paul7ddf1d62003-10-13 09:06:46 +00002788 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002789 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002790 new->data->type,
2791 inet_ntoa (new->data->id),
2792 lsa);
Paul Jakma02d942c2010-01-24 23:36:20 +00002793 ospf_lsa_flush (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002794 }
2795
2796 return new;
2797}
2798
2799
paul4dadc292005-05-06 21:37:42 +00002800static int
paul68980082003-03-25 05:07:42 +00002801ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002802{
paul1eb8ef22005-04-07 07:30:20 +00002803 struct listnode *node, *nnode;
2804 struct ospf_interface *oi;
2805
2806 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002807 {
paul718e3742002-12-13 20:15:29 +00002808 struct route_node *rn;
2809 struct ospf_neighbor *nbr;
2810
2811 if (ospf_if_is_enable (oi))
2812 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2813 if ((nbr = rn->info) != NULL)
2814 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2815 {
2816 route_unlock_node (rn);
2817 return 0;
2818 }
2819 }
2820
2821 return 1;
2822}
2823
2824
paul718e3742002-12-13 20:15:29 +00002825
paul4dadc292005-05-06 21:37:42 +00002826static int
paul718e3742002-12-13 20:15:29 +00002827ospf_maxage_lsa_remover (struct thread *thread)
2828{
paul68980082003-03-25 05:07:42 +00002829 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002830 struct ospf_lsa *lsa;
2831 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002832 int reschedule = 0;
2833
paul68980082003-03-25 05:07:42 +00002834 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002835
2836 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002837 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002838
paul68980082003-03-25 05:07:42 +00002839 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002840
2841 if (!reschedule)
paul1eb8ef22005-04-07 07:30:20 +00002842 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00002843 {
paul718e3742002-12-13 20:15:29 +00002844 if (lsa->retransmit_counter > 0)
2845 {
2846 reschedule = 1;
2847 continue;
2848 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002849
2850 /* TODO: maybe convert this function to a work-queue */
2851 if (thread_should_yield (thread))
2852 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);
2853
paul718e3742002-12-13 20:15:29 +00002854 /* Remove LSA from the LSDB */
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04002855 if (IS_LSA_SELF (lsa))
paul718e3742002-12-13 20:15:29 +00002856 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
Denis Ovsienkoad8d4802011-12-02 20:02:40 +04002857 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-originated: ",
paul7ddf1d62003-10-13 09:06:46 +00002858 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002859
2860 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002861 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002862 lsa->data->type, inet_ntoa (lsa->data->id));
2863
Paul Jakmac363d382010-01-24 22:42:13 +00002864 if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))
paul7ddf1d62003-10-13 09:06:46 +00002865 {
2866 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
Paul Jakmac363d382010-01-24 22:42:13 +00002867 zlog_debug ("originating new lsa for lsa 0x%p\n", lsa);
2868 ospf_lsa_refresh (ospf, lsa);
paul7ddf1d62003-10-13 09:06:46 +00002869 }
2870
paul718e3742002-12-13 20:15:29 +00002871 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002872 if (lsa->lsdb)
2873 {
2874 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2875 ospf_lsdb_delete (lsa->lsdb, lsa);
2876 }
2877 else
2878 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2879 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002880 }
2881
2882 /* A MaxAge LSA must be removed immediately from the router's link
2883 state database as soon as both a) it is no longer contained on any
2884 neighbor Link state retransmission lists and b) none of the router's
2885 neighbors are in states Exchange or Loading. */
2886 if (reschedule)
Paul Jakma02d942c2010-01-24 23:36:20 +00002887 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2888 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002889
2890 return 0;
2891}
2892
paul718e3742002-12-13 20:15:29 +00002893void
paul68980082003-03-25 05:07:42 +00002894ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002895{
hasso52dc7ee2004-09-23 19:18:23 +00002896 struct listnode *n;
paul718e3742002-12-13 20:15:29 +00002897
paul68980082003-03-25 05:07:42 +00002898 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
paul718e3742002-12-13 20:15:29 +00002899 {
paul68980082003-03-25 05:07:42 +00002900 list_delete_node (ospf->maxage_lsa, n);
Stephen Hemminger3106a032009-08-06 12:58:05 -07002901 UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002902 ospf_lsa_unlock (&lsa); /* maxage_lsa */
paul718e3742002-12-13 20:15:29 +00002903 }
2904}
2905
Paul Jakma02d942c2010-01-24 23:36:20 +00002906/* Add LSA onto the MaxAge list, and schedule for removal.
2907 * This does *not* lead to the LSA being flooded, that must be taken
2908 * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
2909 * function).
2910 */
paul718e3742002-12-13 20:15:29 +00002911void
paul68980082003-03-25 05:07:42 +00002912ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002913{
2914 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2915 and schedule the MaxAge LSA remover. */
Stephen Hemminger3106a032009-08-06 12:58:05 -07002916 if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
paul718e3742002-12-13 20:15:29 +00002917 {
2918 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002919 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00002920 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2921 return;
2922 }
2923
paul68980082003-03-25 05:07:42 +00002924 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
Stephen Hemminger3106a032009-08-06 12:58:05 -07002925 SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
paul718e3742002-12-13 20:15:29 +00002926
2927 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002928 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002929
Paul Jakma02d942c2010-01-24 23:36:20 +00002930 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2931 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002932}
2933
paul4dadc292005-05-06 21:37:42 +00002934static int
paul68980082003-03-25 05:07:42 +00002935ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002936{
paul718e3742002-12-13 20:15:29 +00002937 /* Stay away from any Local Translated Type-7 LSAs */
2938 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2939 return 0;
paul718e3742002-12-13 20:15:29 +00002940
2941 if (IS_LSA_MAXAGE (lsa))
2942 /* Self-originated LSAs should NOT time-out instead,
2943 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00002944 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002945 {
2946 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002947 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002948
2949 switch (lsa->data->type)
2950 {
paul718e3742002-12-13 20:15:29 +00002951#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00002952 case OSPF_OPAQUE_LINK_LSA:
2953 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00002954 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00002955 /*
2956 * As a general rule, whenever network topology has changed
2957 * (due to an LSA removal in this case), routing recalculation
2958 * should be triggered. However, this is not true for opaque
2959 * LSAs. Even if an opaque LSA instance is going to be removed
2960 * from the routing domain, it does not mean a change in network
2961 * topology, and thus, routing recalculation is not needed here.
2962 */
2963 break;
paul718e3742002-12-13 20:15:29 +00002964#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00002965 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00002966 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002967 ospf_ase_incremental_update (ospf, lsa);
2968 break;
paul718e3742002-12-13 20:15:29 +00002969 default:
paul68980082003-03-25 05:07:42 +00002970 ospf_spf_calculate_schedule (ospf);
2971 break;
paul718e3742002-12-13 20:15:29 +00002972 }
paul68980082003-03-25 05:07:42 +00002973 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002974 }
2975
Paul Jakmac363d382010-01-24 22:42:13 +00002976 if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa))
2977 if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30)
2978 printf ("Eek! Shouldn't happen!\n");
2979
paul718e3742002-12-13 20:15:29 +00002980 return 0;
2981}
2982
2983/* Periodical check of MaxAge LSA. */
2984int
paul68980082003-03-25 05:07:42 +00002985ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002986{
paul68980082003-03-25 05:07:42 +00002987 struct ospf *ospf = THREAD_ARG (thread);
2988 struct route_node *rn;
2989 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00002990 struct ospf_area *area;
2991 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00002992
paul68980082003-03-25 05:07:42 +00002993 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00002994
paul1eb8ef22005-04-07 07:30:20 +00002995 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00002996 {
paul68980082003-03-25 05:07:42 +00002997 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
2998 ospf_lsa_maxage_walker_remover (ospf, lsa);
2999 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3000 ospf_lsa_maxage_walker_remover (ospf, lsa);
3001 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3002 ospf_lsa_maxage_walker_remover (ospf, lsa);
3003 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3004 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003005#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003006 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3007 ospf_lsa_maxage_walker_remover (ospf, lsa);
3008 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3009 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003010#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003011 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3012 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003013 }
3014
paul4fb949e2003-05-10 20:06:51 +00003015 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003016 if (ospf->lsdb)
3017 {
3018 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3019 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003020#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003021 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3022 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003023#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003024 }
paul718e3742002-12-13 20:15:29 +00003025
paul68980082003-03-25 05:07:42 +00003026 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3027 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003028 return 0;
3029}
3030
paul68980082003-03-25 05:07:42 +00003031struct ospf_lsa *
3032ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3033 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003034{
paul68980082003-03-25 05:07:42 +00003035 struct ospf_lsa *lsa;
3036 struct in_addr mask, id;
3037 struct lsa_header_mask
3038 {
3039 struct lsa_header header;
3040 struct in_addr mask;
3041 } *hmask;
paul718e3742002-12-13 20:15:29 +00003042
paul68980082003-03-25 05:07:42 +00003043 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3044 if (lsa == NULL)
3045 return NULL;
paul718e3742002-12-13 20:15:29 +00003046
paul68980082003-03-25 05:07:42 +00003047 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003048
paul68980082003-03-25 05:07:42 +00003049 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003050
paul68980082003-03-25 05:07:42 +00003051 if (mask.s_addr != hmask->mask.s_addr)
3052 {
3053 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3054 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3055 if (!lsa)
3056 return NULL;
3057 }
paul718e3742002-12-13 20:15:29 +00003058
paul68980082003-03-25 05:07:42 +00003059 return lsa;
paul718e3742002-12-13 20:15:29 +00003060}
3061
3062struct ospf_lsa *
3063ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3064 struct in_addr id, struct in_addr adv_router)
3065{
paule05fba42003-04-13 20:20:53 +00003066 struct ospf *ospf = ospf_lookup();
3067 assert(ospf);
3068
paul718e3742002-12-13 20:15:29 +00003069 switch (type)
3070 {
3071 case OSPF_ROUTER_LSA:
3072 case OSPF_NETWORK_LSA:
3073 case OSPF_SUMMARY_LSA:
3074 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003075 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003076#ifdef HAVE_OPAQUE_LSA
3077 case OSPF_OPAQUE_LINK_LSA:
3078 case OSPF_OPAQUE_AREA_LSA:
3079#endif /* HAVE_OPAQUE_LSA */
3080 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003081 case OSPF_AS_EXTERNAL_LSA:
3082#ifdef HAVE_OPAQUE_LSA
3083 case OSPF_OPAQUE_AS_LSA:
3084#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003085 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003086 default:
3087 break;
3088 }
3089
3090 return NULL;
3091}
3092
3093struct ospf_lsa *
3094ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3095 struct in_addr id)
3096{
3097 struct ospf_lsa *lsa;
3098 struct route_node *rn;
3099
3100 switch (type)
3101 {
3102 case OSPF_ROUTER_LSA:
3103 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003104 case OSPF_NETWORK_LSA:
3105 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3106 if ((lsa = rn->info))
3107 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3108 {
3109 route_unlock_node (rn);
3110 return lsa;
3111 }
3112 break;
3113 case OSPF_SUMMARY_LSA:
3114 case OSPF_ASBR_SUMMARY_LSA:
3115 /* Currently not used. */
3116 assert (1);
3117 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003118 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003119 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003120#ifdef HAVE_OPAQUE_LSA
3121 case OSPF_OPAQUE_LINK_LSA:
3122 case OSPF_OPAQUE_AREA_LSA:
3123 case OSPF_OPAQUE_AS_LSA:
3124 /* Currently not used. */
3125 break;
3126#endif /* HAVE_OPAQUE_LSA */
3127 default:
3128 break;
3129 }
3130
3131 return NULL;
3132}
3133
3134struct ospf_lsa *
3135ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3136{
3137 struct ospf_lsa *match;
3138
3139#ifdef HAVE_OPAQUE_LSA
3140 /*
3141 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3142 * is redefined to have two subfields; opaque-type and opaque-id.
3143 * However, it is harmless to treat the two sub fields together, as if
3144 * they two were forming a unique LSA-ID.
3145 */
3146#endif /* HAVE_OPAQUE_LSA */
3147
3148 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3149
3150 if (match == NULL)
3151 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003152 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003153 lsah->type, inet_ntoa (lsah->id));
3154
3155 return match;
3156}
3157
3158/* return +n, l1 is more recent.
3159 return -n, l2 is more recent.
3160 return 0, l1 and l2 is identical. */
3161int
3162ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3163{
3164 int r;
3165 int x, y;
3166
3167 if (l1 == NULL && l2 == NULL)
3168 return 0;
3169 if (l1 == NULL)
3170 return -1;
3171 if (l2 == NULL)
3172 return 1;
3173
3174 /* compare LS sequence number. */
3175 x = (int) ntohl (l1->data->ls_seqnum);
3176 y = (int) ntohl (l2->data->ls_seqnum);
3177 if (x > y)
3178 return 1;
3179 if (x < y)
3180 return -1;
3181
3182 /* compare LS checksum. */
3183 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3184 if (r)
3185 return r;
3186
3187 /* compare LS age. */
3188 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3189 return 1;
3190 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3191 return -1;
3192
3193 /* compare LS age with MaxAgeDiff. */
3194 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3195 return -1;
3196 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3197 return 1;
3198
3199 /* LSAs are identical. */
3200 return 0;
3201}
3202
3203/* If two LSAs are different, return 1, otherwise return 0. */
3204int
3205ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3206{
3207 char *p1, *p2;
3208 assert (l1);
3209 assert (l2);
3210 assert (l1->data);
3211 assert (l2->data);
3212
3213 if (l1->data->options != l2->data->options)
3214 return 1;
3215
3216 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3217 return 1;
3218
3219 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3220 return 1;
3221
3222 if (l1->data->length != l2->data->length)
3223 return 1;
3224
3225 if (l1->data->length == 0)
3226 return 1;
3227
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02003228 if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
3229 return 1; /* May be a stale LSA in the LSBD */
3230
pauld1825832003-04-03 01:27:01 +00003231 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003232
3233 p1 = (char *) l1->data;
3234 p2 = (char *) l2->data;
3235
3236 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3237 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3238 return 1;
3239
3240 return 0;
3241}
3242
3243#ifdef ORIGINAL_CODING
3244void
3245ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3246 struct ospf_lsa *self,
3247 struct ospf_lsa *new)
3248{
3249 u_int32_t seqnum;
3250
3251 /* Adjust LS Sequence Number. */
3252 seqnum = ntohl (new->data->ls_seqnum) + 1;
3253 self->data->ls_seqnum = htonl (seqnum);
3254
3255 /* Recalculate LSA checksum. */
3256 ospf_lsa_checksum (self->data);
3257
3258 /* Reflooding LSA. */
3259 /* RFC2328 Section 13.3
3260 On non-broadcast networks, separate Link State Update
3261 packets must be sent, as unicasts, to each adjacent neighbor
3262 (i.e., those in state Exchange or greater). The destination
3263 IP addresses for these packets are the neighbors' IP
3264 addresses. */
3265 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3266 {
3267 struct route_node *rn;
3268 struct ospf_neighbor *onbr;
3269
3270 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3271 if ((onbr = rn->info) != NULL)
3272 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3273 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3274 }
3275 else
3276 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3277
3278 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003279 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003280 self->data->type, inet_ntoa (self->data->id));
3281}
3282#else /* ORIGINAL_CODING */
3283static int
paul68980082003-03-25 05:07:42 +00003284ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003285{
3286 if (lsa == NULL || !IS_LSA_SELF (lsa))
3287 return 0;
3288
3289 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003290 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 +00003291
3292 /* Force given lsa's age to MaxAge. */
3293 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3294
3295 switch (lsa->data->type)
3296 {
3297#ifdef HAVE_OPAQUE_LSA
Paul Jakma02d942c2010-01-24 23:36:20 +00003298 /* Opaque wants to be notified of flushes */
paul718e3742002-12-13 20:15:29 +00003299 case OSPF_OPAQUE_LINK_LSA:
3300 case OSPF_OPAQUE_AREA_LSA:
3301 case OSPF_OPAQUE_AS_LSA:
3302 ospf_opaque_lsa_refresh (lsa);
3303 break;
3304#endif /* HAVE_OPAQUE_LSA */
3305 default:
Paul Jakmadfbd5172010-04-14 10:32:12 +01003306 ospf_refresher_unregister_lsa (ospf, lsa);
Paul Jakma02d942c2010-01-24 23:36:20 +00003307 ospf_lsa_flush (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003308 break;
3309 }
3310
3311 return 0;
3312}
3313
3314void
paul68980082003-03-25 05:07:42 +00003315ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003316{
paul1eb8ef22005-04-07 07:30:20 +00003317 struct listnode *node, *nnode;
3318 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003319 struct ospf_area *area;
3320 struct ospf_interface *oi;
3321 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003322 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003323 int need_to_flush_ase = 0;
3324
paul1eb8ef22005-04-07 07:30:20 +00003325 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003326 {
paul718e3742002-12-13 20:15:29 +00003327 if ((lsa = area->router_lsa_self) != NULL)
3328 {
3329 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003330 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3331 lsa->data->type, inet_ntoa (lsa->data->id));
3332
3333 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003334 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003335 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003336 area->router_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003337 }
3338
paul1eb8ef22005-04-07 07:30:20 +00003339 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003340 {
paul718e3742002-12-13 20:15:29 +00003341 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003342 && oi->state == ISM_DR
3343 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003344 {
3345 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003346 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3347 lsa->data->type, inet_ntoa (lsa->data->id));
3348
3349 ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003350 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003351 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003352 oi->network_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003353 }
3354
3355 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3356 && area->external_routing == OSPF_AREA_DEFAULT)
3357 need_to_flush_ase = 1;
3358 }
3359
paul68980082003-03-25 05:07:42 +00003360 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3361 ospf_lsa_flush_schedule (ospf, lsa);
3362 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3363 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003364#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003365 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3366 ospf_lsa_flush_schedule (ospf, lsa);
3367 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3368 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003369#endif /* HAVE_OPAQUE_LSA */
3370 }
3371
3372 if (need_to_flush_ase)
3373 {
paul68980082003-03-25 05:07:42 +00003374 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3375 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003376#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003377 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3378 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003379#endif /* HAVE_OPAQUE_LSA */
3380 }
3381
3382 /*
3383 * Make sure that the MaxAge LSA remover is executed immediately,
3384 * without conflicting to other threads.
3385 */
paul68980082003-03-25 05:07:42 +00003386 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003387 {
paul68980082003-03-25 05:07:42 +00003388 OSPF_TIMER_OFF (ospf->t_maxage);
3389 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003390 }
3391
3392 return;
3393}
3394#endif /* ORIGINAL_CODING */
3395
3396/* If there is self-originated LSA, then return 1, otherwise return 0. */
3397/* An interface-independent version of ospf_lsa_is_self_originated */
3398int
paul68980082003-03-25 05:07:42 +00003399ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003400{
hasso52dc7ee2004-09-23 19:18:23 +00003401 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003402 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003403
3404 /* This LSA is already checked. */
3405 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003406 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003407
3408 /* Make sure LSA is self-checked. */
3409 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3410
3411 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003412 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003413 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3414
3415 /* LSA is router-LSA. */
3416 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003417 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003418 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3419
3420 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3421 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003422 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003423 {
paul718e3742002-12-13 20:15:29 +00003424 /* Ignore virtual link. */
3425 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3426 if (oi->address->family == AF_INET)
3427 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3428 {
3429 /* to make it easier later */
3430 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003431 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003432 }
3433 }
3434
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003435 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003436}
3437
3438/* Get unique Link State ID. */
3439struct in_addr
paul68980082003-03-25 05:07:42 +00003440ospf_lsa_unique_id (struct ospf *ospf,
3441 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003442{
3443 struct ospf_lsa *lsa;
3444 struct in_addr mask, id;
3445
3446 id = p->prefix;
3447
3448 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003449 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003450 if (lsa)
3451 {
3452 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3453 if (ip_masklen (al->mask) == p->prefixlen)
3454 {
3455 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003456 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003457 "Can't get Link State ID for %s/%d",
3458 inet_ntoa (p->prefix), p->prefixlen);
3459 /* id.s_addr = 0; */
3460 id.s_addr = 0xffffffff;
3461 return id;
3462 }
3463 /* Masklen differs, then apply wildcard mask to Link State ID. */
3464 else
3465 {
3466 masklen2ip (p->prefixlen, &mask);
3467
3468 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003469 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3470 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003471 if (lsa)
3472 {
3473 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003474 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003475 "Can't get Link State ID for %s/%d",
3476 inet_ntoa (p->prefix), p->prefixlen);
3477 /* id.s_addr = 0; */
3478 id.s_addr = 0xffffffff;
3479 return id;
3480 }
3481 }
3482 }
3483
3484 return id;
3485}
3486
3487
Paul Jakma70461d72006-05-12 22:57:57 +00003488#define LSA_ACTION_FLOOD_AREA 1
3489#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003490
3491struct lsa_action
3492{
3493 u_char action;
3494 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003495 struct ospf_lsa *lsa;
3496};
3497
paul4dadc292005-05-06 21:37:42 +00003498static int
paul718e3742002-12-13 20:15:29 +00003499ospf_lsa_action (struct thread *t)
3500{
3501 struct lsa_action *data;
3502
3503 data = THREAD_ARG (t);
3504
3505 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003506 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003507 data->action);
3508
3509 switch (data->action)
3510 {
paul718e3742002-12-13 20:15:29 +00003511 case LSA_ACTION_FLOOD_AREA:
3512 ospf_flood_through_area (data->area, NULL, data->lsa);
3513 break;
paul718e3742002-12-13 20:15:29 +00003514 case LSA_ACTION_FLUSH_AREA:
3515 ospf_lsa_flush_area (data->lsa, data->area);
3516 break;
paul718e3742002-12-13 20:15:29 +00003517 }
3518
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003519 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003520 XFREE (MTYPE_OSPF_MESSAGE, data);
3521 return 0;
3522}
3523
3524void
3525ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3526{
3527 struct lsa_action *data;
3528
Stephen Hemminger393deb92008-08-18 14:13:29 -07003529 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003530 data->action = LSA_ACTION_FLOOD_AREA;
3531 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003532 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003533
3534 thread_add_event (master, ospf_lsa_action, data, 0);
3535}
3536
3537void
3538ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3539{
3540 struct lsa_action *data;
3541
Stephen Hemminger393deb92008-08-18 14:13:29 -07003542 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003543 data->action = LSA_ACTION_FLUSH_AREA;
3544 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003545 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003546
3547 thread_add_event (master, ospf_lsa_action, data, 0);
3548}
3549
3550
3551/* LSA Refreshment functions. */
Paul Jakmac363d382010-01-24 22:42:13 +00003552struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00003553ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003554{
3555 struct external_info *ei;
Paul Jakmac363d382010-01-24 22:42:13 +00003556 struct ospf_lsa *new = NULL;
paul718e3742002-12-13 20:15:29 +00003557 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003558 assert (IS_LSA_SELF (lsa));
Paul Jakma66349742010-04-13 22:33:54 +01003559 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003560
3561 switch (lsa->data->type)
3562 {
3563 /* Router and Network LSAs are processed differently. */
3564 case OSPF_ROUTER_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003565 new = ospf_router_lsa_refresh (lsa);
3566 break;
paul718e3742002-12-13 20:15:29 +00003567 case OSPF_NETWORK_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003568 new = ospf_network_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003569 break;
3570 case OSPF_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003571 new = ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003572 break;
3573 case OSPF_ASBR_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003574 new = ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003575 break;
3576 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003577 /* Translated from NSSA Type-5s are refreshed when
3578 * from refresh of Type-7 - do not refresh these directly.
3579 */
3580 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3581 break;
paul718e3742002-12-13 20:15:29 +00003582 ei = ospf_external_info_check (lsa);
3583 if (ei)
Paul Jakmac363d382010-01-24 22:42:13 +00003584 new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003585 else
pauld4a53d52003-07-12 21:30:57 +00003586 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003587 break;
3588#ifdef HAVE_OPAQUE_LSA
3589 case OSPF_OPAQUE_LINK_LSA:
3590 case OSPF_OPAQUE_AREA_LSA:
3591 case OSPF_OPAQUE_AS_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003592 new = ospf_opaque_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003593 break;
pauld7480322003-05-16 17:31:51 +00003594#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003595 default:
3596 break;
paul718e3742002-12-13 20:15:29 +00003597 }
Paul Jakmac363d382010-01-24 22:42:13 +00003598 return new;
paul718e3742002-12-13 20:15:29 +00003599}
3600
3601void
paul68980082003-03-25 05:07:42 +00003602ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003603{
3604 u_int16_t index, current_index;
3605
Paul Jakma66349742010-04-13 22:33:54 +01003606 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003607 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003608
3609 if (lsa->refresh_list < 0)
3610 {
3611 int delay;
3612
3613 if (LS_AGE (lsa) == 0 &&
3614 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3615 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3616 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3617 else
3618 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3619 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3620 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3621
3622 if (delay < 0)
3623 delay = 0;
3624
Paul Jakmac363d382010-01-24 22:42:13 +00003625 current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL)
3626 - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003627
3628 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
Paul Jakmac363d382010-01-24 22:42:13 +00003629 % (OSPF_LSA_REFRESHER_SLOTS);
paul718e3742002-12-13 20:15:29 +00003630
3631 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003632 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003633 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003634 if (!ospf->lsa_refresh_queue.qs[index])
3635 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003636 listnode_add (ospf->lsa_refresh_queue.qs[index],
3637 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003638 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003639 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003640 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003641 "setting refresh_list on lsa %p (slod %d)",
3642 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003643 }
3644}
3645
3646void
paul68980082003-03-25 05:07:42 +00003647ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003648{
Paul Jakma66349742010-04-13 22:33:54 +01003649 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003650 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003651 if (lsa->refresh_list >= 0)
3652 {
hasso52dc7ee2004-09-23 19:18:23 +00003653 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003654 listnode_delete (refresh_list, lsa);
3655 if (!listcount (refresh_list))
3656 {
3657 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003658 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003659 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003660 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003661 lsa->refresh_list = -1;
3662 }
3663}
3664
3665int
3666ospf_lsa_refresh_walker (struct thread *t)
3667{
hasso52dc7ee2004-09-23 19:18:23 +00003668 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003669 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003670 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003671 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003672 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003673 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003674
3675 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003676 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003677
3678
paul68980082003-03-25 05:07:42 +00003679 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003680
ajs9dbc7972005-03-13 19:27:22 +00003681 /* Note: if clock has jumped backwards, then time change could be negative,
3682 so we are careful to cast the expression to unsigned before taking
3683 modulus. */
paul68980082003-03-25 05:07:42 +00003684 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003685 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakmac363d382010-01-24 22:42:13 +00003686 (quagga_time (NULL) - ospf->lsa_refresher_started)
3687 / OSPF_LSA_REFRESHER_GRANULARITY))
3688 % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003689
3690 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003691 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003692 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003693
paul68980082003-03-25 05:07:42 +00003694 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003695 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3696 {
3697 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003698 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003699 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003700
paul68980082003-03-25 05:07:42 +00003701 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003702
Paul Jakma66349742010-04-13 22:33:54 +01003703 assert (i >= 0);
3704
paul68980082003-03-25 05:07:42 +00003705 ospf->lsa_refresh_queue.qs [i] = NULL;
3706
paul718e3742002-12-13 20:15:29 +00003707 if (refresh_list)
3708 {
paul1eb8ef22005-04-07 07:30:20 +00003709 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003710 {
paul718e3742002-12-13 20:15:29 +00003711 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003712 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003713 "refresh lsa %p (slot %d)",
3714 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003715
Paul Jakma66349742010-04-13 22:33:54 +01003716 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003717 list_delete_node (refresh_list, node);
paul718e3742002-12-13 20:15:29 +00003718 lsa->refresh_list = -1;
3719 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003720 }
3721 list_free (refresh_list);
3722 }
3723 }
3724
paul68980082003-03-25 05:07:42 +00003725 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3726 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003727 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003728
paul1eb8ef22005-04-07 07:30:20 +00003729 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
Paul Jakma66349742010-04-13 22:33:54 +01003730 {
3731 ospf_lsa_refresh (ospf, lsa);
3732 assert (lsa->lock > 0);
3733 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
3734 }
paul718e3742002-12-13 20:15:29 +00003735
3736 list_delete (lsa_to_refresh);
3737
3738 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003739 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003740
3741 return 0;
3742}
3743