blob: 0a66b1d4c73130139e2146667144f9410b9a257b [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
Christian Franke4c14b7f2013-02-20 10:00:54 +00002797int
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
Christian Franke4de8bf02013-02-20 10:00:52 +00002846 /* There is at least one neighbor from which we still await an ack
2847 * for that LSA, so we are not allowed to remove it from our lsdb yet
2848 * as per RFC 2328 section 14 para 4 a) */
paul718e3742002-12-13 20:15:29 +00002849 if (lsa->retransmit_counter > 0)
2850 {
2851 reschedule = 1;
2852 continue;
2853 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002854
2855 /* TODO: maybe convert this function to a work-queue */
2856 if (thread_should_yield (thread))
Christian Franke4de8bf02013-02-20 10:00:52 +00002857 {
2858 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);
Christian Frankee387dfd2014-04-28 08:04:58 +00002859 route_unlock_node(rn); /* route_top/route_next */
Christian Franke4de8bf02013-02-20 10:00:52 +00002860 return 0;
2861 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002862
paul718e3742002-12-13 20:15:29 +00002863 /* Remove LSA from the LSDB */
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04002864 if (IS_LSA_SELF (lsa))
paul718e3742002-12-13 20:15:29 +00002865 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
Denis Ovsienkoad8d4802011-12-02 20:02:40 +04002866 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-originated: ",
paul7ddf1d62003-10-13 09:06:46 +00002867 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002868
2869 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002870 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002871 lsa->data->type, inet_ntoa (lsa->data->id));
2872
Paul Jakmac363d382010-01-24 22:42:13 +00002873 if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))
paul7ddf1d62003-10-13 09:06:46 +00002874 {
2875 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
Paul Jakmac363d382010-01-24 22:42:13 +00002876 zlog_debug ("originating new lsa for lsa 0x%p\n", lsa);
2877 ospf_lsa_refresh (ospf, lsa);
paul7ddf1d62003-10-13 09:06:46 +00002878 }
2879
paul718e3742002-12-13 20:15:29 +00002880 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002881 if (lsa->lsdb)
2882 {
2883 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2884 ospf_lsdb_delete (lsa->lsdb, lsa);
2885 }
2886 else
2887 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2888 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002889 }
2890
2891 /* A MaxAge LSA must be removed immediately from the router's link
2892 state database as soon as both a) it is no longer contained on any
2893 neighbor Link state retransmission lists and b) none of the router's
2894 neighbors are in states Exchange or Loading. */
2895 if (reschedule)
Paul Jakma02d942c2010-01-24 23:36:20 +00002896 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2897 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002898
2899 return 0;
2900}
2901
paul718e3742002-12-13 20:15:29 +00002902void
paul68980082003-03-25 05:07:42 +00002903ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002904{
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002905 struct route_node *rn;
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002906 struct prefix_ptr lsa_prefix;
paul718e3742002-12-13 20:15:29 +00002907
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002908 lsa_prefix.family = 0;
2909 lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
2910 lsa_prefix.prefix = (uintptr_t) lsa;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002911
2912 if ((rn = route_node_lookup(ospf->maxage_lsa,
2913 (struct prefix *)&lsa_prefix)))
paul718e3742002-12-13 20:15:29 +00002914 {
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002915 if (rn->info == lsa)
2916 {
2917 UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
2918 ospf_lsa_unlock (&lsa); /* maxage_lsa */
2919 rn->info = NULL;
Christian Franke8afee5c2014-04-28 08:04:59 +00002920 route_unlock_node (rn); /* unlock node because lsa is deleted */
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002921 }
Christian Franke8afee5c2014-04-28 08:04:59 +00002922 route_unlock_node (rn); /* route_node_lookup */
paul718e3742002-12-13 20:15:29 +00002923 }
2924}
2925
Paul Jakma02d942c2010-01-24 23:36:20 +00002926/* Add LSA onto the MaxAge list, and schedule for removal.
2927 * This does *not* lead to the LSA being flooded, that must be taken
2928 * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
2929 * function).
2930 */
paul718e3742002-12-13 20:15:29 +00002931void
paul68980082003-03-25 05:07:42 +00002932ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002933{
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002934 struct prefix_ptr lsa_prefix;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002935 struct route_node *rn;
2936
paul718e3742002-12-13 20:15:29 +00002937 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2938 and schedule the MaxAge LSA remover. */
Stephen Hemminger3106a032009-08-06 12:58:05 -07002939 if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
paul718e3742002-12-13 20:15:29 +00002940 {
2941 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002942 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00002943 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2944 return;
2945 }
2946
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002947 lsa_prefix.family = 0;
2948 lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
2949 lsa_prefix.prefix = (uintptr_t) lsa;
2950
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002951 if ((rn = route_node_get (ospf->maxage_lsa,
2952 (struct prefix *)&lsa_prefix)) != NULL)
2953 {
2954 if (rn->info != NULL)
2955 {
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002956 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2957 zlog_debug ("LSA[%s]: found LSA (%p) in table for LSA %p %d",
2958 dump_lsa_key (lsa), rn->info, lsa, lsa_prefix.prefixlen);
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002959 route_unlock_node (rn);
2960 }
2961 else
2962 {
2963 rn->info = ospf_lsa_lock(lsa);
2964 SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
2965 }
2966 }
2967 else
2968 {
2969 zlog_err("Unable to allocate memory for maxage lsa\n");
2970 assert(0);
2971 }
paul718e3742002-12-13 20:15:29 +00002972
2973 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002974 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002975
Paul Jakma02d942c2010-01-24 23:36:20 +00002976 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2977 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002978}
2979
paul4dadc292005-05-06 21:37:42 +00002980static int
paul68980082003-03-25 05:07:42 +00002981ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002982{
paul718e3742002-12-13 20:15:29 +00002983 /* Stay away from any Local Translated Type-7 LSAs */
2984 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2985 return 0;
paul718e3742002-12-13 20:15:29 +00002986
2987 if (IS_LSA_MAXAGE (lsa))
2988 /* Self-originated LSAs should NOT time-out instead,
2989 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00002990 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002991 {
2992 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002993 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002994
2995 switch (lsa->data->type)
2996 {
paul718e3742002-12-13 20:15:29 +00002997#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00002998 case OSPF_OPAQUE_LINK_LSA:
2999 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003000 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003001 /*
3002 * As a general rule, whenever network topology has changed
3003 * (due to an LSA removal in this case), routing recalculation
3004 * should be triggered. However, this is not true for opaque
3005 * LSAs. Even if an opaque LSA instance is going to be removed
3006 * from the routing domain, it does not mean a change in network
3007 * topology, and thus, routing recalculation is not needed here.
3008 */
3009 break;
paul718e3742002-12-13 20:15:29 +00003010#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00003011 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003012 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003013 ospf_ase_incremental_update (ospf, lsa);
3014 break;
paul718e3742002-12-13 20:15:29 +00003015 default:
paul68980082003-03-25 05:07:42 +00003016 ospf_spf_calculate_schedule (ospf);
3017 break;
paul718e3742002-12-13 20:15:29 +00003018 }
paul68980082003-03-25 05:07:42 +00003019 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003020 }
3021
Paul Jakmac363d382010-01-24 22:42:13 +00003022 if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa))
3023 if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30)
3024 printf ("Eek! Shouldn't happen!\n");
3025
paul718e3742002-12-13 20:15:29 +00003026 return 0;
3027}
3028
3029/* Periodical check of MaxAge LSA. */
3030int
paul68980082003-03-25 05:07:42 +00003031ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003032{
paul68980082003-03-25 05:07:42 +00003033 struct ospf *ospf = THREAD_ARG (thread);
3034 struct route_node *rn;
3035 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003036 struct ospf_area *area;
3037 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003038
paul68980082003-03-25 05:07:42 +00003039 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003040
paul1eb8ef22005-04-07 07:30:20 +00003041 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003042 {
paul68980082003-03-25 05:07:42 +00003043 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3044 ospf_lsa_maxage_walker_remover (ospf, lsa);
3045 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3046 ospf_lsa_maxage_walker_remover (ospf, lsa);
3047 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3048 ospf_lsa_maxage_walker_remover (ospf, lsa);
3049 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), 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_AREA_LSDB (area), rn, lsa)
3053 ospf_lsa_maxage_walker_remover (ospf, lsa);
3054 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3055 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003056#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003057 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3058 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003059 }
3060
paul4fb949e2003-05-10 20:06:51 +00003061 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003062 if (ospf->lsdb)
3063 {
3064 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3065 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003066#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003067 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3068 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003069#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003070 }
paul718e3742002-12-13 20:15:29 +00003071
paul68980082003-03-25 05:07:42 +00003072 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3073 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003074 return 0;
3075}
3076
paul68980082003-03-25 05:07:42 +00003077struct ospf_lsa *
3078ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3079 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003080{
paul68980082003-03-25 05:07:42 +00003081 struct ospf_lsa *lsa;
3082 struct in_addr mask, id;
3083 struct lsa_header_mask
3084 {
3085 struct lsa_header header;
3086 struct in_addr mask;
3087 } *hmask;
paul718e3742002-12-13 20:15:29 +00003088
paul68980082003-03-25 05:07:42 +00003089 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3090 if (lsa == NULL)
3091 return NULL;
paul718e3742002-12-13 20:15:29 +00003092
paul68980082003-03-25 05:07:42 +00003093 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003094
paul68980082003-03-25 05:07:42 +00003095 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003096
paul68980082003-03-25 05:07:42 +00003097 if (mask.s_addr != hmask->mask.s_addr)
3098 {
3099 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3100 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3101 if (!lsa)
3102 return NULL;
3103 }
paul718e3742002-12-13 20:15:29 +00003104
paul68980082003-03-25 05:07:42 +00003105 return lsa;
paul718e3742002-12-13 20:15:29 +00003106}
3107
3108struct ospf_lsa *
3109ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3110 struct in_addr id, struct in_addr adv_router)
3111{
paule05fba42003-04-13 20:20:53 +00003112 struct ospf *ospf = ospf_lookup();
3113 assert(ospf);
3114
paul718e3742002-12-13 20:15:29 +00003115 switch (type)
3116 {
3117 case OSPF_ROUTER_LSA:
3118 case OSPF_NETWORK_LSA:
3119 case OSPF_SUMMARY_LSA:
3120 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003121 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003122#ifdef HAVE_OPAQUE_LSA
3123 case OSPF_OPAQUE_LINK_LSA:
3124 case OSPF_OPAQUE_AREA_LSA:
3125#endif /* HAVE_OPAQUE_LSA */
3126 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003127 case OSPF_AS_EXTERNAL_LSA:
3128#ifdef HAVE_OPAQUE_LSA
3129 case OSPF_OPAQUE_AS_LSA:
3130#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003131 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003132 default:
3133 break;
3134 }
3135
3136 return NULL;
3137}
3138
3139struct ospf_lsa *
3140ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3141 struct in_addr id)
3142{
3143 struct ospf_lsa *lsa;
3144 struct route_node *rn;
3145
3146 switch (type)
3147 {
3148 case OSPF_ROUTER_LSA:
3149 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003150 case OSPF_NETWORK_LSA:
3151 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3152 if ((lsa = rn->info))
3153 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3154 {
3155 route_unlock_node (rn);
3156 return lsa;
3157 }
3158 break;
3159 case OSPF_SUMMARY_LSA:
3160 case OSPF_ASBR_SUMMARY_LSA:
3161 /* Currently not used. */
3162 assert (1);
3163 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003164 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003165 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003166#ifdef HAVE_OPAQUE_LSA
3167 case OSPF_OPAQUE_LINK_LSA:
3168 case OSPF_OPAQUE_AREA_LSA:
3169 case OSPF_OPAQUE_AS_LSA:
3170 /* Currently not used. */
3171 break;
3172#endif /* HAVE_OPAQUE_LSA */
3173 default:
3174 break;
3175 }
3176
3177 return NULL;
3178}
3179
3180struct ospf_lsa *
3181ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3182{
3183 struct ospf_lsa *match;
3184
3185#ifdef HAVE_OPAQUE_LSA
3186 /*
3187 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3188 * is redefined to have two subfields; opaque-type and opaque-id.
3189 * However, it is harmless to treat the two sub fields together, as if
3190 * they two were forming a unique LSA-ID.
3191 */
3192#endif /* HAVE_OPAQUE_LSA */
3193
3194 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3195
3196 if (match == NULL)
3197 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003198 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003199 lsah->type, inet_ntoa (lsah->id));
3200
3201 return match;
3202}
3203
3204/* return +n, l1 is more recent.
3205 return -n, l2 is more recent.
3206 return 0, l1 and l2 is identical. */
3207int
3208ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3209{
3210 int r;
3211 int x, y;
3212
3213 if (l1 == NULL && l2 == NULL)
3214 return 0;
3215 if (l1 == NULL)
3216 return -1;
3217 if (l2 == NULL)
3218 return 1;
3219
3220 /* compare LS sequence number. */
3221 x = (int) ntohl (l1->data->ls_seqnum);
3222 y = (int) ntohl (l2->data->ls_seqnum);
3223 if (x > y)
3224 return 1;
3225 if (x < y)
3226 return -1;
3227
3228 /* compare LS checksum. */
3229 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3230 if (r)
3231 return r;
3232
3233 /* compare LS age. */
3234 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3235 return 1;
3236 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3237 return -1;
3238
3239 /* compare LS age with MaxAgeDiff. */
3240 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3241 return -1;
3242 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3243 return 1;
3244
3245 /* LSAs are identical. */
3246 return 0;
3247}
3248
3249/* If two LSAs are different, return 1, otherwise return 0. */
3250int
3251ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3252{
3253 char *p1, *p2;
3254 assert (l1);
3255 assert (l2);
3256 assert (l1->data);
3257 assert (l2->data);
3258
3259 if (l1->data->options != l2->data->options)
3260 return 1;
3261
3262 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3263 return 1;
3264
3265 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3266 return 1;
3267
3268 if (l1->data->length != l2->data->length)
3269 return 1;
3270
3271 if (l1->data->length == 0)
3272 return 1;
3273
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02003274 if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
3275 return 1; /* May be a stale LSA in the LSBD */
3276
pauld1825832003-04-03 01:27:01 +00003277 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003278
3279 p1 = (char *) l1->data;
3280 p2 = (char *) l2->data;
3281
3282 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3283 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3284 return 1;
3285
3286 return 0;
3287}
3288
3289#ifdef ORIGINAL_CODING
3290void
3291ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3292 struct ospf_lsa *self,
3293 struct ospf_lsa *new)
3294{
3295 u_int32_t seqnum;
3296
3297 /* Adjust LS Sequence Number. */
3298 seqnum = ntohl (new->data->ls_seqnum) + 1;
3299 self->data->ls_seqnum = htonl (seqnum);
3300
3301 /* Recalculate LSA checksum. */
3302 ospf_lsa_checksum (self->data);
3303
3304 /* Reflooding LSA. */
3305 /* RFC2328 Section 13.3
3306 On non-broadcast networks, separate Link State Update
3307 packets must be sent, as unicasts, to each adjacent neighbor
3308 (i.e., those in state Exchange or greater). The destination
3309 IP addresses for these packets are the neighbors' IP
3310 addresses. */
3311 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3312 {
3313 struct route_node *rn;
3314 struct ospf_neighbor *onbr;
3315
3316 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3317 if ((onbr = rn->info) != NULL)
3318 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3319 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3320 }
3321 else
3322 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3323
3324 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003325 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003326 self->data->type, inet_ntoa (self->data->id));
3327}
3328#else /* ORIGINAL_CODING */
3329static int
paul68980082003-03-25 05:07:42 +00003330ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003331{
3332 if (lsa == NULL || !IS_LSA_SELF (lsa))
3333 return 0;
3334
3335 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003336 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 +00003337
3338 /* Force given lsa's age to MaxAge. */
3339 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3340
3341 switch (lsa->data->type)
3342 {
3343#ifdef HAVE_OPAQUE_LSA
Paul Jakma02d942c2010-01-24 23:36:20 +00003344 /* Opaque wants to be notified of flushes */
paul718e3742002-12-13 20:15:29 +00003345 case OSPF_OPAQUE_LINK_LSA:
3346 case OSPF_OPAQUE_AREA_LSA:
3347 case OSPF_OPAQUE_AS_LSA:
3348 ospf_opaque_lsa_refresh (lsa);
3349 break;
3350#endif /* HAVE_OPAQUE_LSA */
3351 default:
Paul Jakmadfbd5172010-04-14 10:32:12 +01003352 ospf_refresher_unregister_lsa (ospf, lsa);
Paul Jakma02d942c2010-01-24 23:36:20 +00003353 ospf_lsa_flush (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003354 break;
3355 }
3356
3357 return 0;
3358}
3359
3360void
paul68980082003-03-25 05:07:42 +00003361ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003362{
paul1eb8ef22005-04-07 07:30:20 +00003363 struct listnode *node, *nnode;
3364 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003365 struct ospf_area *area;
3366 struct ospf_interface *oi;
3367 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003368 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003369 int need_to_flush_ase = 0;
3370
paul1eb8ef22005-04-07 07:30:20 +00003371 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003372 {
paul718e3742002-12-13 20:15:29 +00003373 if ((lsa = area->router_lsa_self) != NULL)
3374 {
3375 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003376 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3377 lsa->data->type, inet_ntoa (lsa->data->id));
3378
3379 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003380 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003381 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003382 area->router_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003383 }
3384
paul1eb8ef22005-04-07 07:30:20 +00003385 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003386 {
paul718e3742002-12-13 20:15:29 +00003387 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003388 && oi->state == ISM_DR
3389 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003390 {
3391 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003392 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3393 lsa->data->type, inet_ntoa (lsa->data->id));
3394
3395 ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003396 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003397 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003398 oi->network_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003399 }
3400
3401 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3402 && area->external_routing == OSPF_AREA_DEFAULT)
3403 need_to_flush_ase = 1;
3404 }
3405
paul68980082003-03-25 05:07:42 +00003406 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3407 ospf_lsa_flush_schedule (ospf, lsa);
3408 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3409 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003410#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003411 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3412 ospf_lsa_flush_schedule (ospf, lsa);
3413 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3414 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003415#endif /* HAVE_OPAQUE_LSA */
3416 }
3417
3418 if (need_to_flush_ase)
3419 {
paul68980082003-03-25 05:07:42 +00003420 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3421 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003422#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003423 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3424 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003425#endif /* HAVE_OPAQUE_LSA */
3426 }
3427
3428 /*
3429 * Make sure that the MaxAge LSA remover is executed immediately,
3430 * without conflicting to other threads.
3431 */
paul68980082003-03-25 05:07:42 +00003432 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003433 {
paul68980082003-03-25 05:07:42 +00003434 OSPF_TIMER_OFF (ospf->t_maxage);
3435 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003436 }
3437
3438 return;
3439}
3440#endif /* ORIGINAL_CODING */
3441
3442/* If there is self-originated LSA, then return 1, otherwise return 0. */
3443/* An interface-independent version of ospf_lsa_is_self_originated */
3444int
paul68980082003-03-25 05:07:42 +00003445ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003446{
hasso52dc7ee2004-09-23 19:18:23 +00003447 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003448 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003449
3450 /* This LSA is already checked. */
3451 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003452 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003453
3454 /* Make sure LSA is self-checked. */
3455 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3456
3457 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003458 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003459 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3460
3461 /* LSA is router-LSA. */
3462 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003463 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003464 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3465
3466 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3467 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003468 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003469 {
paul718e3742002-12-13 20:15:29 +00003470 /* Ignore virtual link. */
3471 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3472 if (oi->address->family == AF_INET)
3473 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3474 {
3475 /* to make it easier later */
3476 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003477 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003478 }
3479 }
3480
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003481 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003482}
3483
3484/* Get unique Link State ID. */
3485struct in_addr
paul68980082003-03-25 05:07:42 +00003486ospf_lsa_unique_id (struct ospf *ospf,
3487 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003488{
3489 struct ospf_lsa *lsa;
3490 struct in_addr mask, id;
3491
3492 id = p->prefix;
3493
3494 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003495 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003496 if (lsa)
3497 {
3498 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3499 if (ip_masklen (al->mask) == p->prefixlen)
3500 {
3501 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003502 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003503 "Can't get Link State ID for %s/%d",
3504 inet_ntoa (p->prefix), p->prefixlen);
3505 /* id.s_addr = 0; */
3506 id.s_addr = 0xffffffff;
3507 return id;
3508 }
3509 /* Masklen differs, then apply wildcard mask to Link State ID. */
3510 else
3511 {
3512 masklen2ip (p->prefixlen, &mask);
3513
3514 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003515 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3516 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003517 if (lsa)
3518 {
3519 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003520 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003521 "Can't get Link State ID for %s/%d",
3522 inet_ntoa (p->prefix), p->prefixlen);
3523 /* id.s_addr = 0; */
3524 id.s_addr = 0xffffffff;
3525 return id;
3526 }
3527 }
3528 }
3529
3530 return id;
3531}
3532
3533
Paul Jakma70461d72006-05-12 22:57:57 +00003534#define LSA_ACTION_FLOOD_AREA 1
3535#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003536
3537struct lsa_action
3538{
3539 u_char action;
3540 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003541 struct ospf_lsa *lsa;
3542};
3543
paul4dadc292005-05-06 21:37:42 +00003544static int
paul718e3742002-12-13 20:15:29 +00003545ospf_lsa_action (struct thread *t)
3546{
3547 struct lsa_action *data;
3548
3549 data = THREAD_ARG (t);
3550
3551 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003552 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003553 data->action);
3554
3555 switch (data->action)
3556 {
paul718e3742002-12-13 20:15:29 +00003557 case LSA_ACTION_FLOOD_AREA:
3558 ospf_flood_through_area (data->area, NULL, data->lsa);
3559 break;
paul718e3742002-12-13 20:15:29 +00003560 case LSA_ACTION_FLUSH_AREA:
3561 ospf_lsa_flush_area (data->lsa, data->area);
3562 break;
paul718e3742002-12-13 20:15:29 +00003563 }
3564
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003565 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003566 XFREE (MTYPE_OSPF_MESSAGE, data);
3567 return 0;
3568}
3569
3570void
3571ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3572{
3573 struct lsa_action *data;
3574
Stephen Hemminger393deb92008-08-18 14:13:29 -07003575 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003576 data->action = LSA_ACTION_FLOOD_AREA;
3577 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003578 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003579
3580 thread_add_event (master, ospf_lsa_action, data, 0);
3581}
3582
3583void
3584ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3585{
3586 struct lsa_action *data;
3587
Stephen Hemminger393deb92008-08-18 14:13:29 -07003588 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003589 data->action = LSA_ACTION_FLUSH_AREA;
3590 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003591 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003592
3593 thread_add_event (master, ospf_lsa_action, data, 0);
3594}
3595
3596
3597/* LSA Refreshment functions. */
Paul Jakmac363d382010-01-24 22:42:13 +00003598struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00003599ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003600{
3601 struct external_info *ei;
Paul Jakmac363d382010-01-24 22:42:13 +00003602 struct ospf_lsa *new = NULL;
paul718e3742002-12-13 20:15:29 +00003603 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003604 assert (IS_LSA_SELF (lsa));
Paul Jakma66349742010-04-13 22:33:54 +01003605 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003606
3607 switch (lsa->data->type)
3608 {
3609 /* Router and Network LSAs are processed differently. */
3610 case OSPF_ROUTER_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003611 new = ospf_router_lsa_refresh (lsa);
3612 break;
paul718e3742002-12-13 20:15:29 +00003613 case OSPF_NETWORK_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003614 new = ospf_network_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003615 break;
3616 case OSPF_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003617 new = ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003618 break;
3619 case OSPF_ASBR_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003620 new = ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003621 break;
3622 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003623 /* Translated from NSSA Type-5s are refreshed when
3624 * from refresh of Type-7 - do not refresh these directly.
3625 */
3626 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3627 break;
paul718e3742002-12-13 20:15:29 +00003628 ei = ospf_external_info_check (lsa);
3629 if (ei)
Paul Jakmac363d382010-01-24 22:42:13 +00003630 new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003631 else
pauld4a53d52003-07-12 21:30:57 +00003632 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003633 break;
3634#ifdef HAVE_OPAQUE_LSA
3635 case OSPF_OPAQUE_LINK_LSA:
3636 case OSPF_OPAQUE_AREA_LSA:
3637 case OSPF_OPAQUE_AS_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003638 new = ospf_opaque_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003639 break;
pauld7480322003-05-16 17:31:51 +00003640#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003641 default:
3642 break;
paul718e3742002-12-13 20:15:29 +00003643 }
Paul Jakmac363d382010-01-24 22:42:13 +00003644 return new;
paul718e3742002-12-13 20:15:29 +00003645}
3646
3647void
paul68980082003-03-25 05:07:42 +00003648ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003649{
3650 u_int16_t index, current_index;
3651
Paul Jakma66349742010-04-13 22:33:54 +01003652 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003653 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003654
3655 if (lsa->refresh_list < 0)
3656 {
3657 int delay;
3658
3659 if (LS_AGE (lsa) == 0 &&
3660 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3661 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3662 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3663 else
3664 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3665 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3666 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3667
3668 if (delay < 0)
3669 delay = 0;
3670
Paul Jakmac363d382010-01-24 22:42:13 +00003671 current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL)
3672 - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003673
3674 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
Paul Jakmac363d382010-01-24 22:42:13 +00003675 % (OSPF_LSA_REFRESHER_SLOTS);
paul718e3742002-12-13 20:15:29 +00003676
3677 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003678 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003679 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003680 if (!ospf->lsa_refresh_queue.qs[index])
3681 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003682 listnode_add (ospf->lsa_refresh_queue.qs[index],
3683 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003684 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003685 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003686 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003687 "setting refresh_list on lsa %p (slod %d)",
3688 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003689 }
3690}
3691
3692void
paul68980082003-03-25 05:07:42 +00003693ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003694{
Paul Jakma66349742010-04-13 22:33:54 +01003695 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003696 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003697 if (lsa->refresh_list >= 0)
3698 {
hasso52dc7ee2004-09-23 19:18:23 +00003699 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003700 listnode_delete (refresh_list, lsa);
3701 if (!listcount (refresh_list))
3702 {
3703 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003704 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003705 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003706 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003707 lsa->refresh_list = -1;
3708 }
3709}
3710
3711int
3712ospf_lsa_refresh_walker (struct thread *t)
3713{
hasso52dc7ee2004-09-23 19:18:23 +00003714 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003715 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003716 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003717 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003718 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003719 struct list *lsa_to_refresh = list_new ();
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(): start");
paul718e3742002-12-13 20:15:29 +00003723
3724
paul68980082003-03-25 05:07:42 +00003725 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003726
ajs9dbc7972005-03-13 19:27:22 +00003727 /* Note: if clock has jumped backwards, then time change could be negative,
3728 so we are careful to cast the expression to unsigned before taking
3729 modulus. */
paul68980082003-03-25 05:07:42 +00003730 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003731 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakmac363d382010-01-24 22:42:13 +00003732 (quagga_time (NULL) - ospf->lsa_refresher_started)
3733 / OSPF_LSA_REFRESHER_GRANULARITY))
3734 % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003735
3736 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003737 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003738 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003739
paul68980082003-03-25 05:07:42 +00003740 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003741 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3742 {
3743 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003744 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003745 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003746
paul68980082003-03-25 05:07:42 +00003747 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003748
Paul Jakma66349742010-04-13 22:33:54 +01003749 assert (i >= 0);
3750
paul68980082003-03-25 05:07:42 +00003751 ospf->lsa_refresh_queue.qs [i] = NULL;
3752
paul718e3742002-12-13 20:15:29 +00003753 if (refresh_list)
3754 {
paul1eb8ef22005-04-07 07:30:20 +00003755 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003756 {
paul718e3742002-12-13 20:15:29 +00003757 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003758 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003759 "refresh lsa %p (slot %d)",
3760 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003761
Paul Jakma66349742010-04-13 22:33:54 +01003762 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003763 list_delete_node (refresh_list, node);
paul718e3742002-12-13 20:15:29 +00003764 lsa->refresh_list = -1;
3765 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003766 }
3767 list_free (refresh_list);
3768 }
3769 }
3770
paul68980082003-03-25 05:07:42 +00003771 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3772 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003773 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003774
paul1eb8ef22005-04-07 07:30:20 +00003775 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
Paul Jakma66349742010-04-13 22:33:54 +01003776 {
3777 ospf_lsa_refresh (ospf, lsa);
3778 assert (lsa->lock > 0);
3779 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
3780 }
paul718e3742002-12-13 20:15:29 +00003781
3782 list_delete (lsa_to_refresh);
3783
3784 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003785 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003786
3787 return 0;
3788}
3789