blob: 66c7e1c0cce5cdef5fba2d024533cfee22550afb [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;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002831 struct route_node *rn;
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)
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002842 for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn))
paul718e3742002-12-13 20:15:29 +00002843 {
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002844 if ((lsa = rn->info) == NULL)
2845 {
2846 continue;
2847 }
2848
paul718e3742002-12-13 20:15:29 +00002849 if (lsa->retransmit_counter > 0)
2850 {
2851 reschedule = 1;
2852 continue;
2853 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002854
2855 /* TODO: maybe convert this function to a work-queue */
2856 if (thread_should_yield (thread))
2857 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);
2858
paul718e3742002-12-13 20:15:29 +00002859 /* Remove LSA from the LSDB */
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04002860 if (IS_LSA_SELF (lsa))
paul718e3742002-12-13 20:15:29 +00002861 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
Denis Ovsienkoad8d4802011-12-02 20:02:40 +04002862 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-originated: ",
paul7ddf1d62003-10-13 09:06:46 +00002863 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002864
2865 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002866 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002867 lsa->data->type, inet_ntoa (lsa->data->id));
2868
Paul Jakmac363d382010-01-24 22:42:13 +00002869 if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))
paul7ddf1d62003-10-13 09:06:46 +00002870 {
2871 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
Paul Jakmac363d382010-01-24 22:42:13 +00002872 zlog_debug ("originating new lsa for lsa 0x%p\n", lsa);
2873 ospf_lsa_refresh (ospf, lsa);
paul7ddf1d62003-10-13 09:06:46 +00002874 }
2875
paul718e3742002-12-13 20:15:29 +00002876 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002877 if (lsa->lsdb)
2878 {
2879 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2880 ospf_lsdb_delete (lsa->lsdb, lsa);
2881 }
2882 else
2883 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2884 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002885 }
2886
2887 /* A MaxAge LSA must be removed immediately from the router's link
2888 state database as soon as both a) it is no longer contained on any
2889 neighbor Link state retransmission lists and b) none of the router's
2890 neighbors are in states Exchange or Loading. */
2891 if (reschedule)
Paul Jakma02d942c2010-01-24 23:36:20 +00002892 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2893 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002894
2895 return 0;
2896}
2897
paul718e3742002-12-13 20:15:29 +00002898void
paul68980082003-03-25 05:07:42 +00002899ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002900{
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002901 struct route_node *rn;
2902 struct prefix_ls lsa_prefix;
paul718e3742002-12-13 20:15:29 +00002903
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002904 ls_prefix_set (&lsa_prefix, lsa);
2905
2906 if ((rn = route_node_lookup(ospf->maxage_lsa,
2907 (struct prefix *)&lsa_prefix)))
paul718e3742002-12-13 20:15:29 +00002908 {
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002909 if (rn->info == lsa)
2910 {
2911 UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
2912 ospf_lsa_unlock (&lsa); /* maxage_lsa */
2913 rn->info = NULL;
2914 route_unlock_node (rn); /* route_node_lookup */
2915 }
2916 route_unlock_node (rn); /* route_node_lookup */
paul718e3742002-12-13 20:15:29 +00002917 }
2918}
2919
Paul Jakma02d942c2010-01-24 23:36:20 +00002920/* Add LSA onto the MaxAge list, and schedule for removal.
2921 * This does *not* lead to the LSA being flooded, that must be taken
2922 * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
2923 * function).
2924 */
paul718e3742002-12-13 20:15:29 +00002925void
paul68980082003-03-25 05:07:42 +00002926ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002927{
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002928 struct prefix_ls lsa_prefix;
2929 struct route_node *rn;
2930
paul718e3742002-12-13 20:15:29 +00002931 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2932 and schedule the MaxAge LSA remover. */
Stephen Hemminger3106a032009-08-06 12:58:05 -07002933 if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
paul718e3742002-12-13 20:15:29 +00002934 {
2935 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002936 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00002937 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2938 return;
2939 }
2940
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002941 ls_prefix_set (&lsa_prefix, lsa);
2942 if ((rn = route_node_get (ospf->maxage_lsa,
2943 (struct prefix *)&lsa_prefix)) != NULL)
2944 {
2945 if (rn->info != NULL)
2946 {
2947 route_unlock_node (rn);
2948 }
2949 else
2950 {
2951 rn->info = ospf_lsa_lock(lsa);
2952 SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
2953 }
2954 }
2955 else
2956 {
2957 zlog_err("Unable to allocate memory for maxage lsa\n");
2958 assert(0);
2959 }
paul718e3742002-12-13 20:15:29 +00002960
2961 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002962 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002963
Paul Jakma02d942c2010-01-24 23:36:20 +00002964 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2965 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002966}
2967
paul4dadc292005-05-06 21:37:42 +00002968static int
paul68980082003-03-25 05:07:42 +00002969ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002970{
paul718e3742002-12-13 20:15:29 +00002971 /* Stay away from any Local Translated Type-7 LSAs */
2972 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2973 return 0;
paul718e3742002-12-13 20:15:29 +00002974
2975 if (IS_LSA_MAXAGE (lsa))
2976 /* Self-originated LSAs should NOT time-out instead,
2977 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00002978 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002979 {
2980 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002981 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002982
2983 switch (lsa->data->type)
2984 {
paul718e3742002-12-13 20:15:29 +00002985#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00002986 case OSPF_OPAQUE_LINK_LSA:
2987 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00002988 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00002989 /*
2990 * As a general rule, whenever network topology has changed
2991 * (due to an LSA removal in this case), routing recalculation
2992 * should be triggered. However, this is not true for opaque
2993 * LSAs. Even if an opaque LSA instance is going to be removed
2994 * from the routing domain, it does not mean a change in network
2995 * topology, and thus, routing recalculation is not needed here.
2996 */
2997 break;
paul718e3742002-12-13 20:15:29 +00002998#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00002999 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003000 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003001 ospf_ase_incremental_update (ospf, lsa);
3002 break;
paul718e3742002-12-13 20:15:29 +00003003 default:
paul68980082003-03-25 05:07:42 +00003004 ospf_spf_calculate_schedule (ospf);
3005 break;
paul718e3742002-12-13 20:15:29 +00003006 }
paul68980082003-03-25 05:07:42 +00003007 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003008 }
3009
Paul Jakmac363d382010-01-24 22:42:13 +00003010 if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa))
3011 if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30)
3012 printf ("Eek! Shouldn't happen!\n");
3013
paul718e3742002-12-13 20:15:29 +00003014 return 0;
3015}
3016
3017/* Periodical check of MaxAge LSA. */
3018int
paul68980082003-03-25 05:07:42 +00003019ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003020{
paul68980082003-03-25 05:07:42 +00003021 struct ospf *ospf = THREAD_ARG (thread);
3022 struct route_node *rn;
3023 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003024 struct ospf_area *area;
3025 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003026
paul68980082003-03-25 05:07:42 +00003027 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003028
paul1eb8ef22005-04-07 07:30:20 +00003029 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003030 {
paul68980082003-03-25 05:07:42 +00003031 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3032 ospf_lsa_maxage_walker_remover (ospf, lsa);
3033 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3034 ospf_lsa_maxage_walker_remover (ospf, lsa);
3035 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3036 ospf_lsa_maxage_walker_remover (ospf, lsa);
3037 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3038 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003039#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003040 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3041 ospf_lsa_maxage_walker_remover (ospf, lsa);
3042 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3043 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003044#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003045 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3046 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003047 }
3048
paul4fb949e2003-05-10 20:06:51 +00003049 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003050 if (ospf->lsdb)
3051 {
3052 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3053 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003054#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003055 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3056 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003057#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003058 }
paul718e3742002-12-13 20:15:29 +00003059
paul68980082003-03-25 05:07:42 +00003060 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3061 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003062 return 0;
3063}
3064
paul68980082003-03-25 05:07:42 +00003065struct ospf_lsa *
3066ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3067 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003068{
paul68980082003-03-25 05:07:42 +00003069 struct ospf_lsa *lsa;
3070 struct in_addr mask, id;
3071 struct lsa_header_mask
3072 {
3073 struct lsa_header header;
3074 struct in_addr mask;
3075 } *hmask;
paul718e3742002-12-13 20:15:29 +00003076
paul68980082003-03-25 05:07:42 +00003077 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3078 if (lsa == NULL)
3079 return NULL;
paul718e3742002-12-13 20:15:29 +00003080
paul68980082003-03-25 05:07:42 +00003081 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003082
paul68980082003-03-25 05:07:42 +00003083 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003084
paul68980082003-03-25 05:07:42 +00003085 if (mask.s_addr != hmask->mask.s_addr)
3086 {
3087 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3088 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3089 if (!lsa)
3090 return NULL;
3091 }
paul718e3742002-12-13 20:15:29 +00003092
paul68980082003-03-25 05:07:42 +00003093 return lsa;
paul718e3742002-12-13 20:15:29 +00003094}
3095
3096struct ospf_lsa *
3097ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3098 struct in_addr id, struct in_addr adv_router)
3099{
paule05fba42003-04-13 20:20:53 +00003100 struct ospf *ospf = ospf_lookup();
3101 assert(ospf);
3102
paul718e3742002-12-13 20:15:29 +00003103 switch (type)
3104 {
3105 case OSPF_ROUTER_LSA:
3106 case OSPF_NETWORK_LSA:
3107 case OSPF_SUMMARY_LSA:
3108 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003109 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003110#ifdef HAVE_OPAQUE_LSA
3111 case OSPF_OPAQUE_LINK_LSA:
3112 case OSPF_OPAQUE_AREA_LSA:
3113#endif /* HAVE_OPAQUE_LSA */
3114 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003115 case OSPF_AS_EXTERNAL_LSA:
3116#ifdef HAVE_OPAQUE_LSA
3117 case OSPF_OPAQUE_AS_LSA:
3118#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003119 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003120 default:
3121 break;
3122 }
3123
3124 return NULL;
3125}
3126
3127struct ospf_lsa *
3128ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3129 struct in_addr id)
3130{
3131 struct ospf_lsa *lsa;
3132 struct route_node *rn;
3133
3134 switch (type)
3135 {
3136 case OSPF_ROUTER_LSA:
3137 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003138 case OSPF_NETWORK_LSA:
3139 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3140 if ((lsa = rn->info))
3141 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3142 {
3143 route_unlock_node (rn);
3144 return lsa;
3145 }
3146 break;
3147 case OSPF_SUMMARY_LSA:
3148 case OSPF_ASBR_SUMMARY_LSA:
3149 /* Currently not used. */
3150 assert (1);
3151 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003152 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003153 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003154#ifdef HAVE_OPAQUE_LSA
3155 case OSPF_OPAQUE_LINK_LSA:
3156 case OSPF_OPAQUE_AREA_LSA:
3157 case OSPF_OPAQUE_AS_LSA:
3158 /* Currently not used. */
3159 break;
3160#endif /* HAVE_OPAQUE_LSA */
3161 default:
3162 break;
3163 }
3164
3165 return NULL;
3166}
3167
3168struct ospf_lsa *
3169ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3170{
3171 struct ospf_lsa *match;
3172
3173#ifdef HAVE_OPAQUE_LSA
3174 /*
3175 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3176 * is redefined to have two subfields; opaque-type and opaque-id.
3177 * However, it is harmless to treat the two sub fields together, as if
3178 * they two were forming a unique LSA-ID.
3179 */
3180#endif /* HAVE_OPAQUE_LSA */
3181
3182 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3183
3184 if (match == NULL)
3185 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003186 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003187 lsah->type, inet_ntoa (lsah->id));
3188
3189 return match;
3190}
3191
3192/* return +n, l1 is more recent.
3193 return -n, l2 is more recent.
3194 return 0, l1 and l2 is identical. */
3195int
3196ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3197{
3198 int r;
3199 int x, y;
3200
3201 if (l1 == NULL && l2 == NULL)
3202 return 0;
3203 if (l1 == NULL)
3204 return -1;
3205 if (l2 == NULL)
3206 return 1;
3207
3208 /* compare LS sequence number. */
3209 x = (int) ntohl (l1->data->ls_seqnum);
3210 y = (int) ntohl (l2->data->ls_seqnum);
3211 if (x > y)
3212 return 1;
3213 if (x < y)
3214 return -1;
3215
3216 /* compare LS checksum. */
3217 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3218 if (r)
3219 return r;
3220
3221 /* compare LS age. */
3222 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3223 return 1;
3224 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3225 return -1;
3226
3227 /* compare LS age with MaxAgeDiff. */
3228 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3229 return -1;
3230 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3231 return 1;
3232
3233 /* LSAs are identical. */
3234 return 0;
3235}
3236
3237/* If two LSAs are different, return 1, otherwise return 0. */
3238int
3239ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3240{
3241 char *p1, *p2;
3242 assert (l1);
3243 assert (l2);
3244 assert (l1->data);
3245 assert (l2->data);
3246
3247 if (l1->data->options != l2->data->options)
3248 return 1;
3249
3250 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3251 return 1;
3252
3253 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3254 return 1;
3255
3256 if (l1->data->length != l2->data->length)
3257 return 1;
3258
3259 if (l1->data->length == 0)
3260 return 1;
3261
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02003262 if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
3263 return 1; /* May be a stale LSA in the LSBD */
3264
pauld1825832003-04-03 01:27:01 +00003265 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003266
3267 p1 = (char *) l1->data;
3268 p2 = (char *) l2->data;
3269
3270 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3271 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3272 return 1;
3273
3274 return 0;
3275}
3276
3277#ifdef ORIGINAL_CODING
3278void
3279ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3280 struct ospf_lsa *self,
3281 struct ospf_lsa *new)
3282{
3283 u_int32_t seqnum;
3284
3285 /* Adjust LS Sequence Number. */
3286 seqnum = ntohl (new->data->ls_seqnum) + 1;
3287 self->data->ls_seqnum = htonl (seqnum);
3288
3289 /* Recalculate LSA checksum. */
3290 ospf_lsa_checksum (self->data);
3291
3292 /* Reflooding LSA. */
3293 /* RFC2328 Section 13.3
3294 On non-broadcast networks, separate Link State Update
3295 packets must be sent, as unicasts, to each adjacent neighbor
3296 (i.e., those in state Exchange or greater). The destination
3297 IP addresses for these packets are the neighbors' IP
3298 addresses. */
3299 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3300 {
3301 struct route_node *rn;
3302 struct ospf_neighbor *onbr;
3303
3304 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3305 if ((onbr = rn->info) != NULL)
3306 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3307 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3308 }
3309 else
3310 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3311
3312 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003313 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003314 self->data->type, inet_ntoa (self->data->id));
3315}
3316#else /* ORIGINAL_CODING */
3317static int
paul68980082003-03-25 05:07:42 +00003318ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003319{
3320 if (lsa == NULL || !IS_LSA_SELF (lsa))
3321 return 0;
3322
3323 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003324 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 +00003325
3326 /* Force given lsa's age to MaxAge. */
3327 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3328
3329 switch (lsa->data->type)
3330 {
3331#ifdef HAVE_OPAQUE_LSA
Paul Jakma02d942c2010-01-24 23:36:20 +00003332 /* Opaque wants to be notified of flushes */
paul718e3742002-12-13 20:15:29 +00003333 case OSPF_OPAQUE_LINK_LSA:
3334 case OSPF_OPAQUE_AREA_LSA:
3335 case OSPF_OPAQUE_AS_LSA:
3336 ospf_opaque_lsa_refresh (lsa);
3337 break;
3338#endif /* HAVE_OPAQUE_LSA */
3339 default:
Paul Jakmadfbd5172010-04-14 10:32:12 +01003340 ospf_refresher_unregister_lsa (ospf, lsa);
Paul Jakma02d942c2010-01-24 23:36:20 +00003341 ospf_lsa_flush (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003342 break;
3343 }
3344
3345 return 0;
3346}
3347
3348void
paul68980082003-03-25 05:07:42 +00003349ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003350{
paul1eb8ef22005-04-07 07:30:20 +00003351 struct listnode *node, *nnode;
3352 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003353 struct ospf_area *area;
3354 struct ospf_interface *oi;
3355 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003356 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003357 int need_to_flush_ase = 0;
3358
paul1eb8ef22005-04-07 07:30:20 +00003359 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003360 {
paul718e3742002-12-13 20:15:29 +00003361 if ((lsa = area->router_lsa_self) != NULL)
3362 {
3363 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003364 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3365 lsa->data->type, inet_ntoa (lsa->data->id));
3366
3367 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003368 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003369 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003370 area->router_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003371 }
3372
paul1eb8ef22005-04-07 07:30:20 +00003373 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003374 {
paul718e3742002-12-13 20:15:29 +00003375 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003376 && oi->state == ISM_DR
3377 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003378 {
3379 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003380 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3381 lsa->data->type, inet_ntoa (lsa->data->id));
3382
3383 ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003384 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003385 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003386 oi->network_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003387 }
3388
3389 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3390 && area->external_routing == OSPF_AREA_DEFAULT)
3391 need_to_flush_ase = 1;
3392 }
3393
paul68980082003-03-25 05:07:42 +00003394 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3395 ospf_lsa_flush_schedule (ospf, lsa);
3396 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3397 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003398#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003399 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3400 ospf_lsa_flush_schedule (ospf, lsa);
3401 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3402 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003403#endif /* HAVE_OPAQUE_LSA */
3404 }
3405
3406 if (need_to_flush_ase)
3407 {
paul68980082003-03-25 05:07:42 +00003408 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3409 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003410#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003411 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3412 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003413#endif /* HAVE_OPAQUE_LSA */
3414 }
3415
3416 /*
3417 * Make sure that the MaxAge LSA remover is executed immediately,
3418 * without conflicting to other threads.
3419 */
paul68980082003-03-25 05:07:42 +00003420 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003421 {
paul68980082003-03-25 05:07:42 +00003422 OSPF_TIMER_OFF (ospf->t_maxage);
3423 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003424 }
3425
3426 return;
3427}
3428#endif /* ORIGINAL_CODING */
3429
3430/* If there is self-originated LSA, then return 1, otherwise return 0. */
3431/* An interface-independent version of ospf_lsa_is_self_originated */
3432int
paul68980082003-03-25 05:07:42 +00003433ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003434{
hasso52dc7ee2004-09-23 19:18:23 +00003435 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003436 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003437
3438 /* This LSA is already checked. */
3439 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003440 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003441
3442 /* Make sure LSA is self-checked. */
3443 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3444
3445 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003446 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003447 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3448
3449 /* LSA is router-LSA. */
3450 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003451 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003452 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3453
3454 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3455 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003456 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003457 {
paul718e3742002-12-13 20:15:29 +00003458 /* Ignore virtual link. */
3459 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3460 if (oi->address->family == AF_INET)
3461 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3462 {
3463 /* to make it easier later */
3464 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003465 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003466 }
3467 }
3468
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003469 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003470}
3471
3472/* Get unique Link State ID. */
3473struct in_addr
paul68980082003-03-25 05:07:42 +00003474ospf_lsa_unique_id (struct ospf *ospf,
3475 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003476{
3477 struct ospf_lsa *lsa;
3478 struct in_addr mask, id;
3479
3480 id = p->prefix;
3481
3482 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003483 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003484 if (lsa)
3485 {
3486 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3487 if (ip_masklen (al->mask) == p->prefixlen)
3488 {
3489 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003490 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003491 "Can't get Link State ID for %s/%d",
3492 inet_ntoa (p->prefix), p->prefixlen);
3493 /* id.s_addr = 0; */
3494 id.s_addr = 0xffffffff;
3495 return id;
3496 }
3497 /* Masklen differs, then apply wildcard mask to Link State ID. */
3498 else
3499 {
3500 masklen2ip (p->prefixlen, &mask);
3501
3502 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003503 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3504 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003505 if (lsa)
3506 {
3507 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003508 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003509 "Can't get Link State ID for %s/%d",
3510 inet_ntoa (p->prefix), p->prefixlen);
3511 /* id.s_addr = 0; */
3512 id.s_addr = 0xffffffff;
3513 return id;
3514 }
3515 }
3516 }
3517
3518 return id;
3519}
3520
3521
Paul Jakma70461d72006-05-12 22:57:57 +00003522#define LSA_ACTION_FLOOD_AREA 1
3523#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003524
3525struct lsa_action
3526{
3527 u_char action;
3528 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003529 struct ospf_lsa *lsa;
3530};
3531
paul4dadc292005-05-06 21:37:42 +00003532static int
paul718e3742002-12-13 20:15:29 +00003533ospf_lsa_action (struct thread *t)
3534{
3535 struct lsa_action *data;
3536
3537 data = THREAD_ARG (t);
3538
3539 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003540 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003541 data->action);
3542
3543 switch (data->action)
3544 {
paul718e3742002-12-13 20:15:29 +00003545 case LSA_ACTION_FLOOD_AREA:
3546 ospf_flood_through_area (data->area, NULL, data->lsa);
3547 break;
paul718e3742002-12-13 20:15:29 +00003548 case LSA_ACTION_FLUSH_AREA:
3549 ospf_lsa_flush_area (data->lsa, data->area);
3550 break;
paul718e3742002-12-13 20:15:29 +00003551 }
3552
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003553 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003554 XFREE (MTYPE_OSPF_MESSAGE, data);
3555 return 0;
3556}
3557
3558void
3559ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3560{
3561 struct lsa_action *data;
3562
Stephen Hemminger393deb92008-08-18 14:13:29 -07003563 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003564 data->action = LSA_ACTION_FLOOD_AREA;
3565 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003566 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003567
3568 thread_add_event (master, ospf_lsa_action, data, 0);
3569}
3570
3571void
3572ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3573{
3574 struct lsa_action *data;
3575
Stephen Hemminger393deb92008-08-18 14:13:29 -07003576 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003577 data->action = LSA_ACTION_FLUSH_AREA;
3578 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003579 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003580
3581 thread_add_event (master, ospf_lsa_action, data, 0);
3582}
3583
3584
3585/* LSA Refreshment functions. */
Paul Jakmac363d382010-01-24 22:42:13 +00003586struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00003587ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003588{
3589 struct external_info *ei;
Paul Jakmac363d382010-01-24 22:42:13 +00003590 struct ospf_lsa *new = NULL;
paul718e3742002-12-13 20:15:29 +00003591 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003592 assert (IS_LSA_SELF (lsa));
Paul Jakma66349742010-04-13 22:33:54 +01003593 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003594
3595 switch (lsa->data->type)
3596 {
3597 /* Router and Network LSAs are processed differently. */
3598 case OSPF_ROUTER_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003599 new = ospf_router_lsa_refresh (lsa);
3600 break;
paul718e3742002-12-13 20:15:29 +00003601 case OSPF_NETWORK_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003602 new = ospf_network_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003603 break;
3604 case OSPF_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003605 new = ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003606 break;
3607 case OSPF_ASBR_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003608 new = ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003609 break;
3610 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003611 /* Translated from NSSA Type-5s are refreshed when
3612 * from refresh of Type-7 - do not refresh these directly.
3613 */
3614 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3615 break;
paul718e3742002-12-13 20:15:29 +00003616 ei = ospf_external_info_check (lsa);
3617 if (ei)
Paul Jakmac363d382010-01-24 22:42:13 +00003618 new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003619 else
pauld4a53d52003-07-12 21:30:57 +00003620 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003621 break;
3622#ifdef HAVE_OPAQUE_LSA
3623 case OSPF_OPAQUE_LINK_LSA:
3624 case OSPF_OPAQUE_AREA_LSA:
3625 case OSPF_OPAQUE_AS_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003626 new = ospf_opaque_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003627 break;
pauld7480322003-05-16 17:31:51 +00003628#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003629 default:
3630 break;
paul718e3742002-12-13 20:15:29 +00003631 }
Paul Jakmac363d382010-01-24 22:42:13 +00003632 return new;
paul718e3742002-12-13 20:15:29 +00003633}
3634
3635void
paul68980082003-03-25 05:07:42 +00003636ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003637{
3638 u_int16_t index, current_index;
3639
Paul Jakma66349742010-04-13 22:33:54 +01003640 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003641 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003642
3643 if (lsa->refresh_list < 0)
3644 {
3645 int delay;
3646
3647 if (LS_AGE (lsa) == 0 &&
3648 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3649 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3650 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3651 else
3652 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3653 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3654 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3655
3656 if (delay < 0)
3657 delay = 0;
3658
Paul Jakmac363d382010-01-24 22:42:13 +00003659 current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL)
3660 - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003661
3662 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
Paul Jakmac363d382010-01-24 22:42:13 +00003663 % (OSPF_LSA_REFRESHER_SLOTS);
paul718e3742002-12-13 20:15:29 +00003664
3665 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003666 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003667 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003668 if (!ospf->lsa_refresh_queue.qs[index])
3669 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003670 listnode_add (ospf->lsa_refresh_queue.qs[index],
3671 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003672 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003673 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003674 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003675 "setting refresh_list on lsa %p (slod %d)",
3676 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003677 }
3678}
3679
3680void
paul68980082003-03-25 05:07:42 +00003681ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003682{
Paul Jakma66349742010-04-13 22:33:54 +01003683 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003684 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003685 if (lsa->refresh_list >= 0)
3686 {
hasso52dc7ee2004-09-23 19:18:23 +00003687 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003688 listnode_delete (refresh_list, lsa);
3689 if (!listcount (refresh_list))
3690 {
3691 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003692 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003693 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003694 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003695 lsa->refresh_list = -1;
3696 }
3697}
3698
3699int
3700ospf_lsa_refresh_walker (struct thread *t)
3701{
hasso52dc7ee2004-09-23 19:18:23 +00003702 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003703 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003704 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003705 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003706 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003707 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003708
3709 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003710 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003711
3712
paul68980082003-03-25 05:07:42 +00003713 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003714
ajs9dbc7972005-03-13 19:27:22 +00003715 /* Note: if clock has jumped backwards, then time change could be negative,
3716 so we are careful to cast the expression to unsigned before taking
3717 modulus. */
paul68980082003-03-25 05:07:42 +00003718 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003719 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakmac363d382010-01-24 22:42:13 +00003720 (quagga_time (NULL) - ospf->lsa_refresher_started)
3721 / OSPF_LSA_REFRESHER_GRANULARITY))
3722 % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003723
3724 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003725 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003726 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003727
paul68980082003-03-25 05:07:42 +00003728 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003729 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3730 {
3731 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003732 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003733 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003734
paul68980082003-03-25 05:07:42 +00003735 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003736
Paul Jakma66349742010-04-13 22:33:54 +01003737 assert (i >= 0);
3738
paul68980082003-03-25 05:07:42 +00003739 ospf->lsa_refresh_queue.qs [i] = NULL;
3740
paul718e3742002-12-13 20:15:29 +00003741 if (refresh_list)
3742 {
paul1eb8ef22005-04-07 07:30:20 +00003743 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003744 {
paul718e3742002-12-13 20:15:29 +00003745 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003746 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003747 "refresh lsa %p (slot %d)",
3748 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003749
Paul Jakma66349742010-04-13 22:33:54 +01003750 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003751 list_delete_node (refresh_list, node);
paul718e3742002-12-13 20:15:29 +00003752 lsa->refresh_list = -1;
3753 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003754 }
3755 list_free (refresh_list);
3756 }
3757 }
3758
paul68980082003-03-25 05:07:42 +00003759 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3760 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003761 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003762
paul1eb8ef22005-04-07 07:30:20 +00003763 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
Paul Jakma66349742010-04-13 22:33:54 +01003764 {
3765 ospf_lsa_refresh (ospf, lsa);
3766 assert (lsa->lock > 0);
3767 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
3768 }
paul718e3742002-12-13 20:15:29 +00003769
3770 list_delete (lsa_to_refresh);
3771
3772 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003773 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003774
3775 return 0;
3776}
3777