blob: 369655163af5af2a08a892d8b0d7cc61c50eb528 [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;
2906 struct prefix_ls lsa_prefix;
paul718e3742002-12-13 20:15:29 +00002907
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002908 ls_prefix_set (&lsa_prefix, lsa);
2909
2910 if ((rn = route_node_lookup(ospf->maxage_lsa,
2911 (struct prefix *)&lsa_prefix)))
paul718e3742002-12-13 20:15:29 +00002912 {
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002913 if (rn->info == lsa)
2914 {
2915 UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
2916 ospf_lsa_unlock (&lsa); /* maxage_lsa */
2917 rn->info = NULL;
Christian Franke8afee5c2014-04-28 08:04:59 +00002918 route_unlock_node (rn); /* unlock node because lsa is deleted */
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002919 }
Christian Franke8afee5c2014-04-28 08:04:59 +00002920 route_unlock_node (rn); /* route_node_lookup */
paul718e3742002-12-13 20:15:29 +00002921 }
2922}
2923
Paul Jakma02d942c2010-01-24 23:36:20 +00002924/* Add LSA onto the MaxAge list, and schedule for removal.
2925 * This does *not* lead to the LSA being flooded, that must be taken
2926 * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
2927 * function).
2928 */
paul718e3742002-12-13 20:15:29 +00002929void
paul68980082003-03-25 05:07:42 +00002930ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002931{
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002932 struct prefix_ls lsa_prefix;
2933 struct route_node *rn;
2934
paul718e3742002-12-13 20:15:29 +00002935 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2936 and schedule the MaxAge LSA remover. */
Stephen Hemminger3106a032009-08-06 12:58:05 -07002937 if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
paul718e3742002-12-13 20:15:29 +00002938 {
2939 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002940 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
paul718e3742002-12-13 20:15:29 +00002941 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2942 return;
2943 }
2944
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002945 ls_prefix_set (&lsa_prefix, lsa);
2946 if ((rn = route_node_get (ospf->maxage_lsa,
2947 (struct prefix *)&lsa_prefix)) != NULL)
2948 {
2949 if (rn->info != NULL)
2950 {
2951 route_unlock_node (rn);
2952 }
2953 else
2954 {
2955 rn->info = ospf_lsa_lock(lsa);
2956 SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
2957 }
2958 }
2959 else
2960 {
2961 zlog_err("Unable to allocate memory for maxage lsa\n");
2962 assert(0);
2963 }
paul718e3742002-12-13 20:15:29 +00002964
2965 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002966 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002967
Paul Jakma02d942c2010-01-24 23:36:20 +00002968 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2969 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002970}
2971
paul4dadc292005-05-06 21:37:42 +00002972static int
paul68980082003-03-25 05:07:42 +00002973ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002974{
paul718e3742002-12-13 20:15:29 +00002975 /* Stay away from any Local Translated Type-7 LSAs */
2976 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2977 return 0;
paul718e3742002-12-13 20:15:29 +00002978
2979 if (IS_LSA_MAXAGE (lsa))
2980 /* Self-originated LSAs should NOT time-out instead,
2981 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00002982 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002983 {
2984 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002985 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002986
2987 switch (lsa->data->type)
2988 {
paul718e3742002-12-13 20:15:29 +00002989#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00002990 case OSPF_OPAQUE_LINK_LSA:
2991 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00002992 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00002993 /*
2994 * As a general rule, whenever network topology has changed
2995 * (due to an LSA removal in this case), routing recalculation
2996 * should be triggered. However, this is not true for opaque
2997 * LSAs. Even if an opaque LSA instance is going to be removed
2998 * from the routing domain, it does not mean a change in network
2999 * topology, and thus, routing recalculation is not needed here.
3000 */
3001 break;
paul718e3742002-12-13 20:15:29 +00003002#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00003003 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003004 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003005 ospf_ase_incremental_update (ospf, lsa);
3006 break;
paul718e3742002-12-13 20:15:29 +00003007 default:
paul68980082003-03-25 05:07:42 +00003008 ospf_spf_calculate_schedule (ospf);
3009 break;
paul718e3742002-12-13 20:15:29 +00003010 }
paul68980082003-03-25 05:07:42 +00003011 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003012 }
3013
Paul Jakmac363d382010-01-24 22:42:13 +00003014 if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa))
3015 if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30)
3016 printf ("Eek! Shouldn't happen!\n");
3017
paul718e3742002-12-13 20:15:29 +00003018 return 0;
3019}
3020
3021/* Periodical check of MaxAge LSA. */
3022int
paul68980082003-03-25 05:07:42 +00003023ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003024{
paul68980082003-03-25 05:07:42 +00003025 struct ospf *ospf = THREAD_ARG (thread);
3026 struct route_node *rn;
3027 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003028 struct ospf_area *area;
3029 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003030
paul68980082003-03-25 05:07:42 +00003031 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003032
paul1eb8ef22005-04-07 07:30:20 +00003033 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003034 {
paul68980082003-03-25 05:07:42 +00003035 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3036 ospf_lsa_maxage_walker_remover (ospf, lsa);
3037 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3038 ospf_lsa_maxage_walker_remover (ospf, lsa);
3039 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3040 ospf_lsa_maxage_walker_remover (ospf, lsa);
3041 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3042 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003043#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003044 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3045 ospf_lsa_maxage_walker_remover (ospf, lsa);
3046 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3047 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003048#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003049 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3050 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003051 }
3052
paul4fb949e2003-05-10 20:06:51 +00003053 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003054 if (ospf->lsdb)
3055 {
3056 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3057 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003058#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003059 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3060 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003061#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003062 }
paul718e3742002-12-13 20:15:29 +00003063
paul68980082003-03-25 05:07:42 +00003064 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3065 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003066 return 0;
3067}
3068
paul68980082003-03-25 05:07:42 +00003069struct ospf_lsa *
3070ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3071 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003072{
paul68980082003-03-25 05:07:42 +00003073 struct ospf_lsa *lsa;
3074 struct in_addr mask, id;
3075 struct lsa_header_mask
3076 {
3077 struct lsa_header header;
3078 struct in_addr mask;
3079 } *hmask;
paul718e3742002-12-13 20:15:29 +00003080
paul68980082003-03-25 05:07:42 +00003081 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3082 if (lsa == NULL)
3083 return NULL;
paul718e3742002-12-13 20:15:29 +00003084
paul68980082003-03-25 05:07:42 +00003085 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003086
paul68980082003-03-25 05:07:42 +00003087 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003088
paul68980082003-03-25 05:07:42 +00003089 if (mask.s_addr != hmask->mask.s_addr)
3090 {
3091 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3092 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3093 if (!lsa)
3094 return NULL;
3095 }
paul718e3742002-12-13 20:15:29 +00003096
paul68980082003-03-25 05:07:42 +00003097 return lsa;
paul718e3742002-12-13 20:15:29 +00003098}
3099
3100struct ospf_lsa *
3101ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3102 struct in_addr id, struct in_addr adv_router)
3103{
paule05fba42003-04-13 20:20:53 +00003104 struct ospf *ospf = ospf_lookup();
3105 assert(ospf);
3106
paul718e3742002-12-13 20:15:29 +00003107 switch (type)
3108 {
3109 case OSPF_ROUTER_LSA:
3110 case OSPF_NETWORK_LSA:
3111 case OSPF_SUMMARY_LSA:
3112 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003113 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003114#ifdef HAVE_OPAQUE_LSA
3115 case OSPF_OPAQUE_LINK_LSA:
3116 case OSPF_OPAQUE_AREA_LSA:
3117#endif /* HAVE_OPAQUE_LSA */
3118 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003119 case OSPF_AS_EXTERNAL_LSA:
3120#ifdef HAVE_OPAQUE_LSA
3121 case OSPF_OPAQUE_AS_LSA:
3122#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003123 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003124 default:
3125 break;
3126 }
3127
3128 return NULL;
3129}
3130
3131struct ospf_lsa *
3132ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3133 struct in_addr id)
3134{
3135 struct ospf_lsa *lsa;
3136 struct route_node *rn;
3137
3138 switch (type)
3139 {
3140 case OSPF_ROUTER_LSA:
3141 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003142 case OSPF_NETWORK_LSA:
3143 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3144 if ((lsa = rn->info))
3145 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3146 {
3147 route_unlock_node (rn);
3148 return lsa;
3149 }
3150 break;
3151 case OSPF_SUMMARY_LSA:
3152 case OSPF_ASBR_SUMMARY_LSA:
3153 /* Currently not used. */
3154 assert (1);
3155 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003156 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003157 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003158#ifdef HAVE_OPAQUE_LSA
3159 case OSPF_OPAQUE_LINK_LSA:
3160 case OSPF_OPAQUE_AREA_LSA:
3161 case OSPF_OPAQUE_AS_LSA:
3162 /* Currently not used. */
3163 break;
3164#endif /* HAVE_OPAQUE_LSA */
3165 default:
3166 break;
3167 }
3168
3169 return NULL;
3170}
3171
3172struct ospf_lsa *
3173ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3174{
3175 struct ospf_lsa *match;
3176
3177#ifdef HAVE_OPAQUE_LSA
3178 /*
3179 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3180 * is redefined to have two subfields; opaque-type and opaque-id.
3181 * However, it is harmless to treat the two sub fields together, as if
3182 * they two were forming a unique LSA-ID.
3183 */
3184#endif /* HAVE_OPAQUE_LSA */
3185
3186 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3187
3188 if (match == NULL)
3189 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003190 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003191 lsah->type, inet_ntoa (lsah->id));
3192
3193 return match;
3194}
3195
3196/* return +n, l1 is more recent.
3197 return -n, l2 is more recent.
3198 return 0, l1 and l2 is identical. */
3199int
3200ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3201{
3202 int r;
3203 int x, y;
3204
3205 if (l1 == NULL && l2 == NULL)
3206 return 0;
3207 if (l1 == NULL)
3208 return -1;
3209 if (l2 == NULL)
3210 return 1;
3211
3212 /* compare LS sequence number. */
3213 x = (int) ntohl (l1->data->ls_seqnum);
3214 y = (int) ntohl (l2->data->ls_seqnum);
3215 if (x > y)
3216 return 1;
3217 if (x < y)
3218 return -1;
3219
3220 /* compare LS checksum. */
3221 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3222 if (r)
3223 return r;
3224
3225 /* compare LS age. */
3226 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3227 return 1;
3228 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3229 return -1;
3230
3231 /* compare LS age with MaxAgeDiff. */
3232 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3233 return -1;
3234 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3235 return 1;
3236
3237 /* LSAs are identical. */
3238 return 0;
3239}
3240
3241/* If two LSAs are different, return 1, otherwise return 0. */
3242int
3243ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3244{
3245 char *p1, *p2;
3246 assert (l1);
3247 assert (l2);
3248 assert (l1->data);
3249 assert (l2->data);
3250
3251 if (l1->data->options != l2->data->options)
3252 return 1;
3253
3254 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3255 return 1;
3256
3257 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3258 return 1;
3259
3260 if (l1->data->length != l2->data->length)
3261 return 1;
3262
3263 if (l1->data->length == 0)
3264 return 1;
3265
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02003266 if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
3267 return 1; /* May be a stale LSA in the LSBD */
3268
pauld1825832003-04-03 01:27:01 +00003269 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003270
3271 p1 = (char *) l1->data;
3272 p2 = (char *) l2->data;
3273
3274 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3275 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3276 return 1;
3277
3278 return 0;
3279}
3280
3281#ifdef ORIGINAL_CODING
3282void
3283ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3284 struct ospf_lsa *self,
3285 struct ospf_lsa *new)
3286{
3287 u_int32_t seqnum;
3288
3289 /* Adjust LS Sequence Number. */
3290 seqnum = ntohl (new->data->ls_seqnum) + 1;
3291 self->data->ls_seqnum = htonl (seqnum);
3292
3293 /* Recalculate LSA checksum. */
3294 ospf_lsa_checksum (self->data);
3295
3296 /* Reflooding LSA. */
3297 /* RFC2328 Section 13.3
3298 On non-broadcast networks, separate Link State Update
3299 packets must be sent, as unicasts, to each adjacent neighbor
3300 (i.e., those in state Exchange or greater). The destination
3301 IP addresses for these packets are the neighbors' IP
3302 addresses. */
3303 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3304 {
3305 struct route_node *rn;
3306 struct ospf_neighbor *onbr;
3307
3308 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3309 if ((onbr = rn->info) != NULL)
3310 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3311 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3312 }
3313 else
3314 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3315
3316 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003317 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003318 self->data->type, inet_ntoa (self->data->id));
3319}
3320#else /* ORIGINAL_CODING */
3321static int
paul68980082003-03-25 05:07:42 +00003322ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003323{
3324 if (lsa == NULL || !IS_LSA_SELF (lsa))
3325 return 0;
3326
3327 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003328 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 +00003329
3330 /* Force given lsa's age to MaxAge. */
3331 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3332
3333 switch (lsa->data->type)
3334 {
3335#ifdef HAVE_OPAQUE_LSA
Paul Jakma02d942c2010-01-24 23:36:20 +00003336 /* Opaque wants to be notified of flushes */
paul718e3742002-12-13 20:15:29 +00003337 case OSPF_OPAQUE_LINK_LSA:
3338 case OSPF_OPAQUE_AREA_LSA:
3339 case OSPF_OPAQUE_AS_LSA:
3340 ospf_opaque_lsa_refresh (lsa);
3341 break;
3342#endif /* HAVE_OPAQUE_LSA */
3343 default:
Paul Jakmadfbd5172010-04-14 10:32:12 +01003344 ospf_refresher_unregister_lsa (ospf, lsa);
Paul Jakma02d942c2010-01-24 23:36:20 +00003345 ospf_lsa_flush (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003346 break;
3347 }
3348
3349 return 0;
3350}
3351
3352void
paul68980082003-03-25 05:07:42 +00003353ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003354{
paul1eb8ef22005-04-07 07:30:20 +00003355 struct listnode *node, *nnode;
3356 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003357 struct ospf_area *area;
3358 struct ospf_interface *oi;
3359 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003360 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003361 int need_to_flush_ase = 0;
3362
paul1eb8ef22005-04-07 07:30:20 +00003363 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003364 {
paul718e3742002-12-13 20:15:29 +00003365 if ((lsa = area->router_lsa_self) != NULL)
3366 {
3367 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003368 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3369 lsa->data->type, inet_ntoa (lsa->data->id));
3370
3371 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003372 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003373 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003374 area->router_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003375 }
3376
paul1eb8ef22005-04-07 07:30:20 +00003377 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003378 {
paul718e3742002-12-13 20:15:29 +00003379 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003380 && oi->state == ISM_DR
3381 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003382 {
3383 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003384 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3385 lsa->data->type, inet_ntoa (lsa->data->id));
3386
3387 ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003388 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003389 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003390 oi->network_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003391 }
3392
3393 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3394 && area->external_routing == OSPF_AREA_DEFAULT)
3395 need_to_flush_ase = 1;
3396 }
3397
paul68980082003-03-25 05:07:42 +00003398 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3399 ospf_lsa_flush_schedule (ospf, lsa);
3400 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3401 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003402#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003403 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3404 ospf_lsa_flush_schedule (ospf, lsa);
3405 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3406 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003407#endif /* HAVE_OPAQUE_LSA */
3408 }
3409
3410 if (need_to_flush_ase)
3411 {
paul68980082003-03-25 05:07:42 +00003412 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3413 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003414#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003415 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3416 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003417#endif /* HAVE_OPAQUE_LSA */
3418 }
3419
3420 /*
3421 * Make sure that the MaxAge LSA remover is executed immediately,
3422 * without conflicting to other threads.
3423 */
paul68980082003-03-25 05:07:42 +00003424 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003425 {
paul68980082003-03-25 05:07:42 +00003426 OSPF_TIMER_OFF (ospf->t_maxage);
3427 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003428 }
3429
3430 return;
3431}
3432#endif /* ORIGINAL_CODING */
3433
3434/* If there is self-originated LSA, then return 1, otherwise return 0. */
3435/* An interface-independent version of ospf_lsa_is_self_originated */
3436int
paul68980082003-03-25 05:07:42 +00003437ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003438{
hasso52dc7ee2004-09-23 19:18:23 +00003439 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003440 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003441
3442 /* This LSA is already checked. */
3443 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003444 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003445
3446 /* Make sure LSA is self-checked. */
3447 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3448
3449 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003450 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003451 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3452
3453 /* LSA is router-LSA. */
3454 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003455 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003456 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3457
3458 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3459 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003460 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003461 {
paul718e3742002-12-13 20:15:29 +00003462 /* Ignore virtual link. */
3463 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3464 if (oi->address->family == AF_INET)
3465 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3466 {
3467 /* to make it easier later */
3468 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003469 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003470 }
3471 }
3472
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003473 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003474}
3475
3476/* Get unique Link State ID. */
3477struct in_addr
paul68980082003-03-25 05:07:42 +00003478ospf_lsa_unique_id (struct ospf *ospf,
3479 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003480{
3481 struct ospf_lsa *lsa;
3482 struct in_addr mask, id;
3483
3484 id = p->prefix;
3485
3486 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003487 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003488 if (lsa)
3489 {
3490 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3491 if (ip_masklen (al->mask) == p->prefixlen)
3492 {
3493 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003494 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003495 "Can't get Link State ID for %s/%d",
3496 inet_ntoa (p->prefix), p->prefixlen);
3497 /* id.s_addr = 0; */
3498 id.s_addr = 0xffffffff;
3499 return id;
3500 }
3501 /* Masklen differs, then apply wildcard mask to Link State ID. */
3502 else
3503 {
3504 masklen2ip (p->prefixlen, &mask);
3505
3506 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003507 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3508 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003509 if (lsa)
3510 {
3511 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003512 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003513 "Can't get Link State ID for %s/%d",
3514 inet_ntoa (p->prefix), p->prefixlen);
3515 /* id.s_addr = 0; */
3516 id.s_addr = 0xffffffff;
3517 return id;
3518 }
3519 }
3520 }
3521
3522 return id;
3523}
3524
3525
Paul Jakma70461d72006-05-12 22:57:57 +00003526#define LSA_ACTION_FLOOD_AREA 1
3527#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003528
3529struct lsa_action
3530{
3531 u_char action;
3532 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003533 struct ospf_lsa *lsa;
3534};
3535
paul4dadc292005-05-06 21:37:42 +00003536static int
paul718e3742002-12-13 20:15:29 +00003537ospf_lsa_action (struct thread *t)
3538{
3539 struct lsa_action *data;
3540
3541 data = THREAD_ARG (t);
3542
3543 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003544 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003545 data->action);
3546
3547 switch (data->action)
3548 {
paul718e3742002-12-13 20:15:29 +00003549 case LSA_ACTION_FLOOD_AREA:
3550 ospf_flood_through_area (data->area, NULL, data->lsa);
3551 break;
paul718e3742002-12-13 20:15:29 +00003552 case LSA_ACTION_FLUSH_AREA:
3553 ospf_lsa_flush_area (data->lsa, data->area);
3554 break;
paul718e3742002-12-13 20:15:29 +00003555 }
3556
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003557 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003558 XFREE (MTYPE_OSPF_MESSAGE, data);
3559 return 0;
3560}
3561
3562void
3563ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3564{
3565 struct lsa_action *data;
3566
Stephen Hemminger393deb92008-08-18 14:13:29 -07003567 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003568 data->action = LSA_ACTION_FLOOD_AREA;
3569 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003570 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003571
3572 thread_add_event (master, ospf_lsa_action, data, 0);
3573}
3574
3575void
3576ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3577{
3578 struct lsa_action *data;
3579
Stephen Hemminger393deb92008-08-18 14:13:29 -07003580 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003581 data->action = LSA_ACTION_FLUSH_AREA;
3582 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003583 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003584
3585 thread_add_event (master, ospf_lsa_action, data, 0);
3586}
3587
3588
3589/* LSA Refreshment functions. */
Paul Jakmac363d382010-01-24 22:42:13 +00003590struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00003591ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003592{
3593 struct external_info *ei;
Paul Jakmac363d382010-01-24 22:42:13 +00003594 struct ospf_lsa *new = NULL;
paul718e3742002-12-13 20:15:29 +00003595 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003596 assert (IS_LSA_SELF (lsa));
Paul Jakma66349742010-04-13 22:33:54 +01003597 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003598
3599 switch (lsa->data->type)
3600 {
3601 /* Router and Network LSAs are processed differently. */
3602 case OSPF_ROUTER_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003603 new = ospf_router_lsa_refresh (lsa);
3604 break;
paul718e3742002-12-13 20:15:29 +00003605 case OSPF_NETWORK_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003606 new = ospf_network_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003607 break;
3608 case OSPF_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003609 new = ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003610 break;
3611 case OSPF_ASBR_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003612 new = ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003613 break;
3614 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003615 /* Translated from NSSA Type-5s are refreshed when
3616 * from refresh of Type-7 - do not refresh these directly.
3617 */
3618 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3619 break;
paul718e3742002-12-13 20:15:29 +00003620 ei = ospf_external_info_check (lsa);
3621 if (ei)
Paul Jakmac363d382010-01-24 22:42:13 +00003622 new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003623 else
pauld4a53d52003-07-12 21:30:57 +00003624 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003625 break;
3626#ifdef HAVE_OPAQUE_LSA
3627 case OSPF_OPAQUE_LINK_LSA:
3628 case OSPF_OPAQUE_AREA_LSA:
3629 case OSPF_OPAQUE_AS_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003630 new = ospf_opaque_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003631 break;
pauld7480322003-05-16 17:31:51 +00003632#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003633 default:
3634 break;
paul718e3742002-12-13 20:15:29 +00003635 }
Paul Jakmac363d382010-01-24 22:42:13 +00003636 return new;
paul718e3742002-12-13 20:15:29 +00003637}
3638
3639void
paul68980082003-03-25 05:07:42 +00003640ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003641{
3642 u_int16_t index, current_index;
3643
Paul Jakma66349742010-04-13 22:33:54 +01003644 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003645 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003646
3647 if (lsa->refresh_list < 0)
3648 {
3649 int delay;
3650
3651 if (LS_AGE (lsa) == 0 &&
3652 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3653 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3654 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3655 else
3656 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3657 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3658 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3659
3660 if (delay < 0)
3661 delay = 0;
3662
Paul Jakmac363d382010-01-24 22:42:13 +00003663 current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL)
3664 - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003665
3666 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
Paul Jakmac363d382010-01-24 22:42:13 +00003667 % (OSPF_LSA_REFRESHER_SLOTS);
paul718e3742002-12-13 20:15:29 +00003668
3669 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003670 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003671 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003672 if (!ospf->lsa_refresh_queue.qs[index])
3673 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003674 listnode_add (ospf->lsa_refresh_queue.qs[index],
3675 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003676 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003677 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003678 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003679 "setting refresh_list on lsa %p (slod %d)",
3680 inet_ntoa (lsa->data->id), lsa, index);
paul718e3742002-12-13 20:15:29 +00003681 }
3682}
3683
3684void
paul68980082003-03-25 05:07:42 +00003685ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003686{
Paul Jakma66349742010-04-13 22:33:54 +01003687 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003688 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003689 if (lsa->refresh_list >= 0)
3690 {
hasso52dc7ee2004-09-23 19:18:23 +00003691 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003692 listnode_delete (refresh_list, lsa);
3693 if (!listcount (refresh_list))
3694 {
3695 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003696 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003697 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003698 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003699 lsa->refresh_list = -1;
3700 }
3701}
3702
3703int
3704ospf_lsa_refresh_walker (struct thread *t)
3705{
hasso52dc7ee2004-09-23 19:18:23 +00003706 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003707 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003708 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003709 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003710 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003711 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003712
3713 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003714 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003715
3716
paul68980082003-03-25 05:07:42 +00003717 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003718
ajs9dbc7972005-03-13 19:27:22 +00003719 /* Note: if clock has jumped backwards, then time change could be negative,
3720 so we are careful to cast the expression to unsigned before taking
3721 modulus. */
paul68980082003-03-25 05:07:42 +00003722 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003723 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakmac363d382010-01-24 22:42:13 +00003724 (quagga_time (NULL) - ospf->lsa_refresher_started)
3725 / OSPF_LSA_REFRESHER_GRANULARITY))
3726 % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003727
3728 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003729 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003730 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003731
paul68980082003-03-25 05:07:42 +00003732 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003733 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3734 {
3735 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003736 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003737 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003738
paul68980082003-03-25 05:07:42 +00003739 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003740
Paul Jakma66349742010-04-13 22:33:54 +01003741 assert (i >= 0);
3742
paul68980082003-03-25 05:07:42 +00003743 ospf->lsa_refresh_queue.qs [i] = NULL;
3744
paul718e3742002-12-13 20:15:29 +00003745 if (refresh_list)
3746 {
paul1eb8ef22005-04-07 07:30:20 +00003747 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003748 {
paul718e3742002-12-13 20:15:29 +00003749 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003750 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003751 "refresh lsa %p (slot %d)",
3752 inet_ntoa (lsa->data->id), lsa, i);
paul718e3742002-12-13 20:15:29 +00003753
Paul Jakma66349742010-04-13 22:33:54 +01003754 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003755 list_delete_node (refresh_list, node);
paul718e3742002-12-13 20:15:29 +00003756 lsa->refresh_list = -1;
3757 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003758 }
3759 list_free (refresh_list);
3760 }
3761 }
3762
paul68980082003-03-25 05:07:42 +00003763 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3764 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003765 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003766
paul1eb8ef22005-04-07 07:30:20 +00003767 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
Paul Jakma66349742010-04-13 22:33:54 +01003768 {
3769 ospf_lsa_refresh (ospf, lsa);
3770 assert (lsa->lock > 0);
3771 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
3772 }
paul718e3742002-12-13 20:15:29 +00003773
3774 list_delete (lsa_to_refresh);
3775
3776 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003777 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003778
3779 return 0;
3780}
3781