blob: dfd1a61e2a3e84efef20a28ba3983b98bccc74cb [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{
paul718e3742002-12-13 20:15:29 +00001343 /* Put Network Mask. */
Leonard Tracy2345a222012-12-04 11:02:35 -08001344 stream_put_ipv4 (s, (u_int32_t) 0);
paul718e3742002-12-13 20:15:29 +00001345
1346 /* Set # TOS. */
1347 stream_putc (s, (u_char) 0);
1348
1349 /* Set metric. */
1350 stream_put_ospf_metric (s, metric);
1351}
1352
paul4dadc292005-05-06 21:37:42 +00001353static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001354ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1355 u_int32_t metric, struct in_addr id)
1356{
1357 struct stream *s;
1358 struct ospf_lsa *new;
1359 struct lsa_header *lsah;
1360 int length;
1361
paulc24d6022005-11-20 14:54:12 +00001362 if (id.s_addr == 0xffffffff)
1363 {
1364 /* Maybe Link State ID not available. */
1365 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1366 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1367 OSPF_ASBR_SUMMARY_LSA);
1368 return NULL;
1369 }
1370
paul718e3742002-12-13 20:15:29 +00001371 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001372 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001373
1374 /* Create new stream for LSA. */
1375 s = stream_new (OSPF_MAX_LSA_SIZE);
1376 lsah = (struct lsa_header *) STREAM_DATA (s);
1377
paul68980082003-03-25 05:07:42 +00001378 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1379 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001380
1381 /* Set summary-LSA body fields. */
1382 ospf_summary_asbr_lsa_body_set (s, p, metric);
1383
1384 /* Set length. */
1385 length = stream_get_endp (s);
1386 lsah->length = htons (length);
1387
1388 /* Create OSPF LSA instance. */
1389 new = ospf_lsa_new ();
1390 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001391 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001392
1393 /* Copy LSA to store. */
1394 new->data = ospf_lsa_data_new (length);
1395 memcpy (new->data, lsah, length);
1396 stream_free (s);
1397
1398 return new;
1399}
1400
1401/* Originate summary-ASBR-LSA. */
1402struct ospf_lsa *
1403ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1404 struct ospf_area *area)
1405{
1406 struct ospf_lsa *new;
1407 struct in_addr id;
1408
paul68980082003-03-25 05:07:42 +00001409 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001410
paulc24d6022005-11-20 14:54:12 +00001411 if (id.s_addr == 0xffffffff)
1412 {
1413 /* Maybe Link State ID not available. */
1414 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1415 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1416 OSPF_ASBR_SUMMARY_LSA);
1417 return NULL;
1418 }
1419
paul718e3742002-12-13 20:15:29 +00001420 /* Create new summary-LSA instance. */
1421 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001422 if (!new)
1423 return NULL;
paul718e3742002-12-13 20:15:29 +00001424
1425 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001426 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001427
1428 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001429 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001430
1431 /* Flooding new LSA through area. */
1432 ospf_flood_through_area (area, NULL, new);
1433
1434 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1435 {
ajse588f212004-12-08 18:12:06 +00001436 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
paul718e3742002-12-13 20:15:29 +00001437 new->data->type, inet_ntoa (new->data->id), new);
1438 ospf_lsa_header_dump (new->data);
1439 }
1440
1441 return new;
1442}
1443
Paul Jakmac363d382010-01-24 22:42:13 +00001444static struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001445ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001446{
1447 struct ospf_lsa *new;
1448 struct summary_lsa *sl;
1449 struct prefix p;
1450
1451 /* Sanity check. */
1452 assert (lsa->data);
1453
1454 sl = (struct summary_lsa *)lsa->data;
1455 p.prefixlen = ip_masklen (sl->mask);
1456 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1457 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001458 if (!new)
1459 return NULL;
paul718e3742002-12-13 20:15:29 +00001460
1461 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001462
paul68980082003-03-25 05:07:42 +00001463 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001464
1465 /* Flood LSA through area. */
1466 ospf_flood_through_area (new->area, NULL, new);
1467
1468 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1469 {
ajse588f212004-12-08 18:12:06 +00001470 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001471 new->data->type, inet_ntoa (new->data->id));
1472 ospf_lsa_header_dump (new->data);
1473 }
1474
1475 return new;
1476}
1477
1478/* AS-external-LSA related functions. */
1479
1480/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1481 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001482static struct in_addr
paul68980082003-03-25 05:07:42 +00001483ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001484{
1485 struct in_addr fwd;
1486 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001487 struct listnode *node;
1488 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001489
1490 fwd.s_addr = 0;
1491
1492 if (!nexthop.s_addr)
1493 return fwd;
1494
1495 /* Check whether nexthop is covered by OSPF network. */
1496 nh.family = AF_INET;
1497 nh.u.prefix4 = nexthop;
1498 nh.prefixlen = IPV4_MAX_BITLEN;
Paul Jakma4ca15d42009-08-03 15:16:41 +01001499
1500 /* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be
1501 * better to make use of the per-ifp table of ois.
1502 */
paul1eb8ef22005-04-07 07:30:20 +00001503 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1504 if (if_is_operative (oi->ifp))
1505 if (oi->address->family == AF_INET)
1506 if (prefix_match (oi->address, &nh))
1507 return nexthop;
paul718e3742002-12-13 20:15:29 +00001508
1509 return fwd;
1510}
1511
paul718e3742002-12-13 20:15:29 +00001512/* NSSA-external-LSA related functions. */
1513
1514/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001515
paul718e3742002-12-13 20:15:29 +00001516struct in_addr
1517ospf_get_ip_from_ifp (struct ospf_interface *oi)
1518{
1519 struct in_addr fwd;
1520
1521 fwd.s_addr = 0;
1522
paul2e3b2e42002-12-13 21:03:13 +00001523 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001524 return oi->address->u.prefix4;
1525
1526 return fwd;
1527}
1528
1529/* Get 1st IP connection for Forward Addr */
1530struct in_addr
paulf2c80652002-12-13 21:44:27 +00001531ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001532{
1533 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001534 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001535 struct listnode *node;
1536 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001537
1538 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001539 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001540
paul1eb8ef22005-04-07 07:30:20 +00001541 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001542 {
paul2e3b2e42002-12-13 21:03:13 +00001543 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001544 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001545 if (oi->address && oi->address->family == AF_INET)
1546 {
1547 if (best_default.s_addr == 0)
1548 best_default = oi->address->u.prefix4;
1549 if (oi->area == area)
1550 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001551 }
paul718e3742002-12-13 20:15:29 +00001552 }
paulf2c80652002-12-13 21:44:27 +00001553 if (best_default.s_addr != 0)
1554 return best_default;
paul718e3742002-12-13 20:15:29 +00001555
paul68980082003-03-25 05:07:42 +00001556 if (best_default.s_addr != 0)
1557 return best_default;
1558
paul718e3742002-12-13 20:15:29 +00001559 return fwd;
1560}
hassobeebba72004-06-20 21:00:27 +00001561
paul718e3742002-12-13 20:15:29 +00001562#define DEFAULT_DEFAULT_METRIC 20
1563#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1564#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1565
1566#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1567
1568int
paul68980082003-03-25 05:07:42 +00001569metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001570{
paul68980082003-03-25 05:07:42 +00001571 return (ospf->dmetric[src].type < 0 ?
1572 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001573}
1574
1575int
paul68980082003-03-25 05:07:42 +00001576metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001577{
paul68980082003-03-25 05:07:42 +00001578 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001579 {
1580 if (src == DEFAULT_ROUTE)
1581 {
paul68980082003-03-25 05:07:42 +00001582 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001583 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1584 else
1585 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1586 }
paul68980082003-03-25 05:07:42 +00001587 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001588 return DEFAULT_DEFAULT_METRIC;
1589 else
paul68980082003-03-25 05:07:42 +00001590 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001591 }
1592
paul68980082003-03-25 05:07:42 +00001593 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001594}
1595
1596/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001597static void
paul68980082003-03-25 05:07:42 +00001598ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1599 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001600{
1601 struct prefix_ipv4 *p = &ei->p;
1602 struct in_addr mask, fwd_addr;
1603 u_int32_t mvalue;
1604 int mtype;
1605 int type;
1606
1607 /* Put Network Mask. */
1608 masklen2ip (p->prefixlen, &mask);
1609 stream_put_ipv4 (s, mask.s_addr);
1610
1611 /* If prefix is default, specify DEFAULT_ROUTE. */
1612 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1613
1614 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001615 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001616
1617 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001618 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001619
1620 /* Put type of external metric. */
1621 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1622
1623 /* Put 0 metric. TOS metric is not supported. */
1624 stream_put_ospf_metric (s, mvalue);
1625
1626 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001627 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001628
1629 /* Put forwarding address. */
1630 stream_put_ipv4 (s, fwd_addr.s_addr);
1631
1632 /* Put route tag -- This value should be introduced from configuration. */
1633 stream_putl (s, 0);
1634}
1635
1636/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001637static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001638ospf_external_lsa_new (struct ospf *ospf,
1639 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001640{
1641 struct stream *s;
1642 struct lsa_header *lsah;
1643 struct ospf_lsa *new;
1644 struct in_addr id;
1645 int length;
1646
1647 if (ei == NULL)
1648 {
1649 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
Denis Ovsienkoad8d4802011-12-02 20:02:40 +04001650 zlog_debug ("LSA[Type5]: External info is NULL, can't originate");
paul718e3742002-12-13 20:15:29 +00001651 return NULL;
1652 }
1653
1654 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001655 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001656
1657 /* If old Link State ID is specified, refresh LSA with same ID. */
1658 if (old_id)
1659 id = *old_id;
1660 /* Get Link State with unique ID. */
1661 else
1662 {
paul68980082003-03-25 05:07:42 +00001663 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001664 if (id.s_addr == 0xffffffff)
1665 {
1666 /* Maybe Link State ID not available. */
1667 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001668 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001669 return NULL;
1670 }
1671 }
1672
1673 /* Create new stream for LSA. */
1674 s = stream_new (OSPF_MAX_LSA_SIZE);
1675 lsah = (struct lsa_header *) STREAM_DATA (s);
1676
1677 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001678 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1679 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001680
1681 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001682 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001683
1684 /* Set length. */
1685 length = stream_get_endp (s);
1686 lsah->length = htons (length);
1687
1688 /* Now, create OSPF LSA instance. */
1689 new = ospf_lsa_new ();
1690 new->area = NULL;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001691 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001692
1693 /* Copy LSA data to store, discard stream. */
1694 new->data = ospf_lsa_data_new (length);
1695 memcpy (new->data, lsah, length);
1696 stream_free (s);
1697
1698 return new;
1699}
1700
paul718e3742002-12-13 20:15:29 +00001701/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001702static void
paul68980082003-03-25 05:07:42 +00001703ospf_install_flood_nssa (struct ospf *ospf,
1704 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001705{
pauld4a53d52003-07-12 21:30:57 +00001706 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001707 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001708 struct ospf_area *area;
1709 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001710
pauld4a53d52003-07-12 21:30:57 +00001711 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1712 * which originated from an NSSA area. In which case it should not be
1713 * flooded back to NSSA areas.
1714 */
1715 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1716 return;
1717
paul718e3742002-12-13 20:15:29 +00001718 /* NSSA Originate or Refresh (If anyNSSA)
1719
1720 LSA is self-originated. And just installed as Type-5.
1721 Additionally, install as Type-7 LSDB for every attached NSSA.
1722
1723 P-Bit controls which ABR performs translation to outside world; If
1724 we are an ABR....do not set the P-bit, because we send the Type-5,
1725 not as the ABR Translator, but as the ASBR owner within the AS!
1726
1727 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1728 elected ABR Translator will see the P-bit, Translate, and re-flood.
1729
1730 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1731 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1732
paul1eb8ef22005-04-07 07:30:20 +00001733 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001734 {
hasso0c14ad82003-07-03 08:36:02 +00001735 /* Don't install Type-7 LSA's into nonNSSA area */
1736 if (area->external_routing != OSPF_AREA_NSSA)
1737 continue;
paul718e3742002-12-13 20:15:29 +00001738
paul68980082003-03-25 05:07:42 +00001739 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001740 new = ospf_lsa_dup (lsa);
1741 new->area = area;
1742 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001743
paul68980082003-03-25 05:07:42 +00001744 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001745 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001746 {
pauld4a53d52003-07-12 21:30:57 +00001747 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001748
1749 /* set non-zero FWD ADDR
1750
1751 draft-ietf-ospf-nssa-update-09.txt
1752
1753 if the network between the NSSA AS boundary router and the
1754 adjacent AS is advertised into OSPF as an internal OSPF route,
1755 the forwarding address should be the next op address as is cu
1756 currently done with type-5 LSAs. If the intervening network is
1757 not adversited into OSPF as an internal OSPF route and the
1758 type-7 LSA's P-bit is set a forwarding address should be
1759 selected from one of the router's active OSPF inteface addresses
1760 which belong to the NSSA. If no such addresses exist, then
1761 no type-7 LSA's with the P-bit set should originate from this
1762 router. */
1763
pauld4a53d52003-07-12 21:30:57 +00001764 /* kevinm: not updating lsa anymore, just new */
1765 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001766
1767 if (extlsa->e[0].fwd_addr.s_addr == 0)
1768 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001769
pauld7480322003-05-16 17:31:51 +00001770 if (extlsa->e[0].fwd_addr.s_addr == 0)
1771 {
1772 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001773 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001774 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001775 return;
1776 }
paulf2c80652002-12-13 21:44:27 +00001777 }
paul718e3742002-12-13 20:15:29 +00001778
paul68980082003-03-25 05:07:42 +00001779 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001780 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001781
1782 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001783 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001784 }
paul718e3742002-12-13 20:15:29 +00001785}
pauld4a53d52003-07-12 21:30:57 +00001786
paul4dadc292005-05-06 21:37:42 +00001787static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001788ospf_lsa_translated_nssa_new (struct ospf *ospf,
1789 struct ospf_lsa *type7)
1790{
1791
1792 struct ospf_lsa *new;
1793 struct as_external_lsa *ext, *extnew;
1794 struct external_info ei;
1795
1796 ext = (struct as_external_lsa *)(type7->data);
1797
1798 /* need external_info struct, fill in bare minimum */
1799 ei.p.family = AF_INET;
1800 ei.p.prefix = type7->data->id;
1801 ei.p.prefixlen = ip_masklen (ext->mask);
1802 ei.type = ZEBRA_ROUTE_OSPF;
1803 ei.nexthop = ext->header.adv_router;
1804 ei.route_map_set.metric = -1;
1805 ei.route_map_set.metric_type = -1;
1806 ei.tag = 0;
1807
1808 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1809 {
1810 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001811 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001812 "Translated Type-5 for %s",
1813 inet_ntoa (ei.p.prefix));
1814 return NULL;
1815 }
1816
1817 extnew = (struct as_external_lsa *)(new->data);
1818
1819 /* copy over Type-7 data to new */
1820 extnew->e[0].tos = ext->e[0].tos;
1821 extnew->e[0].route_tag = ext->e[0].route_tag;
1822 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1823 new->data->ls_seqnum = type7->data->ls_seqnum;
1824
1825 /* add translated flag, checksum and lock new lsa */
1826 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
pauld4a53d52003-07-12 21:30:57 +00001827 new = ospf_lsa_lock (new);
1828
1829 return new;
1830}
1831
pauld4a53d52003-07-12 21:30:57 +00001832/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1833struct ospf_lsa *
1834ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1835{
1836 struct ospf_lsa *new;
1837 struct as_external_lsa *extnew;
1838
1839 /* we cant use ospf_external_lsa_originate() as we need to set
1840 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1841 */
1842
1843 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1844 {
1845 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001846 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001847 "Type-7, Id %s, to Type-5",
1848 inet_ntoa (type7->data->id));
1849 return NULL;
1850 }
1851
1852 extnew = (struct as_external_lsa *)new;
1853
1854 if (IS_DEBUG_OSPF_NSSA)
1855 {
ajse588f212004-12-08 18:12:06 +00001856 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001857 "translated Type 7, installed:");
1858 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001859 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1860 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001861 }
1862
1863 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1864 {
Hasso Tepper8c9ed272012-10-11 11:15:18 +00001865 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001866 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001867 "Could not install LSA "
1868 "id %s", inet_ntoa (type7->data->id));
1869 return NULL;
1870 }
1871
1872 ospf->lsa_originate_count++;
1873 ospf_flood_through_as (ospf, NULL, new);
1874
1875 return new;
1876}
1877
1878/* Refresh Translated from NSSA AS-external-LSA. */
1879struct ospf_lsa *
1880ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1881 struct ospf_lsa *type5)
1882{
1883 struct ospf_lsa *new = NULL;
1884
1885 /* Sanity checks. */
1886 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00001887 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00001888 return NULL;
pauld4a53d52003-07-12 21:30:57 +00001889 if (type7)
1890 assert (type7->data);
1891 if (type5)
1892 assert (type5->data);
1893 assert (ospf->anyNSSA);
1894
1895 /* get required data according to what has been given */
1896 if (type7 && type5 == NULL)
1897 {
1898 /* find the translated Type-5 for this Type-7 */
1899 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1900 struct prefix_ipv4 p =
1901 {
1902 .prefix = type7->data->id,
1903 .prefixlen = ip_masklen (ext->mask),
1904 .family = AF_INET,
1905 };
1906
1907 type5 = ospf_external_info_find_lsa (ospf, &p);
1908 }
1909 else if (type5 && type7 == NULL)
1910 {
1911 /* find the type-7 from which supplied type-5 was translated,
1912 * ie find first type-7 with same LSA Id.
1913 */
paul1eb8ef22005-04-07 07:30:20 +00001914 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00001915 struct route_node *rn;
1916 struct ospf_lsa *lsa;
1917 struct ospf_area *area;
1918
paul1eb8ef22005-04-07 07:30:20 +00001919 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00001920 {
1921 if (area->external_routing != OSPF_AREA_NSSA
1922 && !type7)
1923 continue;
1924
1925 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
1926 {
1927 if (lsa->data->id.s_addr == type5->data->id.s_addr)
1928 {
1929 type7 = lsa;
1930 break;
1931 }
1932 }
1933 }
1934 }
1935
1936 /* do we have type7? */
1937 if (!type7)
1938 {
1939 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001940 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00001941 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00001942 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00001943 return NULL;
1944 }
1945
1946 /* do we have valid translated type5? */
1947 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
1948 {
1949 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001950 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00001951 "found for Type-7 with Id %s",
1952 inet_ntoa (type7->data->id));
1953 return NULL;
1954 }
1955
1956 /* Delete LSA from neighbor retransmit-list. */
1957 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
1958
1959 /* create new translated LSA */
1960 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1961 {
1962 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001963 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001964 "Type-7 for %s to Type-5",
1965 inet_ntoa (type7->data->id));
1966 return NULL;
1967 }
1968
1969 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
1970 {
1971 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001972 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00001973 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00001974 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00001975 return NULL;
1976 }
1977
1978 /* Flood LSA through area. */
1979 ospf_flood_through_as (ospf, NULL, new);
1980
1981 return new;
1982}
paul718e3742002-12-13 20:15:29 +00001983
1984int
1985is_prefix_default (struct prefix_ipv4 *p)
1986{
1987 struct prefix_ipv4 q;
1988
1989 q.family = AF_INET;
1990 q.prefix.s_addr = 0;
1991 q.prefixlen = 0;
1992
1993 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
1994}
1995
1996/* Originate an AS-external-LSA, install and flood. */
1997struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001998ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001999{
2000 struct ospf_lsa *new;
2001
2002 /* Added for NSSA project....
2003
2004 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2005 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2006 every area. The Type-7's are flooded to every IR and every ABR; We
2007 install the Type-5 LSDB so that the normal "refresh" code operates
2008 as usual, and flag them as not used during ASE calculations. The
2009 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2010 Address of non-zero.
2011
2012 If an ABR is the elected NSSA translator, following SPF and during
2013 the ABR task it will translate all the scanned Type-7's, with P-bit
2014 ON and not-self generated, and translate to Type-5's throughout the
2015 non-NSSA/STUB AS.
2016
2017 A difference in operation depends whether this ASBR is an ABR
2018 or not. If not an ABR, the P-bit is ON, to indicate that any
2019 elected NSSA-ABR can perform its translation.
2020
2021 If an ABR, the P-bit is OFF; No ABR will perform translation and
2022 this ASBR will flood the Type-5 LSA as usual.
2023
2024 For the case where this ASBR is not an ABR, the ASE calculations
2025 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2026 demonstrate to the user that there are LSA's that belong to any
2027 attached NSSA.
2028
2029 Finally, it just so happens that when the ABR is translating every
2030 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2031 approved Type-5 (translated from Type-7); at the end of translation
2032 if any Translated Type-5's remain unapproved, then they must be
2033 flushed from the AS.
2034
2035 */
2036
2037 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002038 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002039 return NULL;
2040
2041 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002042 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002043 {
2044 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002045 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002046 inet_ntoa (ei->p.prefix));
2047 return NULL;
2048 }
2049
2050 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002051 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002052
2053 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002054 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002055
2056 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002057 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002058
paul718e3742002-12-13 20:15:29 +00002059 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002060 if (ospf->anyNSSA &&
2061 /* stay away from translated LSAs! */
2062 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002063 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002064
2065 /* Debug logging. */
2066 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2067 {
ajse588f212004-12-08 18:12:06 +00002068 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
paul718e3742002-12-13 20:15:29 +00002069 new->data->type, inet_ntoa (new->data->id), new);
2070 ospf_lsa_header_dump (new->data);
2071 }
2072
2073 return new;
2074}
2075
2076/* Originate AS-external-LSA from external info with initial flag. */
2077int
paul68980082003-03-25 05:07:42 +00002078ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002079{
paul68980082003-03-25 05:07:42 +00002080 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002081 struct route_node *rn;
2082 struct external_info *ei;
2083 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002084 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002085
paul68980082003-03-25 05:07:42 +00002086 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002087
2088 /* Originate As-external-LSA from all type of distribute source. */
2089 if ((rt = EXTERNAL_INFO (type)))
2090 for (rn = route_top (rt); rn; rn = route_next (rn))
2091 if ((ei = rn->info) != NULL)
2092 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002093 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002094 zlog_warn ("LSA: AS-external-LSA was not originated.");
2095
2096 return 0;
2097}
2098
paul4dadc292005-05-06 21:37:42 +00002099static struct external_info *
paul020709f2003-04-04 02:44:16 +00002100ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002101{
2102 int type;
2103 struct route_node *rn;
2104 struct prefix_ipv4 p;
2105
2106 p.family = AF_INET;
2107 p.prefix.s_addr = 0;
2108 p.prefixlen = 0;
2109
2110 /* First, lookup redistributed default route. */
2111 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2112 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2113 {
2114 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2115 if (rn != NULL)
2116 {
2117 route_unlock_node (rn);
2118 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002119 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002120 return rn->info;
2121 }
2122 }
2123
2124 return NULL;
2125}
2126
2127int
paul68980082003-03-25 05:07:42 +00002128ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002129{
paul718e3742002-12-13 20:15:29 +00002130 struct prefix_ipv4 p;
2131 struct in_addr nexthop;
2132 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002133 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002134
Paul Jakma4021b602006-05-12 22:55:41 +00002135 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002136
2137 p.family = AF_INET;
2138 p.prefix.s_addr = 0;
2139 p.prefixlen = 0;
2140
Paul Jakma4021b602006-05-12 22:55:41 +00002141 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002142 {
2143 /* If there is no default route via redistribute,
2144 then originate AS-external-LSA with nexthop 0 (self). */
2145 nexthop.s_addr = 0;
2146 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2147 }
2148
paul020709f2003-04-04 02:44:16 +00002149 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002150 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002151
2152 return 0;
2153}
2154
paul645878f2003-04-13 21:42:11 +00002155/* Flush any NSSA LSAs for given prefix */
2156void
2157ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2158{
paul1eb8ef22005-04-07 07:30:20 +00002159 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002160 struct ospf_lsa *lsa;
2161 struct ospf_area *area;
2162
paul1eb8ef22005-04-07 07:30:20 +00002163 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002164 {
paul1eb8ef22005-04-07 07:30:20 +00002165 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002166 {
2167 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2168 ospf->router_id)))
2169 {
2170 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002171 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002172 inet_ntoa (p->prefix), p->prefixlen);
2173 continue;
2174 }
2175 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2176 if (!IS_LSA_MAXAGE (lsa))
2177 {
2178 ospf_refresher_unregister_lsa (ospf, lsa);
2179 ospf_lsa_flush_area (lsa, area);
2180 }
2181 }
paul645878f2003-04-13 21:42:11 +00002182 }
2183}
paul645878f2003-04-13 21:42:11 +00002184
paul718e3742002-12-13 20:15:29 +00002185/* Flush an AS-external-LSA from LSDB and routing domain. */
2186void
paul68980082003-03-25 05:07:42 +00002187ospf_external_lsa_flush (struct ospf *ospf,
2188 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002189 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002190{
2191 struct ospf_lsa *lsa;
2192
2193 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002194 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002195 inet_ntoa (p->prefix), p->prefixlen);
2196
2197 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002198 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002199 {
2200 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002201 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002202 inet_ntoa (p->prefix), p->prefixlen);
2203 return;
2204 }
hassobeebba72004-06-20 21:00:27 +00002205
pauld4a53d52003-07-12 21:30:57 +00002206 /* If LSA is selforiginated, not a translated LSA, and there is
2207 * NSSA area, flush Type-7 LSA's at first.
2208 */
2209 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2210 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002211 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002212
2213 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002214 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002215
2216 /* There must be no self-originated LSA in rtrs_external. */
2217#if 0
2218 /* Remove External route from Zebra. */
2219 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2220#endif
2221
2222 if (!IS_LSA_MAXAGE (lsa))
2223 {
2224 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002225 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002226
2227 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002228 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002229 }
2230
2231 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002232 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002233}
2234
2235void
paul68980082003-03-25 05:07:42 +00002236ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002237{
2238 struct prefix_ipv4 p;
2239 struct external_info *ei;
2240 struct ospf_lsa *lsa;
2241
2242 p.family = AF_INET;
2243 p.prefixlen = 0;
2244 p.prefix.s_addr = 0;
2245
paul020709f2003-04-04 02:44:16 +00002246 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002247 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002248
2249 if (ei)
2250 {
2251 if (lsa)
2252 {
2253 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002254 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
paul68980082003-03-25 05:07:42 +00002255 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002256 }
2257 else
2258 {
2259 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002260 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002261 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002262 }
2263 }
2264 else
2265 {
2266 if (lsa)
2267 {
2268 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002269 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
Paul Jakmadfbd5172010-04-14 10:32:12 +01002270 ospf_refresher_unregister_lsa (ospf, lsa);
paul68980082003-03-25 05:07:42 +00002271 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002272 }
2273 }
2274}
2275
2276void
paul68980082003-03-25 05:07:42 +00002277ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002278{
2279 struct route_node *rn;
2280 struct external_info *ei;
2281
2282 if (type != DEFAULT_ROUTE)
2283 if (EXTERNAL_INFO(type))
2284 /* Refresh each redistributed AS-external-LSAs. */
2285 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2286 if ((ei = rn->info))
2287 if (!is_prefix_default (&ei->p))
2288 {
2289 struct ospf_lsa *lsa;
2290
paul68980082003-03-25 05:07:42 +00002291 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2292 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002293 else
paul68980082003-03-25 05:07:42 +00002294 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002295 }
2296}
2297
2298/* Refresh AS-external-LSA. */
Paul Jakmac363d382010-01-24 22:42:13 +00002299struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002300ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002301 struct external_info *ei, int force)
2302{
2303 struct ospf_lsa *new;
2304 int changed;
2305
2306 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002307 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002308 {
pauld4a53d52003-07-12 21:30:57 +00002309 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002310 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002311 "redist check fail",
2312 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002313 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002314 ei->ifindex /*, ei->nexthop */);
Paul Jakmac363d382010-01-24 22:42:13 +00002315 return NULL;
paul718e3742002-12-13 20:15:29 +00002316 }
2317
2318 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002319 {
2320 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002321 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002322 lsa->data->type, inet_ntoa (lsa->data->id));
Paul Jakmac363d382010-01-24 22:42:13 +00002323 return NULL;
pauld4a53d52003-07-12 21:30:57 +00002324 }
paul718e3742002-12-13 20:15:29 +00002325
2326 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002327 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002328
2329 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002330 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002331
paul68980082003-03-25 05:07:42 +00002332 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002333
2334 if (new == NULL)
2335 {
2336 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002337 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002338 inet_ntoa (lsa->data->id));
Paul Jakmac363d382010-01-24 22:42:13 +00002339 return NULL;
paul718e3742002-12-13 20:15:29 +00002340 }
2341
2342 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2343
paul68980082003-03-25 05:07:42 +00002344 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002345
2346 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002347 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002348
paul718e3742002-12-13 20:15:29 +00002349 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002350 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002351 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002352
pauld4a53d52003-07-12 21:30:57 +00002353 /* Register self-originated LSA to refresh queue.
2354 * Translated LSAs should not be registered, but refreshed upon
2355 * refresh of the Type-7
2356 */
2357 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2358 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002359
2360 /* Debug logging. */
2361 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2362 {
ajse588f212004-12-08 18:12:06 +00002363 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002364 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002365 ospf_lsa_header_dump (new->data);
2366 }
2367
Paul Jakmac363d382010-01-24 22:42:13 +00002368 return new;
paul718e3742002-12-13 20:15:29 +00002369}
2370
2371
2372/* LSA installation functions. */
2373
2374/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002375static struct ospf_lsa *
Paul Jakmac363d382010-01-24 22:42:13 +00002376ospf_router_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2377 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002378{
2379 struct ospf_area *area = new->area;
2380
2381 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2382 The entire routing table must be recalculated, starting with
2383 the shortest path calculations for each area (not just the
2384 area whose link-state database has changed).
2385 */
paul718e3742002-12-13 20:15:29 +00002386
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002387 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002388 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002389
2390 /* Only install LSA if it is originated/refreshed by us.
2391 * If LSA was received by flooding, the RECEIVED flag is set so do
2392 * not link the LSA */
2393 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2394 return new; /* ignore stale LSA */
2395
paul718e3742002-12-13 20:15:29 +00002396 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002397 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002398 area->router_lsa_self = ospf_lsa_lock (new);
2399
Paul Jakmac363d382010-01-24 22:42:13 +00002400 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002401 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002402 if (rt_recalc)
2403 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002404
2405 return new;
2406}
2407
2408#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2409 if (!(T)) \
2410 (T) = thread_add_timer (master, (F), oi, (V))
2411
2412/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002413static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002414ospf_network_lsa_install (struct ospf *ospf,
2415 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002416 struct ospf_lsa *new,
2417 int rt_recalc)
2418{
2419
2420 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2421 The entire routing table must be recalculated, starting with
2422 the shortest path calculations for each area (not just the
2423 area whose link-state database has changed).
2424 */
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002425 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002426 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002427 /* We supposed that when LSA is originated by us, we pass the int
2428 for which it was originated. If LSA was received by flooding,
2429 the RECEIVED flag is set, so we do not link the LSA to the int. */
2430 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2431 return new; /* ignore stale LSA */
2432
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002433 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002434 oi->network_lsa_self = ospf_lsa_lock (new);
Paul Jakmac363d382010-01-24 22:42:13 +00002435 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002436 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002437 if (rt_recalc)
2438 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002439
2440 return new;
2441}
2442
2443/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002444static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002445ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2446 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002447{
paul718e3742002-12-13 20:15:29 +00002448 if (rt_recalc && !IS_LSA_SELF (new))
2449 {
2450 /* RFC 2328 Section 13.2 Summary-LSAs
2451 The best route to the destination described by the summary-
2452 LSA must be recalculated (see Section 16.5). If this
2453 destination is an AS boundary router, it may also be
2454 necessary to re-examine all the AS-external-LSAs.
2455 */
2456
2457#if 0
2458 /* This doesn't exist yet... */
2459 ospf_summary_incremental_update(new); */
2460#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002461 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002462#endif /* #if 0 */
2463
2464 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002465 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
paul718e3742002-12-13 20:15:29 +00002466 }
2467
2468 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002469 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002470
2471 return new;
2472}
2473
2474/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002475static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002476ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2477 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002478{
2479 if (rt_recalc && !IS_LSA_SELF (new))
2480 {
2481 /* RFC 2328 Section 13.2 Summary-LSAs
2482 The best route to the destination described by the summary-
2483 LSA must be recalculated (see Section 16.5). If this
2484 destination is an AS boundary router, it may also be
2485 necessary to re-examine all the AS-external-LSAs.
2486 */
2487#if 0
2488 /* These don't exist yet... */
2489 ospf_summary_incremental_update(new);
2490 /* Isn't this done by the above call?
2491 - RFC 2328 Section 16.5 implies it should be */
2492 /* ospf_ase_calculate_schedule(); */
2493#else /* #if 0 */
paul68980082003-03-25 05:07:42 +00002494 ospf_spf_calculate_schedule (ospf);
paul718e3742002-12-13 20:15:29 +00002495#endif /* #if 0 */
2496 }
2497
2498 /* register LSA to refresh-list. */
2499 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002500 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002501
2502 return new;
2503}
2504
2505/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002506static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002507ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2508 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002509{
paul68980082003-03-25 05:07:42 +00002510 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002511 /* If LSA is not self-originated, calculate an external route. */
2512 if (rt_recalc)
2513 {
2514 /* RFC 2328 Section 13.2 AS-external-LSAs
2515 The best route to the destination described by the AS-
2516 external-LSA must be recalculated (see Section 16.6).
2517 */
2518
2519 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002520 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002521 }
2522
pauld4a53d52003-07-12 21:30:57 +00002523 if (new->data->type == OSPF_AS_NSSA_LSA)
2524 {
2525 /* There is no point to register selforiginate Type-7 LSA for
2526 * refreshing. We rely on refreshing Type-5 LSA's
2527 */
2528 if (IS_LSA_SELF (new))
2529 return new;
2530 else
2531 {
2532 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2533 * New translations will be taken care of by the abr_task.
2534 */
2535 ospf_translated_nssa_refresh (ospf, new, NULL);
2536 }
2537 }
pauld7480322003-05-16 17:31:51 +00002538
pauld4a53d52003-07-12 21:30:57 +00002539 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002540 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002541 */
hassobeebba72004-06-20 21:00:27 +00002542 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002543 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002544
2545 return new;
2546}
2547
2548void
paul68980082003-03-25 05:07:42 +00002549ospf_discard_from_db (struct ospf *ospf,
2550 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002551{
2552 struct ospf_lsa *old;
2553
Paul Jakmaac904de2006-06-15 12:04:57 +00002554 if (!lsdb)
2555 {
2556 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2557 if (!lsa)
2558 zlog_warn ("%s: and NULL LSA!", __func__);
2559 else
2560 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2561 lsa->data->type, inet_ntoa (lsa->data->id));
2562 return;
2563 }
2564
paul718e3742002-12-13 20:15:29 +00002565 old = ospf_lsdb_lookup (lsdb, lsa);
2566
2567 if (!old)
2568 return;
2569
2570 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002571 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002572
2573 switch (old->data->type)
2574 {
2575 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002576 ospf_ase_unregister_external_lsa (old, ospf);
2577 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2578 break;
paul718e3742002-12-13 20:15:29 +00002579#ifdef HAVE_OPAQUE_LSA
2580 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002581 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002582 break;
paul69310a62005-05-11 18:09:59 +00002583#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002584 case OSPF_AS_NSSA_LSA:
2585 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2586 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002587 break;
paul718e3742002-12-13 20:15:29 +00002588 default:
paul68980082003-03-25 05:07:42 +00002589 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002590 break;
2591 }
2592
paul68980082003-03-25 05:07:42 +00002593 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002594 ospf_lsa_discard (old);
2595}
2596
paul718e3742002-12-13 20:15:29 +00002597struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002598ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2599 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002600{
2601 struct ospf_lsa *new = NULL;
2602 struct ospf_lsa *old = NULL;
2603 struct ospf_lsdb *lsdb = NULL;
2604 int rt_recalc;
2605
2606 /* Set LSDB. */
2607 switch (lsa->data->type)
2608 {
paulf2c80652002-12-13 21:44:27 +00002609 /* kevinm */
2610 case OSPF_AS_NSSA_LSA:
2611 if (lsa->area)
2612 lsdb = lsa->area->lsdb;
2613 else
paul68980082003-03-25 05:07:42 +00002614 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002615 break;
paul718e3742002-12-13 20:15:29 +00002616 case OSPF_AS_EXTERNAL_LSA:
2617#ifdef HAVE_OPAQUE_LSA
2618 case OSPF_OPAQUE_AS_LSA:
2619#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002620 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002621 break;
2622 default:
2623 lsdb = lsa->area->lsdb;
2624 break;
2625 }
2626
paul718e3742002-12-13 20:15:29 +00002627 assert (lsdb);
2628
2629 /* RFC 2328 13.2. Installing LSAs in the database
2630
2631 Installing a new LSA in the database, either as the result of
2632 flooding or a newly self-originated LSA, may cause the OSPF
2633 routing table structure to be recalculated. The contents of the
2634 new LSA should be compared to the old instance, if present. If
2635 there is no difference, there is no need to recalculate the
2636 routing table. When comparing an LSA to its previous instance,
2637 the following are all considered to be differences in contents:
2638
2639 o The LSA's Options field has changed.
2640
2641 o One of the LSA instances has LS age set to MaxAge, and
2642 the other does not.
2643
2644 o The length field in the LSA header has changed.
2645
2646 o The body of the LSA (i.e., anything outside the 20-byte
2647 LSA header) has changed. Note that this excludes changes
2648 in LS Sequence Number and LS Checksum.
2649
2650 */
2651 /* Look up old LSA and determine if any SPF calculation or incremental
2652 update is needed */
2653 old = ospf_lsdb_lookup (lsdb, lsa);
2654
2655 /* Do comparision and record if recalc needed. */
2656 rt_recalc = 0;
2657 if ( old == NULL || ospf_lsa_different(old, lsa))
2658 rt_recalc = 1;
2659
paul7ddf1d62003-10-13 09:06:46 +00002660 /*
2661 Sequence number check (Section 14.1 of rfc 2328)
2662 "Premature aging is used when it is time for a self-originated
2663 LSA's sequence number field to wrap. At this point, the current
2664 LSA instance (having LS sequence number MaxSequenceNumber) must
2665 be prematurely aged and flushed from the routing domain before a
2666 new instance with sequence number equal to InitialSequenceNumber
2667 can be originated. "
2668 */
2669
Paul Jakmac2b478d2006-03-30 14:16:11 +00002670 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002671 {
2672 if (ospf_lsa_is_self_originated(ospf, lsa))
2673 {
paul0c2be262004-05-31 14:16:54 +00002674 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2675
2676 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002677 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2678 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2679
2680 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2681 {
ajse588f212004-12-08 18:12:06 +00002682 zlog_debug ("ospf_lsa_install() Premature Aging "
Paul Jakmac363d382010-01-24 22:42:13 +00002683 "lsa 0x%p, seqnum 0x%x",
2684 lsa, ntohl(lsa->data->ls_seqnum));
paul7ddf1d62003-10-13 09:06:46 +00002685 ospf_lsa_header_dump (lsa->data);
2686 }
2687 }
2688 else
2689 {
2690 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2691 {
ajse588f212004-12-08 18:12:06 +00002692 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002693 "that was not self originated. Ignoring\n");
2694 ospf_lsa_header_dump (lsa->data);
2695 }
2696 return old;
2697 }
2698 }
2699
paul718e3742002-12-13 20:15:29 +00002700 /* discard old LSA from LSDB */
2701 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002702 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002703
paul718e3742002-12-13 20:15:29 +00002704 /* Calculate Checksum if self-originated?. */
2705 if (IS_LSA_SELF (lsa))
2706 ospf_lsa_checksum (lsa->data);
2707
hassofe71a972004-12-22 16:16:02 +00002708 /* Insert LSA to LSDB. */
2709 ospf_lsdb_add (lsdb, lsa);
2710 lsa->lsdb = lsdb;
2711
paul718e3742002-12-13 20:15:29 +00002712 /* Do LSA specific installation process. */
2713 switch (lsa->data->type)
2714 {
2715 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002716 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002717 break;
2718 case OSPF_NETWORK_LSA:
2719 assert (oi);
paul68980082003-03-25 05:07:42 +00002720 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002721 break;
2722 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002723 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002724 break;
2725 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002726 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002727 break;
2728 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002729 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002730 break;
2731#ifdef HAVE_OPAQUE_LSA
2732 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002733 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002734 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002735 else
Andrew Certain0798cee2012-12-04 13:43:42 -08002736 {
2737 /* Incoming "oi" for this LSA has set at LSUpd reception. */
2738 }
paul09e4efd2003-01-18 00:12:02 +00002739 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002740 case OSPF_OPAQUE_AREA_LSA:
2741 case OSPF_OPAQUE_AS_LSA:
2742 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2743 break;
2744#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002745 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002746 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002747 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002748 break;
2749 }
2750
2751 if (new == NULL)
2752 return new; /* Installation failed, cannot proceed further -- endo. */
2753
2754 /* Debug logs. */
2755 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2756 {
2757 char area_str[INET_ADDRSTRLEN];
2758
2759 switch (lsa->data->type)
2760 {
2761 case OSPF_AS_EXTERNAL_LSA:
2762#ifdef HAVE_OPAQUE_LSA
2763 case OSPF_OPAQUE_AS_LSA:
2764#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002765 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002766 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002767 dump_lsa_key (new),
2768 LOOKUP (ospf_lsa_type_msg, new->data->type));
2769 break;
2770 default:
2771 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002772 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002773 dump_lsa_key (new),
2774 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2775 break;
2776 }
2777 }
2778
paul7ddf1d62003-10-13 09:06:46 +00002779 /*
2780 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2781 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2782 */
Dinesh G Dutte0630cb2013-01-07 10:12:52 -08002783 if (IS_LSA_MAXAGE (new))
paul718e3742002-12-13 20:15:29 +00002784 {
paul7ddf1d62003-10-13 09:06:46 +00002785 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002786 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
paul0c2be262004-05-31 14:16:54 +00002787 new->data->type,
2788 inet_ntoa (new->data->id),
2789 lsa);
Dinesh G Dutte0630cb2013-01-07 10:12:52 -08002790 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002791 }
2792
2793 return new;
2794}
2795
2796
paul4dadc292005-05-06 21:37:42 +00002797static int
paul68980082003-03-25 05:07:42 +00002798ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002799{
paul1eb8ef22005-04-07 07:30:20 +00002800 struct listnode *node, *nnode;
2801 struct ospf_interface *oi;
2802
2803 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002804 {
paul718e3742002-12-13 20:15:29 +00002805 struct route_node *rn;
2806 struct ospf_neighbor *nbr;
2807
2808 if (ospf_if_is_enable (oi))
2809 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2810 if ((nbr = rn->info) != NULL)
2811 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2812 {
2813 route_unlock_node (rn);
2814 return 0;
2815 }
2816 }
2817
2818 return 1;
2819}
2820
2821
paul718e3742002-12-13 20:15:29 +00002822
paul4dadc292005-05-06 21:37:42 +00002823static int
paul718e3742002-12-13 20:15:29 +00002824ospf_maxage_lsa_remover (struct thread *thread)
2825{
paul68980082003-03-25 05:07:42 +00002826 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002827 struct ospf_lsa *lsa;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002828 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00002829 int reschedule = 0;
2830
paul68980082003-03-25 05:07:42 +00002831 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002832
2833 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002834 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002835
paul68980082003-03-25 05:07:42 +00002836 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002837
2838 if (!reschedule)
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002839 for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn))
paul718e3742002-12-13 20:15:29 +00002840 {
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002841 if ((lsa = rn->info) == NULL)
2842 {
2843 continue;
2844 }
2845
paul718e3742002-12-13 20:15:29 +00002846 if (lsa->retransmit_counter > 0)
2847 {
2848 reschedule = 1;
2849 continue;
2850 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002851
2852 /* TODO: maybe convert this function to a work-queue */
2853 if (thread_should_yield (thread))
2854 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);
2855
paul718e3742002-12-13 20:15:29 +00002856 /* Remove LSA from the LSDB */
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04002857 if (IS_LSA_SELF (lsa))
paul718e3742002-12-13 20:15:29 +00002858 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
Denis Ovsienkoad8d4802011-12-02 20:02:40 +04002859 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-originated: ",
paul7ddf1d62003-10-13 09:06:46 +00002860 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002861
2862 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002863 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002864 lsa->data->type, inet_ntoa (lsa->data->id));
2865
Paul Jakmac363d382010-01-24 22:42:13 +00002866 if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))
paul7ddf1d62003-10-13 09:06:46 +00002867 {
2868 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
Paul Jakmac363d382010-01-24 22:42:13 +00002869 zlog_debug ("originating new lsa for lsa 0x%p\n", lsa);
2870 ospf_lsa_refresh (ospf, lsa);
paul7ddf1d62003-10-13 09:06:46 +00002871 }
2872
paul718e3742002-12-13 20:15:29 +00002873 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002874 if (lsa->lsdb)
2875 {
2876 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2877 ospf_lsdb_delete (lsa->lsdb, lsa);
2878 }
2879 else
2880 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2881 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002882 }
2883
2884 /* A MaxAge LSA must be removed immediately from the router's link
2885 state database as soon as both a) it is no longer contained on any
2886 neighbor Link state retransmission lists and b) none of the router's
2887 neighbors are in states Exchange or Loading. */
2888 if (reschedule)
Paul Jakma02d942c2010-01-24 23:36:20 +00002889 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2890 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002891
2892 return 0;
2893}
2894
paul718e3742002-12-13 20:15:29 +00002895void
paul68980082003-03-25 05:07:42 +00002896ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002897{
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002898 struct route_node *rn;
2899 struct prefix_ls lsa_prefix;
paul718e3742002-12-13 20:15:29 +00002900
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002901 ls_prefix_set (&lsa_prefix, lsa);
2902
2903 if ((rn = route_node_lookup(ospf->maxage_lsa,
2904 (struct prefix *)&lsa_prefix)))
paul718e3742002-12-13 20:15:29 +00002905 {
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002906 if (rn->info == lsa)
2907 {
2908 UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
2909 ospf_lsa_unlock (&lsa); /* maxage_lsa */
2910 rn->info = NULL;
2911 route_unlock_node (rn); /* route_node_lookup */
2912 }
2913 route_unlock_node (rn); /* route_node_lookup */
paul718e3742002-12-13 20:15:29 +00002914 }
2915}
2916
Paul Jakma02d942c2010-01-24 23:36:20 +00002917/* Add LSA onto the MaxAge list, and schedule for removal.
2918 * This does *not* lead to the LSA being flooded, that must be taken
2919 * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
2920 * function).
2921 */
paul718e3742002-12-13 20:15:29 +00002922void
paul68980082003-03-25 05:07:42 +00002923ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002924{
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002925 struct prefix_ls lsa_prefix;
2926 struct route_node *rn;
2927
paul718e3742002-12-13 20:15:29 +00002928 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2929 and schedule the MaxAge LSA remover. */
Stephen Hemminger3106a032009-08-06 12:58:05 -07002930 if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
paul718e3742002-12-13 20:15:29 +00002931 {
2932 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002933 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00002934 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2935 return;
2936 }
2937
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002938 ls_prefix_set (&lsa_prefix, lsa);
2939 if ((rn = route_node_get (ospf->maxage_lsa,
2940 (struct prefix *)&lsa_prefix)) != NULL)
2941 {
2942 if (rn->info != NULL)
2943 {
2944 route_unlock_node (rn);
2945 }
2946 else
2947 {
2948 rn->info = ospf_lsa_lock(lsa);
2949 SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
2950 }
2951 }
2952 else
2953 {
2954 zlog_err("Unable to allocate memory for maxage lsa\n");
2955 assert(0);
2956 }
paul718e3742002-12-13 20:15:29 +00002957
2958 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002959 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002960
Paul Jakma02d942c2010-01-24 23:36:20 +00002961 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2962 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002963}
2964
paul4dadc292005-05-06 21:37:42 +00002965static int
paul68980082003-03-25 05:07:42 +00002966ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002967{
paul718e3742002-12-13 20:15:29 +00002968 /* Stay away from any Local Translated Type-7 LSAs */
2969 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2970 return 0;
paul718e3742002-12-13 20:15:29 +00002971
2972 if (IS_LSA_MAXAGE (lsa))
2973 /* Self-originated LSAs should NOT time-out instead,
2974 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00002975 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002976 {
2977 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002978 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002979
2980 switch (lsa->data->type)
2981 {
paul718e3742002-12-13 20:15:29 +00002982#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00002983 case OSPF_OPAQUE_LINK_LSA:
2984 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00002985 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00002986 /*
2987 * As a general rule, whenever network topology has changed
2988 * (due to an LSA removal in this case), routing recalculation
2989 * should be triggered. However, this is not true for opaque
2990 * LSAs. Even if an opaque LSA instance is going to be removed
2991 * from the routing domain, it does not mean a change in network
2992 * topology, and thus, routing recalculation is not needed here.
2993 */
2994 break;
paul718e3742002-12-13 20:15:29 +00002995#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00002996 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00002997 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002998 ospf_ase_incremental_update (ospf, lsa);
2999 break;
paul718e3742002-12-13 20:15:29 +00003000 default:
paul68980082003-03-25 05:07:42 +00003001 ospf_spf_calculate_schedule (ospf);
3002 break;
paul718e3742002-12-13 20:15:29 +00003003 }
paul68980082003-03-25 05:07:42 +00003004 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003005 }
3006
Paul Jakmac363d382010-01-24 22:42:13 +00003007 if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa))
3008 if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30)
3009 printf ("Eek! Shouldn't happen!\n");
3010
paul718e3742002-12-13 20:15:29 +00003011 return 0;
3012}
3013
3014/* Periodical check of MaxAge LSA. */
3015int
paul68980082003-03-25 05:07:42 +00003016ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003017{
paul68980082003-03-25 05:07:42 +00003018 struct ospf *ospf = THREAD_ARG (thread);
3019 struct route_node *rn;
3020 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003021 struct ospf_area *area;
3022 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003023
paul68980082003-03-25 05:07:42 +00003024 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003025
paul1eb8ef22005-04-07 07:30:20 +00003026 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003027 {
paul68980082003-03-25 05:07:42 +00003028 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3029 ospf_lsa_maxage_walker_remover (ospf, lsa);
3030 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3031 ospf_lsa_maxage_walker_remover (ospf, lsa);
3032 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3033 ospf_lsa_maxage_walker_remover (ospf, lsa);
3034 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3035 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003036#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003037 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3038 ospf_lsa_maxage_walker_remover (ospf, lsa);
3039 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3040 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003041#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003042 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3043 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003044 }
3045
paul4fb949e2003-05-10 20:06:51 +00003046 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003047 if (ospf->lsdb)
3048 {
3049 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3050 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003051#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003052 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3053 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003054#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003055 }
paul718e3742002-12-13 20:15:29 +00003056
paul68980082003-03-25 05:07:42 +00003057 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3058 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003059 return 0;
3060}
3061
paul68980082003-03-25 05:07:42 +00003062struct ospf_lsa *
3063ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3064 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003065{
paul68980082003-03-25 05:07:42 +00003066 struct ospf_lsa *lsa;
3067 struct in_addr mask, id;
3068 struct lsa_header_mask
3069 {
3070 struct lsa_header header;
3071 struct in_addr mask;
3072 } *hmask;
paul718e3742002-12-13 20:15:29 +00003073
paul68980082003-03-25 05:07:42 +00003074 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3075 if (lsa == NULL)
3076 return NULL;
paul718e3742002-12-13 20:15:29 +00003077
paul68980082003-03-25 05:07:42 +00003078 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003079
paul68980082003-03-25 05:07:42 +00003080 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003081
paul68980082003-03-25 05:07:42 +00003082 if (mask.s_addr != hmask->mask.s_addr)
3083 {
3084 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3085 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3086 if (!lsa)
3087 return NULL;
3088 }
paul718e3742002-12-13 20:15:29 +00003089
paul68980082003-03-25 05:07:42 +00003090 return lsa;
paul718e3742002-12-13 20:15:29 +00003091}
3092
3093struct ospf_lsa *
3094ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3095 struct in_addr id, struct in_addr adv_router)
3096{
paule05fba42003-04-13 20:20:53 +00003097 struct ospf *ospf = ospf_lookup();
3098 assert(ospf);
3099
paul718e3742002-12-13 20:15:29 +00003100 switch (type)
3101 {
3102 case OSPF_ROUTER_LSA:
3103 case OSPF_NETWORK_LSA:
3104 case OSPF_SUMMARY_LSA:
3105 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003106 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003107#ifdef HAVE_OPAQUE_LSA
3108 case OSPF_OPAQUE_LINK_LSA:
3109 case OSPF_OPAQUE_AREA_LSA:
3110#endif /* HAVE_OPAQUE_LSA */
3111 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003112 case OSPF_AS_EXTERNAL_LSA:
3113#ifdef HAVE_OPAQUE_LSA
3114 case OSPF_OPAQUE_AS_LSA:
3115#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003116 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003117 default:
3118 break;
3119 }
3120
3121 return NULL;
3122}
3123
3124struct ospf_lsa *
3125ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3126 struct in_addr id)
3127{
3128 struct ospf_lsa *lsa;
3129 struct route_node *rn;
3130
3131 switch (type)
3132 {
3133 case OSPF_ROUTER_LSA:
3134 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003135 case OSPF_NETWORK_LSA:
3136 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3137 if ((lsa = rn->info))
3138 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3139 {
3140 route_unlock_node (rn);
3141 return lsa;
3142 }
3143 break;
3144 case OSPF_SUMMARY_LSA:
3145 case OSPF_ASBR_SUMMARY_LSA:
3146 /* Currently not used. */
3147 assert (1);
3148 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003149 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003150 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003151#ifdef HAVE_OPAQUE_LSA
3152 case OSPF_OPAQUE_LINK_LSA:
3153 case OSPF_OPAQUE_AREA_LSA:
3154 case OSPF_OPAQUE_AS_LSA:
3155 /* Currently not used. */
3156 break;
3157#endif /* HAVE_OPAQUE_LSA */
3158 default:
3159 break;
3160 }
3161
3162 return NULL;
3163}
3164
3165struct ospf_lsa *
3166ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3167{
3168 struct ospf_lsa *match;
3169
3170#ifdef HAVE_OPAQUE_LSA
3171 /*
3172 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3173 * is redefined to have two subfields; opaque-type and opaque-id.
3174 * However, it is harmless to treat the two sub fields together, as if
3175 * they two were forming a unique LSA-ID.
3176 */
3177#endif /* HAVE_OPAQUE_LSA */
3178
3179 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3180
3181 if (match == NULL)
3182 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003183 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003184 lsah->type, inet_ntoa (lsah->id));
3185
3186 return match;
3187}
3188
3189/* return +n, l1 is more recent.
3190 return -n, l2 is more recent.
3191 return 0, l1 and l2 is identical. */
3192int
3193ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3194{
3195 int r;
3196 int x, y;
3197
3198 if (l1 == NULL && l2 == NULL)
3199 return 0;
3200 if (l1 == NULL)
3201 return -1;
3202 if (l2 == NULL)
3203 return 1;
3204
3205 /* compare LS sequence number. */
3206 x = (int) ntohl (l1->data->ls_seqnum);
3207 y = (int) ntohl (l2->data->ls_seqnum);
3208 if (x > y)
3209 return 1;
3210 if (x < y)
3211 return -1;
3212
3213 /* compare LS checksum. */
3214 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3215 if (r)
3216 return r;
3217
3218 /* compare LS age. */
3219 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3220 return 1;
3221 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3222 return -1;
3223
3224 /* compare LS age with MaxAgeDiff. */
3225 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3226 return -1;
3227 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3228 return 1;
3229
3230 /* LSAs are identical. */
3231 return 0;
3232}
3233
3234/* If two LSAs are different, return 1, otherwise return 0. */
3235int
3236ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3237{
3238 char *p1, *p2;
3239 assert (l1);
3240 assert (l2);
3241 assert (l1->data);
3242 assert (l2->data);
3243
3244 if (l1->data->options != l2->data->options)
3245 return 1;
3246
3247 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3248 return 1;
3249
3250 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3251 return 1;
3252
3253 if (l1->data->length != l2->data->length)
3254 return 1;
3255
3256 if (l1->data->length == 0)
3257 return 1;
3258
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02003259 if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
3260 return 1; /* May be a stale LSA in the LSBD */
3261
pauld1825832003-04-03 01:27:01 +00003262 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003263
3264 p1 = (char *) l1->data;
3265 p2 = (char *) l2->data;
3266
3267 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3268 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3269 return 1;
3270
3271 return 0;
3272}
3273
3274#ifdef ORIGINAL_CODING
3275void
3276ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3277 struct ospf_lsa *self,
3278 struct ospf_lsa *new)
3279{
3280 u_int32_t seqnum;
3281
3282 /* Adjust LS Sequence Number. */
3283 seqnum = ntohl (new->data->ls_seqnum) + 1;
3284 self->data->ls_seqnum = htonl (seqnum);
3285
3286 /* Recalculate LSA checksum. */
3287 ospf_lsa_checksum (self->data);
3288
3289 /* Reflooding LSA. */
3290 /* RFC2328 Section 13.3
3291 On non-broadcast networks, separate Link State Update
3292 packets must be sent, as unicasts, to each adjacent neighbor
3293 (i.e., those in state Exchange or greater). The destination
3294 IP addresses for these packets are the neighbors' IP
3295 addresses. */
3296 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3297 {
3298 struct route_node *rn;
3299 struct ospf_neighbor *onbr;
3300
3301 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3302 if ((onbr = rn->info) != NULL)
3303 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3304 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3305 }
3306 else
3307 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3308
3309 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003310 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003311 self->data->type, inet_ntoa (self->data->id));
3312}
3313#else /* ORIGINAL_CODING */
3314static int
paul68980082003-03-25 05:07:42 +00003315ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003316{
3317 if (lsa == NULL || !IS_LSA_SELF (lsa))
3318 return 0;
3319
3320 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003321 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 +00003322
3323 /* Force given lsa's age to MaxAge. */
3324 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3325
3326 switch (lsa->data->type)
3327 {
3328#ifdef HAVE_OPAQUE_LSA
Paul Jakma02d942c2010-01-24 23:36:20 +00003329 /* Opaque wants to be notified of flushes */
paul718e3742002-12-13 20:15:29 +00003330 case OSPF_OPAQUE_LINK_LSA:
3331 case OSPF_OPAQUE_AREA_LSA:
3332 case OSPF_OPAQUE_AS_LSA:
3333 ospf_opaque_lsa_refresh (lsa);
3334 break;
3335#endif /* HAVE_OPAQUE_LSA */
3336 default:
Paul Jakmadfbd5172010-04-14 10:32:12 +01003337 ospf_refresher_unregister_lsa (ospf, lsa);
Paul Jakma02d942c2010-01-24 23:36:20 +00003338 ospf_lsa_flush (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003339 break;
3340 }
3341
3342 return 0;
3343}
3344
3345void
paul68980082003-03-25 05:07:42 +00003346ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003347{
paul1eb8ef22005-04-07 07:30:20 +00003348 struct listnode *node, *nnode;
3349 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003350 struct ospf_area *area;
3351 struct ospf_interface *oi;
3352 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003353 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003354 int need_to_flush_ase = 0;
3355
paul1eb8ef22005-04-07 07:30:20 +00003356 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003357 {
paul718e3742002-12-13 20:15:29 +00003358 if ((lsa = area->router_lsa_self) != NULL)
3359 {
3360 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003361 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3362 lsa->data->type, inet_ntoa (lsa->data->id));
3363
3364 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003365 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003366 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003367 area->router_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003368 }
3369
paul1eb8ef22005-04-07 07:30:20 +00003370 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003371 {
paul718e3742002-12-13 20:15:29 +00003372 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003373 && oi->state == ISM_DR
3374 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003375 {
3376 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003377 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3378 lsa->data->type, inet_ntoa (lsa->data->id));
3379
3380 ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003381 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003382 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003383 oi->network_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003384 }
3385
3386 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3387 && area->external_routing == OSPF_AREA_DEFAULT)
3388 need_to_flush_ase = 1;
3389 }
3390
paul68980082003-03-25 05:07:42 +00003391 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3392 ospf_lsa_flush_schedule (ospf, lsa);
3393 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3394 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003395#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003396 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3397 ospf_lsa_flush_schedule (ospf, lsa);
3398 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3399 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003400#endif /* HAVE_OPAQUE_LSA */
3401 }
3402
3403 if (need_to_flush_ase)
3404 {
paul68980082003-03-25 05:07:42 +00003405 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3406 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003407#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003408 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3409 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003410#endif /* HAVE_OPAQUE_LSA */
3411 }
3412
3413 /*
3414 * Make sure that the MaxAge LSA remover is executed immediately,
3415 * without conflicting to other threads.
3416 */
paul68980082003-03-25 05:07:42 +00003417 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003418 {
paul68980082003-03-25 05:07:42 +00003419 OSPF_TIMER_OFF (ospf->t_maxage);
3420 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003421 }
3422
3423 return;
3424}
3425#endif /* ORIGINAL_CODING */
3426
3427/* If there is self-originated LSA, then return 1, otherwise return 0. */
3428/* An interface-independent version of ospf_lsa_is_self_originated */
3429int
paul68980082003-03-25 05:07:42 +00003430ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003431{
hasso52dc7ee2004-09-23 19:18:23 +00003432 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003433 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003434
3435 /* This LSA is already checked. */
3436 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003437 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003438
3439 /* Make sure LSA is self-checked. */
3440 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3441
3442 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003443 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003444 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3445
3446 /* LSA is router-LSA. */
3447 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003448 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003449 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3450
3451 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3452 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003453 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003454 {
paul718e3742002-12-13 20:15:29 +00003455 /* Ignore virtual link. */
3456 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3457 if (oi->address->family == AF_INET)
3458 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3459 {
3460 /* to make it easier later */
3461 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003462 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003463 }
3464 }
3465
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003466 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003467}
3468
3469/* Get unique Link State ID. */
3470struct in_addr
paul68980082003-03-25 05:07:42 +00003471ospf_lsa_unique_id (struct ospf *ospf,
3472 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003473{
3474 struct ospf_lsa *lsa;
3475 struct in_addr mask, id;
3476
3477 id = p->prefix;
3478
3479 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003480 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003481 if (lsa)
3482 {
3483 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3484 if (ip_masklen (al->mask) == p->prefixlen)
3485 {
3486 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003487 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003488 "Can't get Link State ID for %s/%d",
3489 inet_ntoa (p->prefix), p->prefixlen);
3490 /* id.s_addr = 0; */
3491 id.s_addr = 0xffffffff;
3492 return id;
3493 }
3494 /* Masklen differs, then apply wildcard mask to Link State ID. */
3495 else
3496 {
3497 masklen2ip (p->prefixlen, &mask);
3498
3499 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003500 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3501 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003502 if (lsa)
3503 {
3504 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003505 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003506 "Can't get Link State ID for %s/%d",
3507 inet_ntoa (p->prefix), p->prefixlen);
3508 /* id.s_addr = 0; */
3509 id.s_addr = 0xffffffff;
3510 return id;
3511 }
3512 }
3513 }
3514
3515 return id;
3516}
3517
3518
Paul Jakma70461d72006-05-12 22:57:57 +00003519#define LSA_ACTION_FLOOD_AREA 1
3520#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003521
3522struct lsa_action
3523{
3524 u_char action;
3525 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003526 struct ospf_lsa *lsa;
3527};
3528
paul4dadc292005-05-06 21:37:42 +00003529static int
paul718e3742002-12-13 20:15:29 +00003530ospf_lsa_action (struct thread *t)
3531{
3532 struct lsa_action *data;
3533
3534 data = THREAD_ARG (t);
3535
3536 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003537 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003538 data->action);
3539
3540 switch (data->action)
3541 {
paul718e3742002-12-13 20:15:29 +00003542 case LSA_ACTION_FLOOD_AREA:
3543 ospf_flood_through_area (data->area, NULL, data->lsa);
3544 break;
paul718e3742002-12-13 20:15:29 +00003545 case LSA_ACTION_FLUSH_AREA:
3546 ospf_lsa_flush_area (data->lsa, data->area);
3547 break;
paul718e3742002-12-13 20:15:29 +00003548 }
3549
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003550 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003551 XFREE (MTYPE_OSPF_MESSAGE, data);
3552 return 0;
3553}
3554
3555void
3556ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3557{
3558 struct lsa_action *data;
3559
Stephen Hemminger393deb92008-08-18 14:13:29 -07003560 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003561 data->action = LSA_ACTION_FLOOD_AREA;
3562 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003563 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003564
3565 thread_add_event (master, ospf_lsa_action, data, 0);
3566}
3567
3568void
3569ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3570{
3571 struct lsa_action *data;
3572
Stephen Hemminger393deb92008-08-18 14:13:29 -07003573 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003574 data->action = LSA_ACTION_FLUSH_AREA;
3575 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003576 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003577
3578 thread_add_event (master, ospf_lsa_action, data, 0);
3579}
3580
3581
3582/* LSA Refreshment functions. */
Paul Jakmac363d382010-01-24 22:42:13 +00003583struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00003584ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003585{
3586 struct external_info *ei;
Paul Jakmac363d382010-01-24 22:42:13 +00003587 struct ospf_lsa *new = NULL;
paul718e3742002-12-13 20:15:29 +00003588 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003589 assert (IS_LSA_SELF (lsa));
Paul Jakma66349742010-04-13 22:33:54 +01003590 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003591
3592 switch (lsa->data->type)
3593 {
3594 /* Router and Network LSAs are processed differently. */
3595 case OSPF_ROUTER_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003596 new = ospf_router_lsa_refresh (lsa);
3597 break;
paul718e3742002-12-13 20:15:29 +00003598 case OSPF_NETWORK_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003599 new = ospf_network_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003600 break;
3601 case OSPF_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003602 new = ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003603 break;
3604 case OSPF_ASBR_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003605 new = ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003606 break;
3607 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003608 /* Translated from NSSA Type-5s are refreshed when
3609 * from refresh of Type-7 - do not refresh these directly.
3610 */
3611 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3612 break;
paul718e3742002-12-13 20:15:29 +00003613 ei = ospf_external_info_check (lsa);
3614 if (ei)
Paul Jakmac363d382010-01-24 22:42:13 +00003615 new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003616 else
pauld4a53d52003-07-12 21:30:57 +00003617 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003618 break;
3619#ifdef HAVE_OPAQUE_LSA
3620 case OSPF_OPAQUE_LINK_LSA:
3621 case OSPF_OPAQUE_AREA_LSA:
3622 case OSPF_OPAQUE_AS_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003623 new = ospf_opaque_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003624 break;
pauld7480322003-05-16 17:31:51 +00003625#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003626 default:
3627 break;
paul718e3742002-12-13 20:15:29 +00003628 }
Paul Jakmac363d382010-01-24 22:42:13 +00003629 return new;
paul718e3742002-12-13 20:15:29 +00003630}
3631
3632void
paul68980082003-03-25 05:07:42 +00003633ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003634{
3635 u_int16_t index, current_index;
3636
Paul Jakma66349742010-04-13 22:33:54 +01003637 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003638 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003639
3640 if (lsa->refresh_list < 0)
3641 {
3642 int delay;
3643
3644 if (LS_AGE (lsa) == 0 &&
3645 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3646 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3647 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3648 else
3649 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3650 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3651 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3652
3653 if (delay < 0)
3654 delay = 0;
3655
Paul Jakmac363d382010-01-24 22:42:13 +00003656 current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL)
3657 - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003658
3659 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
Paul Jakmac363d382010-01-24 22:42:13 +00003660 % (OSPF_LSA_REFRESHER_SLOTS);
paul718e3742002-12-13 20:15:29 +00003661
3662 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003663 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003664 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003665 if (!ospf->lsa_refresh_queue.qs[index])
3666 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003667 listnode_add (ospf->lsa_refresh_queue.qs[index],
3668 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003669 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003670 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003671 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003672 "setting refresh_list on lsa %p (slod %d)",
3673 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003674 }
3675}
3676
3677void
paul68980082003-03-25 05:07:42 +00003678ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003679{
Paul Jakma66349742010-04-13 22:33:54 +01003680 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003681 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003682 if (lsa->refresh_list >= 0)
3683 {
hasso52dc7ee2004-09-23 19:18:23 +00003684 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003685 listnode_delete (refresh_list, lsa);
3686 if (!listcount (refresh_list))
3687 {
3688 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003689 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003690 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003691 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003692 lsa->refresh_list = -1;
3693 }
3694}
3695
3696int
3697ospf_lsa_refresh_walker (struct thread *t)
3698{
hasso52dc7ee2004-09-23 19:18:23 +00003699 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003700 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003701 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003702 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003703 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003704 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003705
3706 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003707 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003708
3709
paul68980082003-03-25 05:07:42 +00003710 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003711
ajs9dbc7972005-03-13 19:27:22 +00003712 /* Note: if clock has jumped backwards, then time change could be negative,
3713 so we are careful to cast the expression to unsigned before taking
3714 modulus. */
paul68980082003-03-25 05:07:42 +00003715 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003716 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakmac363d382010-01-24 22:42:13 +00003717 (quagga_time (NULL) - ospf->lsa_refresher_started)
3718 / OSPF_LSA_REFRESHER_GRANULARITY))
3719 % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003720
3721 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003722 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003723 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003724
paul68980082003-03-25 05:07:42 +00003725 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003726 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3727 {
3728 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003729 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003730 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003731
paul68980082003-03-25 05:07:42 +00003732 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003733
Paul Jakma66349742010-04-13 22:33:54 +01003734 assert (i >= 0);
3735
paul68980082003-03-25 05:07:42 +00003736 ospf->lsa_refresh_queue.qs [i] = NULL;
3737
paul718e3742002-12-13 20:15:29 +00003738 if (refresh_list)
3739 {
paul1eb8ef22005-04-07 07:30:20 +00003740 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003741 {
paul718e3742002-12-13 20:15:29 +00003742 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003743 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003744 "refresh lsa %p (slot %d)",
3745 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003746
Paul Jakma66349742010-04-13 22:33:54 +01003747 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003748 list_delete_node (refresh_list, node);
paul718e3742002-12-13 20:15:29 +00003749 lsa->refresh_list = -1;
3750 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003751 }
3752 list_free (refresh_list);
3753 }
3754 }
3755
paul68980082003-03-25 05:07:42 +00003756 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3757 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003758 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003759
paul1eb8ef22005-04-07 07:30:20 +00003760 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
Paul Jakma66349742010-04-13 22:33:54 +01003761 {
3762 ospf_lsa_refresh (ospf, lsa);
3763 assert (lsa->lock > 0);
3764 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
3765 }
paul718e3742002-12-13 20:15:29 +00003766
3767 list_delete (lsa_to_refresh);
3768
3769 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003770 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003771
3772 return 0;
3773}
3774