blob: f49e263c8e7bf96e6568bb0dbd0376d614bf69ce [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"
Denis Ovsienkoe7c65f62012-02-20 00:54:05 +040052#include "ospfd/ospf_abr.h"
paul718e3742002-12-13 20:15:29 +000053
David Lamparter6b0655a2014-06-04 06:53:35 +020054
paul718e3742002-12-13 20:15:29 +000055u_int32_t
56get_metric (u_char *metric)
57{
58 u_int32_t m;
59 m = metric[0];
60 m = (m << 8) + metric[1];
61 m = (m << 8) + metric[2];
62 return m;
63}
64
David Lamparter6b0655a2014-06-04 06:53:35 +020065
paul718e3742002-12-13 20:15:29 +000066struct timeval
67tv_adjust (struct timeval a)
68{
69 while (a.tv_usec >= 1000000)
70 {
71 a.tv_usec -= 1000000;
72 a.tv_sec++;
73 }
74
75 while (a.tv_usec < 0)
76 {
77 a.tv_usec += 1000000;
78 a.tv_sec--;
79 }
80
81 return a;
82}
83
84int
85tv_ceil (struct timeval a)
86{
87 a = tv_adjust (a);
88
89 return (a.tv_usec ? a.tv_sec + 1 : a.tv_sec);
90}
91
92int
93tv_floor (struct timeval a)
94{
95 a = tv_adjust (a);
96
97 return a.tv_sec;
98}
99
100struct timeval
101int2tv (int a)
102{
103 struct timeval ret;
104
105 ret.tv_sec = a;
106 ret.tv_usec = 0;
107
108 return ret;
109}
110
111struct timeval
Michael Rossberg2ef762e2015-07-27 07:56:25 +0200112msec2tv (int a)
113{
114 struct timeval ret;
115
116 ret.tv_sec = 0;
117 ret.tv_usec = a * 1000;
118
119 return tv_adjust (ret);
120}
121
122struct timeval
paul718e3742002-12-13 20:15:29 +0000123tv_add (struct timeval a, struct timeval b)
124{
125 struct timeval ret;
126
127 ret.tv_sec = a.tv_sec + b.tv_sec;
128 ret.tv_usec = a.tv_usec + b.tv_usec;
129
130 return tv_adjust (ret);
131}
132
133struct timeval
134tv_sub (struct timeval a, struct timeval b)
135{
136 struct timeval ret;
137
138 ret.tv_sec = a.tv_sec - b.tv_sec;
139 ret.tv_usec = a.tv_usec - b.tv_usec;
140
141 return tv_adjust (ret);
142}
143
144int
145tv_cmp (struct timeval a, struct timeval b)
146{
147 return (a.tv_sec == b.tv_sec ?
148 a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
149}
150
151int
152ospf_lsa_refresh_delay (struct ospf_lsa *lsa)
153{
154 struct timeval delta, now;
155 int delay = 0;
156
Paul Jakma2518efd2006-08-27 06:49:29 +0000157 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +0000158 delta = tv_sub (now, lsa->tv_orig);
159
Michael Rossberg2ef762e2015-07-27 07:56:25 +0200160 if (tv_cmp (delta, msec2tv (OSPF_MIN_LS_INTERVAL)) < 0)
paul718e3742002-12-13 20:15:29 +0000161 {
Michael Rossberg2ef762e2015-07-27 07:56:25 +0200162 delay = tv_ceil (tv_sub (msec2tv (OSPF_MIN_LS_INTERVAL), delta));
paul718e3742002-12-13 20:15:29 +0000163
164 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000165 zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
paul718e3742002-12-13 20:15:29 +0000166 lsa->data->type, inet_ntoa (lsa->data->id), delay);
167
168 assert (delay > 0);
169 }
170
171 return delay;
172}
173
David Lamparter6b0655a2014-06-04 06:53:35 +0200174
paul718e3742002-12-13 20:15:29 +0000175int
176get_age (struct ospf_lsa *lsa)
177{
178 int age;
paul718e3742002-12-13 20:15:29 +0000179
Paul Jakma2518efd2006-08-27 06:49:29 +0000180 age = ntohs (lsa->data->ls_age)
181 + tv_floor (tv_sub (recent_relative_time (), lsa->tv_recv));
paul718e3742002-12-13 20:15:29 +0000182
183 return age;
184}
185
David Lamparter6b0655a2014-06-04 06:53:35 +0200186
paul718e3742002-12-13 20:15:29 +0000187/* Fletcher Checksum -- Refer to RFC1008. */
paul718e3742002-12-13 20:15:29 +0000188
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100189/* All the offsets are zero-based. The offsets in the RFC1008 are
190 one-based. */
paul718e3742002-12-13 20:15:29 +0000191u_int16_t
192ospf_lsa_checksum (struct lsa_header *lsa)
193{
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100194 u_char *buffer = (u_char *) &lsa->options;
195 int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */
paul718e3742002-12-13 20:15:29 +0000196
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100197 /* Skip the AGE field */
198 u_int16_t len = ntohs(lsa->length) - options_offset;
paul718e3742002-12-13 20:15:29 +0000199
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100200 /* Checksum offset starts from "options" field, not the beginning of the
201 lsa_header struct. The offset is 14, rather than 16. */
202 int checksum_offset = (u_char *) &lsa->checksum - buffer;
paul718e3742002-12-13 20:15:29 +0000203
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100204 return fletcher_checksum(buffer, len, checksum_offset);
paul718e3742002-12-13 20:15:29 +0000205}
206
JR Riversd8a4e422012-09-13 17:17:36 +0000207int
208ospf_lsa_checksum_valid (struct lsa_header *lsa)
209{
210 u_char *buffer = (u_char *) &lsa->options;
211 int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */
212
213 /* Skip the AGE field */
214 u_int16_t len = ntohs(lsa->length) - options_offset;
215
216 return(fletcher_checksum(buffer, len, FLETCHER_CHECKSUM_VALIDATE) == 0);
217}
218
paul718e3742002-12-13 20:15:29 +0000219
David Lamparter6b0655a2014-06-04 06:53:35 +0200220
paul718e3742002-12-13 20:15:29 +0000221/* Create OSPF LSA. */
222struct ospf_lsa *
223ospf_lsa_new ()
224{
225 struct ospf_lsa *new;
226
227 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
paul718e3742002-12-13 20:15:29 +0000228
229 new->flags = 0;
230 new->lock = 1;
231 new->retransmit_counter = 0;
Paul Jakma2518efd2006-08-27 06:49:29 +0000232 new->tv_recv = recent_relative_time ();
paul718e3742002-12-13 20:15:29 +0000233 new->tv_orig = new->tv_recv;
234 new->refresh_list = -1;
235
236 return new;
237}
238
239/* Duplicate OSPF LSA. */
240struct ospf_lsa *
241ospf_lsa_dup (struct ospf_lsa *lsa)
242{
243 struct ospf_lsa *new;
244
245 if (lsa == NULL)
246 return NULL;
247
248 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
249
250 memcpy (new, lsa, sizeof (struct ospf_lsa));
251 UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
252 new->lock = 1;
253 new->retransmit_counter = 0;
254 new->data = ospf_lsa_data_dup (lsa->data);
255
paulf2c80652002-12-13 21:44:27 +0000256 /* kevinm: Clear the refresh_list, otherwise there are going
257 to be problems when we try to remove the LSA from the
258 queue (which it's not a member of.)
259 XXX: Should we add the LSA to the refresh_list queue? */
260 new->refresh_list = -1;
261
262 if (IS_DEBUG_OSPF (lsa, LSA))
David Lampartereed3c482015-03-03 08:51:53 +0100263 zlog_debug ("LSA: duplicated %p (new: %p)", (void *)lsa, (void *)new);
paulf2c80652002-12-13 21:44:27 +0000264
paul718e3742002-12-13 20:15:29 +0000265 return new;
266}
267
268/* Free OSPF LSA. */
269void
270ospf_lsa_free (struct ospf_lsa *lsa)
271{
272 assert (lsa->lock == 0);
273
274 if (IS_DEBUG_OSPF (lsa, LSA))
David Lampartereed3c482015-03-03 08:51:53 +0100275 zlog_debug ("LSA: freed %p", (void *)lsa);
paul718e3742002-12-13 20:15:29 +0000276
277 /* Delete LSA data. */
278 if (lsa->data != NULL)
279 ospf_lsa_data_free (lsa->data);
280
281 assert (lsa->refresh_list < 0);
282
283 memset (lsa, 0, sizeof (struct ospf_lsa));
284 XFREE (MTYPE_OSPF_LSA, lsa);
285}
286
287/* Lock LSA. */
288struct ospf_lsa *
289ospf_lsa_lock (struct ospf_lsa *lsa)
290{
291 lsa->lock++;
292 return lsa;
293}
294
295/* Unlock LSA. */
296void
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000297ospf_lsa_unlock (struct ospf_lsa **lsa)
paul718e3742002-12-13 20:15:29 +0000298{
299 /* This is sanity check. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000300 if (!lsa || !*lsa)
paul718e3742002-12-13 20:15:29 +0000301 return;
302
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000303 (*lsa)->lock--;
paul718e3742002-12-13 20:15:29 +0000304
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000305 assert ((*lsa)->lock >= 0);
paul718e3742002-12-13 20:15:29 +0000306
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000307 if ((*lsa)->lock == 0)
paul718e3742002-12-13 20:15:29 +0000308 {
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000309 assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
310 ospf_lsa_free (*lsa);
311 *lsa = NULL;
paul718e3742002-12-13 20:15:29 +0000312 }
313}
314
315/* Check discard flag. */
316void
317ospf_lsa_discard (struct ospf_lsa *lsa)
318{
319 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
320 {
321 SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000322 ospf_lsa_unlock (&lsa);
paul718e3742002-12-13 20:15:29 +0000323 }
324}
325
326/* Create LSA data. */
327struct lsa_header *
328ospf_lsa_data_new (size_t size)
329{
Stephen Hemminger393deb92008-08-18 14:13:29 -0700330 return XCALLOC (MTYPE_OSPF_LSA_DATA, size);
paul718e3742002-12-13 20:15:29 +0000331}
332
333/* Duplicate LSA data. */
334struct lsa_header *
335ospf_lsa_data_dup (struct lsa_header *lsah)
336{
337 struct lsa_header *new;
338
339 new = ospf_lsa_data_new (ntohs (lsah->length));
340 memcpy (new, lsah, ntohs (lsah->length));
341
342 return new;
343}
344
345/* Free LSA data. */
346void
347ospf_lsa_data_free (struct lsa_header *lsah)
348{
349 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000350 zlog_debug ("LSA[Type%d:%s]: data freed %p",
David Lampartereed3c482015-03-03 08:51:53 +0100351 lsah->type, inet_ntoa (lsah->id), (void *)lsah);
paul718e3742002-12-13 20:15:29 +0000352
353 XFREE (MTYPE_OSPF_LSA_DATA, lsah);
354}
355
David Lamparter6b0655a2014-06-04 06:53:35 +0200356
paul718e3742002-12-13 20:15:29 +0000357/* LSA general functions. */
358
359const char *
360dump_lsa_key (struct ospf_lsa *lsa)
361{
362 static char buf[] = {
hasso52dc7ee2004-09-23 19:18:23 +0000363 "Type255,id(255.255.255.255),ar(255.255.255.255)"
paul718e3742002-12-13 20:15:29 +0000364 };
365 struct lsa_header *lsah;
366
367 if (lsa != NULL && (lsah = lsa->data) != NULL)
368 {
369 char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
370 strcpy (id, inet_ntoa (lsah->id));
371 strcpy (ar, inet_ntoa (lsah->adv_router));
372
373 sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
374 }
375 else
376 strcpy (buf, "NULL");
377
378 return buf;
379}
380
381u_int32_t
382lsa_seqnum_increment (struct ospf_lsa *lsa)
383{
384 u_int32_t seqnum;
385
386 seqnum = ntohl (lsa->data->ls_seqnum) + 1;
387
388 return htonl (seqnum);
389}
390
391void
392lsa_header_set (struct stream *s, u_char options,
paul68980082003-03-25 05:07:42 +0000393 u_char type, struct in_addr id, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +0000394{
395 struct lsa_header *lsah;
396
397 lsah = (struct lsa_header *) STREAM_DATA (s);
398
Paul Jakma02d942c2010-01-24 23:36:20 +0000399 lsah->ls_age = htons (OSPF_LSA_INITIAL_AGE);
paul718e3742002-12-13 20:15:29 +0000400 lsah->options = options;
401 lsah->type = type;
402 lsah->id = id;
paul68980082003-03-25 05:07:42 +0000403 lsah->adv_router = router_id;
paul718e3742002-12-13 20:15:29 +0000404 lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
405
paul9985f832005-02-09 15:51:56 +0000406 stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000407}
David Lamparter6b0655a2014-06-04 06:53:35 +0200408
paul68980082003-03-25 05:07:42 +0000409
paul718e3742002-12-13 20:15:29 +0000410/* router-LSA related functions. */
411/* Get router-LSA flags. */
paul4dadc292005-05-06 21:37:42 +0000412static u_char
paul718e3742002-12-13 20:15:29 +0000413router_lsa_flags (struct ospf_area *area)
414{
415 u_char flags;
416
paul68980082003-03-25 05:07:42 +0000417 flags = area->ospf->flags;
paul718e3742002-12-13 20:15:29 +0000418
419 /* Set virtual link flag. */
420 if (ospf_full_virtual_nbrs (area))
421 SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
422 else
423 /* Just sanity check */
424 UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);
425
426 /* Set Shortcut ABR behabiour flag. */
427 UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
paul68980082003-03-25 05:07:42 +0000428 if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
paul718e3742002-12-13 20:15:29 +0000429 if (!OSPF_IS_AREA_BACKBONE (area))
430 if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
paul68980082003-03-25 05:07:42 +0000431 area->ospf->backbone == NULL) ||
paul718e3742002-12-13 20:15:29 +0000432 area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
433 SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
434
435 /* ASBR can't exit in stub area. */
Greg Troxelfc787e82007-08-06 15:50:20 +0000436 if (area->external_routing == OSPF_AREA_STUB)
paul942b6c12003-06-22 08:22:18 +0000437 UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
438 /* If ASBR set External flag */
439 else if (IS_OSPF_ASBR (area->ospf))
440 SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
441
442 /* Set ABR dependent flags */
443 if (IS_OSPF_ABR (area->ospf))
444 {
445 SET_FLAG (flags, ROUTER_LSA_BORDER);
paul942b6c12003-06-22 08:22:18 +0000446 /* If Area is NSSA and we are both ABR and unconditional translator,
pauld4a53d52003-07-12 21:30:57 +0000447 * set Nt bit to inform other routers.
paul942b6c12003-06-22 08:22:18 +0000448 */
pauld4a53d52003-07-12 21:30:57 +0000449 if ( (area->external_routing == OSPF_AREA_NSSA)
450 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
451 SET_FLAG (flags, ROUTER_LSA_NT);
paul942b6c12003-06-22 08:22:18 +0000452 }
paul718e3742002-12-13 20:15:29 +0000453 return flags;
454}
455
456/* Lookup neighbor other than myself.
457 And check neighbor count,
458 Point-to-Point link must have only 1 neighbor. */
459struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +0000460ospf_nbr_lookup_ptop (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +0000461{
paul718e3742002-12-13 20:15:29 +0000462 struct ospf_neighbor *nbr = NULL;
paul68980082003-03-25 05:07:42 +0000463 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000464
465 /* Search neighbor, there must be one of two nbrs. */
paul68980082003-03-25 05:07:42 +0000466 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
467 if ((nbr = rn->info))
468 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000469 if (nbr->state == NSM_Full)
paul68980082003-03-25 05:07:42 +0000470 {
471 route_unlock_node (rn);
472 break;
473 }
paul718e3742002-12-13 20:15:29 +0000474
475 /* PtoP link must have only 1 neighbor. */
paul68980082003-03-25 05:07:42 +0000476 if (ospf_nbr_count (oi, 0) > 1)
paul718e3742002-12-13 20:15:29 +0000477 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
478
479 return nbr;
480}
481
paul88d6cf32005-10-29 12:50:09 +0000482/* Determine cost of link, taking RFC3137 stub-router support into
483 * consideration
484 */
485static u_int16_t
486ospf_link_cost (struct ospf_interface *oi)
487{
488 /* RFC3137 stub router support */
489 if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
490 return oi->output_cost;
491 else
492 return OSPF_OUTPUT_COST_INFINITE;
493}
494
paul718e3742002-12-13 20:15:29 +0000495/* Set a link information. */
paul779adb02006-01-18 15:07:38 +0000496static char
paul718e3742002-12-13 20:15:29 +0000497link_info_set (struct stream *s, struct in_addr id,
498 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
499{
paul779adb02006-01-18 15:07:38 +0000500 /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
501 * vast majority of cases. Some rare routers with lots of links need more.
502 * we try accomodate those here.
503 */
504 if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
505 {
506 size_t ret = OSPF_MAX_LSA_SIZE;
507
508 /* Can we enlarge the stream still? */
509 if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
510 {
511 /* we futz the size here for simplicity, really we need to account
512 * for just:
513 * IP Header - (sizeof (struct ip))
514 * OSPF Header - OSPF_HEADER_SIZE
515 * LSA Header - OSPF_LSA_HEADER_SIZE
516 * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
517 *
518 * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
519 */
520 ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
521 }
522
523 if (ret == OSPF_MAX_LSA_SIZE)
524 {
Paul Jakma53725102009-08-03 16:34:16 +0100525 zlog_warn ("%s: Out of space in LSA stream, left %zd, size %zd",
paul779adb02006-01-18 15:07:38 +0000526 __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
527 return 0;
528 }
529 }
530
paul718e3742002-12-13 20:15:29 +0000531 /* TOS based routing is not supported. */
532 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
533 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
534 stream_putc (s, type); /* Link Type. */
535 stream_putc (s, tos); /* TOS = 0. */
536 stream_putw (s, cost); /* Link Cost. */
paul779adb02006-01-18 15:07:38 +0000537
538 return 1;
paul718e3742002-12-13 20:15:29 +0000539}
540
Andrew J. Schorre4529632006-12-12 19:18:21 +0000541/* Describe Point-to-Point link (Section 12.4.1.1). */
paul4dadc292005-05-06 21:37:42 +0000542static int
paul718e3742002-12-13 20:15:29 +0000543lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
544{
545 int links = 0;
546 struct ospf_neighbor *nbr;
547 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000548 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000549
550 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000551 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
paul718e3742002-12-13 20:15:29 +0000552
paul68980082003-03-25 05:07:42 +0000553 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000554 if (nbr->state == NSM_Full)
555 {
556 /* For unnumbered point-to-point networks, the Link Data field
557 should specify the interface's MIB-II ifIndex value. */
paul779adb02006-01-18 15:07:38 +0000558 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
559 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000560 }
561
Andrew J. Schorre4529632006-12-12 19:18:21 +0000562 /* Regardless of the state of the neighboring router, we must
563 add a Type 3 link (stub network).
564 N.B. Options 1 & 2 share basically the same logic. */
565 masklen2ip (oi->address->prefixlen, &mask);
566 id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
567 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
568 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000569 return links;
570}
571
572/* Describe Broadcast Link. */
paul4dadc292005-05-06 21:37:42 +0000573static int
paul718e3742002-12-13 20:15:29 +0000574lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
575{
576 struct ospf_neighbor *dr;
577 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000578 u_int16_t cost = ospf_link_cost (oi);
579
paul718e3742002-12-13 20:15:29 +0000580 /* Describe Type 3 Link. */
581 if (oi->state == ISM_Waiting)
582 {
Christian Frankecbf435c2014-04-28 11:42:20 +0000583 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
584 zlog_debug ("LSA[Type1]: Interface %s is in state Waiting. "
585 "Adding stub interface", oi->ifp->name);
paul718e3742002-12-13 20:15:29 +0000586 masklen2ip (oi->address->prefixlen, &mask);
587 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000588 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
589 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000590 }
591
592 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
593 /* Describe Type 2 link. */
594 if (dr && (dr->state == NSM_Full ||
595 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000596 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000597 {
Christian Frankecbf435c2014-04-28 11:42:20 +0000598 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
599 zlog_debug ("LSA[Type1]: Interface %s has a DR. "
600 "Adding transit interface", oi->ifp->name);
paul779adb02006-01-18 15:07:38 +0000601 return link_info_set (s, DR (oi), oi->address->u.prefix4,
602 LSA_LINK_TYPE_TRANSIT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000603 }
604 /* Describe type 3 link. */
605 else
606 {
Christian Frankecbf435c2014-04-28 11:42:20 +0000607 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
608 zlog_debug ("LSA[Type1]: Interface %s has no DR. "
609 "Adding stub interface", oi->ifp->name);
paul718e3742002-12-13 20:15:29 +0000610 masklen2ip (oi->address->prefixlen, &mask);
611 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000612 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
613 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000614 }
paul718e3742002-12-13 20:15:29 +0000615}
616
paul4dadc292005-05-06 21:37:42 +0000617static int
paul718e3742002-12-13 20:15:29 +0000618lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
619{
620 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000621
paul718e3742002-12-13 20:15:29 +0000622 /* Describe Type 3 Link. */
623 if (oi->state != ISM_Loopback)
624 return 0;
625
626 mask.s_addr = 0xffffffff;
627 id.s_addr = oi->address->u.prefix4.s_addr;
kitty7bd31772016-02-18 21:33:40 -0800628 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
paul718e3742002-12-13 20:15:29 +0000629}
630
631/* Describe Virtual Link. */
paul4dadc292005-05-06 21:37:42 +0000632static int
paul718e3742002-12-13 20:15:29 +0000633lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
634{
635 struct ospf_neighbor *nbr;
paul88d6cf32005-10-29 12:50:09 +0000636 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000637
paul718e3742002-12-13 20:15:29 +0000638 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000639 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000640 if (nbr->state == NSM_Full)
641 {
paul779adb02006-01-18 15:07:38 +0000642 return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
643 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
paul718e3742002-12-13 20:15:29 +0000644 }
645
646 return 0;
647}
648
649#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
650
paul7afa08d2002-12-13 20:59:45 +0000651/* this function add for support point-to-multipoint ,see rfc2328
65212.4.1.4.*/
653/* from "edward rrr" <edward_rrr@hotmail.com>
654 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul4dadc292005-05-06 21:37:42 +0000655static int
paul68980082003-03-25 05:07:42 +0000656lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000657{
658 int links = 0;
659 struct route_node *rn;
660 struct ospf_neighbor *nbr = NULL;
661 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000662 u_int16_t cost = ospf_link_cost (oi);
paul7afa08d2002-12-13 20:59:45 +0000663
664 mask.s_addr = 0xffffffff;
665 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000666 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
paul7afa08d2002-12-13 20:59:45 +0000667
paul1cc8f762003-04-05 19:34:32 +0000668 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000669 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000670
671 /* Search neighbor, */
672 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
673 if ((nbr = rn->info) != NULL)
674 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000675 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000676 if (nbr->state == NSM_Full)
677
678 {
paul779adb02006-01-18 15:07:38 +0000679 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
680 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul1cc8f762003-04-05 19:34:32 +0000681 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000682 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000683 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000684 }
685
686 return links;
paul7afa08d2002-12-13 20:59:45 +0000687}
688
paul718e3742002-12-13 20:15:29 +0000689/* Set router-LSA link information. */
paul4dadc292005-05-06 21:37:42 +0000690static int
paul718e3742002-12-13 20:15:29 +0000691router_lsa_link_set (struct stream *s, struct ospf_area *area)
692{
hasso52dc7ee2004-09-23 19:18:23 +0000693 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000694 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000695 int links = 0;
696
paul1eb8ef22005-04-07 07:30:20 +0000697 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +0000698 {
paul718e3742002-12-13 20:15:29 +0000699 struct interface *ifp = oi->ifp;
700
701 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000702 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000703 {
704 if (oi->state != ISM_Down)
705 {
Joakim Tjernlundc81ee5c2012-07-07 17:06:11 +0200706 oi->lsa_pos_beg = links;
paul718e3742002-12-13 20:15:29 +0000707 /* Describe each link. */
708 switch (oi->type)
709 {
710 case OSPF_IFTYPE_POINTOPOINT:
711 links += lsa_link_ptop_set (s, oi);
712 break;
713 case OSPF_IFTYPE_BROADCAST:
714 links += lsa_link_broadcast_set (s, oi);
715 break;
716 case OSPF_IFTYPE_NBMA:
717 links += lsa_link_nbma_set (s, oi);
718 break;
719 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000720 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000721 break;
722 case OSPF_IFTYPE_VIRTUALLINK:
723 links += lsa_link_virtuallink_set (s, oi);
724 break;
725 case OSPF_IFTYPE_LOOPBACK:
726 links += lsa_link_loopback_set (s, oi);
727 }
Joakim Tjernlundc81ee5c2012-07-07 17:06:11 +0200728 oi->lsa_pos_end = links;
paul718e3742002-12-13 20:15:29 +0000729 }
730 }
731 }
732
733 return links;
734}
735
736/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000737static void
paul718e3742002-12-13 20:15:29 +0000738ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
739{
740 unsigned long putp;
741 u_int16_t cnt;
742
743 /* Set flags. */
744 stream_putc (s, router_lsa_flags (area));
745
746 /* Set Zero fields. */
747 stream_putc (s, 0);
748
749 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000750 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000751
752 /* Forward word */
753 stream_putw(s, 0);
754
755 /* Set all link information. */
756 cnt = router_lsa_link_set (s, area);
757
758 /* Set # of links here. */
759 stream_putw_at (s, putp, cnt);
760}
David Lamparter6b0655a2014-06-04 06:53:35 +0200761
paul88d6cf32005-10-29 12:50:09 +0000762static int
763ospf_stub_router_timer (struct thread *t)
764{
765 struct ospf_area *area = THREAD_ARG (t);
766
767 area->t_stub_router = NULL;
768
769 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
770
771 /* clear stub route state and generate router-lsa refresh, don't
772 * clobber an administratively set stub-router state though.
773 */
774 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
775 return 0;
776
777 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
778
Paul Jakmac363d382010-01-24 22:42:13 +0000779 ospf_router_lsa_update_area (area);
paul88d6cf32005-10-29 12:50:09 +0000780
781 return 0;
782}
paul718e3742002-12-13 20:15:29 +0000783
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100784static void
paul88d6cf32005-10-29 12:50:09 +0000785ospf_stub_router_check (struct ospf_area *area)
786{
787 /* area must either be administratively configured to be stub
788 * or startup-time stub-router must be configured and we must in a pre-stub
789 * state.
790 */
791 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
792 {
793 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
794 return;
795 }
796
797 /* not admin-stubbed, check whether startup stubbing is configured and
798 * whether it's not been done yet
799 */
800 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
801 return;
802
803 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
804 {
805 /* stub-router is hence done forever for this area, even if someone
806 * tries configure it (take effect next restart).
807 */
808 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
809 return;
810 }
811
812 /* startup stub-router configured and not yet done */
813 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
814
815 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
816 area->ospf->stub_router_startup_time);
817}
David Lamparter6b0655a2014-06-04 06:53:35 +0200818
paul718e3742002-12-13 20:15:29 +0000819/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000820static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000821ospf_router_lsa_new (struct ospf_area *area)
822{
paul68980082003-03-25 05:07:42 +0000823 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000824 struct stream *s;
825 struct lsa_header *lsah;
826 struct ospf_lsa *new;
827 int length;
828
829 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000830 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000831
paul88d6cf32005-10-29 12:50:09 +0000832 /* check whether stub-router is desired, and if this is the first
833 * router LSA.
834 */
835 ospf_stub_router_check (area);
836
paul718e3742002-12-13 20:15:29 +0000837 /* Create a stream for LSA. */
838 s = stream_new (OSPF_MAX_LSA_SIZE);
paul718e3742002-12-13 20:15:29 +0000839 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000840 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000841 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000842
843 /* Set router-LSA body fields. */
844 ospf_router_lsa_body_set (s, area);
845
846 /* Set length. */
847 length = stream_get_endp (s);
paul779adb02006-01-18 15:07:38 +0000848 lsah = (struct lsa_header *) STREAM_DATA (s);
paul718e3742002-12-13 20:15:29 +0000849 lsah->length = htons (length);
850
851 /* Now, create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000852 if ( (new = ospf_lsa_new ()) == NULL)
853 {
854 zlog_err ("%s: Unable to create new lsa", __func__);
855 return NULL;
856 }
857
paul718e3742002-12-13 20:15:29 +0000858 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +0000859 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +0000860
861 /* Copy LSA data to store, discard stream. */
862 new->data = ospf_lsa_data_new (length);
863 memcpy (new->data, lsah, length);
864 stream_free (s);
865
866 return new;
867}
868
869/* Originate Router-LSA. */
paul88d6cf32005-10-29 12:50:09 +0000870static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000871ospf_router_lsa_originate (struct ospf_area *area)
872{
873 struct ospf_lsa *new;
paul88d6cf32005-10-29 12:50:09 +0000874
paul718e3742002-12-13 20:15:29 +0000875 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000876 if ( (new = ospf_router_lsa_new (area)) == NULL)
877 {
878 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
879 return NULL;
880 }
paul718e3742002-12-13 20:15:29 +0000881
882 /* Sanity check. */
883 if (new->data->adv_router.s_addr == 0)
884 {
885 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000886 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000887 ospf_lsa_discard (new);
888 return NULL;
889 }
890
891 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000892 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000893
894 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000895 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000896
897 /* Flooding new LSA through area. */
898 ospf_flood_through_area (area, NULL, new);
899
900 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
901 {
ajse588f212004-12-08 18:12:06 +0000902 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
David Lampartereed3c482015-03-03 08:51:53 +0100903 new->data->type, inet_ntoa (new->data->id), (void *)new);
paul718e3742002-12-13 20:15:29 +0000904 ospf_lsa_header_dump (new->data);
905 }
906
907 return new;
908}
909
910/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000911static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000912ospf_router_lsa_refresh (struct ospf_lsa *lsa)
913{
914 struct ospf_area *area = lsa->area;
915 struct ospf_lsa *new;
916
917 /* Sanity check. */
918 assert (lsa->data);
919
920 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000921 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000922
Paul Jakmac363d382010-01-24 22:42:13 +0000923 /* Unregister LSA from refresh-list */
924 ospf_refresher_unregister_lsa (area->ospf, lsa);
925
paul718e3742002-12-13 20:15:29 +0000926 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000927 if ( (new = ospf_router_lsa_new (area)) == NULL)
928 {
929 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
930 return NULL;
931 }
932
paul718e3742002-12-13 20:15:29 +0000933 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
934
paul68980082003-03-25 05:07:42 +0000935 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000936
937 /* Flood LSA through area. */
938 ospf_flood_through_area (area, NULL, new);
939
940 /* Debug logging. */
941 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
942 {
ajse588f212004-12-08 18:12:06 +0000943 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000944 new->data->type, inet_ntoa (new->data->id));
945 ospf_lsa_header_dump (new->data);
946 }
947
948 return NULL;
949}
950
Paul Jakmac363d382010-01-24 22:42:13 +0000951int
952ospf_router_lsa_update_area (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000953{
paul718e3742002-12-13 20:15:29 +0000954 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmac363d382010-01-24 22:42:13 +0000955 zlog_debug ("[router-LSA]: (router-LSA area update)");
paul718e3742002-12-13 20:15:29 +0000956
957 /* Now refresh router-LSA. */
958 if (area->router_lsa_self)
Paul Jakmac363d382010-01-24 22:42:13 +0000959 ospf_lsa_refresh (area->ospf, area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000960 /* Newly originate router-LSA. */
961 else
962 ospf_router_lsa_originate (area);
963
964 return 0;
965}
966
paul718e3742002-12-13 20:15:29 +0000967int
Paul Jakmac363d382010-01-24 22:42:13 +0000968ospf_router_lsa_update (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000969{
paul1eb8ef22005-04-07 07:30:20 +0000970 struct listnode *node, *nnode;
971 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +0000972
973 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000974 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +0000975
paul1eb8ef22005-04-07 07:30:20 +0000976 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000977 {
paul718e3742002-12-13 20:15:29 +0000978 struct ospf_lsa *lsa = area->router_lsa_self;
979 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +0000980 const char *area_str;
paul718e3742002-12-13 20:15:29 +0000981
982 /* Keep Area ID string. */
983 area_str = AREA_NAME (area);
984
985 /* If LSA not exist in this Area, originate new. */
986 if (lsa == NULL)
987 {
988 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000989 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +0000990
991 ospf_router_lsa_originate (area);
992 }
993 /* If router-ID is changed, Link ID must change.
994 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +0000995 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000996 {
997 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000998 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +0000999 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
Paul Jakmadfbd5172010-04-14 10:32:12 +01001000 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00001001 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001002 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00001003 area->router_lsa_self = NULL;
1004
1005 /* Refresh router-LSA, (not install) and flood through area. */
Paul Jakmac363d382010-01-24 22:42:13 +00001006 ospf_router_lsa_update_area (area);
paul718e3742002-12-13 20:15:29 +00001007 }
1008 else
1009 {
1010 rl = (struct router_lsa *) lsa->data;
1011 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +00001012 if (rl->flags != ospf->flags)
Paul Jakmac363d382010-01-24 22:42:13 +00001013 ospf_router_lsa_update_area (area);
paul718e3742002-12-13 20:15:29 +00001014 }
1015 }
1016
1017 return 0;
1018}
1019
David Lamparter6b0655a2014-06-04 06:53:35 +02001020
paul718e3742002-12-13 20:15:29 +00001021/* network-LSA related functions. */
1022/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001023static void
paul718e3742002-12-13 20:15:29 +00001024ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1025{
1026 struct in_addr mask;
1027 struct route_node *rn;
1028 struct ospf_neighbor *nbr;
1029
1030 masklen2ip (oi->address->prefixlen, &mask);
1031 stream_put_ipv4 (s, mask.s_addr);
1032
1033 /* The network-LSA lists those routers that are fully adjacent to
1034 the Designated Router; each fully adjacent router is identified by
1035 its OSPF Router ID. The Designated Router includes itself in this
1036 list. RFC2328, Section 12.4.2 */
1037
1038 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1039 if ((nbr = rn->info) != NULL)
1040 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1041 stream_put_ipv4 (s, nbr->router_id.s_addr);
1042}
1043
paul4dadc292005-05-06 21:37:42 +00001044static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001045ospf_network_lsa_new (struct ospf_interface *oi)
1046{
1047 struct stream *s;
1048 struct ospf_lsa *new;
1049 struct lsa_header *lsah;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001050 struct ospf_if_params *oip;
paul718e3742002-12-13 20:15:29 +00001051 int length;
1052
1053 /* If there are no neighbours on this network (the net is stub),
1054 the router does not originate network-LSA (see RFC 12.4.2) */
1055 if (oi->full_nbrs == 0)
1056 return NULL;
1057
1058 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001059 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001060
1061 /* Create new stream for LSA. */
1062 s = stream_new (OSPF_MAX_LSA_SIZE);
1063 lsah = (struct lsa_header *) STREAM_DATA (s);
1064
1065 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001066 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001067
1068 /* Set network-LSA body fields. */
1069 ospf_network_lsa_body_set (s, oi);
1070
1071 /* Set length. */
1072 length = stream_get_endp (s);
1073 lsah->length = htons (length);
1074
1075 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001076 if ( (new = ospf_lsa_new ()) == NULL)
1077 {
1078 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1079 return NULL;
1080 }
1081
paul718e3742002-12-13 20:15:29 +00001082 new->area = oi->area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001083 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001084
1085 /* Copy LSA to store. */
1086 new->data = ospf_lsa_data_new (length);
1087 memcpy (new->data, lsah, length);
1088 stream_free (s);
Paul Jakma7eb5b472009-10-13 16:13:13 +01001089
1090 /* Remember prior network LSA sequence numbers, even if we stop
1091 * originating one for this oi, to try avoid re-originating LSAs with a
1092 * prior sequence number, and thus speed up adjency forming & convergence.
1093 */
1094 if ((oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4)))
1095 {
1096 new->data->ls_seqnum = oip->network_lsa_seqnum;
1097 new->data->ls_seqnum = lsa_seqnum_increment (new);
1098 }
1099 else
1100 {
1101 oip = ospf_get_if_params (oi->ifp, oi->address->u.prefix4);
1102 ospf_if_update_params (oi->ifp, oi->address->u.prefix4);
1103 }
1104 oip->network_lsa_seqnum = new->data->ls_seqnum;
1105
paul718e3742002-12-13 20:15:29 +00001106 return new;
1107}
1108
1109/* Originate network-LSA. */
Paul Jakmac363d382010-01-24 22:42:13 +00001110void
1111ospf_network_lsa_update (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001112{
1113 struct ospf_lsa *new;
Paul Jakmac363d382010-01-24 22:42:13 +00001114
1115 if (oi->network_lsa_self != NULL)
1116 {
1117 ospf_lsa_refresh (oi->ospf, oi->network_lsa_self);
1118 return;
1119 }
1120
paul718e3742002-12-13 20:15:29 +00001121 /* Create new network-LSA instance. */
1122 new = ospf_network_lsa_new (oi);
1123 if (new == NULL)
Paul Jakmac363d382010-01-24 22:42:13 +00001124 return;
paul718e3742002-12-13 20:15:29 +00001125
1126 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001127 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001128
1129 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001130 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001131
1132 /* Flooding new LSA through area. */
1133 ospf_flood_through_area (oi->area, NULL, new);
1134
1135 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1136 {
ajse588f212004-12-08 18:12:06 +00001137 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
David Lampartereed3c482015-03-03 08:51:53 +01001138 new->data->type, inet_ntoa (new->data->id), (void *)new);
paul718e3742002-12-13 20:15:29 +00001139 ospf_lsa_header_dump (new->data);
1140 }
1141
Paul Jakmac363d382010-01-24 22:42:13 +00001142 return;
paul718e3742002-12-13 20:15:29 +00001143}
1144
Paul Jakmac363d382010-01-24 22:42:13 +00001145static struct ospf_lsa *
1146ospf_network_lsa_refresh (struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001147{
1148 struct ospf_area *area = lsa->area;
Paul Jakmac363d382010-01-24 22:42:13 +00001149 struct ospf_lsa *new, *new2;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001150 struct ospf_if_params *oip;
Paul Jakma4dd87df2010-04-15 08:11:51 +01001151 struct ospf_interface *oi;
Paul Jakmac363d382010-01-24 22:42:13 +00001152
paul718e3742002-12-13 20:15:29 +00001153 assert (lsa->data);
Paul Jakma4dd87df2010-04-15 08:11:51 +01001154
1155 /* Retrieve the oi for the network LSA */
1156 oi = ospf_if_lookup_by_local_addr (area->ospf, NULL, lsa->data->id);
1157 if (oi == NULL)
1158 {
1159 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1160 {
1161 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh: "
1162 "no oi found, ick, ignoring.",
1163 lsa->data->type, inet_ntoa (lsa->data->id));
1164 ospf_lsa_header_dump (lsa->data);
1165 }
1166 return NULL;
1167 }
paul718e3742002-12-13 20:15:29 +00001168 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001169 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001170
Paul Jakmac363d382010-01-24 22:42:13 +00001171 /* Unregister LSA from refresh-list */
1172 ospf_refresher_unregister_lsa (area->ospf, lsa);
1173
paul718e3742002-12-13 20:15:29 +00001174 /* Create new network-LSA instance. */
1175 new = ospf_network_lsa_new (oi);
1176 if (new == NULL)
Paul Jakmac363d382010-01-24 22:42:13 +00001177 return NULL;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001178
1179 oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4);
1180 assert (oip != NULL);
1181 oip->network_lsa_seqnum = new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001182
Paul Jakmac363d382010-01-24 22:42:13 +00001183 new2 = ospf_lsa_install (area->ospf, oi, new);
1184
1185 assert (new2 == new);
1186
paul718e3742002-12-13 20:15:29 +00001187 /* Flood LSA through aera. */
1188 ospf_flood_through_area (area, NULL, new);
1189
1190 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1191 {
ajse588f212004-12-08 18:12:06 +00001192 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001193 new->data->type, inet_ntoa (new->data->id));
1194 ospf_lsa_header_dump (new->data);
1195 }
1196
Paul Jakmac363d382010-01-24 22:42:13 +00001197 return new;
paul718e3742002-12-13 20:15:29 +00001198}
David Lamparter6b0655a2014-06-04 06:53:35 +02001199
paul4dadc292005-05-06 21:37:42 +00001200static void
paul718e3742002-12-13 20:15:29 +00001201stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1202{
1203 u_int32_t metric;
1204 char *mp;
1205
1206 /* Put 0 metric. TOS metric is not supported. */
1207 metric = htonl (metric_value);
1208 mp = (char *) &metric;
1209 mp++;
1210 stream_put (s, mp, 3);
1211}
1212
1213/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001214static void
paul718e3742002-12-13 20:15:29 +00001215ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1216 u_int32_t metric)
1217{
1218 struct in_addr mask;
1219
1220 masklen2ip (p->prefixlen, &mask);
1221
1222 /* Put Network Mask. */
1223 stream_put_ipv4 (s, mask.s_addr);
1224
1225 /* Set # TOS. */
1226 stream_putc (s, (u_char) 0);
1227
1228 /* Set metric. */
1229 stream_put_ospf_metric (s, metric);
1230}
1231
paul4dadc292005-05-06 21:37:42 +00001232static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001233ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1234 u_int32_t metric, struct in_addr id)
1235{
1236 struct stream *s;
1237 struct ospf_lsa *new;
1238 struct lsa_header *lsah;
1239 int length;
1240
paulc24d6022005-11-20 14:54:12 +00001241 if (id.s_addr == 0xffffffff)
1242 {
1243 /* Maybe Link State ID not available. */
1244 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1245 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1246 OSPF_SUMMARY_LSA);
1247 return NULL;
1248 }
1249
paul718e3742002-12-13 20:15:29 +00001250 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001251 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001252
1253 /* Create new stream for LSA. */
1254 s = stream_new (OSPF_MAX_LSA_SIZE);
1255 lsah = (struct lsa_header *) STREAM_DATA (s);
1256
paul68980082003-03-25 05:07:42 +00001257 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1258 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001259
1260 /* Set summary-LSA body fields. */
1261 ospf_summary_lsa_body_set (s, p, metric);
1262
1263 /* Set length. */
1264 length = stream_get_endp (s);
1265 lsah->length = htons (length);
1266
1267 /* Create OSPF LSA instance. */
1268 new = ospf_lsa_new ();
1269 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001270 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001271
1272 /* Copy LSA to store. */
1273 new->data = ospf_lsa_data_new (length);
1274 memcpy (new->data, lsah, length);
1275 stream_free (s);
1276
1277 return new;
1278}
1279
1280/* Originate Summary-LSA. */
1281struct ospf_lsa *
1282ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1283 struct ospf_area *area)
1284{
1285 struct ospf_lsa *new;
1286 struct in_addr id;
1287
paul68980082003-03-25 05:07:42 +00001288 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001289
paulc24d6022005-11-20 14:54:12 +00001290 if (id.s_addr == 0xffffffff)
1291 {
1292 /* Maybe Link State ID not available. */
1293 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1294 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1295 OSPF_SUMMARY_LSA);
1296 return NULL;
1297 }
1298
paul718e3742002-12-13 20:15:29 +00001299 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001300 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1301 return NULL;
paul718e3742002-12-13 20:15:29 +00001302
1303 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001304 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001305
1306 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001307 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001308
1309 /* Flooding new LSA through area. */
1310 ospf_flood_through_area (area, NULL, new);
1311
1312 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1313 {
ajse588f212004-12-08 18:12:06 +00001314 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
David Lampartereed3c482015-03-03 08:51:53 +01001315 new->data->type, inet_ntoa (new->data->id), (void *)new);
paul718e3742002-12-13 20:15:29 +00001316 ospf_lsa_header_dump (new->data);
1317 }
1318
1319 return new;
1320}
1321
Paul Jakmac363d382010-01-24 22:42:13 +00001322static struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001323ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001324{
1325 struct ospf_lsa *new;
1326 struct summary_lsa *sl;
1327 struct prefix p;
1328
1329 /* Sanity check. */
1330 assert (lsa->data);
1331
1332 sl = (struct summary_lsa *)lsa->data;
1333 p.prefixlen = ip_masklen (sl->mask);
1334 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1335 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001336
1337 if (!new)
1338 return NULL;
1339
paul718e3742002-12-13 20:15:29 +00001340 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001341
paul68980082003-03-25 05:07:42 +00001342 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001343
1344 /* Flood LSA through AS. */
1345 ospf_flood_through_area (new->area, NULL, new);
1346
1347 /* Debug logging. */
1348 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1349 {
ajse588f212004-12-08 18:12:06 +00001350 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001351 new->data->type, inet_ntoa (new->data->id));
1352 ospf_lsa_header_dump (new->data);
1353 }
1354
1355 return new;
1356}
1357
David Lamparter6b0655a2014-06-04 06:53:35 +02001358
paul718e3742002-12-13 20:15:29 +00001359/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001360static void
paul718e3742002-12-13 20:15:29 +00001361ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1362 u_int32_t metric)
1363{
paul718e3742002-12-13 20:15:29 +00001364 /* Put Network Mask. */
Leonard Tracy2345a222012-12-04 11:02:35 -08001365 stream_put_ipv4 (s, (u_int32_t) 0);
paul718e3742002-12-13 20:15:29 +00001366
1367 /* Set # TOS. */
1368 stream_putc (s, (u_char) 0);
1369
1370 /* Set metric. */
1371 stream_put_ospf_metric (s, metric);
1372}
1373
paul4dadc292005-05-06 21:37:42 +00001374static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001375ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1376 u_int32_t metric, struct in_addr id)
1377{
1378 struct stream *s;
1379 struct ospf_lsa *new;
1380 struct lsa_header *lsah;
1381 int length;
1382
paulc24d6022005-11-20 14:54:12 +00001383 if (id.s_addr == 0xffffffff)
1384 {
1385 /* Maybe Link State ID not available. */
1386 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1387 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1388 OSPF_ASBR_SUMMARY_LSA);
1389 return NULL;
1390 }
1391
paul718e3742002-12-13 20:15:29 +00001392 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001393 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001394
1395 /* Create new stream for LSA. */
1396 s = stream_new (OSPF_MAX_LSA_SIZE);
1397 lsah = (struct lsa_header *) STREAM_DATA (s);
1398
paul68980082003-03-25 05:07:42 +00001399 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1400 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001401
1402 /* Set summary-LSA body fields. */
1403 ospf_summary_asbr_lsa_body_set (s, p, metric);
1404
1405 /* Set length. */
1406 length = stream_get_endp (s);
1407 lsah->length = htons (length);
1408
1409 /* Create OSPF LSA instance. */
1410 new = ospf_lsa_new ();
1411 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001412 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001413
1414 /* Copy LSA to store. */
1415 new->data = ospf_lsa_data_new (length);
1416 memcpy (new->data, lsah, length);
1417 stream_free (s);
1418
1419 return new;
1420}
1421
1422/* Originate summary-ASBR-LSA. */
1423struct ospf_lsa *
1424ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1425 struct ospf_area *area)
1426{
1427 struct ospf_lsa *new;
1428 struct in_addr id;
1429
paul68980082003-03-25 05:07:42 +00001430 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001431
paulc24d6022005-11-20 14:54:12 +00001432 if (id.s_addr == 0xffffffff)
1433 {
1434 /* Maybe Link State ID not available. */
1435 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1436 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1437 OSPF_ASBR_SUMMARY_LSA);
1438 return NULL;
1439 }
1440
paul718e3742002-12-13 20:15:29 +00001441 /* Create new summary-LSA instance. */
1442 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001443 if (!new)
1444 return NULL;
paul718e3742002-12-13 20:15:29 +00001445
1446 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001447 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001448
1449 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001450 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001451
1452 /* Flooding new LSA through area. */
1453 ospf_flood_through_area (area, NULL, new);
1454
1455 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1456 {
ajse588f212004-12-08 18:12:06 +00001457 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
David Lampartereed3c482015-03-03 08:51:53 +01001458 new->data->type, inet_ntoa (new->data->id), (void *)new);
paul718e3742002-12-13 20:15:29 +00001459 ospf_lsa_header_dump (new->data);
1460 }
1461
1462 return new;
1463}
1464
Paul Jakmac363d382010-01-24 22:42:13 +00001465static struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001466ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001467{
1468 struct ospf_lsa *new;
1469 struct summary_lsa *sl;
1470 struct prefix p;
1471
1472 /* Sanity check. */
1473 assert (lsa->data);
1474
1475 sl = (struct summary_lsa *)lsa->data;
1476 p.prefixlen = ip_masklen (sl->mask);
1477 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1478 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001479 if (!new)
1480 return NULL;
paul718e3742002-12-13 20:15:29 +00001481
1482 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001483
paul68980082003-03-25 05:07:42 +00001484 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001485
1486 /* Flood LSA through area. */
1487 ospf_flood_through_area (new->area, NULL, new);
1488
1489 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1490 {
ajse588f212004-12-08 18:12:06 +00001491 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001492 new->data->type, inet_ntoa (new->data->id));
1493 ospf_lsa_header_dump (new->data);
1494 }
1495
1496 return new;
1497}
1498
1499/* AS-external-LSA related functions. */
1500
1501/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1502 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001503static struct in_addr
paul68980082003-03-25 05:07:42 +00001504ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001505{
1506 struct in_addr fwd;
1507 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001508 struct listnode *node;
1509 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001510
1511 fwd.s_addr = 0;
1512
1513 if (!nexthop.s_addr)
1514 return fwd;
1515
1516 /* Check whether nexthop is covered by OSPF network. */
1517 nh.family = AF_INET;
1518 nh.u.prefix4 = nexthop;
1519 nh.prefixlen = IPV4_MAX_BITLEN;
Paul Jakma4ca15d42009-08-03 15:16:41 +01001520
1521 /* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be
1522 * better to make use of the per-ifp table of ois.
1523 */
paul1eb8ef22005-04-07 07:30:20 +00001524 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1525 if (if_is_operative (oi->ifp))
1526 if (oi->address->family == AF_INET)
1527 if (prefix_match (oi->address, &nh))
1528 return nexthop;
paul718e3742002-12-13 20:15:29 +00001529
1530 return fwd;
1531}
1532
paul718e3742002-12-13 20:15:29 +00001533/* NSSA-external-LSA related functions. */
1534
1535/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001536
paul718e3742002-12-13 20:15:29 +00001537struct in_addr
1538ospf_get_ip_from_ifp (struct ospf_interface *oi)
1539{
1540 struct in_addr fwd;
1541
1542 fwd.s_addr = 0;
1543
paul2e3b2e42002-12-13 21:03:13 +00001544 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001545 return oi->address->u.prefix4;
1546
1547 return fwd;
1548}
1549
1550/* Get 1st IP connection for Forward Addr */
1551struct in_addr
paulf2c80652002-12-13 21:44:27 +00001552ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001553{
1554 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001555 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001556 struct listnode *node;
1557 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001558
1559 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001560 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001561
paul1eb8ef22005-04-07 07:30:20 +00001562 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001563 {
paul2e3b2e42002-12-13 21:03:13 +00001564 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001565 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001566 if (oi->address && oi->address->family == AF_INET)
1567 {
1568 if (best_default.s_addr == 0)
1569 best_default = oi->address->u.prefix4;
1570 if (oi->area == area)
1571 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001572 }
paul718e3742002-12-13 20:15:29 +00001573 }
paulf2c80652002-12-13 21:44:27 +00001574 if (best_default.s_addr != 0)
1575 return best_default;
paul718e3742002-12-13 20:15:29 +00001576
paul68980082003-03-25 05:07:42 +00001577 if (best_default.s_addr != 0)
1578 return best_default;
1579
paul718e3742002-12-13 20:15:29 +00001580 return fwd;
1581}
hassobeebba72004-06-20 21:00:27 +00001582
paul718e3742002-12-13 20:15:29 +00001583#define DEFAULT_DEFAULT_METRIC 20
1584#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1585#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1586
1587#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1588
1589int
paul68980082003-03-25 05:07:42 +00001590metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001591{
paul68980082003-03-25 05:07:42 +00001592 return (ospf->dmetric[src].type < 0 ?
1593 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001594}
1595
1596int
paul68980082003-03-25 05:07:42 +00001597metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001598{
paul68980082003-03-25 05:07:42 +00001599 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001600 {
1601 if (src == DEFAULT_ROUTE)
1602 {
paul68980082003-03-25 05:07:42 +00001603 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001604 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1605 else
1606 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1607 }
paul68980082003-03-25 05:07:42 +00001608 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001609 return DEFAULT_DEFAULT_METRIC;
1610 else
paul68980082003-03-25 05:07:42 +00001611 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001612 }
1613
paul68980082003-03-25 05:07:42 +00001614 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001615}
1616
1617/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001618static void
paul68980082003-03-25 05:07:42 +00001619ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1620 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001621{
1622 struct prefix_ipv4 *p = &ei->p;
1623 struct in_addr mask, fwd_addr;
1624 u_int32_t mvalue;
1625 int mtype;
1626 int type;
1627
1628 /* Put Network Mask. */
1629 masklen2ip (p->prefixlen, &mask);
1630 stream_put_ipv4 (s, mask.s_addr);
1631
1632 /* If prefix is default, specify DEFAULT_ROUTE. */
1633 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1634
1635 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001636 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001637
1638 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001639 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001640
1641 /* Put type of external metric. */
1642 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1643
1644 /* Put 0 metric. TOS metric is not supported. */
1645 stream_put_ospf_metric (s, mvalue);
1646
1647 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001648 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001649
1650 /* Put forwarding address. */
1651 stream_put_ipv4 (s, fwd_addr.s_addr);
1652
Paul Jakma96d10602016-07-01 14:23:45 +01001653 /* Put route tag */
Piotr Chytła2b2e38c2015-12-01 10:10:41 -05001654 stream_putl (s, ei->tag);
paul718e3742002-12-13 20:15:29 +00001655}
1656
1657/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001658static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001659ospf_external_lsa_new (struct ospf *ospf,
1660 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001661{
1662 struct stream *s;
1663 struct lsa_header *lsah;
1664 struct ospf_lsa *new;
1665 struct in_addr id;
1666 int length;
1667
1668 if (ei == NULL)
1669 {
1670 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
Denis Ovsienkoad8d4802011-12-02 20:02:40 +04001671 zlog_debug ("LSA[Type5]: External info is NULL, can't originate");
paul718e3742002-12-13 20:15:29 +00001672 return NULL;
1673 }
1674
1675 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001676 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001677
1678 /* If old Link State ID is specified, refresh LSA with same ID. */
1679 if (old_id)
1680 id = *old_id;
1681 /* Get Link State with unique ID. */
1682 else
1683 {
paul68980082003-03-25 05:07:42 +00001684 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001685 if (id.s_addr == 0xffffffff)
1686 {
1687 /* Maybe Link State ID not available. */
1688 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001689 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001690 return NULL;
1691 }
1692 }
1693
1694 /* Create new stream for LSA. */
1695 s = stream_new (OSPF_MAX_LSA_SIZE);
1696 lsah = (struct lsa_header *) STREAM_DATA (s);
1697
1698 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001699 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1700 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001701
1702 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001703 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001704
1705 /* Set length. */
1706 length = stream_get_endp (s);
1707 lsah->length = htons (length);
1708
1709 /* Now, create OSPF LSA instance. */
1710 new = ospf_lsa_new ();
1711 new->area = NULL;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001712 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001713
1714 /* Copy LSA data to store, discard stream. */
1715 new->data = ospf_lsa_data_new (length);
1716 memcpy (new->data, lsah, length);
1717 stream_free (s);
1718
1719 return new;
1720}
1721
paul718e3742002-12-13 20:15:29 +00001722/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001723static void
paul68980082003-03-25 05:07:42 +00001724ospf_install_flood_nssa (struct ospf *ospf,
1725 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001726{
pauld4a53d52003-07-12 21:30:57 +00001727 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001728 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001729 struct ospf_area *area;
1730 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001731
pauld4a53d52003-07-12 21:30:57 +00001732 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1733 * which originated from an NSSA area. In which case it should not be
1734 * flooded back to NSSA areas.
1735 */
1736 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1737 return;
1738
paul718e3742002-12-13 20:15:29 +00001739 /* NSSA Originate or Refresh (If anyNSSA)
1740
1741 LSA is self-originated. And just installed as Type-5.
1742 Additionally, install as Type-7 LSDB for every attached NSSA.
1743
1744 P-Bit controls which ABR performs translation to outside world; If
1745 we are an ABR....do not set the P-bit, because we send the Type-5,
1746 not as the ABR Translator, but as the ASBR owner within the AS!
1747
1748 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1749 elected ABR Translator will see the P-bit, Translate, and re-flood.
1750
1751 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1752 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1753
paul1eb8ef22005-04-07 07:30:20 +00001754 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001755 {
hasso0c14ad82003-07-03 08:36:02 +00001756 /* Don't install Type-7 LSA's into nonNSSA area */
1757 if (area->external_routing != OSPF_AREA_NSSA)
1758 continue;
paul718e3742002-12-13 20:15:29 +00001759
paul68980082003-03-25 05:07:42 +00001760 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001761 new = ospf_lsa_dup (lsa);
1762 new->area = area;
1763 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001764
paul68980082003-03-25 05:07:42 +00001765 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001766 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001767 {
pauld4a53d52003-07-12 21:30:57 +00001768 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001769
1770 /* set non-zero FWD ADDR
1771
1772 draft-ietf-ospf-nssa-update-09.txt
1773
1774 if the network between the NSSA AS boundary router and the
1775 adjacent AS is advertised into OSPF as an internal OSPF route,
1776 the forwarding address should be the next op address as is cu
1777 currently done with type-5 LSAs. If the intervening network is
1778 not adversited into OSPF as an internal OSPF route and the
1779 type-7 LSA's P-bit is set a forwarding address should be
1780 selected from one of the router's active OSPF inteface addresses
1781 which belong to the NSSA. If no such addresses exist, then
1782 no type-7 LSA's with the P-bit set should originate from this
1783 router. */
1784
pauld4a53d52003-07-12 21:30:57 +00001785 /* kevinm: not updating lsa anymore, just new */
1786 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001787
1788 if (extlsa->e[0].fwd_addr.s_addr == 0)
1789 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001790
pauld7480322003-05-16 17:31:51 +00001791 if (extlsa->e[0].fwd_addr.s_addr == 0)
1792 {
1793 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001794 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001795 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001796 return;
1797 }
paulf2c80652002-12-13 21:44:27 +00001798 }
paul718e3742002-12-13 20:15:29 +00001799
paul68980082003-03-25 05:07:42 +00001800 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001801 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001802
1803 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001804 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001805 }
paul718e3742002-12-13 20:15:29 +00001806}
pauld4a53d52003-07-12 21:30:57 +00001807
paul4dadc292005-05-06 21:37:42 +00001808static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001809ospf_lsa_translated_nssa_new (struct ospf *ospf,
1810 struct ospf_lsa *type7)
1811{
1812
1813 struct ospf_lsa *new;
1814 struct as_external_lsa *ext, *extnew;
1815 struct external_info ei;
1816
1817 ext = (struct as_external_lsa *)(type7->data);
1818
1819 /* need external_info struct, fill in bare minimum */
1820 ei.p.family = AF_INET;
1821 ei.p.prefix = type7->data->id;
1822 ei.p.prefixlen = ip_masklen (ext->mask);
1823 ei.type = ZEBRA_ROUTE_OSPF;
1824 ei.nexthop = ext->header.adv_router;
1825 ei.route_map_set.metric = -1;
1826 ei.route_map_set.metric_type = -1;
1827 ei.tag = 0;
1828
1829 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1830 {
1831 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001832 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001833 "Translated Type-5 for %s",
1834 inet_ntoa (ei.p.prefix));
1835 return NULL;
1836 }
1837
1838 extnew = (struct as_external_lsa *)(new->data);
1839
1840 /* copy over Type-7 data to new */
1841 extnew->e[0].tos = ext->e[0].tos;
1842 extnew->e[0].route_tag = ext->e[0].route_tag;
1843 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1844 new->data->ls_seqnum = type7->data->ls_seqnum;
1845
1846 /* add translated flag, checksum and lock new lsa */
1847 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
pauld4a53d52003-07-12 21:30:57 +00001848 new = ospf_lsa_lock (new);
1849
1850 return new;
1851}
1852
pauld4a53d52003-07-12 21:30:57 +00001853/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1854struct ospf_lsa *
1855ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1856{
1857 struct ospf_lsa *new;
1858 struct as_external_lsa *extnew;
1859
1860 /* we cant use ospf_external_lsa_originate() as we need to set
1861 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1862 */
1863
1864 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1865 {
1866 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001867 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001868 "Type-7, Id %s, to Type-5",
1869 inet_ntoa (type7->data->id));
1870 return NULL;
1871 }
1872
1873 extnew = (struct as_external_lsa *)new;
1874
1875 if (IS_DEBUG_OSPF_NSSA)
1876 {
ajse588f212004-12-08 18:12:06 +00001877 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001878 "translated Type 7, installed:");
1879 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001880 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1881 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001882 }
1883
1884 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1885 {
Hasso Tepper8c9ed272012-10-11 11:15:18 +00001886 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001887 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001888 "Could not install LSA "
1889 "id %s", inet_ntoa (type7->data->id));
1890 return NULL;
1891 }
1892
1893 ospf->lsa_originate_count++;
1894 ospf_flood_through_as (ospf, NULL, new);
1895
1896 return new;
1897}
1898
1899/* Refresh Translated from NSSA AS-external-LSA. */
1900struct ospf_lsa *
1901ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1902 struct ospf_lsa *type5)
1903{
1904 struct ospf_lsa *new = NULL;
1905
1906 /* Sanity checks. */
1907 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00001908 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00001909 return NULL;
pauld4a53d52003-07-12 21:30:57 +00001910 if (type7)
1911 assert (type7->data);
1912 if (type5)
1913 assert (type5->data);
1914 assert (ospf->anyNSSA);
1915
1916 /* get required data according to what has been given */
1917 if (type7 && type5 == NULL)
1918 {
1919 /* find the translated Type-5 for this Type-7 */
1920 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1921 struct prefix_ipv4 p =
1922 {
1923 .prefix = type7->data->id,
1924 .prefixlen = ip_masklen (ext->mask),
1925 .family = AF_INET,
1926 };
1927
1928 type5 = ospf_external_info_find_lsa (ospf, &p);
1929 }
1930 else if (type5 && type7 == NULL)
1931 {
1932 /* find the type-7 from which supplied type-5 was translated,
1933 * ie find first type-7 with same LSA Id.
1934 */
paul1eb8ef22005-04-07 07:30:20 +00001935 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00001936 struct route_node *rn;
1937 struct ospf_lsa *lsa;
1938 struct ospf_area *area;
1939
paul1eb8ef22005-04-07 07:30:20 +00001940 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00001941 {
1942 if (area->external_routing != OSPF_AREA_NSSA
1943 && !type7)
1944 continue;
1945
1946 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
1947 {
1948 if (lsa->data->id.s_addr == type5->data->id.s_addr)
1949 {
1950 type7 = lsa;
1951 break;
1952 }
1953 }
1954 }
1955 }
1956
1957 /* do we have type7? */
1958 if (!type7)
1959 {
1960 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001961 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00001962 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00001963 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00001964 return NULL;
1965 }
1966
1967 /* do we have valid translated type5? */
1968 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
1969 {
1970 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001971 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00001972 "found for Type-7 with Id %s",
1973 inet_ntoa (type7->data->id));
1974 return NULL;
1975 }
1976
1977 /* Delete LSA from neighbor retransmit-list. */
1978 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
1979
1980 /* create new translated LSA */
1981 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1982 {
1983 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001984 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001985 "Type-7 for %s to Type-5",
1986 inet_ntoa (type7->data->id));
1987 return NULL;
1988 }
1989
1990 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
1991 {
1992 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001993 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00001994 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00001995 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00001996 return NULL;
1997 }
1998
1999 /* Flood LSA through area. */
2000 ospf_flood_through_as (ospf, NULL, new);
2001
2002 return new;
2003}
paul718e3742002-12-13 20:15:29 +00002004
2005int
2006is_prefix_default (struct prefix_ipv4 *p)
2007{
2008 struct prefix_ipv4 q;
2009
2010 q.family = AF_INET;
2011 q.prefix.s_addr = 0;
2012 q.prefixlen = 0;
2013
2014 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
2015}
2016
2017/* Originate an AS-external-LSA, install and flood. */
2018struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002019ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00002020{
2021 struct ospf_lsa *new;
2022
2023 /* Added for NSSA project....
2024
2025 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2026 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2027 every area. The Type-7's are flooded to every IR and every ABR; We
2028 install the Type-5 LSDB so that the normal "refresh" code operates
2029 as usual, and flag them as not used during ASE calculations. The
2030 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2031 Address of non-zero.
2032
2033 If an ABR is the elected NSSA translator, following SPF and during
2034 the ABR task it will translate all the scanned Type-7's, with P-bit
2035 ON and not-self generated, and translate to Type-5's throughout the
2036 non-NSSA/STUB AS.
2037
2038 A difference in operation depends whether this ASBR is an ABR
2039 or not. If not an ABR, the P-bit is ON, to indicate that any
2040 elected NSSA-ABR can perform its translation.
2041
2042 If an ABR, the P-bit is OFF; No ABR will perform translation and
2043 this ASBR will flood the Type-5 LSA as usual.
2044
2045 For the case where this ASBR is not an ABR, the ASE calculations
2046 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2047 demonstrate to the user that there are LSA's that belong to any
2048 attached NSSA.
2049
2050 Finally, it just so happens that when the ABR is translating every
2051 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2052 approved Type-5 (translated from Type-7); at the end of translation
2053 if any Translated Type-5's remain unapproved, then they must be
2054 flushed from the AS.
2055
2056 */
2057
2058 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002059 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002060 return NULL;
2061
2062 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002063 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002064 {
2065 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002066 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002067 inet_ntoa (ei->p.prefix));
2068 return NULL;
2069 }
2070
2071 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002072 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002073
2074 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002075 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002076
2077 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002078 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002079
paul718e3742002-12-13 20:15:29 +00002080 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002081 if (ospf->anyNSSA &&
2082 /* stay away from translated LSAs! */
2083 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002084 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002085
2086 /* Debug logging. */
2087 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2088 {
ajse588f212004-12-08 18:12:06 +00002089 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
David Lampartereed3c482015-03-03 08:51:53 +01002090 new->data->type, inet_ntoa (new->data->id), (void *)new);
paul718e3742002-12-13 20:15:29 +00002091 ospf_lsa_header_dump (new->data);
2092 }
2093
2094 return new;
2095}
2096
2097/* Originate AS-external-LSA from external info with initial flag. */
2098int
paul68980082003-03-25 05:07:42 +00002099ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002100{
paul68980082003-03-25 05:07:42 +00002101 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002102 struct route_node *rn;
2103 struct external_info *ei;
2104 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002105 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002106
paul68980082003-03-25 05:07:42 +00002107 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002108
2109 /* Originate As-external-LSA from all type of distribute source. */
2110 if ((rt = EXTERNAL_INFO (type)))
2111 for (rn = route_top (rt); rn; rn = route_next (rn))
2112 if ((ei = rn->info) != NULL)
2113 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002114 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002115 zlog_warn ("LSA: AS-external-LSA was not originated.");
2116
2117 return 0;
2118}
2119
paul4dadc292005-05-06 21:37:42 +00002120static struct external_info *
paul020709f2003-04-04 02:44:16 +00002121ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002122{
2123 int type;
2124 struct route_node *rn;
2125 struct prefix_ipv4 p;
2126
2127 p.family = AF_INET;
2128 p.prefix.s_addr = 0;
2129 p.prefixlen = 0;
2130
2131 /* First, lookup redistributed default route. */
2132 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2133 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2134 {
2135 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2136 if (rn != NULL)
2137 {
2138 route_unlock_node (rn);
2139 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002140 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002141 return rn->info;
2142 }
2143 }
2144
2145 return NULL;
2146}
2147
2148int
paul68980082003-03-25 05:07:42 +00002149ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002150{
paul718e3742002-12-13 20:15:29 +00002151 struct prefix_ipv4 p;
2152 struct in_addr nexthop;
2153 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002154 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002155
Paul Jakma4021b602006-05-12 22:55:41 +00002156 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002157
2158 p.family = AF_INET;
2159 p.prefix.s_addr = 0;
2160 p.prefixlen = 0;
2161
Paul Jakma4021b602006-05-12 22:55:41 +00002162 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002163 {
2164 /* If there is no default route via redistribute,
2165 then originate AS-external-LSA with nexthop 0 (self). */
2166 nexthop.s_addr = 0;
Piotr Chytła2b2e38c2015-12-01 10:10:41 -05002167 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop, 0);
paul718e3742002-12-13 20:15:29 +00002168 }
2169
paul020709f2003-04-04 02:44:16 +00002170 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002171 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002172
2173 return 0;
2174}
2175
paul645878f2003-04-13 21:42:11 +00002176/* Flush any NSSA LSAs for given prefix */
2177void
2178ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2179{
paul1eb8ef22005-04-07 07:30:20 +00002180 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002181 struct ospf_lsa *lsa;
2182 struct ospf_area *area;
2183
paul1eb8ef22005-04-07 07:30:20 +00002184 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002185 {
paul1eb8ef22005-04-07 07:30:20 +00002186 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002187 {
2188 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2189 ospf->router_id)))
2190 {
2191 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002192 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002193 inet_ntoa (p->prefix), p->prefixlen);
2194 continue;
2195 }
2196 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2197 if (!IS_LSA_MAXAGE (lsa))
2198 {
2199 ospf_refresher_unregister_lsa (ospf, lsa);
2200 ospf_lsa_flush_area (lsa, area);
2201 }
2202 }
paul645878f2003-04-13 21:42:11 +00002203 }
2204}
paul645878f2003-04-13 21:42:11 +00002205
paul718e3742002-12-13 20:15:29 +00002206/* Flush an AS-external-LSA from LSDB and routing domain. */
2207void
paul68980082003-03-25 05:07:42 +00002208ospf_external_lsa_flush (struct ospf *ospf,
2209 u_char type, struct prefix_ipv4 *p,
Paul Jakma9099f9b2016-01-18 10:12:10 +00002210 ifindex_t ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002211{
2212 struct ospf_lsa *lsa;
2213
2214 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002215 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002216 inet_ntoa (p->prefix), p->prefixlen);
2217
2218 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002219 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002220 {
2221 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002222 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002223 inet_ntoa (p->prefix), p->prefixlen);
2224 return;
2225 }
hassobeebba72004-06-20 21:00:27 +00002226
pauld4a53d52003-07-12 21:30:57 +00002227 /* If LSA is selforiginated, not a translated LSA, and there is
2228 * NSSA area, flush Type-7 LSA's at first.
2229 */
2230 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2231 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002232 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002233
2234 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002235 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002236
2237 /* There must be no self-originated LSA in rtrs_external. */
2238#if 0
2239 /* Remove External route from Zebra. */
2240 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2241#endif
2242
2243 if (!IS_LSA_MAXAGE (lsa))
2244 {
2245 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002246 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002247
2248 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002249 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002250 }
2251
2252 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002253 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002254}
2255
2256void
paul68980082003-03-25 05:07:42 +00002257ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002258{
2259 struct prefix_ipv4 p;
2260 struct external_info *ei;
2261 struct ospf_lsa *lsa;
2262
2263 p.family = AF_INET;
2264 p.prefixlen = 0;
2265 p.prefix.s_addr = 0;
2266
paul020709f2003-04-04 02:44:16 +00002267 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002268 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002269
2270 if (ei)
2271 {
2272 if (lsa)
2273 {
2274 if (IS_DEBUG_OSPF_EVENT)
David Lampartereed3c482015-03-03 08:51:53 +01002275 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p",
2276 (void *)lsa);
paul68980082003-03-25 05:07:42 +00002277 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002278 }
2279 else
2280 {
2281 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002282 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002283 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002284 }
2285 }
2286 else
2287 {
2288 if (lsa)
2289 {
2290 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002291 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
Paul Jakmadfbd5172010-04-14 10:32:12 +01002292 ospf_refresher_unregister_lsa (ospf, lsa);
paul68980082003-03-25 05:07:42 +00002293 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002294 }
2295 }
2296}
2297
2298void
paul68980082003-03-25 05:07:42 +00002299ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002300{
2301 struct route_node *rn;
2302 struct external_info *ei;
2303
2304 if (type != DEFAULT_ROUTE)
2305 if (EXTERNAL_INFO(type))
2306 /* Refresh each redistributed AS-external-LSAs. */
2307 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2308 if ((ei = rn->info))
2309 if (!is_prefix_default (&ei->p))
2310 {
2311 struct ospf_lsa *lsa;
2312
paul68980082003-03-25 05:07:42 +00002313 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2314 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002315 else
paul68980082003-03-25 05:07:42 +00002316 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002317 }
2318}
2319
2320/* Refresh AS-external-LSA. */
Paul Jakmac363d382010-01-24 22:42:13 +00002321struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002322ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002323 struct external_info *ei, int force)
2324{
2325 struct ospf_lsa *new;
2326 int changed;
2327
2328 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002329 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002330 {
pauld4a53d52003-07-12 21:30:57 +00002331 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002332 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002333 "redist check fail",
2334 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002335 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002336 ei->ifindex /*, ei->nexthop */);
Paul Jakmac363d382010-01-24 22:42:13 +00002337 return NULL;
paul718e3742002-12-13 20:15:29 +00002338 }
2339
2340 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002341 {
2342 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002343 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002344 lsa->data->type, inet_ntoa (lsa->data->id));
Paul Jakmac363d382010-01-24 22:42:13 +00002345 return NULL;
pauld4a53d52003-07-12 21:30:57 +00002346 }
paul718e3742002-12-13 20:15:29 +00002347
2348 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002349 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002350
2351 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002352 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002353
paul68980082003-03-25 05:07:42 +00002354 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002355
2356 if (new == NULL)
2357 {
2358 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002359 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002360 inet_ntoa (lsa->data->id));
Paul Jakmac363d382010-01-24 22:42:13 +00002361 return NULL;
paul718e3742002-12-13 20:15:29 +00002362 }
2363
2364 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2365
paul68980082003-03-25 05:07:42 +00002366 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002367
2368 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002369 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002370
paul718e3742002-12-13 20:15:29 +00002371 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002372 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002373 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002374
pauld4a53d52003-07-12 21:30:57 +00002375 /* Register self-originated LSA to refresh queue.
2376 * Translated LSAs should not be registered, but refreshed upon
2377 * refresh of the Type-7
2378 */
2379 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2380 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002381
2382 /* Debug logging. */
2383 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2384 {
ajse588f212004-12-08 18:12:06 +00002385 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002386 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002387 ospf_lsa_header_dump (new->data);
2388 }
2389
Paul Jakmac363d382010-01-24 22:42:13 +00002390 return new;
paul718e3742002-12-13 20:15:29 +00002391}
2392
David Lamparter6b0655a2014-06-04 06:53:35 +02002393
paul718e3742002-12-13 20:15:29 +00002394/* LSA installation functions. */
2395
2396/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002397static struct ospf_lsa *
Paul Jakmac363d382010-01-24 22:42:13 +00002398ospf_router_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2399 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002400{
2401 struct ospf_area *area = new->area;
2402
2403 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2404 The entire routing table must be recalculated, starting with
2405 the shortest path calculations for each area (not just the
2406 area whose link-state database has changed).
2407 */
paul718e3742002-12-13 20:15:29 +00002408
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002409 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002410 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002411
2412 /* Only install LSA if it is originated/refreshed by us.
2413 * If LSA was received by flooding, the RECEIVED flag is set so do
2414 * not link the LSA */
2415 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2416 return new; /* ignore stale LSA */
2417
paul718e3742002-12-13 20:15:29 +00002418 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002419 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002420 area->router_lsa_self = ospf_lsa_lock (new);
2421
Paul Jakmac363d382010-01-24 22:42:13 +00002422 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002423 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002424 if (rt_recalc)
Paul Jakmab6eef002014-10-09 14:19:51 +01002425 ospf_spf_calculate_schedule (ospf, SPF_FLAG_ROUTER_LSA_INSTALL);
paul718e3742002-12-13 20:15:29 +00002426 return new;
2427}
2428
2429#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2430 if (!(T)) \
2431 (T) = thread_add_timer (master, (F), oi, (V))
2432
2433/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002434static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002435ospf_network_lsa_install (struct ospf *ospf,
2436 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002437 struct ospf_lsa *new,
2438 int rt_recalc)
2439{
2440
2441 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2442 The entire routing table must be recalculated, starting with
2443 the shortest path calculations for each area (not just the
2444 area whose link-state database has changed).
2445 */
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002446 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002447 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002448 /* We supposed that when LSA is originated by us, we pass the int
2449 for which it was originated. If LSA was received by flooding,
2450 the RECEIVED flag is set, so we do not link the LSA to the int. */
2451 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2452 return new; /* ignore stale LSA */
2453
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002454 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002455 oi->network_lsa_self = ospf_lsa_lock (new);
Paul Jakmac363d382010-01-24 22:42:13 +00002456 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002457 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002458 if (rt_recalc)
Paul Jakmab6eef002014-10-09 14:19:51 +01002459 ospf_spf_calculate_schedule (ospf, SPF_FLAG_NETWORK_LSA_INSTALL);
paul718e3742002-12-13 20:15:29 +00002460
2461 return new;
2462}
2463
2464/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002465static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002466ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2467 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002468{
paul718e3742002-12-13 20:15:29 +00002469 if (rt_recalc && !IS_LSA_SELF (new))
2470 {
2471 /* RFC 2328 Section 13.2 Summary-LSAs
2472 The best route to the destination described by the summary-
2473 LSA must be recalculated (see Section 16.5). If this
2474 destination is an AS boundary router, it may also be
2475 necessary to re-examine all the AS-external-LSAs.
2476 */
2477
2478#if 0
2479 /* This doesn't exist yet... */
2480 ospf_summary_incremental_update(new); */
2481#else /* #if 0 */
Paul Jakmab6eef002014-10-09 14:19:51 +01002482 ospf_spf_calculate_schedule (ospf, SPF_FLAG_SUMMARY_LSA_INSTALL);
paul718e3742002-12-13 20:15:29 +00002483#endif /* #if 0 */
2484
paul718e3742002-12-13 20:15:29 +00002485 }
2486
2487 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002488 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002489
2490 return new;
2491}
2492
2493/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002494static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002495ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2496 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002497{
2498 if (rt_recalc && !IS_LSA_SELF (new))
2499 {
2500 /* RFC 2328 Section 13.2 Summary-LSAs
2501 The best route to the destination described by the summary-
2502 LSA must be recalculated (see Section 16.5). If this
2503 destination is an AS boundary router, it may also be
2504 necessary to re-examine all the AS-external-LSAs.
2505 */
2506#if 0
2507 /* These don't exist yet... */
2508 ospf_summary_incremental_update(new);
2509 /* Isn't this done by the above call?
2510 - RFC 2328 Section 16.5 implies it should be */
2511 /* ospf_ase_calculate_schedule(); */
2512#else /* #if 0 */
Paul Jakmab6eef002014-10-09 14:19:51 +01002513 ospf_spf_calculate_schedule (ospf, SPF_FLAG_ASBR_SUMMARY_LSA_INSTALL);
paul718e3742002-12-13 20:15:29 +00002514#endif /* #if 0 */
2515 }
2516
2517 /* register LSA to refresh-list. */
2518 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002519 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002520
2521 return new;
2522}
2523
2524/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002525static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002526ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2527 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002528{
paul68980082003-03-25 05:07:42 +00002529 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002530 /* If LSA is not self-originated, calculate an external route. */
2531 if (rt_recalc)
2532 {
2533 /* RFC 2328 Section 13.2 AS-external-LSAs
2534 The best route to the destination described by the AS-
2535 external-LSA must be recalculated (see Section 16.6).
2536 */
2537
2538 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002539 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002540 }
2541
pauld4a53d52003-07-12 21:30:57 +00002542 if (new->data->type == OSPF_AS_NSSA_LSA)
2543 {
2544 /* There is no point to register selforiginate Type-7 LSA for
2545 * refreshing. We rely on refreshing Type-5 LSA's
2546 */
2547 if (IS_LSA_SELF (new))
2548 return new;
2549 else
2550 {
2551 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2552 * New translations will be taken care of by the abr_task.
2553 */
2554 ospf_translated_nssa_refresh (ospf, new, NULL);
Svata Dedic21e8b422011-12-22 18:07:15 +04002555 ospf_schedule_abr_task(ospf);
pauld4a53d52003-07-12 21:30:57 +00002556 }
2557 }
pauld7480322003-05-16 17:31:51 +00002558
pauld4a53d52003-07-12 21:30:57 +00002559 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002560 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002561 */
hassobeebba72004-06-20 21:00:27 +00002562 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002563 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002564
2565 return new;
2566}
2567
2568void
paul68980082003-03-25 05:07:42 +00002569ospf_discard_from_db (struct ospf *ospf,
2570 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002571{
2572 struct ospf_lsa *old;
2573
Paul Jakmaac904de2006-06-15 12:04:57 +00002574 if (!lsdb)
2575 {
2576 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2577 if (!lsa)
2578 zlog_warn ("%s: and NULL LSA!", __func__);
2579 else
2580 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2581 lsa->data->type, inet_ntoa (lsa->data->id));
2582 return;
2583 }
2584
paul718e3742002-12-13 20:15:29 +00002585 old = ospf_lsdb_lookup (lsdb, lsa);
2586
2587 if (!old)
2588 return;
2589
2590 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002591 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002592
2593 switch (old->data->type)
2594 {
2595 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002596 ospf_ase_unregister_external_lsa (old, ospf);
2597 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2598 break;
paul718e3742002-12-13 20:15:29 +00002599 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002600 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002601 break;
pauld7480322003-05-16 17:31:51 +00002602 case OSPF_AS_NSSA_LSA:
2603 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2604 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002605 break;
paul718e3742002-12-13 20:15:29 +00002606 default:
paul68980082003-03-25 05:07:42 +00002607 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002608 break;
2609 }
2610
paul68980082003-03-25 05:07:42 +00002611 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002612 ospf_lsa_discard (old);
2613}
2614
paul718e3742002-12-13 20:15:29 +00002615struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002616ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2617 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002618{
2619 struct ospf_lsa *new = NULL;
2620 struct ospf_lsa *old = NULL;
2621 struct ospf_lsdb *lsdb = NULL;
2622 int rt_recalc;
2623
2624 /* Set LSDB. */
2625 switch (lsa->data->type)
2626 {
paulf2c80652002-12-13 21:44:27 +00002627 /* kevinm */
2628 case OSPF_AS_NSSA_LSA:
2629 if (lsa->area)
2630 lsdb = lsa->area->lsdb;
2631 else
paul68980082003-03-25 05:07:42 +00002632 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002633 break;
paul718e3742002-12-13 20:15:29 +00002634 case OSPF_AS_EXTERNAL_LSA:
paul718e3742002-12-13 20:15:29 +00002635 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002636 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002637 break;
2638 default:
2639 lsdb = lsa->area->lsdb;
2640 break;
2641 }
2642
paul718e3742002-12-13 20:15:29 +00002643 assert (lsdb);
2644
2645 /* RFC 2328 13.2. Installing LSAs in the database
2646
2647 Installing a new LSA in the database, either as the result of
2648 flooding or a newly self-originated LSA, may cause the OSPF
2649 routing table structure to be recalculated. The contents of the
2650 new LSA should be compared to the old instance, if present. If
2651 there is no difference, there is no need to recalculate the
2652 routing table. When comparing an LSA to its previous instance,
2653 the following are all considered to be differences in contents:
2654
2655 o The LSA's Options field has changed.
2656
2657 o One of the LSA instances has LS age set to MaxAge, and
2658 the other does not.
2659
2660 o The length field in the LSA header has changed.
2661
2662 o The body of the LSA (i.e., anything outside the 20-byte
2663 LSA header) has changed. Note that this excludes changes
2664 in LS Sequence Number and LS Checksum.
2665
2666 */
2667 /* Look up old LSA and determine if any SPF calculation or incremental
2668 update is needed */
2669 old = ospf_lsdb_lookup (lsdb, lsa);
2670
2671 /* Do comparision and record if recalc needed. */
2672 rt_recalc = 0;
2673 if ( old == NULL || ospf_lsa_different(old, lsa))
2674 rt_recalc = 1;
2675
paul7ddf1d62003-10-13 09:06:46 +00002676 /*
2677 Sequence number check (Section 14.1 of rfc 2328)
2678 "Premature aging is used when it is time for a self-originated
2679 LSA's sequence number field to wrap. At this point, the current
2680 LSA instance (having LS sequence number MaxSequenceNumber) must
2681 be prematurely aged and flushed from the routing domain before a
2682 new instance with sequence number equal to InitialSequenceNumber
2683 can be originated. "
2684 */
2685
Paul Jakmac2b478d2006-03-30 14:16:11 +00002686 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002687 {
2688 if (ospf_lsa_is_self_originated(ospf, lsa))
2689 {
paul0c2be262004-05-31 14:16:54 +00002690 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2691
2692 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002693 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2694 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2695
2696 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2697 {
ajse588f212004-12-08 18:12:06 +00002698 zlog_debug ("ospf_lsa_install() Premature Aging "
Paul Jakmac363d382010-01-24 22:42:13 +00002699 "lsa 0x%p, seqnum 0x%x",
David Lampartereed3c482015-03-03 08:51:53 +01002700 (void *)lsa, ntohl(lsa->data->ls_seqnum));
paul7ddf1d62003-10-13 09:06:46 +00002701 ospf_lsa_header_dump (lsa->data);
2702 }
2703 }
2704 else
2705 {
2706 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2707 {
ajse588f212004-12-08 18:12:06 +00002708 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002709 "that was not self originated. Ignoring\n");
2710 ospf_lsa_header_dump (lsa->data);
2711 }
2712 return old;
2713 }
2714 }
2715
paul718e3742002-12-13 20:15:29 +00002716 /* discard old LSA from LSDB */
2717 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002718 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002719
paul718e3742002-12-13 20:15:29 +00002720 /* Calculate Checksum if self-originated?. */
2721 if (IS_LSA_SELF (lsa))
2722 ospf_lsa_checksum (lsa->data);
2723
hassofe71a972004-12-22 16:16:02 +00002724 /* Insert LSA to LSDB. */
2725 ospf_lsdb_add (lsdb, lsa);
2726 lsa->lsdb = lsdb;
2727
paul718e3742002-12-13 20:15:29 +00002728 /* Do LSA specific installation process. */
2729 switch (lsa->data->type)
2730 {
2731 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002732 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002733 break;
2734 case OSPF_NETWORK_LSA:
2735 assert (oi);
paul68980082003-03-25 05:07:42 +00002736 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002737 break;
2738 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002739 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002740 break;
2741 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002742 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002743 break;
2744 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002745 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002746 break;
paul718e3742002-12-13 20:15:29 +00002747 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002748 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002749 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002750 else
Andrew Certain0798cee2012-12-04 13:43:42 -08002751 {
2752 /* Incoming "oi" for this LSA has set at LSUpd reception. */
2753 }
paul09e4efd2003-01-18 00:12:02 +00002754 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002755 case OSPF_OPAQUE_AREA_LSA:
2756 case OSPF_OPAQUE_AS_LSA:
2757 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2758 break;
pauld4a53d52003-07-12 21:30:57 +00002759 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002760 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002761 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002762 break;
2763 }
2764
2765 if (new == NULL)
2766 return new; /* Installation failed, cannot proceed further -- endo. */
2767
2768 /* Debug logs. */
2769 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2770 {
2771 char area_str[INET_ADDRSTRLEN];
2772
2773 switch (lsa->data->type)
2774 {
2775 case OSPF_AS_EXTERNAL_LSA:
paul718e3742002-12-13 20:15:29 +00002776 case OSPF_OPAQUE_AS_LSA:
hassobeebba72004-06-20 21:00:27 +00002777 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002778 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002779 dump_lsa_key (new),
2780 LOOKUP (ospf_lsa_type_msg, new->data->type));
2781 break;
2782 default:
2783 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002784 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002785 dump_lsa_key (new),
2786 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2787 break;
2788 }
2789 }
2790
paul7ddf1d62003-10-13 09:06:46 +00002791 /*
2792 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2793 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2794 */
Dinesh G Dutte0630cb2013-01-07 10:12:52 -08002795 if (IS_LSA_MAXAGE (new))
paul718e3742002-12-13 20:15:29 +00002796 {
paul7ddf1d62003-10-13 09:06:46 +00002797 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002798 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
David Lampartereed3c482015-03-03 08:51:53 +01002799 new->data->type,
2800 inet_ntoa (new->data->id),
2801 (void *)lsa);
Dinesh G Dutte0630cb2013-01-07 10:12:52 -08002802 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002803 }
2804
2805 return new;
2806}
2807
David Lamparter6b0655a2014-06-04 06:53:35 +02002808
Christian Franke4c14b7f2013-02-20 10:00:54 +00002809int
paul68980082003-03-25 05:07:42 +00002810ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002811{
paul1eb8ef22005-04-07 07:30:20 +00002812 struct listnode *node, *nnode;
2813 struct ospf_interface *oi;
2814
2815 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002816 {
paul718e3742002-12-13 20:15:29 +00002817 struct route_node *rn;
2818 struct ospf_neighbor *nbr;
2819
2820 if (ospf_if_is_enable (oi))
2821 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2822 if ((nbr = rn->info) != NULL)
2823 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2824 {
2825 route_unlock_node (rn);
2826 return 0;
2827 }
2828 }
2829
2830 return 1;
2831}
2832
David Lamparter6b0655a2014-06-04 06:53:35 +02002833
paul718e3742002-12-13 20:15:29 +00002834
paul4dadc292005-05-06 21:37:42 +00002835static int
paul718e3742002-12-13 20:15:29 +00002836ospf_maxage_lsa_remover (struct thread *thread)
2837{
paul68980082003-03-25 05:07:42 +00002838 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002839 struct ospf_lsa *lsa;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002840 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00002841 int reschedule = 0;
2842
paul68980082003-03-25 05:07:42 +00002843 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002844
2845 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002846 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002847
paul68980082003-03-25 05:07:42 +00002848 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002849
2850 if (!reschedule)
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002851 for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn))
paul718e3742002-12-13 20:15:29 +00002852 {
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002853 if ((lsa = rn->info) == NULL)
2854 {
2855 continue;
2856 }
2857
Christian Franke4de8bf02013-02-20 10:00:52 +00002858 /* There is at least one neighbor from which we still await an ack
2859 * for that LSA, so we are not allowed to remove it from our lsdb yet
2860 * as per RFC 2328 section 14 para 4 a) */
paul718e3742002-12-13 20:15:29 +00002861 if (lsa->retransmit_counter > 0)
2862 {
2863 reschedule = 1;
2864 continue;
2865 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002866
2867 /* TODO: maybe convert this function to a work-queue */
2868 if (thread_should_yield (thread))
Christian Franke4de8bf02013-02-20 10:00:52 +00002869 {
2870 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);
Christian Frankee387dfd2014-04-28 08:04:58 +00002871 route_unlock_node(rn); /* route_top/route_next */
Christian Franke4de8bf02013-02-20 10:00:52 +00002872 return 0;
2873 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002874
paul718e3742002-12-13 20:15:29 +00002875 /* Remove LSA from the LSDB */
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04002876 if (IS_LSA_SELF (lsa))
paul718e3742002-12-13 20:15:29 +00002877 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
Denis Ovsienkoad8d4802011-12-02 20:02:40 +04002878 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-originated: ",
paul7ddf1d62003-10-13 09:06:46 +00002879 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002880
2881 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002882 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002883 lsa->data->type, inet_ntoa (lsa->data->id));
2884
Paul Jakmac363d382010-01-24 22:42:13 +00002885 if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))
paul7ddf1d62003-10-13 09:06:46 +00002886 {
2887 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
David Lampartereed3c482015-03-03 08:51:53 +01002888 zlog_debug ("originating new lsa for lsa 0x%p\n", (void *)lsa);
Paul Jakmac363d382010-01-24 22:42:13 +00002889 ospf_lsa_refresh (ospf, lsa);
paul7ddf1d62003-10-13 09:06:46 +00002890 }
2891
paul718e3742002-12-13 20:15:29 +00002892 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002893 if (lsa->lsdb)
2894 {
2895 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2896 ospf_lsdb_delete (lsa->lsdb, lsa);
2897 }
2898 else
2899 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2900 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002901 }
2902
2903 /* A MaxAge LSA must be removed immediately from the router's link
2904 state database as soon as both a) it is no longer contained on any
2905 neighbor Link state retransmission lists and b) none of the router's
2906 neighbors are in states Exchange or Loading. */
2907 if (reschedule)
Paul Jakma02d942c2010-01-24 23:36:20 +00002908 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2909 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002910
2911 return 0;
2912}
2913
paul718e3742002-12-13 20:15:29 +00002914void
paul68980082003-03-25 05:07:42 +00002915ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002916{
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002917 struct route_node *rn;
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002918 struct prefix_ptr lsa_prefix;
paul718e3742002-12-13 20:15:29 +00002919
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002920 lsa_prefix.family = 0;
2921 lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
2922 lsa_prefix.prefix = (uintptr_t) lsa;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002923
2924 if ((rn = route_node_lookup(ospf->maxage_lsa,
2925 (struct prefix *)&lsa_prefix)))
paul718e3742002-12-13 20:15:29 +00002926 {
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002927 if (rn->info == lsa)
2928 {
2929 UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
2930 ospf_lsa_unlock (&lsa); /* maxage_lsa */
2931 rn->info = NULL;
Christian Franke8afee5c2014-04-28 08:04:59 +00002932 route_unlock_node (rn); /* unlock node because lsa is deleted */
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002933 }
Christian Franke8afee5c2014-04-28 08:04:59 +00002934 route_unlock_node (rn); /* route_node_lookup */
paul718e3742002-12-13 20:15:29 +00002935 }
2936}
2937
Paul Jakma02d942c2010-01-24 23:36:20 +00002938/* Add LSA onto the MaxAge list, and schedule for removal.
2939 * This does *not* lead to the LSA being flooded, that must be taken
2940 * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
2941 * function).
2942 */
paul718e3742002-12-13 20:15:29 +00002943void
paul68980082003-03-25 05:07:42 +00002944ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002945{
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002946 struct prefix_ptr lsa_prefix;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002947 struct route_node *rn;
2948
paul718e3742002-12-13 20:15:29 +00002949 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2950 and schedule the MaxAge LSA remover. */
Stephen Hemminger3106a032009-08-06 12:58:05 -07002951 if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
paul718e3742002-12-13 20:15:29 +00002952 {
2953 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002954 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
David Lampartereed3c482015-03-03 08:51:53 +01002955 lsa->data->type, inet_ntoa (lsa->data->id), (void *)lsa);
paul718e3742002-12-13 20:15:29 +00002956 return;
2957 }
2958
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002959 lsa_prefix.family = 0;
2960 lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
2961 lsa_prefix.prefix = (uintptr_t) lsa;
2962
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002963 if ((rn = route_node_get (ospf->maxage_lsa,
2964 (struct prefix *)&lsa_prefix)) != NULL)
2965 {
2966 if (rn->info != NULL)
2967 {
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002968 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2969 zlog_debug ("LSA[%s]: found LSA (%p) in table for LSA %p %d",
David Lampartereed3c482015-03-03 08:51:53 +01002970 dump_lsa_key (lsa), rn->info, (void *)lsa,
2971 lsa_prefix.prefixlen);
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002972 route_unlock_node (rn);
2973 }
2974 else
2975 {
2976 rn->info = ospf_lsa_lock(lsa);
2977 SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
2978 }
2979 }
2980 else
2981 {
2982 zlog_err("Unable to allocate memory for maxage lsa\n");
2983 assert(0);
2984 }
paul718e3742002-12-13 20:15:29 +00002985
2986 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002987 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002988
Paul Jakma02d942c2010-01-24 23:36:20 +00002989 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2990 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002991}
2992
paul4dadc292005-05-06 21:37:42 +00002993static int
paul68980082003-03-25 05:07:42 +00002994ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002995{
paul718e3742002-12-13 20:15:29 +00002996 /* Stay away from any Local Translated Type-7 LSAs */
2997 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2998 return 0;
paul718e3742002-12-13 20:15:29 +00002999
3000 if (IS_LSA_MAXAGE (lsa))
3001 /* Self-originated LSAs should NOT time-out instead,
3002 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00003003 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003004 {
3005 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003006 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003007
3008 switch (lsa->data->type)
3009 {
paul37163d62003-02-03 18:40:56 +00003010 case OSPF_OPAQUE_LINK_LSA:
3011 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003012 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003013 /*
3014 * As a general rule, whenever network topology has changed
3015 * (due to an LSA removal in this case), routing recalculation
3016 * should be triggered. However, this is not true for opaque
3017 * LSAs. Even if an opaque LSA instance is going to be removed
3018 * from the routing domain, it does not mean a change in network
3019 * topology, and thus, routing recalculation is not needed here.
3020 */
3021 break;
paul09e4efd2003-01-18 00:12:02 +00003022 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003023 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003024 ospf_ase_incremental_update (ospf, lsa);
3025 break;
paul718e3742002-12-13 20:15:29 +00003026 default:
Paul Jakmab6eef002014-10-09 14:19:51 +01003027 ospf_spf_calculate_schedule (ospf, SPF_FLAG_MAXAGE);
paul68980082003-03-25 05:07:42 +00003028 break;
paul718e3742002-12-13 20:15:29 +00003029 }
paul68980082003-03-25 05:07:42 +00003030 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003031 }
3032
Paul Jakmac363d382010-01-24 22:42:13 +00003033 if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa))
3034 if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30)
3035 printf ("Eek! Shouldn't happen!\n");
3036
paul718e3742002-12-13 20:15:29 +00003037 return 0;
3038}
3039
3040/* Periodical check of MaxAge LSA. */
3041int
paul68980082003-03-25 05:07:42 +00003042ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003043{
paul68980082003-03-25 05:07:42 +00003044 struct ospf *ospf = THREAD_ARG (thread);
3045 struct route_node *rn;
3046 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003047 struct ospf_area *area;
3048 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003049
paul68980082003-03-25 05:07:42 +00003050 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003051
paul1eb8ef22005-04-07 07:30:20 +00003052 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003053 {
paul68980082003-03-25 05:07:42 +00003054 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3055 ospf_lsa_maxage_walker_remover (ospf, lsa);
3056 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3057 ospf_lsa_maxage_walker_remover (ospf, lsa);
3058 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3059 ospf_lsa_maxage_walker_remover (ospf, lsa);
3060 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3061 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul68980082003-03-25 05:07:42 +00003062 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3063 ospf_lsa_maxage_walker_remover (ospf, lsa);
3064 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3065 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul4fb949e2003-05-10 20:06:51 +00003066 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3067 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003068 }
3069
paul4fb949e2003-05-10 20:06:51 +00003070 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003071 if (ospf->lsdb)
3072 {
3073 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3074 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul68980082003-03-25 05:07:42 +00003075 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3076 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul68980082003-03-25 05:07:42 +00003077 }
paul718e3742002-12-13 20:15:29 +00003078
paul68980082003-03-25 05:07:42 +00003079 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3080 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003081 return 0;
3082}
3083
paul68980082003-03-25 05:07:42 +00003084struct ospf_lsa *
3085ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3086 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003087{
paul68980082003-03-25 05:07:42 +00003088 struct ospf_lsa *lsa;
3089 struct in_addr mask, id;
3090 struct lsa_header_mask
3091 {
3092 struct lsa_header header;
3093 struct in_addr mask;
3094 } *hmask;
paul718e3742002-12-13 20:15:29 +00003095
paul68980082003-03-25 05:07:42 +00003096 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3097 if (lsa == NULL)
3098 return NULL;
paul718e3742002-12-13 20:15:29 +00003099
paul68980082003-03-25 05:07:42 +00003100 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003101
paul68980082003-03-25 05:07:42 +00003102 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003103
paul68980082003-03-25 05:07:42 +00003104 if (mask.s_addr != hmask->mask.s_addr)
3105 {
3106 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3107 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3108 if (!lsa)
3109 return NULL;
3110 }
paul718e3742002-12-13 20:15:29 +00003111
paul68980082003-03-25 05:07:42 +00003112 return lsa;
paul718e3742002-12-13 20:15:29 +00003113}
3114
3115struct ospf_lsa *
3116ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3117 struct in_addr id, struct in_addr adv_router)
3118{
paule05fba42003-04-13 20:20:53 +00003119 struct ospf *ospf = ospf_lookup();
3120 assert(ospf);
3121
paul718e3742002-12-13 20:15:29 +00003122 switch (type)
3123 {
3124 case OSPF_ROUTER_LSA:
3125 case OSPF_NETWORK_LSA:
3126 case OSPF_SUMMARY_LSA:
3127 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003128 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003129 case OSPF_OPAQUE_LINK_LSA:
3130 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003131 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003132 case OSPF_AS_EXTERNAL_LSA:
paul718e3742002-12-13 20:15:29 +00003133 case OSPF_OPAQUE_AS_LSA:
paule05fba42003-04-13 20:20:53 +00003134 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003135 default:
3136 break;
3137 }
3138
3139 return NULL;
3140}
3141
3142struct ospf_lsa *
3143ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3144 struct in_addr id)
3145{
3146 struct ospf_lsa *lsa;
3147 struct route_node *rn;
3148
3149 switch (type)
3150 {
3151 case OSPF_ROUTER_LSA:
3152 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003153 case OSPF_NETWORK_LSA:
3154 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3155 if ((lsa = rn->info))
3156 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3157 {
3158 route_unlock_node (rn);
3159 return lsa;
3160 }
3161 break;
3162 case OSPF_SUMMARY_LSA:
3163 case OSPF_ASBR_SUMMARY_LSA:
3164 /* Currently not used. */
3165 assert (1);
3166 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003167 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003168 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003169 case OSPF_OPAQUE_LINK_LSA:
3170 case OSPF_OPAQUE_AREA_LSA:
3171 case OSPF_OPAQUE_AS_LSA:
3172 /* Currently not used. */
3173 break;
paul718e3742002-12-13 20:15:29 +00003174 default:
3175 break;
3176 }
3177
3178 return NULL;
3179}
3180
3181struct ospf_lsa *
3182ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3183{
3184 struct ospf_lsa *match;
3185
paul718e3742002-12-13 20:15:29 +00003186 /*
3187 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3188 * is redefined to have two subfields; opaque-type and opaque-id.
3189 * However, it is harmless to treat the two sub fields together, as if
3190 * they two were forming a unique LSA-ID.
3191 */
paul718e3742002-12-13 20:15:29 +00003192
3193 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3194
3195 if (match == NULL)
3196 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003197 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003198 lsah->type, inet_ntoa (lsah->id));
3199
3200 return match;
3201}
3202
3203/* return +n, l1 is more recent.
3204 return -n, l2 is more recent.
3205 return 0, l1 and l2 is identical. */
3206int
3207ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3208{
3209 int r;
3210 int x, y;
3211
3212 if (l1 == NULL && l2 == NULL)
3213 return 0;
3214 if (l1 == NULL)
3215 return -1;
3216 if (l2 == NULL)
3217 return 1;
3218
3219 /* compare LS sequence number. */
3220 x = (int) ntohl (l1->data->ls_seqnum);
3221 y = (int) ntohl (l2->data->ls_seqnum);
3222 if (x > y)
3223 return 1;
3224 if (x < y)
3225 return -1;
3226
3227 /* compare LS checksum. */
3228 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3229 if (r)
3230 return r;
3231
3232 /* compare LS age. */
3233 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3234 return 1;
3235 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3236 return -1;
3237
3238 /* compare LS age with MaxAgeDiff. */
3239 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3240 return -1;
3241 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3242 return 1;
3243
3244 /* LSAs are identical. */
3245 return 0;
3246}
3247
3248/* If two LSAs are different, return 1, otherwise return 0. */
3249int
3250ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3251{
3252 char *p1, *p2;
3253 assert (l1);
3254 assert (l2);
3255 assert (l1->data);
3256 assert (l2->data);
3257
3258 if (l1->data->options != l2->data->options)
3259 return 1;
3260
3261 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3262 return 1;
3263
3264 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3265 return 1;
3266
3267 if (l1->data->length != l2->data->length)
3268 return 1;
3269
3270 if (l1->data->length == 0)
3271 return 1;
3272
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02003273 if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
3274 return 1; /* May be a stale LSA in the LSBD */
3275
pauld1825832003-04-03 01:27:01 +00003276 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003277
3278 p1 = (char *) l1->data;
3279 p2 = (char *) l2->data;
3280
3281 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3282 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3283 return 1;
3284
3285 return 0;
3286}
3287
3288#ifdef ORIGINAL_CODING
3289void
3290ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3291 struct ospf_lsa *self,
3292 struct ospf_lsa *new)
3293{
3294 u_int32_t seqnum;
3295
3296 /* Adjust LS Sequence Number. */
3297 seqnum = ntohl (new->data->ls_seqnum) + 1;
3298 self->data->ls_seqnum = htonl (seqnum);
3299
3300 /* Recalculate LSA checksum. */
3301 ospf_lsa_checksum (self->data);
3302
3303 /* Reflooding LSA. */
3304 /* RFC2328 Section 13.3
3305 On non-broadcast networks, separate Link State Update
3306 packets must be sent, as unicasts, to each adjacent neighbor
3307 (i.e., those in state Exchange or greater). The destination
3308 IP addresses for these packets are the neighbors' IP
3309 addresses. */
3310 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3311 {
3312 struct route_node *rn;
3313 struct ospf_neighbor *onbr;
3314
3315 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3316 if ((onbr = rn->info) != NULL)
3317 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3318 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3319 }
3320 else
3321 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3322
3323 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003324 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003325 self->data->type, inet_ntoa (self->data->id));
3326}
3327#else /* ORIGINAL_CODING */
3328static int
paul68980082003-03-25 05:07:42 +00003329ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003330{
3331 if (lsa == NULL || !IS_LSA_SELF (lsa))
3332 return 0;
3333
3334 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003335 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 +00003336
3337 /* Force given lsa's age to MaxAge. */
3338 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3339
3340 switch (lsa->data->type)
3341 {
Paul Jakma02d942c2010-01-24 23:36:20 +00003342 /* Opaque wants to be notified of flushes */
paul718e3742002-12-13 20:15:29 +00003343 case OSPF_OPAQUE_LINK_LSA:
3344 case OSPF_OPAQUE_AREA_LSA:
3345 case OSPF_OPAQUE_AS_LSA:
3346 ospf_opaque_lsa_refresh (lsa);
3347 break;
paul718e3742002-12-13 20:15:29 +00003348 default:
Paul Jakmadfbd5172010-04-14 10:32:12 +01003349 ospf_refresher_unregister_lsa (ospf, lsa);
Paul Jakma02d942c2010-01-24 23:36:20 +00003350 ospf_lsa_flush (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003351 break;
3352 }
3353
3354 return 0;
3355}
3356
3357void
paul68980082003-03-25 05:07:42 +00003358ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003359{
paul1eb8ef22005-04-07 07:30:20 +00003360 struct listnode *node, *nnode;
3361 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003362 struct ospf_area *area;
3363 struct ospf_interface *oi;
3364 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003365 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003366 int need_to_flush_ase = 0;
3367
paul1eb8ef22005-04-07 07:30:20 +00003368 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003369 {
paul718e3742002-12-13 20:15:29 +00003370 if ((lsa = area->router_lsa_self) != NULL)
3371 {
3372 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003373 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3374 lsa->data->type, inet_ntoa (lsa->data->id));
3375
3376 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003377 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003378 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003379 area->router_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003380 }
3381
paul1eb8ef22005-04-07 07:30:20 +00003382 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003383 {
paul718e3742002-12-13 20:15:29 +00003384 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003385 && oi->state == ISM_DR
3386 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003387 {
3388 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003389 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3390 lsa->data->type, inet_ntoa (lsa->data->id));
3391
3392 ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003393 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003394 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003395 oi->network_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003396 }
3397
3398 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3399 && area->external_routing == OSPF_AREA_DEFAULT)
3400 need_to_flush_ase = 1;
3401 }
3402
paul68980082003-03-25 05:07:42 +00003403 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3404 ospf_lsa_flush_schedule (ospf, lsa);
3405 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3406 ospf_lsa_flush_schedule (ospf, lsa);
paul68980082003-03-25 05:07:42 +00003407 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3408 ospf_lsa_flush_schedule (ospf, lsa);
3409 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3410 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003411 }
3412
3413 if (need_to_flush_ase)
3414 {
paul68980082003-03-25 05:07:42 +00003415 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3416 ospf_lsa_flush_schedule (ospf, lsa);
paul68980082003-03-25 05:07:42 +00003417 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3418 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003419 }
3420
3421 /*
3422 * Make sure that the MaxAge LSA remover is executed immediately,
3423 * without conflicting to other threads.
3424 */
paul68980082003-03-25 05:07:42 +00003425 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003426 {
paul68980082003-03-25 05:07:42 +00003427 OSPF_TIMER_OFF (ospf->t_maxage);
3428 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003429 }
3430
3431 return;
3432}
3433#endif /* ORIGINAL_CODING */
3434
3435/* If there is self-originated LSA, then return 1, otherwise return 0. */
3436/* An interface-independent version of ospf_lsa_is_self_originated */
3437int
paul68980082003-03-25 05:07:42 +00003438ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003439{
hasso52dc7ee2004-09-23 19:18:23 +00003440 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003441 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003442
3443 /* This LSA is already checked. */
3444 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003445 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003446
3447 /* Make sure LSA is self-checked. */
3448 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3449
3450 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003451 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003452 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3453
3454 /* LSA is router-LSA. */
3455 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003456 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003457 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3458
3459 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3460 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003461 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003462 {
paul718e3742002-12-13 20:15:29 +00003463 /* Ignore virtual link. */
3464 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3465 if (oi->address->family == AF_INET)
3466 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3467 {
3468 /* to make it easier later */
3469 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003470 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003471 }
3472 }
3473
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003474 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003475}
3476
3477/* Get unique Link State ID. */
3478struct in_addr
paul68980082003-03-25 05:07:42 +00003479ospf_lsa_unique_id (struct ospf *ospf,
3480 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003481{
3482 struct ospf_lsa *lsa;
3483 struct in_addr mask, id;
3484
3485 id = p->prefix;
3486
3487 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003488 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003489 if (lsa)
3490 {
3491 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3492 if (ip_masklen (al->mask) == p->prefixlen)
3493 {
3494 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003495 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003496 "Can't get Link State ID for %s/%d",
3497 inet_ntoa (p->prefix), p->prefixlen);
3498 /* id.s_addr = 0; */
3499 id.s_addr = 0xffffffff;
3500 return id;
3501 }
3502 /* Masklen differs, then apply wildcard mask to Link State ID. */
3503 else
3504 {
3505 masklen2ip (p->prefixlen, &mask);
3506
3507 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003508 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3509 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003510 if (lsa)
3511 {
3512 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003513 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003514 "Can't get Link State ID for %s/%d",
3515 inet_ntoa (p->prefix), p->prefixlen);
3516 /* id.s_addr = 0; */
3517 id.s_addr = 0xffffffff;
3518 return id;
3519 }
3520 }
3521 }
3522
3523 return id;
3524}
3525
David Lamparter6b0655a2014-06-04 06:53:35 +02003526
Paul Jakma70461d72006-05-12 22:57:57 +00003527#define LSA_ACTION_FLOOD_AREA 1
3528#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003529
3530struct lsa_action
3531{
3532 u_char action;
3533 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003534 struct ospf_lsa *lsa;
3535};
3536
paul4dadc292005-05-06 21:37:42 +00003537static int
paul718e3742002-12-13 20:15:29 +00003538ospf_lsa_action (struct thread *t)
3539{
3540 struct lsa_action *data;
3541
3542 data = THREAD_ARG (t);
3543
3544 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003545 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003546 data->action);
3547
3548 switch (data->action)
3549 {
paul718e3742002-12-13 20:15:29 +00003550 case LSA_ACTION_FLOOD_AREA:
3551 ospf_flood_through_area (data->area, NULL, data->lsa);
3552 break;
paul718e3742002-12-13 20:15:29 +00003553 case LSA_ACTION_FLUSH_AREA:
3554 ospf_lsa_flush_area (data->lsa, data->area);
3555 break;
paul718e3742002-12-13 20:15:29 +00003556 }
3557
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003558 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003559 XFREE (MTYPE_OSPF_MESSAGE, data);
3560 return 0;
3561}
3562
3563void
3564ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3565{
3566 struct lsa_action *data;
3567
Stephen Hemminger393deb92008-08-18 14:13:29 -07003568 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003569 data->action = LSA_ACTION_FLOOD_AREA;
3570 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003571 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003572
3573 thread_add_event (master, ospf_lsa_action, data, 0);
3574}
3575
3576void
3577ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3578{
3579 struct lsa_action *data;
3580
Stephen Hemminger393deb92008-08-18 14:13:29 -07003581 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003582 data->action = LSA_ACTION_FLUSH_AREA;
3583 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003584 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003585
3586 thread_add_event (master, ospf_lsa_action, data, 0);
3587}
3588
David Lamparter6b0655a2014-06-04 06:53:35 +02003589
paul718e3742002-12-13 20:15:29 +00003590/* LSA Refreshment functions. */
Paul Jakmac363d382010-01-24 22:42:13 +00003591struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00003592ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003593{
3594 struct external_info *ei;
Paul Jakmac363d382010-01-24 22:42:13 +00003595 struct ospf_lsa *new = NULL;
paul718e3742002-12-13 20:15:29 +00003596 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003597 assert (IS_LSA_SELF (lsa));
Paul Jakma66349742010-04-13 22:33:54 +01003598 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003599
3600 switch (lsa->data->type)
3601 {
3602 /* Router and Network LSAs are processed differently. */
3603 case OSPF_ROUTER_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003604 new = ospf_router_lsa_refresh (lsa);
3605 break;
paul718e3742002-12-13 20:15:29 +00003606 case OSPF_NETWORK_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003607 new = ospf_network_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003608 break;
3609 case OSPF_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003610 new = ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003611 break;
3612 case OSPF_ASBR_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003613 new = ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003614 break;
3615 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003616 /* Translated from NSSA Type-5s are refreshed when
3617 * from refresh of Type-7 - do not refresh these directly.
3618 */
3619 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3620 break;
paul718e3742002-12-13 20:15:29 +00003621 ei = ospf_external_info_check (lsa);
3622 if (ei)
Paul Jakmac363d382010-01-24 22:42:13 +00003623 new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003624 else
pauld4a53d52003-07-12 21:30:57 +00003625 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003626 break;
paul718e3742002-12-13 20:15:29 +00003627 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;
3632 default:
3633 break;
paul718e3742002-12-13 20:15:29 +00003634 }
Paul Jakmac363d382010-01-24 22:42:13 +00003635 return new;
paul718e3742002-12-13 20:15:29 +00003636}
3637
3638void
paul68980082003-03-25 05:07:42 +00003639ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003640{
3641 u_int16_t index, current_index;
3642
Paul Jakma66349742010-04-13 22:33:54 +01003643 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003644 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003645
3646 if (lsa->refresh_list < 0)
3647 {
3648 int delay;
3649
3650 if (LS_AGE (lsa) == 0 &&
3651 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3652 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3653 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3654 else
3655 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3656 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3657 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3658
3659 if (delay < 0)
3660 delay = 0;
3661
Paul Jakmac363d382010-01-24 22:42:13 +00003662 current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL)
3663 - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003664
3665 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
Paul Jakmac363d382010-01-24 22:42:13 +00003666 % (OSPF_LSA_REFRESHER_SLOTS);
paul718e3742002-12-13 20:15:29 +00003667
3668 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003669 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003670 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003671 if (!ospf->lsa_refresh_queue.qs[index])
3672 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003673 listnode_add (ospf->lsa_refresh_queue.qs[index],
3674 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003675 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003676 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003677 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003678 "setting refresh_list on lsa %p (slod %d)",
David Lampartereed3c482015-03-03 08:51:53 +01003679 inet_ntoa (lsa->data->id), (void *)lsa, index);
paul718e3742002-12-13 20:15:29 +00003680 }
3681}
3682
3683void
paul68980082003-03-25 05:07:42 +00003684ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003685{
Paul Jakma66349742010-04-13 22:33:54 +01003686 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003687 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003688 if (lsa->refresh_list >= 0)
3689 {
hasso52dc7ee2004-09-23 19:18:23 +00003690 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003691 listnode_delete (refresh_list, lsa);
3692 if (!listcount (refresh_list))
3693 {
3694 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003695 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003696 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003697 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003698 lsa->refresh_list = -1;
3699 }
3700}
3701
3702int
3703ospf_lsa_refresh_walker (struct thread *t)
3704{
hasso52dc7ee2004-09-23 19:18:23 +00003705 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003706 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003707 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003708 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003709 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003710 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003711
3712 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003713 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003714
3715
paul68980082003-03-25 05:07:42 +00003716 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003717
ajs9dbc7972005-03-13 19:27:22 +00003718 /* Note: if clock has jumped backwards, then time change could be negative,
3719 so we are careful to cast the expression to unsigned before taking
3720 modulus. */
paul68980082003-03-25 05:07:42 +00003721 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003722 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakmac363d382010-01-24 22:42:13 +00003723 (quagga_time (NULL) - ospf->lsa_refresher_started)
3724 / OSPF_LSA_REFRESHER_GRANULARITY))
3725 % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003726
3727 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003728 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003729 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003730
paul68980082003-03-25 05:07:42 +00003731 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003732 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3733 {
3734 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003735 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003736 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003737
paul68980082003-03-25 05:07:42 +00003738 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003739
Paul Jakma66349742010-04-13 22:33:54 +01003740 assert (i >= 0);
3741
paul68980082003-03-25 05:07:42 +00003742 ospf->lsa_refresh_queue.qs [i] = NULL;
3743
paul718e3742002-12-13 20:15:29 +00003744 if (refresh_list)
3745 {
paul1eb8ef22005-04-07 07:30:20 +00003746 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003747 {
paul718e3742002-12-13 20:15:29 +00003748 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003749 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
David Lampartereed3c482015-03-03 08:51:53 +01003750 "refresh lsa %p (slot %d)",
3751 inet_ntoa (lsa->data->id), (void *)lsa, i);
3752
Paul Jakma66349742010-04-13 22:33:54 +01003753 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003754 list_delete_node (refresh_list, node);
paul718e3742002-12-13 20:15:29 +00003755 lsa->refresh_list = -1;
3756 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003757 }
3758 list_free (refresh_list);
3759 }
3760 }
3761
paul68980082003-03-25 05:07:42 +00003762 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3763 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003764 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003765
paul1eb8ef22005-04-07 07:30:20 +00003766 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
Paul Jakma66349742010-04-13 22:33:54 +01003767 {
3768 ospf_lsa_refresh (ospf, lsa);
3769 assert (lsa->lock > 0);
3770 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
3771 }
paul718e3742002-12-13 20:15:29 +00003772
3773 list_delete (lsa_to_refresh);
3774
3775 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003776 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003777
3778 return 0;
3779}
3780