blob: f032601a34e61f646bcb2d6772873a78bbaf615c [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/*
2 * OSPF Link State Advertisement
3 * Copyright (C) 1999, 2000 Toshiaki Takada
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <zebra.h>
24
25#include "linklist.h"
26#include "prefix.h"
27#include "if.h"
28#include "table.h"
29#include "memory.h"
30#include "stream.h"
31#include "log.h"
32#include "thread.h"
33#include "hash.h"
34#include "sockunion.h" /* for inet_aton() */
Jingjing Duan6a270cd2008-08-13 19:09:10 +010035#include "checksum.h"
paul718e3742002-12-13 20:15:29 +000036
37#include "ospfd/ospfd.h"
38#include "ospfd/ospf_interface.h"
39#include "ospfd/ospf_ism.h"
40#include "ospfd/ospf_asbr.h"
41#include "ospfd/ospf_lsa.h"
42#include "ospfd/ospf_lsdb.h"
43#include "ospfd/ospf_neighbor.h"
44#include "ospfd/ospf_nsm.h"
45#include "ospfd/ospf_flood.h"
46#include "ospfd/ospf_packet.h"
47#include "ospfd/ospf_spf.h"
48#include "ospfd/ospf_dump.h"
49#include "ospfd/ospf_route.h"
50#include "ospfd/ospf_ase.h"
51#include "ospfd/ospf_zebra.h"
52
David Lamparter6b0655a2014-06-04 06:53:35 +020053
paul718e3742002-12-13 20:15:29 +000054u_int32_t
55get_metric (u_char *metric)
56{
57 u_int32_t m;
58 m = metric[0];
59 m = (m << 8) + metric[1];
60 m = (m << 8) + metric[2];
61 return m;
62}
63
David Lamparter6b0655a2014-06-04 06:53:35 +020064
paul718e3742002-12-13 20:15:29 +000065struct timeval
66tv_adjust (struct timeval a)
67{
68 while (a.tv_usec >= 1000000)
69 {
70 a.tv_usec -= 1000000;
71 a.tv_sec++;
72 }
73
74 while (a.tv_usec < 0)
75 {
76 a.tv_usec += 1000000;
77 a.tv_sec--;
78 }
79
80 return a;
81}
82
83int
84tv_ceil (struct timeval a)
85{
86 a = tv_adjust (a);
87
88 return (a.tv_usec ? a.tv_sec + 1 : a.tv_sec);
89}
90
91int
92tv_floor (struct timeval a)
93{
94 a = tv_adjust (a);
95
96 return a.tv_sec;
97}
98
99struct timeval
100int2tv (int a)
101{
102 struct timeval ret;
103
104 ret.tv_sec = a;
105 ret.tv_usec = 0;
106
107 return ret;
108}
109
110struct timeval
111tv_add (struct timeval a, struct timeval b)
112{
113 struct timeval ret;
114
115 ret.tv_sec = a.tv_sec + b.tv_sec;
116 ret.tv_usec = a.tv_usec + b.tv_usec;
117
118 return tv_adjust (ret);
119}
120
121struct timeval
122tv_sub (struct timeval a, struct timeval b)
123{
124 struct timeval ret;
125
126 ret.tv_sec = a.tv_sec - b.tv_sec;
127 ret.tv_usec = a.tv_usec - b.tv_usec;
128
129 return tv_adjust (ret);
130}
131
132int
133tv_cmp (struct timeval a, struct timeval b)
134{
135 return (a.tv_sec == b.tv_sec ?
136 a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
137}
138
139int
140ospf_lsa_refresh_delay (struct ospf_lsa *lsa)
141{
142 struct timeval delta, now;
143 int delay = 0;
144
Paul Jakma2518efd2006-08-27 06:49:29 +0000145 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +0000146 delta = tv_sub (now, lsa->tv_orig);
147
148 if (tv_cmp (delta, int2tv (OSPF_MIN_LS_INTERVAL)) < 0)
149 {
150 delay = tv_ceil (tv_sub (int2tv (OSPF_MIN_LS_INTERVAL), delta));
151
152 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000153 zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
paul718e3742002-12-13 20:15:29 +0000154 lsa->data->type, inet_ntoa (lsa->data->id), delay);
155
156 assert (delay > 0);
157 }
158
159 return delay;
160}
161
David Lamparter6b0655a2014-06-04 06:53:35 +0200162
paul718e3742002-12-13 20:15:29 +0000163int
164get_age (struct ospf_lsa *lsa)
165{
166 int age;
paul718e3742002-12-13 20:15:29 +0000167
Paul Jakma2518efd2006-08-27 06:49:29 +0000168 age = ntohs (lsa->data->ls_age)
169 + tv_floor (tv_sub (recent_relative_time (), lsa->tv_recv));
paul718e3742002-12-13 20:15:29 +0000170
171 return age;
172}
173
David Lamparter6b0655a2014-06-04 06:53:35 +0200174
paul718e3742002-12-13 20:15:29 +0000175/* Fletcher Checksum -- Refer to RFC1008. */
paul718e3742002-12-13 20:15:29 +0000176
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100177/* All the offsets are zero-based. The offsets in the RFC1008 are
178 one-based. */
paul718e3742002-12-13 20:15:29 +0000179u_int16_t
180ospf_lsa_checksum (struct lsa_header *lsa)
181{
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100182 u_char *buffer = (u_char *) &lsa->options;
183 int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */
paul718e3742002-12-13 20:15:29 +0000184
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100185 /* Skip the AGE field */
186 u_int16_t len = ntohs(lsa->length) - options_offset;
paul718e3742002-12-13 20:15:29 +0000187
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100188 /* Checksum offset starts from "options" field, not the beginning of the
189 lsa_header struct. The offset is 14, rather than 16. */
190 int checksum_offset = (u_char *) &lsa->checksum - buffer;
paul718e3742002-12-13 20:15:29 +0000191
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100192 return fletcher_checksum(buffer, len, checksum_offset);
paul718e3742002-12-13 20:15:29 +0000193}
194
JR Riversd8a4e422012-09-13 17:17:36 +0000195int
196ospf_lsa_checksum_valid (struct lsa_header *lsa)
197{
198 u_char *buffer = (u_char *) &lsa->options;
199 int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */
200
201 /* Skip the AGE field */
202 u_int16_t len = ntohs(lsa->length) - options_offset;
203
204 return(fletcher_checksum(buffer, len, FLETCHER_CHECKSUM_VALIDATE) == 0);
205}
206
paul718e3742002-12-13 20:15:29 +0000207
David Lamparter6b0655a2014-06-04 06:53:35 +0200208
paul718e3742002-12-13 20:15:29 +0000209/* Create OSPF LSA. */
210struct ospf_lsa *
211ospf_lsa_new ()
212{
213 struct ospf_lsa *new;
214
215 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
paul718e3742002-12-13 20:15:29 +0000216
217 new->flags = 0;
218 new->lock = 1;
219 new->retransmit_counter = 0;
Paul Jakma2518efd2006-08-27 06:49:29 +0000220 new->tv_recv = recent_relative_time ();
paul718e3742002-12-13 20:15:29 +0000221 new->tv_orig = new->tv_recv;
222 new->refresh_list = -1;
223
224 return new;
225}
226
227/* Duplicate OSPF LSA. */
228struct ospf_lsa *
229ospf_lsa_dup (struct ospf_lsa *lsa)
230{
231 struct ospf_lsa *new;
232
233 if (lsa == NULL)
234 return NULL;
235
236 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
237
238 memcpy (new, lsa, sizeof (struct ospf_lsa));
239 UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
240 new->lock = 1;
241 new->retransmit_counter = 0;
242 new->data = ospf_lsa_data_dup (lsa->data);
243
paulf2c80652002-12-13 21:44:27 +0000244 /* kevinm: Clear the refresh_list, otherwise there are going
245 to be problems when we try to remove the LSA from the
246 queue (which it's not a member of.)
247 XXX: Should we add the LSA to the refresh_list queue? */
248 new->refresh_list = -1;
249
250 if (IS_DEBUG_OSPF (lsa, LSA))
David Lampartereed3c482015-03-03 08:51:53 +0100251 zlog_debug ("LSA: duplicated %p (new: %p)", (void *)lsa, (void *)new);
paulf2c80652002-12-13 21:44:27 +0000252
paul718e3742002-12-13 20:15:29 +0000253 return new;
254}
255
256/* Free OSPF LSA. */
257void
258ospf_lsa_free (struct ospf_lsa *lsa)
259{
260 assert (lsa->lock == 0);
261
262 if (IS_DEBUG_OSPF (lsa, LSA))
David Lampartereed3c482015-03-03 08:51:53 +0100263 zlog_debug ("LSA: freed %p", (void *)lsa);
paul718e3742002-12-13 20:15:29 +0000264
265 /* Delete LSA data. */
266 if (lsa->data != NULL)
267 ospf_lsa_data_free (lsa->data);
268
269 assert (lsa->refresh_list < 0);
270
271 memset (lsa, 0, sizeof (struct ospf_lsa));
272 XFREE (MTYPE_OSPF_LSA, lsa);
273}
274
275/* Lock LSA. */
276struct ospf_lsa *
277ospf_lsa_lock (struct ospf_lsa *lsa)
278{
279 lsa->lock++;
280 return lsa;
281}
282
283/* Unlock LSA. */
284void
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000285ospf_lsa_unlock (struct ospf_lsa **lsa)
paul718e3742002-12-13 20:15:29 +0000286{
287 /* This is sanity check. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000288 if (!lsa || !*lsa)
paul718e3742002-12-13 20:15:29 +0000289 return;
290
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000291 (*lsa)->lock--;
paul718e3742002-12-13 20:15:29 +0000292
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000293 assert ((*lsa)->lock >= 0);
paul718e3742002-12-13 20:15:29 +0000294
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000295 if ((*lsa)->lock == 0)
paul718e3742002-12-13 20:15:29 +0000296 {
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000297 assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
298 ospf_lsa_free (*lsa);
299 *lsa = NULL;
paul718e3742002-12-13 20:15:29 +0000300 }
301}
302
303/* Check discard flag. */
304void
305ospf_lsa_discard (struct ospf_lsa *lsa)
306{
307 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
308 {
309 SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000310 ospf_lsa_unlock (&lsa);
paul718e3742002-12-13 20:15:29 +0000311 }
312}
313
314/* Create LSA data. */
315struct lsa_header *
316ospf_lsa_data_new (size_t size)
317{
Stephen Hemminger393deb92008-08-18 14:13:29 -0700318 return XCALLOC (MTYPE_OSPF_LSA_DATA, size);
paul718e3742002-12-13 20:15:29 +0000319}
320
321/* Duplicate LSA data. */
322struct lsa_header *
323ospf_lsa_data_dup (struct lsa_header *lsah)
324{
325 struct lsa_header *new;
326
327 new = ospf_lsa_data_new (ntohs (lsah->length));
328 memcpy (new, lsah, ntohs (lsah->length));
329
330 return new;
331}
332
333/* Free LSA data. */
334void
335ospf_lsa_data_free (struct lsa_header *lsah)
336{
337 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000338 zlog_debug ("LSA[Type%d:%s]: data freed %p",
David Lampartereed3c482015-03-03 08:51:53 +0100339 lsah->type, inet_ntoa (lsah->id), (void *)lsah);
paul718e3742002-12-13 20:15:29 +0000340
341 XFREE (MTYPE_OSPF_LSA_DATA, lsah);
342}
343
David Lamparter6b0655a2014-06-04 06:53:35 +0200344
paul718e3742002-12-13 20:15:29 +0000345/* LSA general functions. */
346
347const char *
348dump_lsa_key (struct ospf_lsa *lsa)
349{
350 static char buf[] = {
hasso52dc7ee2004-09-23 19:18:23 +0000351 "Type255,id(255.255.255.255),ar(255.255.255.255)"
paul718e3742002-12-13 20:15:29 +0000352 };
353 struct lsa_header *lsah;
354
355 if (lsa != NULL && (lsah = lsa->data) != NULL)
356 {
357 char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
358 strcpy (id, inet_ntoa (lsah->id));
359 strcpy (ar, inet_ntoa (lsah->adv_router));
360
361 sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
362 }
363 else
364 strcpy (buf, "NULL");
365
366 return buf;
367}
368
369u_int32_t
370lsa_seqnum_increment (struct ospf_lsa *lsa)
371{
372 u_int32_t seqnum;
373
374 seqnum = ntohl (lsa->data->ls_seqnum) + 1;
375
376 return htonl (seqnum);
377}
378
379void
380lsa_header_set (struct stream *s, u_char options,
paul68980082003-03-25 05:07:42 +0000381 u_char type, struct in_addr id, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +0000382{
383 struct lsa_header *lsah;
384
385 lsah = (struct lsa_header *) STREAM_DATA (s);
386
Paul Jakma02d942c2010-01-24 23:36:20 +0000387 lsah->ls_age = htons (OSPF_LSA_INITIAL_AGE);
paul718e3742002-12-13 20:15:29 +0000388 lsah->options = options;
389 lsah->type = type;
390 lsah->id = id;
paul68980082003-03-25 05:07:42 +0000391 lsah->adv_router = router_id;
paul718e3742002-12-13 20:15:29 +0000392 lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
393
paul9985f832005-02-09 15:51:56 +0000394 stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000395}
David Lamparter6b0655a2014-06-04 06:53:35 +0200396
paul68980082003-03-25 05:07:42 +0000397
paul718e3742002-12-13 20:15:29 +0000398/* router-LSA related functions. */
399/* Get router-LSA flags. */
paul4dadc292005-05-06 21:37:42 +0000400static u_char
paul718e3742002-12-13 20:15:29 +0000401router_lsa_flags (struct ospf_area *area)
402{
403 u_char flags;
404
paul68980082003-03-25 05:07:42 +0000405 flags = area->ospf->flags;
paul718e3742002-12-13 20:15:29 +0000406
407 /* Set virtual link flag. */
408 if (ospf_full_virtual_nbrs (area))
409 SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
410 else
411 /* Just sanity check */
412 UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);
413
414 /* Set Shortcut ABR behabiour flag. */
415 UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
paul68980082003-03-25 05:07:42 +0000416 if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
paul718e3742002-12-13 20:15:29 +0000417 if (!OSPF_IS_AREA_BACKBONE (area))
418 if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
paul68980082003-03-25 05:07:42 +0000419 area->ospf->backbone == NULL) ||
paul718e3742002-12-13 20:15:29 +0000420 area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
421 SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
422
423 /* ASBR can't exit in stub area. */
Greg Troxelfc787e82007-08-06 15:50:20 +0000424 if (area->external_routing == OSPF_AREA_STUB)
paul942b6c12003-06-22 08:22:18 +0000425 UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
426 /* If ASBR set External flag */
427 else if (IS_OSPF_ASBR (area->ospf))
428 SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
429
430 /* Set ABR dependent flags */
431 if (IS_OSPF_ABR (area->ospf))
432 {
433 SET_FLAG (flags, ROUTER_LSA_BORDER);
paul942b6c12003-06-22 08:22:18 +0000434 /* If Area is NSSA and we are both ABR and unconditional translator,
pauld4a53d52003-07-12 21:30:57 +0000435 * set Nt bit to inform other routers.
paul942b6c12003-06-22 08:22:18 +0000436 */
pauld4a53d52003-07-12 21:30:57 +0000437 if ( (area->external_routing == OSPF_AREA_NSSA)
438 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
439 SET_FLAG (flags, ROUTER_LSA_NT);
paul942b6c12003-06-22 08:22:18 +0000440 }
paul718e3742002-12-13 20:15:29 +0000441 return flags;
442}
443
444/* Lookup neighbor other than myself.
445 And check neighbor count,
446 Point-to-Point link must have only 1 neighbor. */
447struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +0000448ospf_nbr_lookup_ptop (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +0000449{
paul718e3742002-12-13 20:15:29 +0000450 struct ospf_neighbor *nbr = NULL;
paul68980082003-03-25 05:07:42 +0000451 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000452
453 /* Search neighbor, there must be one of two nbrs. */
paul68980082003-03-25 05:07:42 +0000454 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
455 if ((nbr = rn->info))
456 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000457 if (nbr->state == NSM_Full)
paul68980082003-03-25 05:07:42 +0000458 {
459 route_unlock_node (rn);
460 break;
461 }
paul718e3742002-12-13 20:15:29 +0000462
463 /* PtoP link must have only 1 neighbor. */
paul68980082003-03-25 05:07:42 +0000464 if (ospf_nbr_count (oi, 0) > 1)
paul718e3742002-12-13 20:15:29 +0000465 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
466
467 return nbr;
468}
469
paul88d6cf32005-10-29 12:50:09 +0000470/* Determine cost of link, taking RFC3137 stub-router support into
471 * consideration
472 */
473static u_int16_t
474ospf_link_cost (struct ospf_interface *oi)
475{
476 /* RFC3137 stub router support */
477 if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
478 return oi->output_cost;
479 else
480 return OSPF_OUTPUT_COST_INFINITE;
481}
482
paul718e3742002-12-13 20:15:29 +0000483/* Set a link information. */
paul779adb02006-01-18 15:07:38 +0000484static char
paul718e3742002-12-13 20:15:29 +0000485link_info_set (struct stream *s, struct in_addr id,
486 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
487{
paul779adb02006-01-18 15:07:38 +0000488 /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
489 * vast majority of cases. Some rare routers with lots of links need more.
490 * we try accomodate those here.
491 */
492 if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
493 {
494 size_t ret = OSPF_MAX_LSA_SIZE;
495
496 /* Can we enlarge the stream still? */
497 if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
498 {
499 /* we futz the size here for simplicity, really we need to account
500 * for just:
501 * IP Header - (sizeof (struct ip))
502 * OSPF Header - OSPF_HEADER_SIZE
503 * LSA Header - OSPF_LSA_HEADER_SIZE
504 * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
505 *
506 * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
507 */
508 ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
509 }
510
511 if (ret == OSPF_MAX_LSA_SIZE)
512 {
Paul Jakma53725102009-08-03 16:34:16 +0100513 zlog_warn ("%s: Out of space in LSA stream, left %zd, size %zd",
paul779adb02006-01-18 15:07:38 +0000514 __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
515 return 0;
516 }
517 }
518
paul718e3742002-12-13 20:15:29 +0000519 /* TOS based routing is not supported. */
520 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
521 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
522 stream_putc (s, type); /* Link Type. */
523 stream_putc (s, tos); /* TOS = 0. */
524 stream_putw (s, cost); /* Link Cost. */
paul779adb02006-01-18 15:07:38 +0000525
526 return 1;
paul718e3742002-12-13 20:15:29 +0000527}
528
Andrew J. Schorre4529632006-12-12 19:18:21 +0000529/* Describe Point-to-Point link (Section 12.4.1.1). */
paul4dadc292005-05-06 21:37:42 +0000530static int
paul718e3742002-12-13 20:15:29 +0000531lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
532{
533 int links = 0;
534 struct ospf_neighbor *nbr;
535 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000536 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000537
538 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000539 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
paul718e3742002-12-13 20:15:29 +0000540
paul68980082003-03-25 05:07:42 +0000541 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000542 if (nbr->state == NSM_Full)
543 {
544 /* For unnumbered point-to-point networks, the Link Data field
545 should specify the interface's MIB-II ifIndex value. */
paul779adb02006-01-18 15:07:38 +0000546 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
547 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000548 }
549
Andrew J. Schorre4529632006-12-12 19:18:21 +0000550 /* Regardless of the state of the neighboring router, we must
551 add a Type 3 link (stub network).
552 N.B. Options 1 & 2 share basically the same logic. */
553 masklen2ip (oi->address->prefixlen, &mask);
554 id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
555 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
556 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000557 return links;
558}
559
560/* Describe Broadcast Link. */
paul4dadc292005-05-06 21:37:42 +0000561static int
paul718e3742002-12-13 20:15:29 +0000562lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
563{
564 struct ospf_neighbor *dr;
565 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000566 u_int16_t cost = ospf_link_cost (oi);
567
paul718e3742002-12-13 20:15:29 +0000568 /* Describe Type 3 Link. */
569 if (oi->state == ISM_Waiting)
570 {
Christian Frankecbf435c2014-04-28 11:42:20 +0000571 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
572 zlog_debug ("LSA[Type1]: Interface %s is in state Waiting. "
573 "Adding stub interface", oi->ifp->name);
paul718e3742002-12-13 20:15:29 +0000574 masklen2ip (oi->address->prefixlen, &mask);
575 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000576 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
577 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000578 }
579
580 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
581 /* Describe Type 2 link. */
582 if (dr && (dr->state == NSM_Full ||
583 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000584 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000585 {
Christian Frankecbf435c2014-04-28 11:42:20 +0000586 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
587 zlog_debug ("LSA[Type1]: Interface %s has a DR. "
588 "Adding transit interface", oi->ifp->name);
paul779adb02006-01-18 15:07:38 +0000589 return link_info_set (s, DR (oi), oi->address->u.prefix4,
590 LSA_LINK_TYPE_TRANSIT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000591 }
592 /* Describe type 3 link. */
593 else
594 {
Christian Frankecbf435c2014-04-28 11:42:20 +0000595 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
596 zlog_debug ("LSA[Type1]: Interface %s has no DR. "
597 "Adding stub interface", oi->ifp->name);
paul718e3742002-12-13 20:15:29 +0000598 masklen2ip (oi->address->prefixlen, &mask);
599 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000600 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
601 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000602 }
paul718e3742002-12-13 20:15:29 +0000603}
604
paul4dadc292005-05-06 21:37:42 +0000605static int
paul718e3742002-12-13 20:15:29 +0000606lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
607{
608 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000609
paul718e3742002-12-13 20:15:29 +0000610 /* Describe Type 3 Link. */
611 if (oi->state != ISM_Loopback)
612 return 0;
613
614 mask.s_addr = 0xffffffff;
615 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000616 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000617}
618
619/* Describe Virtual Link. */
paul4dadc292005-05-06 21:37:42 +0000620static int
paul718e3742002-12-13 20:15:29 +0000621lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
622{
623 struct ospf_neighbor *nbr;
paul88d6cf32005-10-29 12:50:09 +0000624 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000625
paul718e3742002-12-13 20:15:29 +0000626 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000627 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000628 if (nbr->state == NSM_Full)
629 {
paul779adb02006-01-18 15:07:38 +0000630 return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
631 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
paul718e3742002-12-13 20:15:29 +0000632 }
633
634 return 0;
635}
636
637#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
638
paul7afa08d2002-12-13 20:59:45 +0000639/* this function add for support point-to-multipoint ,see rfc2328
64012.4.1.4.*/
641/* from "edward rrr" <edward_rrr@hotmail.com>
642 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul4dadc292005-05-06 21:37:42 +0000643static int
paul68980082003-03-25 05:07:42 +0000644lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000645{
646 int links = 0;
647 struct route_node *rn;
648 struct ospf_neighbor *nbr = NULL;
649 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000650 u_int16_t cost = ospf_link_cost (oi);
paul7afa08d2002-12-13 20:59:45 +0000651
652 mask.s_addr = 0xffffffff;
653 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000654 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
paul7afa08d2002-12-13 20:59:45 +0000655
paul1cc8f762003-04-05 19:34:32 +0000656 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000657 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000658
659 /* Search neighbor, */
660 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
661 if ((nbr = rn->info) != NULL)
662 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000663 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000664 if (nbr->state == NSM_Full)
665
666 {
paul779adb02006-01-18 15:07:38 +0000667 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
668 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul1cc8f762003-04-05 19:34:32 +0000669 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000670 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000671 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000672 }
673
674 return links;
paul7afa08d2002-12-13 20:59:45 +0000675}
676
paul718e3742002-12-13 20:15:29 +0000677/* Set router-LSA link information. */
paul4dadc292005-05-06 21:37:42 +0000678static int
paul718e3742002-12-13 20:15:29 +0000679router_lsa_link_set (struct stream *s, struct ospf_area *area)
680{
hasso52dc7ee2004-09-23 19:18:23 +0000681 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000682 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000683 int links = 0;
684
paul1eb8ef22005-04-07 07:30:20 +0000685 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +0000686 {
paul718e3742002-12-13 20:15:29 +0000687 struct interface *ifp = oi->ifp;
688
689 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000690 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000691 {
692 if (oi->state != ISM_Down)
693 {
Joakim Tjernlundc81ee5c2012-07-07 17:06:11 +0200694 oi->lsa_pos_beg = links;
paul718e3742002-12-13 20:15:29 +0000695 /* Describe each link. */
696 switch (oi->type)
697 {
698 case OSPF_IFTYPE_POINTOPOINT:
699 links += lsa_link_ptop_set (s, oi);
700 break;
701 case OSPF_IFTYPE_BROADCAST:
702 links += lsa_link_broadcast_set (s, oi);
703 break;
704 case OSPF_IFTYPE_NBMA:
705 links += lsa_link_nbma_set (s, oi);
706 break;
707 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000708 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000709 break;
710 case OSPF_IFTYPE_VIRTUALLINK:
711 links += lsa_link_virtuallink_set (s, oi);
712 break;
713 case OSPF_IFTYPE_LOOPBACK:
714 links += lsa_link_loopback_set (s, oi);
715 }
Joakim Tjernlundc81ee5c2012-07-07 17:06:11 +0200716 oi->lsa_pos_end = links;
paul718e3742002-12-13 20:15:29 +0000717 }
718 }
719 }
720
721 return links;
722}
723
724/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000725static void
paul718e3742002-12-13 20:15:29 +0000726ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
727{
728 unsigned long putp;
729 u_int16_t cnt;
730
731 /* Set flags. */
732 stream_putc (s, router_lsa_flags (area));
733
734 /* Set Zero fields. */
735 stream_putc (s, 0);
736
737 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000738 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000739
740 /* Forward word */
741 stream_putw(s, 0);
742
743 /* Set all link information. */
744 cnt = router_lsa_link_set (s, area);
745
746 /* Set # of links here. */
747 stream_putw_at (s, putp, cnt);
748}
David Lamparter6b0655a2014-06-04 06:53:35 +0200749
paul88d6cf32005-10-29 12:50:09 +0000750static int
751ospf_stub_router_timer (struct thread *t)
752{
753 struct ospf_area *area = THREAD_ARG (t);
754
755 area->t_stub_router = NULL;
756
757 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
758
759 /* clear stub route state and generate router-lsa refresh, don't
760 * clobber an administratively set stub-router state though.
761 */
762 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
763 return 0;
764
765 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
766
Paul Jakmac363d382010-01-24 22:42:13 +0000767 ospf_router_lsa_update_area (area);
paul88d6cf32005-10-29 12:50:09 +0000768
769 return 0;
770}
paul718e3742002-12-13 20:15:29 +0000771
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100772static void
paul88d6cf32005-10-29 12:50:09 +0000773ospf_stub_router_check (struct ospf_area *area)
774{
775 /* area must either be administratively configured to be stub
776 * or startup-time stub-router must be configured and we must in a pre-stub
777 * state.
778 */
779 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
780 {
781 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
782 return;
783 }
784
785 /* not admin-stubbed, check whether startup stubbing is configured and
786 * whether it's not been done yet
787 */
788 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
789 return;
790
791 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
792 {
793 /* stub-router is hence done forever for this area, even if someone
794 * tries configure it (take effect next restart).
795 */
796 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
797 return;
798 }
799
800 /* startup stub-router configured and not yet done */
801 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
802
803 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
804 area->ospf->stub_router_startup_time);
805}
David Lamparter6b0655a2014-06-04 06:53:35 +0200806
paul718e3742002-12-13 20:15:29 +0000807/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000808static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000809ospf_router_lsa_new (struct ospf_area *area)
810{
paul68980082003-03-25 05:07:42 +0000811 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000812 struct stream *s;
813 struct lsa_header *lsah;
814 struct ospf_lsa *new;
815 int length;
816
817 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000818 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000819
paul88d6cf32005-10-29 12:50:09 +0000820 /* check whether stub-router is desired, and if this is the first
821 * router LSA.
822 */
823 ospf_stub_router_check (area);
824
paul718e3742002-12-13 20:15:29 +0000825 /* Create a stream for LSA. */
826 s = stream_new (OSPF_MAX_LSA_SIZE);
paul718e3742002-12-13 20:15:29 +0000827 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000828 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000829 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000830
831 /* Set router-LSA body fields. */
832 ospf_router_lsa_body_set (s, area);
833
834 /* Set length. */
835 length = stream_get_endp (s);
paul779adb02006-01-18 15:07:38 +0000836 lsah = (struct lsa_header *) STREAM_DATA (s);
paul718e3742002-12-13 20:15:29 +0000837 lsah->length = htons (length);
838
839 /* Now, create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000840 if ( (new = ospf_lsa_new ()) == NULL)
841 {
842 zlog_err ("%s: Unable to create new lsa", __func__);
843 return NULL;
844 }
845
paul718e3742002-12-13 20:15:29 +0000846 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +0000847 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +0000848
849 /* Copy LSA data to store, discard stream. */
850 new->data = ospf_lsa_data_new (length);
851 memcpy (new->data, lsah, length);
852 stream_free (s);
853
854 return new;
855}
856
857/* Originate Router-LSA. */
paul88d6cf32005-10-29 12:50:09 +0000858static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000859ospf_router_lsa_originate (struct ospf_area *area)
860{
861 struct ospf_lsa *new;
paul88d6cf32005-10-29 12:50:09 +0000862
paul718e3742002-12-13 20:15:29 +0000863 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000864 if ( (new = ospf_router_lsa_new (area)) == NULL)
865 {
866 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
867 return NULL;
868 }
paul718e3742002-12-13 20:15:29 +0000869
870 /* Sanity check. */
871 if (new->data->adv_router.s_addr == 0)
872 {
873 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000874 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000875 ospf_lsa_discard (new);
876 return NULL;
877 }
878
879 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000880 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000881
882 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000883 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000884
885 /* Flooding new LSA through area. */
886 ospf_flood_through_area (area, NULL, new);
887
888 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
889 {
ajse588f212004-12-08 18:12:06 +0000890 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
David Lampartereed3c482015-03-03 08:51:53 +0100891 new->data->type, inet_ntoa (new->data->id), (void *)new);
paul718e3742002-12-13 20:15:29 +0000892 ospf_lsa_header_dump (new->data);
893 }
894
895 return new;
896}
897
898/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000899static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000900ospf_router_lsa_refresh (struct ospf_lsa *lsa)
901{
902 struct ospf_area *area = lsa->area;
903 struct ospf_lsa *new;
904
905 /* Sanity check. */
906 assert (lsa->data);
907
908 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000909 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000910
Paul Jakmac363d382010-01-24 22:42:13 +0000911 /* Unregister LSA from refresh-list */
912 ospf_refresher_unregister_lsa (area->ospf, lsa);
913
paul718e3742002-12-13 20:15:29 +0000914 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000915 if ( (new = ospf_router_lsa_new (area)) == NULL)
916 {
917 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
918 return NULL;
919 }
920
paul718e3742002-12-13 20:15:29 +0000921 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
922
paul68980082003-03-25 05:07:42 +0000923 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000924
925 /* Flood LSA through area. */
926 ospf_flood_through_area (area, NULL, new);
927
928 /* Debug logging. */
929 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
930 {
ajse588f212004-12-08 18:12:06 +0000931 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000932 new->data->type, inet_ntoa (new->data->id));
933 ospf_lsa_header_dump (new->data);
934 }
935
936 return NULL;
937}
938
Paul Jakmac363d382010-01-24 22:42:13 +0000939int
940ospf_router_lsa_update_area (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000941{
paul718e3742002-12-13 20:15:29 +0000942 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmac363d382010-01-24 22:42:13 +0000943 zlog_debug ("[router-LSA]: (router-LSA area update)");
paul718e3742002-12-13 20:15:29 +0000944
945 /* Now refresh router-LSA. */
946 if (area->router_lsa_self)
Paul Jakmac363d382010-01-24 22:42:13 +0000947 ospf_lsa_refresh (area->ospf, area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000948 /* Newly originate router-LSA. */
949 else
950 ospf_router_lsa_originate (area);
951
952 return 0;
953}
954
paul718e3742002-12-13 20:15:29 +0000955int
Paul Jakmac363d382010-01-24 22:42:13 +0000956ospf_router_lsa_update (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000957{
paul1eb8ef22005-04-07 07:30:20 +0000958 struct listnode *node, *nnode;
959 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +0000960
961 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000962 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +0000963
paul1eb8ef22005-04-07 07:30:20 +0000964 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000965 {
paul718e3742002-12-13 20:15:29 +0000966 struct ospf_lsa *lsa = area->router_lsa_self;
967 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +0000968 const char *area_str;
paul718e3742002-12-13 20:15:29 +0000969
970 /* Keep Area ID string. */
971 area_str = AREA_NAME (area);
972
973 /* If LSA not exist in this Area, originate new. */
974 if (lsa == NULL)
975 {
976 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000977 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +0000978
979 ospf_router_lsa_originate (area);
980 }
981 /* If router-ID is changed, Link ID must change.
982 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +0000983 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000984 {
985 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000986 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +0000987 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
Paul Jakmadfbd5172010-04-14 10:32:12 +0100988 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +0000989 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000990 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000991 area->router_lsa_self = NULL;
992
993 /* Refresh router-LSA, (not install) and flood through area. */
Paul Jakmac363d382010-01-24 22:42:13 +0000994 ospf_router_lsa_update_area (area);
paul718e3742002-12-13 20:15:29 +0000995 }
996 else
997 {
998 rl = (struct router_lsa *) lsa->data;
999 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +00001000 if (rl->flags != ospf->flags)
Paul Jakmac363d382010-01-24 22:42:13 +00001001 ospf_router_lsa_update_area (area);
paul718e3742002-12-13 20:15:29 +00001002 }
1003 }
1004
1005 return 0;
1006}
1007
David Lamparter6b0655a2014-06-04 06:53:35 +02001008
paul718e3742002-12-13 20:15:29 +00001009/* network-LSA related functions. */
1010/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001011static void
paul718e3742002-12-13 20:15:29 +00001012ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1013{
1014 struct in_addr mask;
1015 struct route_node *rn;
1016 struct ospf_neighbor *nbr;
1017
1018 masklen2ip (oi->address->prefixlen, &mask);
1019 stream_put_ipv4 (s, mask.s_addr);
1020
1021 /* The network-LSA lists those routers that are fully adjacent to
1022 the Designated Router; each fully adjacent router is identified by
1023 its OSPF Router ID. The Designated Router includes itself in this
1024 list. RFC2328, Section 12.4.2 */
1025
1026 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1027 if ((nbr = rn->info) != NULL)
1028 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1029 stream_put_ipv4 (s, nbr->router_id.s_addr);
1030}
1031
paul4dadc292005-05-06 21:37:42 +00001032static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001033ospf_network_lsa_new (struct ospf_interface *oi)
1034{
1035 struct stream *s;
1036 struct ospf_lsa *new;
1037 struct lsa_header *lsah;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001038 struct ospf_if_params *oip;
paul718e3742002-12-13 20:15:29 +00001039 int length;
1040
1041 /* If there are no neighbours on this network (the net is stub),
1042 the router does not originate network-LSA (see RFC 12.4.2) */
1043 if (oi->full_nbrs == 0)
1044 return NULL;
1045
1046 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001047 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001048
1049 /* Create new stream for LSA. */
1050 s = stream_new (OSPF_MAX_LSA_SIZE);
1051 lsah = (struct lsa_header *) STREAM_DATA (s);
1052
1053 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001054 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001055
1056 /* Set network-LSA body fields. */
1057 ospf_network_lsa_body_set (s, oi);
1058
1059 /* Set length. */
1060 length = stream_get_endp (s);
1061 lsah->length = htons (length);
1062
1063 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001064 if ( (new = ospf_lsa_new ()) == NULL)
1065 {
1066 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1067 return NULL;
1068 }
1069
paul718e3742002-12-13 20:15:29 +00001070 new->area = oi->area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001071 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001072
1073 /* Copy LSA to store. */
1074 new->data = ospf_lsa_data_new (length);
1075 memcpy (new->data, lsah, length);
1076 stream_free (s);
Paul Jakma7eb5b472009-10-13 16:13:13 +01001077
1078 /* Remember prior network LSA sequence numbers, even if we stop
1079 * originating one for this oi, to try avoid re-originating LSAs with a
1080 * prior sequence number, and thus speed up adjency forming & convergence.
1081 */
1082 if ((oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4)))
1083 {
1084 new->data->ls_seqnum = oip->network_lsa_seqnum;
1085 new->data->ls_seqnum = lsa_seqnum_increment (new);
1086 }
1087 else
1088 {
1089 oip = ospf_get_if_params (oi->ifp, oi->address->u.prefix4);
1090 ospf_if_update_params (oi->ifp, oi->address->u.prefix4);
1091 }
1092 oip->network_lsa_seqnum = new->data->ls_seqnum;
1093
paul718e3742002-12-13 20:15:29 +00001094 return new;
1095}
1096
1097/* Originate network-LSA. */
Paul Jakmac363d382010-01-24 22:42:13 +00001098void
1099ospf_network_lsa_update (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001100{
1101 struct ospf_lsa *new;
Paul Jakmac363d382010-01-24 22:42:13 +00001102
1103 if (oi->network_lsa_self != NULL)
1104 {
1105 ospf_lsa_refresh (oi->ospf, oi->network_lsa_self);
1106 return;
1107 }
1108
paul718e3742002-12-13 20:15:29 +00001109 /* Create new network-LSA instance. */
1110 new = ospf_network_lsa_new (oi);
1111 if (new == NULL)
Paul Jakmac363d382010-01-24 22:42:13 +00001112 return;
paul718e3742002-12-13 20:15:29 +00001113
1114 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001115 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001116
1117 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001118 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001119
1120 /* Flooding new LSA through area. */
1121 ospf_flood_through_area (oi->area, NULL, new);
1122
1123 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1124 {
ajse588f212004-12-08 18:12:06 +00001125 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
David Lampartereed3c482015-03-03 08:51:53 +01001126 new->data->type, inet_ntoa (new->data->id), (void *)new);
paul718e3742002-12-13 20:15:29 +00001127 ospf_lsa_header_dump (new->data);
1128 }
1129
Paul Jakmac363d382010-01-24 22:42:13 +00001130 return;
paul718e3742002-12-13 20:15:29 +00001131}
1132
Paul Jakmac363d382010-01-24 22:42:13 +00001133static struct ospf_lsa *
1134ospf_network_lsa_refresh (struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001135{
1136 struct ospf_area *area = lsa->area;
Paul Jakmac363d382010-01-24 22:42:13 +00001137 struct ospf_lsa *new, *new2;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001138 struct ospf_if_params *oip;
Paul Jakma4dd87df2010-04-15 08:11:51 +01001139 struct ospf_interface *oi;
Paul Jakmac363d382010-01-24 22:42:13 +00001140
paul718e3742002-12-13 20:15:29 +00001141 assert (lsa->data);
Paul Jakma4dd87df2010-04-15 08:11:51 +01001142
1143 /* Retrieve the oi for the network LSA */
1144 oi = ospf_if_lookup_by_local_addr (area->ospf, NULL, lsa->data->id);
1145 if (oi == NULL)
1146 {
1147 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1148 {
1149 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh: "
1150 "no oi found, ick, ignoring.",
1151 lsa->data->type, inet_ntoa (lsa->data->id));
1152 ospf_lsa_header_dump (lsa->data);
1153 }
1154 return NULL;
1155 }
paul718e3742002-12-13 20:15:29 +00001156 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001157 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001158
Paul Jakmac363d382010-01-24 22:42:13 +00001159 /* Unregister LSA from refresh-list */
1160 ospf_refresher_unregister_lsa (area->ospf, lsa);
1161
paul718e3742002-12-13 20:15:29 +00001162 /* Create new network-LSA instance. */
1163 new = ospf_network_lsa_new (oi);
1164 if (new == NULL)
Paul Jakmac363d382010-01-24 22:42:13 +00001165 return NULL;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001166
1167 oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4);
1168 assert (oip != NULL);
1169 oip->network_lsa_seqnum = new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001170
Paul Jakmac363d382010-01-24 22:42:13 +00001171 new2 = ospf_lsa_install (area->ospf, oi, new);
1172
1173 assert (new2 == new);
1174
paul718e3742002-12-13 20:15:29 +00001175 /* Flood LSA through aera. */
1176 ospf_flood_through_area (area, NULL, new);
1177
1178 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1179 {
ajse588f212004-12-08 18:12:06 +00001180 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001181 new->data->type, inet_ntoa (new->data->id));
1182 ospf_lsa_header_dump (new->data);
1183 }
1184
Paul Jakmac363d382010-01-24 22:42:13 +00001185 return new;
paul718e3742002-12-13 20:15:29 +00001186}
David Lamparter6b0655a2014-06-04 06:53:35 +02001187
paul4dadc292005-05-06 21:37:42 +00001188static void
paul718e3742002-12-13 20:15:29 +00001189stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1190{
1191 u_int32_t metric;
1192 char *mp;
1193
1194 /* Put 0 metric. TOS metric is not supported. */
1195 metric = htonl (metric_value);
1196 mp = (char *) &metric;
1197 mp++;
1198 stream_put (s, mp, 3);
1199}
1200
1201/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001202static void
paul718e3742002-12-13 20:15:29 +00001203ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1204 u_int32_t metric)
1205{
1206 struct in_addr mask;
1207
1208 masklen2ip (p->prefixlen, &mask);
1209
1210 /* Put Network Mask. */
1211 stream_put_ipv4 (s, mask.s_addr);
1212
1213 /* Set # TOS. */
1214 stream_putc (s, (u_char) 0);
1215
1216 /* Set metric. */
1217 stream_put_ospf_metric (s, metric);
1218}
1219
paul4dadc292005-05-06 21:37:42 +00001220static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001221ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1222 u_int32_t metric, struct in_addr id)
1223{
1224 struct stream *s;
1225 struct ospf_lsa *new;
1226 struct lsa_header *lsah;
1227 int length;
1228
paulc24d6022005-11-20 14:54:12 +00001229 if (id.s_addr == 0xffffffff)
1230 {
1231 /* Maybe Link State ID not available. */
1232 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1233 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1234 OSPF_SUMMARY_LSA);
1235 return NULL;
1236 }
1237
paul718e3742002-12-13 20:15:29 +00001238 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001239 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001240
1241 /* Create new stream for LSA. */
1242 s = stream_new (OSPF_MAX_LSA_SIZE);
1243 lsah = (struct lsa_header *) STREAM_DATA (s);
1244
paul68980082003-03-25 05:07:42 +00001245 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1246 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001247
1248 /* Set summary-LSA body fields. */
1249 ospf_summary_lsa_body_set (s, p, metric);
1250
1251 /* Set length. */
1252 length = stream_get_endp (s);
1253 lsah->length = htons (length);
1254
1255 /* Create OSPF LSA instance. */
1256 new = ospf_lsa_new ();
1257 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001258 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001259
1260 /* Copy LSA to store. */
1261 new->data = ospf_lsa_data_new (length);
1262 memcpy (new->data, lsah, length);
1263 stream_free (s);
1264
1265 return new;
1266}
1267
1268/* Originate Summary-LSA. */
1269struct ospf_lsa *
1270ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1271 struct ospf_area *area)
1272{
1273 struct ospf_lsa *new;
1274 struct in_addr id;
1275
paul68980082003-03-25 05:07:42 +00001276 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001277
paulc24d6022005-11-20 14:54:12 +00001278 if (id.s_addr == 0xffffffff)
1279 {
1280 /* Maybe Link State ID not available. */
1281 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1282 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1283 OSPF_SUMMARY_LSA);
1284 return NULL;
1285 }
1286
paul718e3742002-12-13 20:15:29 +00001287 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001288 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1289 return NULL;
paul718e3742002-12-13 20:15:29 +00001290
1291 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001292 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001293
1294 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001295 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001296
1297 /* Flooding new LSA through area. */
1298 ospf_flood_through_area (area, NULL, new);
1299
1300 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1301 {
ajse588f212004-12-08 18:12:06 +00001302 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
David Lampartereed3c482015-03-03 08:51:53 +01001303 new->data->type, inet_ntoa (new->data->id), (void *)new);
paul718e3742002-12-13 20:15:29 +00001304 ospf_lsa_header_dump (new->data);
1305 }
1306
1307 return new;
1308}
1309
Paul Jakmac363d382010-01-24 22:42:13 +00001310static struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001311ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001312{
1313 struct ospf_lsa *new;
1314 struct summary_lsa *sl;
1315 struct prefix p;
1316
1317 /* Sanity check. */
1318 assert (lsa->data);
1319
1320 sl = (struct summary_lsa *)lsa->data;
1321 p.prefixlen = ip_masklen (sl->mask);
1322 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1323 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001324
1325 if (!new)
1326 return NULL;
1327
paul718e3742002-12-13 20:15:29 +00001328 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001329
paul68980082003-03-25 05:07:42 +00001330 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001331
1332 /* Flood LSA through AS. */
1333 ospf_flood_through_area (new->area, NULL, new);
1334
1335 /* Debug logging. */
1336 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1337 {
ajse588f212004-12-08 18:12:06 +00001338 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001339 new->data->type, inet_ntoa (new->data->id));
1340 ospf_lsa_header_dump (new->data);
1341 }
1342
1343 return new;
1344}
1345
David Lamparter6b0655a2014-06-04 06:53:35 +02001346
paul718e3742002-12-13 20:15:29 +00001347/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001348static void
paul718e3742002-12-13 20:15:29 +00001349ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1350 u_int32_t metric)
1351{
paul718e3742002-12-13 20:15:29 +00001352 /* Put Network Mask. */
Leonard Tracy2345a222012-12-04 11:02:35 -08001353 stream_put_ipv4 (s, (u_int32_t) 0);
paul718e3742002-12-13 20:15:29 +00001354
1355 /* Set # TOS. */
1356 stream_putc (s, (u_char) 0);
1357
1358 /* Set metric. */
1359 stream_put_ospf_metric (s, metric);
1360}
1361
paul4dadc292005-05-06 21:37:42 +00001362static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001363ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1364 u_int32_t metric, struct in_addr id)
1365{
1366 struct stream *s;
1367 struct ospf_lsa *new;
1368 struct lsa_header *lsah;
1369 int length;
1370
paulc24d6022005-11-20 14:54:12 +00001371 if (id.s_addr == 0xffffffff)
1372 {
1373 /* Maybe Link State ID not available. */
1374 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1375 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1376 OSPF_ASBR_SUMMARY_LSA);
1377 return NULL;
1378 }
1379
paul718e3742002-12-13 20:15:29 +00001380 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001381 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001382
1383 /* Create new stream for LSA. */
1384 s = stream_new (OSPF_MAX_LSA_SIZE);
1385 lsah = (struct lsa_header *) STREAM_DATA (s);
1386
paul68980082003-03-25 05:07:42 +00001387 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1388 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001389
1390 /* Set summary-LSA body fields. */
1391 ospf_summary_asbr_lsa_body_set (s, p, metric);
1392
1393 /* Set length. */
1394 length = stream_get_endp (s);
1395 lsah->length = htons (length);
1396
1397 /* Create OSPF LSA instance. */
1398 new = ospf_lsa_new ();
1399 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001400 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001401
1402 /* Copy LSA to store. */
1403 new->data = ospf_lsa_data_new (length);
1404 memcpy (new->data, lsah, length);
1405 stream_free (s);
1406
1407 return new;
1408}
1409
1410/* Originate summary-ASBR-LSA. */
1411struct ospf_lsa *
1412ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1413 struct ospf_area *area)
1414{
1415 struct ospf_lsa *new;
1416 struct in_addr id;
1417
paul68980082003-03-25 05:07:42 +00001418 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001419
paulc24d6022005-11-20 14:54:12 +00001420 if (id.s_addr == 0xffffffff)
1421 {
1422 /* Maybe Link State ID not available. */
1423 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1424 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1425 OSPF_ASBR_SUMMARY_LSA);
1426 return NULL;
1427 }
1428
paul718e3742002-12-13 20:15:29 +00001429 /* Create new summary-LSA instance. */
1430 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001431 if (!new)
1432 return NULL;
paul718e3742002-12-13 20:15:29 +00001433
1434 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001435 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001436
1437 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001438 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001439
1440 /* Flooding new LSA through area. */
1441 ospf_flood_through_area (area, NULL, new);
1442
1443 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1444 {
ajse588f212004-12-08 18:12:06 +00001445 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
David Lampartereed3c482015-03-03 08:51:53 +01001446 new->data->type, inet_ntoa (new->data->id), (void *)new);
paul718e3742002-12-13 20:15:29 +00001447 ospf_lsa_header_dump (new->data);
1448 }
1449
1450 return new;
1451}
1452
Paul Jakmac363d382010-01-24 22:42:13 +00001453static struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001454ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001455{
1456 struct ospf_lsa *new;
1457 struct summary_lsa *sl;
1458 struct prefix p;
1459
1460 /* Sanity check. */
1461 assert (lsa->data);
1462
1463 sl = (struct summary_lsa *)lsa->data;
1464 p.prefixlen = ip_masklen (sl->mask);
1465 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1466 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001467 if (!new)
1468 return NULL;
paul718e3742002-12-13 20:15:29 +00001469
1470 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001471
paul68980082003-03-25 05:07:42 +00001472 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001473
1474 /* Flood LSA through area. */
1475 ospf_flood_through_area (new->area, NULL, new);
1476
1477 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1478 {
ajse588f212004-12-08 18:12:06 +00001479 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001480 new->data->type, inet_ntoa (new->data->id));
1481 ospf_lsa_header_dump (new->data);
1482 }
1483
1484 return new;
1485}
1486
1487/* AS-external-LSA related functions. */
1488
1489/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1490 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001491static struct in_addr
paul68980082003-03-25 05:07:42 +00001492ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001493{
1494 struct in_addr fwd;
1495 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001496 struct listnode *node;
1497 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001498
1499 fwd.s_addr = 0;
1500
1501 if (!nexthop.s_addr)
1502 return fwd;
1503
1504 /* Check whether nexthop is covered by OSPF network. */
1505 nh.family = AF_INET;
1506 nh.u.prefix4 = nexthop;
1507 nh.prefixlen = IPV4_MAX_BITLEN;
Paul Jakma4ca15d42009-08-03 15:16:41 +01001508
1509 /* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be
1510 * better to make use of the per-ifp table of ois.
1511 */
paul1eb8ef22005-04-07 07:30:20 +00001512 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1513 if (if_is_operative (oi->ifp))
1514 if (oi->address->family == AF_INET)
1515 if (prefix_match (oi->address, &nh))
1516 return nexthop;
paul718e3742002-12-13 20:15:29 +00001517
1518 return fwd;
1519}
1520
paul718e3742002-12-13 20:15:29 +00001521/* NSSA-external-LSA related functions. */
1522
1523/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001524
paul718e3742002-12-13 20:15:29 +00001525struct in_addr
1526ospf_get_ip_from_ifp (struct ospf_interface *oi)
1527{
1528 struct in_addr fwd;
1529
1530 fwd.s_addr = 0;
1531
paul2e3b2e42002-12-13 21:03:13 +00001532 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001533 return oi->address->u.prefix4;
1534
1535 return fwd;
1536}
1537
1538/* Get 1st IP connection for Forward Addr */
1539struct in_addr
paulf2c80652002-12-13 21:44:27 +00001540ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001541{
1542 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001543 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001544 struct listnode *node;
1545 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001546
1547 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001548 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001549
paul1eb8ef22005-04-07 07:30:20 +00001550 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001551 {
paul2e3b2e42002-12-13 21:03:13 +00001552 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001553 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001554 if (oi->address && oi->address->family == AF_INET)
1555 {
1556 if (best_default.s_addr == 0)
1557 best_default = oi->address->u.prefix4;
1558 if (oi->area == area)
1559 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001560 }
paul718e3742002-12-13 20:15:29 +00001561 }
paulf2c80652002-12-13 21:44:27 +00001562 if (best_default.s_addr != 0)
1563 return best_default;
paul718e3742002-12-13 20:15:29 +00001564
paul68980082003-03-25 05:07:42 +00001565 if (best_default.s_addr != 0)
1566 return best_default;
1567
paul718e3742002-12-13 20:15:29 +00001568 return fwd;
1569}
hassobeebba72004-06-20 21:00:27 +00001570
paul718e3742002-12-13 20:15:29 +00001571#define DEFAULT_DEFAULT_METRIC 20
1572#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1573#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1574
1575#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1576
1577int
paul68980082003-03-25 05:07:42 +00001578metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001579{
paul68980082003-03-25 05:07:42 +00001580 return (ospf->dmetric[src].type < 0 ?
1581 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001582}
1583
1584int
paul68980082003-03-25 05:07:42 +00001585metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001586{
paul68980082003-03-25 05:07:42 +00001587 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001588 {
1589 if (src == DEFAULT_ROUTE)
1590 {
paul68980082003-03-25 05:07:42 +00001591 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001592 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1593 else
1594 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1595 }
paul68980082003-03-25 05:07:42 +00001596 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001597 return DEFAULT_DEFAULT_METRIC;
1598 else
paul68980082003-03-25 05:07:42 +00001599 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001600 }
1601
paul68980082003-03-25 05:07:42 +00001602 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001603}
1604
1605/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001606static void
paul68980082003-03-25 05:07:42 +00001607ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1608 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001609{
1610 struct prefix_ipv4 *p = &ei->p;
1611 struct in_addr mask, fwd_addr;
1612 u_int32_t mvalue;
1613 int mtype;
1614 int type;
1615
1616 /* Put Network Mask. */
1617 masklen2ip (p->prefixlen, &mask);
1618 stream_put_ipv4 (s, mask.s_addr);
1619
1620 /* If prefix is default, specify DEFAULT_ROUTE. */
1621 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1622
1623 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001624 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001625
1626 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001627 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001628
1629 /* Put type of external metric. */
1630 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1631
1632 /* Put 0 metric. TOS metric is not supported. */
1633 stream_put_ospf_metric (s, mvalue);
1634
1635 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001636 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001637
1638 /* Put forwarding address. */
1639 stream_put_ipv4 (s, fwd_addr.s_addr);
1640
1641 /* Put route tag -- This value should be introduced from configuration. */
1642 stream_putl (s, 0);
1643}
1644
1645/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001646static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001647ospf_external_lsa_new (struct ospf *ospf,
1648 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001649{
1650 struct stream *s;
1651 struct lsa_header *lsah;
1652 struct ospf_lsa *new;
1653 struct in_addr id;
1654 int length;
1655
1656 if (ei == NULL)
1657 {
1658 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
Denis Ovsienkoad8d4802011-12-02 20:02:40 +04001659 zlog_debug ("LSA[Type5]: External info is NULL, can't originate");
paul718e3742002-12-13 20:15:29 +00001660 return NULL;
1661 }
1662
1663 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001664 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001665
1666 /* If old Link State ID is specified, refresh LSA with same ID. */
1667 if (old_id)
1668 id = *old_id;
1669 /* Get Link State with unique ID. */
1670 else
1671 {
paul68980082003-03-25 05:07:42 +00001672 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001673 if (id.s_addr == 0xffffffff)
1674 {
1675 /* Maybe Link State ID not available. */
1676 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001677 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001678 return NULL;
1679 }
1680 }
1681
1682 /* Create new stream for LSA. */
1683 s = stream_new (OSPF_MAX_LSA_SIZE);
1684 lsah = (struct lsa_header *) STREAM_DATA (s);
1685
1686 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001687 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1688 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001689
1690 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001691 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001692
1693 /* Set length. */
1694 length = stream_get_endp (s);
1695 lsah->length = htons (length);
1696
1697 /* Now, create OSPF LSA instance. */
1698 new = ospf_lsa_new ();
1699 new->area = NULL;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001700 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001701
1702 /* Copy LSA data to store, discard stream. */
1703 new->data = ospf_lsa_data_new (length);
1704 memcpy (new->data, lsah, length);
1705 stream_free (s);
1706
1707 return new;
1708}
1709
paul718e3742002-12-13 20:15:29 +00001710/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001711static void
paul68980082003-03-25 05:07:42 +00001712ospf_install_flood_nssa (struct ospf *ospf,
1713 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001714{
pauld4a53d52003-07-12 21:30:57 +00001715 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001716 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001717 struct ospf_area *area;
1718 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001719
pauld4a53d52003-07-12 21:30:57 +00001720 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1721 * which originated from an NSSA area. In which case it should not be
1722 * flooded back to NSSA areas.
1723 */
1724 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1725 return;
1726
paul718e3742002-12-13 20:15:29 +00001727 /* NSSA Originate or Refresh (If anyNSSA)
1728
1729 LSA is self-originated. And just installed as Type-5.
1730 Additionally, install as Type-7 LSDB for every attached NSSA.
1731
1732 P-Bit controls which ABR performs translation to outside world; If
1733 we are an ABR....do not set the P-bit, because we send the Type-5,
1734 not as the ABR Translator, but as the ASBR owner within the AS!
1735
1736 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1737 elected ABR Translator will see the P-bit, Translate, and re-flood.
1738
1739 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1740 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1741
paul1eb8ef22005-04-07 07:30:20 +00001742 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001743 {
hasso0c14ad82003-07-03 08:36:02 +00001744 /* Don't install Type-7 LSA's into nonNSSA area */
1745 if (area->external_routing != OSPF_AREA_NSSA)
1746 continue;
paul718e3742002-12-13 20:15:29 +00001747
paul68980082003-03-25 05:07:42 +00001748 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001749 new = ospf_lsa_dup (lsa);
1750 new->area = area;
1751 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001752
paul68980082003-03-25 05:07:42 +00001753 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001754 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001755 {
pauld4a53d52003-07-12 21:30:57 +00001756 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001757
1758 /* set non-zero FWD ADDR
1759
1760 draft-ietf-ospf-nssa-update-09.txt
1761
1762 if the network between the NSSA AS boundary router and the
1763 adjacent AS is advertised into OSPF as an internal OSPF route,
1764 the forwarding address should be the next op address as is cu
1765 currently done with type-5 LSAs. If the intervening network is
1766 not adversited into OSPF as an internal OSPF route and the
1767 type-7 LSA's P-bit is set a forwarding address should be
1768 selected from one of the router's active OSPF inteface addresses
1769 which belong to the NSSA. If no such addresses exist, then
1770 no type-7 LSA's with the P-bit set should originate from this
1771 router. */
1772
pauld4a53d52003-07-12 21:30:57 +00001773 /* kevinm: not updating lsa anymore, just new */
1774 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001775
1776 if (extlsa->e[0].fwd_addr.s_addr == 0)
1777 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001778
pauld7480322003-05-16 17:31:51 +00001779 if (extlsa->e[0].fwd_addr.s_addr == 0)
1780 {
1781 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001782 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001783 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001784 return;
1785 }
paulf2c80652002-12-13 21:44:27 +00001786 }
paul718e3742002-12-13 20:15:29 +00001787
paul68980082003-03-25 05:07:42 +00001788 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001789 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001790
1791 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001792 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001793 }
paul718e3742002-12-13 20:15:29 +00001794}
pauld4a53d52003-07-12 21:30:57 +00001795
paul4dadc292005-05-06 21:37:42 +00001796static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001797ospf_lsa_translated_nssa_new (struct ospf *ospf,
1798 struct ospf_lsa *type7)
1799{
1800
1801 struct ospf_lsa *new;
1802 struct as_external_lsa *ext, *extnew;
1803 struct external_info ei;
1804
1805 ext = (struct as_external_lsa *)(type7->data);
1806
1807 /* need external_info struct, fill in bare minimum */
1808 ei.p.family = AF_INET;
1809 ei.p.prefix = type7->data->id;
1810 ei.p.prefixlen = ip_masklen (ext->mask);
1811 ei.type = ZEBRA_ROUTE_OSPF;
1812 ei.nexthop = ext->header.adv_router;
1813 ei.route_map_set.metric = -1;
1814 ei.route_map_set.metric_type = -1;
1815 ei.tag = 0;
1816
1817 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1818 {
1819 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001820 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001821 "Translated Type-5 for %s",
1822 inet_ntoa (ei.p.prefix));
1823 return NULL;
1824 }
1825
1826 extnew = (struct as_external_lsa *)(new->data);
1827
1828 /* copy over Type-7 data to new */
1829 extnew->e[0].tos = ext->e[0].tos;
1830 extnew->e[0].route_tag = ext->e[0].route_tag;
1831 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1832 new->data->ls_seqnum = type7->data->ls_seqnum;
1833
1834 /* add translated flag, checksum and lock new lsa */
1835 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
pauld4a53d52003-07-12 21:30:57 +00001836 new = ospf_lsa_lock (new);
1837
1838 return new;
1839}
1840
pauld4a53d52003-07-12 21:30:57 +00001841/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1842struct ospf_lsa *
1843ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1844{
1845 struct ospf_lsa *new;
1846 struct as_external_lsa *extnew;
1847
1848 /* we cant use ospf_external_lsa_originate() as we need to set
1849 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1850 */
1851
1852 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1853 {
1854 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001855 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001856 "Type-7, Id %s, to Type-5",
1857 inet_ntoa (type7->data->id));
1858 return NULL;
1859 }
1860
1861 extnew = (struct as_external_lsa *)new;
1862
1863 if (IS_DEBUG_OSPF_NSSA)
1864 {
ajse588f212004-12-08 18:12:06 +00001865 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001866 "translated Type 7, installed:");
1867 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001868 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1869 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001870 }
1871
1872 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1873 {
Hasso Tepper8c9ed272012-10-11 11:15:18 +00001874 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001875 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001876 "Could not install LSA "
1877 "id %s", inet_ntoa (type7->data->id));
1878 return NULL;
1879 }
1880
1881 ospf->lsa_originate_count++;
1882 ospf_flood_through_as (ospf, NULL, new);
1883
1884 return new;
1885}
1886
1887/* Refresh Translated from NSSA AS-external-LSA. */
1888struct ospf_lsa *
1889ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1890 struct ospf_lsa *type5)
1891{
1892 struct ospf_lsa *new = NULL;
1893
1894 /* Sanity checks. */
1895 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00001896 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00001897 return NULL;
pauld4a53d52003-07-12 21:30:57 +00001898 if (type7)
1899 assert (type7->data);
1900 if (type5)
1901 assert (type5->data);
1902 assert (ospf->anyNSSA);
1903
1904 /* get required data according to what has been given */
1905 if (type7 && type5 == NULL)
1906 {
1907 /* find the translated Type-5 for this Type-7 */
1908 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1909 struct prefix_ipv4 p =
1910 {
1911 .prefix = type7->data->id,
1912 .prefixlen = ip_masklen (ext->mask),
1913 .family = AF_INET,
1914 };
1915
1916 type5 = ospf_external_info_find_lsa (ospf, &p);
1917 }
1918 else if (type5 && type7 == NULL)
1919 {
1920 /* find the type-7 from which supplied type-5 was translated,
1921 * ie find first type-7 with same LSA Id.
1922 */
paul1eb8ef22005-04-07 07:30:20 +00001923 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00001924 struct route_node *rn;
1925 struct ospf_lsa *lsa;
1926 struct ospf_area *area;
1927
paul1eb8ef22005-04-07 07:30:20 +00001928 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00001929 {
1930 if (area->external_routing != OSPF_AREA_NSSA
1931 && !type7)
1932 continue;
1933
1934 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
1935 {
1936 if (lsa->data->id.s_addr == type5->data->id.s_addr)
1937 {
1938 type7 = lsa;
1939 break;
1940 }
1941 }
1942 }
1943 }
1944
1945 /* do we have type7? */
1946 if (!type7)
1947 {
1948 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001949 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00001950 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00001951 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00001952 return NULL;
1953 }
1954
1955 /* do we have valid translated type5? */
1956 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
1957 {
1958 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001959 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00001960 "found for Type-7 with Id %s",
1961 inet_ntoa (type7->data->id));
1962 return NULL;
1963 }
1964
1965 /* Delete LSA from neighbor retransmit-list. */
1966 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
1967
1968 /* create new translated LSA */
1969 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1970 {
1971 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001972 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001973 "Type-7 for %s to Type-5",
1974 inet_ntoa (type7->data->id));
1975 return NULL;
1976 }
1977
1978 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
1979 {
1980 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001981 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00001982 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00001983 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00001984 return NULL;
1985 }
1986
1987 /* Flood LSA through area. */
1988 ospf_flood_through_as (ospf, NULL, new);
1989
1990 return new;
1991}
paul718e3742002-12-13 20:15:29 +00001992
1993int
1994is_prefix_default (struct prefix_ipv4 *p)
1995{
1996 struct prefix_ipv4 q;
1997
1998 q.family = AF_INET;
1999 q.prefix.s_addr = 0;
2000 q.prefixlen = 0;
2001
2002 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
2003}
2004
2005/* Originate an AS-external-LSA, install and flood. */
2006struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002007ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00002008{
2009 struct ospf_lsa *new;
2010
2011 /* Added for NSSA project....
2012
2013 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2014 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2015 every area. The Type-7's are flooded to every IR and every ABR; We
2016 install the Type-5 LSDB so that the normal "refresh" code operates
2017 as usual, and flag them as not used during ASE calculations. The
2018 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2019 Address of non-zero.
2020
2021 If an ABR is the elected NSSA translator, following SPF and during
2022 the ABR task it will translate all the scanned Type-7's, with P-bit
2023 ON and not-self generated, and translate to Type-5's throughout the
2024 non-NSSA/STUB AS.
2025
2026 A difference in operation depends whether this ASBR is an ABR
2027 or not. If not an ABR, the P-bit is ON, to indicate that any
2028 elected NSSA-ABR can perform its translation.
2029
2030 If an ABR, the P-bit is OFF; No ABR will perform translation and
2031 this ASBR will flood the Type-5 LSA as usual.
2032
2033 For the case where this ASBR is not an ABR, the ASE calculations
2034 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2035 demonstrate to the user that there are LSA's that belong to any
2036 attached NSSA.
2037
2038 Finally, it just so happens that when the ABR is translating every
2039 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2040 approved Type-5 (translated from Type-7); at the end of translation
2041 if any Translated Type-5's remain unapproved, then they must be
2042 flushed from the AS.
2043
2044 */
2045
2046 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002047 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002048 return NULL;
2049
2050 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002051 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002052 {
2053 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002054 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002055 inet_ntoa (ei->p.prefix));
2056 return NULL;
2057 }
2058
2059 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002060 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002061
2062 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002063 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002064
2065 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002066 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002067
paul718e3742002-12-13 20:15:29 +00002068 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002069 if (ospf->anyNSSA &&
2070 /* stay away from translated LSAs! */
2071 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002072 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002073
2074 /* Debug logging. */
2075 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2076 {
ajse588f212004-12-08 18:12:06 +00002077 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
David Lampartereed3c482015-03-03 08:51:53 +01002078 new->data->type, inet_ntoa (new->data->id), (void *)new);
paul718e3742002-12-13 20:15:29 +00002079 ospf_lsa_header_dump (new->data);
2080 }
2081
2082 return new;
2083}
2084
2085/* Originate AS-external-LSA from external info with initial flag. */
2086int
paul68980082003-03-25 05:07:42 +00002087ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002088{
paul68980082003-03-25 05:07:42 +00002089 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002090 struct route_node *rn;
2091 struct external_info *ei;
2092 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002093 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002094
paul68980082003-03-25 05:07:42 +00002095 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002096
2097 /* Originate As-external-LSA from all type of distribute source. */
2098 if ((rt = EXTERNAL_INFO (type)))
2099 for (rn = route_top (rt); rn; rn = route_next (rn))
2100 if ((ei = rn->info) != NULL)
2101 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002102 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002103 zlog_warn ("LSA: AS-external-LSA was not originated.");
2104
2105 return 0;
2106}
2107
paul4dadc292005-05-06 21:37:42 +00002108static struct external_info *
paul020709f2003-04-04 02:44:16 +00002109ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002110{
2111 int type;
2112 struct route_node *rn;
2113 struct prefix_ipv4 p;
2114
2115 p.family = AF_INET;
2116 p.prefix.s_addr = 0;
2117 p.prefixlen = 0;
2118
2119 /* First, lookup redistributed default route. */
2120 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2121 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2122 {
2123 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2124 if (rn != NULL)
2125 {
2126 route_unlock_node (rn);
2127 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002128 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002129 return rn->info;
2130 }
2131 }
2132
2133 return NULL;
2134}
2135
2136int
paul68980082003-03-25 05:07:42 +00002137ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002138{
paul718e3742002-12-13 20:15:29 +00002139 struct prefix_ipv4 p;
2140 struct in_addr nexthop;
2141 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002142 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002143
Paul Jakma4021b602006-05-12 22:55:41 +00002144 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002145
2146 p.family = AF_INET;
2147 p.prefix.s_addr = 0;
2148 p.prefixlen = 0;
2149
Paul Jakma4021b602006-05-12 22:55:41 +00002150 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002151 {
2152 /* If there is no default route via redistribute,
2153 then originate AS-external-LSA with nexthop 0 (self). */
2154 nexthop.s_addr = 0;
2155 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2156 }
2157
paul020709f2003-04-04 02:44:16 +00002158 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002159 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002160
2161 return 0;
2162}
2163
paul645878f2003-04-13 21:42:11 +00002164/* Flush any NSSA LSAs for given prefix */
2165void
2166ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2167{
paul1eb8ef22005-04-07 07:30:20 +00002168 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002169 struct ospf_lsa *lsa;
2170 struct ospf_area *area;
2171
paul1eb8ef22005-04-07 07:30:20 +00002172 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002173 {
paul1eb8ef22005-04-07 07:30:20 +00002174 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002175 {
2176 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2177 ospf->router_id)))
2178 {
2179 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002180 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002181 inet_ntoa (p->prefix), p->prefixlen);
2182 continue;
2183 }
2184 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2185 if (!IS_LSA_MAXAGE (lsa))
2186 {
2187 ospf_refresher_unregister_lsa (ospf, lsa);
2188 ospf_lsa_flush_area (lsa, area);
2189 }
2190 }
paul645878f2003-04-13 21:42:11 +00002191 }
2192}
paul645878f2003-04-13 21:42:11 +00002193
paul718e3742002-12-13 20:15:29 +00002194/* Flush an AS-external-LSA from LSDB and routing domain. */
2195void
paul68980082003-03-25 05:07:42 +00002196ospf_external_lsa_flush (struct ospf *ospf,
2197 u_char type, struct prefix_ipv4 *p,
ajs5339cfd2005-09-19 13:28:05 +00002198 unsigned int ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002199{
2200 struct ospf_lsa *lsa;
2201
2202 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002203 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002204 inet_ntoa (p->prefix), p->prefixlen);
2205
2206 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002207 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002208 {
2209 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002210 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002211 inet_ntoa (p->prefix), p->prefixlen);
2212 return;
2213 }
hassobeebba72004-06-20 21:00:27 +00002214
pauld4a53d52003-07-12 21:30:57 +00002215 /* If LSA is selforiginated, not a translated LSA, and there is
2216 * NSSA area, flush Type-7 LSA's at first.
2217 */
2218 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2219 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002220 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002221
2222 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002223 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002224
2225 /* There must be no self-originated LSA in rtrs_external. */
2226#if 0
2227 /* Remove External route from Zebra. */
2228 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2229#endif
2230
2231 if (!IS_LSA_MAXAGE (lsa))
2232 {
2233 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002234 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002235
2236 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002237 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002238 }
2239
2240 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002241 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002242}
2243
2244void
paul68980082003-03-25 05:07:42 +00002245ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002246{
2247 struct prefix_ipv4 p;
2248 struct external_info *ei;
2249 struct ospf_lsa *lsa;
2250
2251 p.family = AF_INET;
2252 p.prefixlen = 0;
2253 p.prefix.s_addr = 0;
2254
paul020709f2003-04-04 02:44:16 +00002255 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002256 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002257
2258 if (ei)
2259 {
2260 if (lsa)
2261 {
2262 if (IS_DEBUG_OSPF_EVENT)
David Lampartereed3c482015-03-03 08:51:53 +01002263 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p",
2264 (void *)lsa);
paul68980082003-03-25 05:07:42 +00002265 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002266 }
2267 else
2268 {
2269 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002270 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002271 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002272 }
2273 }
2274 else
2275 {
2276 if (lsa)
2277 {
2278 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002279 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
Paul Jakmadfbd5172010-04-14 10:32:12 +01002280 ospf_refresher_unregister_lsa (ospf, lsa);
paul68980082003-03-25 05:07:42 +00002281 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002282 }
2283 }
2284}
2285
2286void
paul68980082003-03-25 05:07:42 +00002287ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002288{
2289 struct route_node *rn;
2290 struct external_info *ei;
2291
2292 if (type != DEFAULT_ROUTE)
2293 if (EXTERNAL_INFO(type))
2294 /* Refresh each redistributed AS-external-LSAs. */
2295 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2296 if ((ei = rn->info))
2297 if (!is_prefix_default (&ei->p))
2298 {
2299 struct ospf_lsa *lsa;
2300
paul68980082003-03-25 05:07:42 +00002301 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2302 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002303 else
paul68980082003-03-25 05:07:42 +00002304 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002305 }
2306}
2307
2308/* Refresh AS-external-LSA. */
Paul Jakmac363d382010-01-24 22:42:13 +00002309struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002310ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002311 struct external_info *ei, int force)
2312{
2313 struct ospf_lsa *new;
2314 int changed;
2315
2316 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002317 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002318 {
pauld4a53d52003-07-12 21:30:57 +00002319 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002320 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002321 "redist check fail",
2322 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002323 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002324 ei->ifindex /*, ei->nexthop */);
Paul Jakmac363d382010-01-24 22:42:13 +00002325 return NULL;
paul718e3742002-12-13 20:15:29 +00002326 }
2327
2328 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002329 {
2330 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002331 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002332 lsa->data->type, inet_ntoa (lsa->data->id));
Paul Jakmac363d382010-01-24 22:42:13 +00002333 return NULL;
pauld4a53d52003-07-12 21:30:57 +00002334 }
paul718e3742002-12-13 20:15:29 +00002335
2336 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002337 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002338
2339 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002340 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002341
paul68980082003-03-25 05:07:42 +00002342 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002343
2344 if (new == NULL)
2345 {
2346 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002347 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002348 inet_ntoa (lsa->data->id));
Paul Jakmac363d382010-01-24 22:42:13 +00002349 return NULL;
paul718e3742002-12-13 20:15:29 +00002350 }
2351
2352 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2353
paul68980082003-03-25 05:07:42 +00002354 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002355
2356 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002357 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002358
paul718e3742002-12-13 20:15:29 +00002359 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002360 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002361 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002362
pauld4a53d52003-07-12 21:30:57 +00002363 /* Register self-originated LSA to refresh queue.
2364 * Translated LSAs should not be registered, but refreshed upon
2365 * refresh of the Type-7
2366 */
2367 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2368 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002369
2370 /* Debug logging. */
2371 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2372 {
ajse588f212004-12-08 18:12:06 +00002373 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002374 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002375 ospf_lsa_header_dump (new->data);
2376 }
2377
Paul Jakmac363d382010-01-24 22:42:13 +00002378 return new;
paul718e3742002-12-13 20:15:29 +00002379}
2380
David Lamparter6b0655a2014-06-04 06:53:35 +02002381
paul718e3742002-12-13 20:15:29 +00002382/* LSA installation functions. */
2383
2384/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002385static struct ospf_lsa *
Paul Jakmac363d382010-01-24 22:42:13 +00002386ospf_router_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2387 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002388{
2389 struct ospf_area *area = new->area;
2390
2391 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2392 The entire routing table must be recalculated, starting with
2393 the shortest path calculations for each area (not just the
2394 area whose link-state database has changed).
2395 */
paul718e3742002-12-13 20:15:29 +00002396
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002397 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002398 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002399
2400 /* Only install LSA if it is originated/refreshed by us.
2401 * If LSA was received by flooding, the RECEIVED flag is set so do
2402 * not link the LSA */
2403 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2404 return new; /* ignore stale LSA */
2405
paul718e3742002-12-13 20:15:29 +00002406 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002407 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002408 area->router_lsa_self = ospf_lsa_lock (new);
2409
Paul Jakmac363d382010-01-24 22:42:13 +00002410 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002411 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002412 if (rt_recalc)
Paul Jakmab6eef002014-10-09 14:19:51 +01002413 ospf_spf_calculate_schedule (ospf, SPF_FLAG_ROUTER_LSA_INSTALL);
paul718e3742002-12-13 20:15:29 +00002414 return new;
2415}
2416
2417#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2418 if (!(T)) \
2419 (T) = thread_add_timer (master, (F), oi, (V))
2420
2421/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002422static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002423ospf_network_lsa_install (struct ospf *ospf,
2424 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002425 struct ospf_lsa *new,
2426 int rt_recalc)
2427{
2428
2429 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2430 The entire routing table must be recalculated, starting with
2431 the shortest path calculations for each area (not just the
2432 area whose link-state database has changed).
2433 */
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002434 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002435 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002436 /* We supposed that when LSA is originated by us, we pass the int
2437 for which it was originated. If LSA was received by flooding,
2438 the RECEIVED flag is set, so we do not link the LSA to the int. */
2439 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2440 return new; /* ignore stale LSA */
2441
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002442 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002443 oi->network_lsa_self = ospf_lsa_lock (new);
Paul Jakmac363d382010-01-24 22:42:13 +00002444 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002445 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002446 if (rt_recalc)
Paul Jakmab6eef002014-10-09 14:19:51 +01002447 ospf_spf_calculate_schedule (ospf, SPF_FLAG_NETWORK_LSA_INSTALL);
paul718e3742002-12-13 20:15:29 +00002448
2449 return new;
2450}
2451
2452/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002453static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002454ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2455 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002456{
paul718e3742002-12-13 20:15:29 +00002457 if (rt_recalc && !IS_LSA_SELF (new))
2458 {
2459 /* RFC 2328 Section 13.2 Summary-LSAs
2460 The best route to the destination described by the summary-
2461 LSA must be recalculated (see Section 16.5). If this
2462 destination is an AS boundary router, it may also be
2463 necessary to re-examine all the AS-external-LSAs.
2464 */
2465
2466#if 0
2467 /* This doesn't exist yet... */
2468 ospf_summary_incremental_update(new); */
2469#else /* #if 0 */
Paul Jakmab6eef002014-10-09 14:19:51 +01002470 ospf_spf_calculate_schedule (ospf, SPF_FLAG_SUMMARY_LSA_INSTALL);
paul718e3742002-12-13 20:15:29 +00002471#endif /* #if 0 */
2472
paul718e3742002-12-13 20:15:29 +00002473 }
2474
2475 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002476 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002477
2478 return new;
2479}
2480
2481/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002482static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002483ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2484 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002485{
2486 if (rt_recalc && !IS_LSA_SELF (new))
2487 {
2488 /* RFC 2328 Section 13.2 Summary-LSAs
2489 The best route to the destination described by the summary-
2490 LSA must be recalculated (see Section 16.5). If this
2491 destination is an AS boundary router, it may also be
2492 necessary to re-examine all the AS-external-LSAs.
2493 */
2494#if 0
2495 /* These don't exist yet... */
2496 ospf_summary_incremental_update(new);
2497 /* Isn't this done by the above call?
2498 - RFC 2328 Section 16.5 implies it should be */
2499 /* ospf_ase_calculate_schedule(); */
2500#else /* #if 0 */
Paul Jakmab6eef002014-10-09 14:19:51 +01002501 ospf_spf_calculate_schedule (ospf, SPF_FLAG_ASBR_SUMMARY_LSA_INSTALL);
paul718e3742002-12-13 20:15:29 +00002502#endif /* #if 0 */
2503 }
2504
2505 /* register LSA to refresh-list. */
2506 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002507 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002508
2509 return new;
2510}
2511
2512/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002513static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002514ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2515 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002516{
paul68980082003-03-25 05:07:42 +00002517 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002518 /* If LSA is not self-originated, calculate an external route. */
2519 if (rt_recalc)
2520 {
2521 /* RFC 2328 Section 13.2 AS-external-LSAs
2522 The best route to the destination described by the AS-
2523 external-LSA must be recalculated (see Section 16.6).
2524 */
2525
2526 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002527 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002528 }
2529
pauld4a53d52003-07-12 21:30:57 +00002530 if (new->data->type == OSPF_AS_NSSA_LSA)
2531 {
2532 /* There is no point to register selforiginate Type-7 LSA for
2533 * refreshing. We rely on refreshing Type-5 LSA's
2534 */
2535 if (IS_LSA_SELF (new))
2536 return new;
2537 else
2538 {
2539 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2540 * New translations will be taken care of by the abr_task.
2541 */
2542 ospf_translated_nssa_refresh (ospf, new, NULL);
2543 }
2544 }
pauld7480322003-05-16 17:31:51 +00002545
pauld4a53d52003-07-12 21:30:57 +00002546 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002547 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002548 */
hassobeebba72004-06-20 21:00:27 +00002549 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002550 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002551
2552 return new;
2553}
2554
2555void
paul68980082003-03-25 05:07:42 +00002556ospf_discard_from_db (struct ospf *ospf,
2557 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002558{
2559 struct ospf_lsa *old;
2560
Paul Jakmaac904de2006-06-15 12:04:57 +00002561 if (!lsdb)
2562 {
2563 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2564 if (!lsa)
2565 zlog_warn ("%s: and NULL LSA!", __func__);
2566 else
2567 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2568 lsa->data->type, inet_ntoa (lsa->data->id));
2569 return;
2570 }
2571
paul718e3742002-12-13 20:15:29 +00002572 old = ospf_lsdb_lookup (lsdb, lsa);
2573
2574 if (!old)
2575 return;
2576
2577 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002578 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002579
2580 switch (old->data->type)
2581 {
2582 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002583 ospf_ase_unregister_external_lsa (old, ospf);
2584 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2585 break;
paul718e3742002-12-13 20:15:29 +00002586#ifdef HAVE_OPAQUE_LSA
2587 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002588 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002589 break;
paul69310a62005-05-11 18:09:59 +00002590#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002591 case OSPF_AS_NSSA_LSA:
2592 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2593 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002594 break;
paul718e3742002-12-13 20:15:29 +00002595 default:
paul68980082003-03-25 05:07:42 +00002596 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002597 break;
2598 }
2599
paul68980082003-03-25 05:07:42 +00002600 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002601 ospf_lsa_discard (old);
2602}
2603
paul718e3742002-12-13 20:15:29 +00002604struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002605ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2606 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002607{
2608 struct ospf_lsa *new = NULL;
2609 struct ospf_lsa *old = NULL;
2610 struct ospf_lsdb *lsdb = NULL;
2611 int rt_recalc;
2612
2613 /* Set LSDB. */
2614 switch (lsa->data->type)
2615 {
paulf2c80652002-12-13 21:44:27 +00002616 /* kevinm */
2617 case OSPF_AS_NSSA_LSA:
2618 if (lsa->area)
2619 lsdb = lsa->area->lsdb;
2620 else
paul68980082003-03-25 05:07:42 +00002621 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002622 break;
paul718e3742002-12-13 20:15:29 +00002623 case OSPF_AS_EXTERNAL_LSA:
2624#ifdef HAVE_OPAQUE_LSA
2625 case OSPF_OPAQUE_AS_LSA:
2626#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002627 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002628 break;
2629 default:
2630 lsdb = lsa->area->lsdb;
2631 break;
2632 }
2633
paul718e3742002-12-13 20:15:29 +00002634 assert (lsdb);
2635
2636 /* RFC 2328 13.2. Installing LSAs in the database
2637
2638 Installing a new LSA in the database, either as the result of
2639 flooding or a newly self-originated LSA, may cause the OSPF
2640 routing table structure to be recalculated. The contents of the
2641 new LSA should be compared to the old instance, if present. If
2642 there is no difference, there is no need to recalculate the
2643 routing table. When comparing an LSA to its previous instance,
2644 the following are all considered to be differences in contents:
2645
2646 o The LSA's Options field has changed.
2647
2648 o One of the LSA instances has LS age set to MaxAge, and
2649 the other does not.
2650
2651 o The length field in the LSA header has changed.
2652
2653 o The body of the LSA (i.e., anything outside the 20-byte
2654 LSA header) has changed. Note that this excludes changes
2655 in LS Sequence Number and LS Checksum.
2656
2657 */
2658 /* Look up old LSA and determine if any SPF calculation or incremental
2659 update is needed */
2660 old = ospf_lsdb_lookup (lsdb, lsa);
2661
2662 /* Do comparision and record if recalc needed. */
2663 rt_recalc = 0;
2664 if ( old == NULL || ospf_lsa_different(old, lsa))
2665 rt_recalc = 1;
2666
paul7ddf1d62003-10-13 09:06:46 +00002667 /*
2668 Sequence number check (Section 14.1 of rfc 2328)
2669 "Premature aging is used when it is time for a self-originated
2670 LSA's sequence number field to wrap. At this point, the current
2671 LSA instance (having LS sequence number MaxSequenceNumber) must
2672 be prematurely aged and flushed from the routing domain before a
2673 new instance with sequence number equal to InitialSequenceNumber
2674 can be originated. "
2675 */
2676
Paul Jakmac2b478d2006-03-30 14:16:11 +00002677 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002678 {
2679 if (ospf_lsa_is_self_originated(ospf, lsa))
2680 {
paul0c2be262004-05-31 14:16:54 +00002681 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2682
2683 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002684 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2685 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2686
2687 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2688 {
ajse588f212004-12-08 18:12:06 +00002689 zlog_debug ("ospf_lsa_install() Premature Aging "
Paul Jakmac363d382010-01-24 22:42:13 +00002690 "lsa 0x%p, seqnum 0x%x",
David Lampartereed3c482015-03-03 08:51:53 +01002691 (void *)lsa, ntohl(lsa->data->ls_seqnum));
paul7ddf1d62003-10-13 09:06:46 +00002692 ospf_lsa_header_dump (lsa->data);
2693 }
2694 }
2695 else
2696 {
2697 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2698 {
ajse588f212004-12-08 18:12:06 +00002699 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002700 "that was not self originated. Ignoring\n");
2701 ospf_lsa_header_dump (lsa->data);
2702 }
2703 return old;
2704 }
2705 }
2706
paul718e3742002-12-13 20:15:29 +00002707 /* discard old LSA from LSDB */
2708 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002709 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002710
paul718e3742002-12-13 20:15:29 +00002711 /* Calculate Checksum if self-originated?. */
2712 if (IS_LSA_SELF (lsa))
2713 ospf_lsa_checksum (lsa->data);
2714
hassofe71a972004-12-22 16:16:02 +00002715 /* Insert LSA to LSDB. */
2716 ospf_lsdb_add (lsdb, lsa);
2717 lsa->lsdb = lsdb;
2718
paul718e3742002-12-13 20:15:29 +00002719 /* Do LSA specific installation process. */
2720 switch (lsa->data->type)
2721 {
2722 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002723 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002724 break;
2725 case OSPF_NETWORK_LSA:
2726 assert (oi);
paul68980082003-03-25 05:07:42 +00002727 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002728 break;
2729 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002730 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002731 break;
2732 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002733 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002734 break;
2735 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002736 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002737 break;
2738#ifdef HAVE_OPAQUE_LSA
2739 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002740 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002741 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002742 else
Andrew Certain0798cee2012-12-04 13:43:42 -08002743 {
2744 /* Incoming "oi" for this LSA has set at LSUpd reception. */
2745 }
paul09e4efd2003-01-18 00:12:02 +00002746 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002747 case OSPF_OPAQUE_AREA_LSA:
2748 case OSPF_OPAQUE_AS_LSA:
2749 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2750 break;
2751#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002752 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002753 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002754 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002755 break;
2756 }
2757
2758 if (new == NULL)
2759 return new; /* Installation failed, cannot proceed further -- endo. */
2760
2761 /* Debug logs. */
2762 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2763 {
2764 char area_str[INET_ADDRSTRLEN];
2765
2766 switch (lsa->data->type)
2767 {
2768 case OSPF_AS_EXTERNAL_LSA:
2769#ifdef HAVE_OPAQUE_LSA
2770 case OSPF_OPAQUE_AS_LSA:
2771#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002772 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002773 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002774 dump_lsa_key (new),
2775 LOOKUP (ospf_lsa_type_msg, new->data->type));
2776 break;
2777 default:
2778 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002779 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002780 dump_lsa_key (new),
2781 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2782 break;
2783 }
2784 }
2785
paul7ddf1d62003-10-13 09:06:46 +00002786 /*
2787 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2788 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2789 */
Dinesh G Dutte0630cb2013-01-07 10:12:52 -08002790 if (IS_LSA_MAXAGE (new))
paul718e3742002-12-13 20:15:29 +00002791 {
paul7ddf1d62003-10-13 09:06:46 +00002792 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002793 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
David Lampartereed3c482015-03-03 08:51:53 +01002794 new->data->type,
2795 inet_ntoa (new->data->id),
2796 (void *)lsa);
Dinesh G Dutte0630cb2013-01-07 10:12:52 -08002797 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002798 }
2799
2800 return new;
2801}
2802
David Lamparter6b0655a2014-06-04 06:53:35 +02002803
Christian Franke4c14b7f2013-02-20 10:00:54 +00002804int
paul68980082003-03-25 05:07:42 +00002805ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002806{
paul1eb8ef22005-04-07 07:30:20 +00002807 struct listnode *node, *nnode;
2808 struct ospf_interface *oi;
2809
2810 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002811 {
paul718e3742002-12-13 20:15:29 +00002812 struct route_node *rn;
2813 struct ospf_neighbor *nbr;
2814
2815 if (ospf_if_is_enable (oi))
2816 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2817 if ((nbr = rn->info) != NULL)
2818 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2819 {
2820 route_unlock_node (rn);
2821 return 0;
2822 }
2823 }
2824
2825 return 1;
2826}
2827
David Lamparter6b0655a2014-06-04 06:53:35 +02002828
paul718e3742002-12-13 20:15:29 +00002829
paul4dadc292005-05-06 21:37:42 +00002830static int
paul718e3742002-12-13 20:15:29 +00002831ospf_maxage_lsa_remover (struct thread *thread)
2832{
paul68980082003-03-25 05:07:42 +00002833 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002834 struct ospf_lsa *lsa;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002835 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00002836 int reschedule = 0;
2837
paul68980082003-03-25 05:07:42 +00002838 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002839
2840 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002841 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002842
paul68980082003-03-25 05:07:42 +00002843 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002844
2845 if (!reschedule)
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002846 for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn))
paul718e3742002-12-13 20:15:29 +00002847 {
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002848 if ((lsa = rn->info) == NULL)
2849 {
2850 continue;
2851 }
2852
Christian Franke4de8bf02013-02-20 10:00:52 +00002853 /* There is at least one neighbor from which we still await an ack
2854 * for that LSA, so we are not allowed to remove it from our lsdb yet
2855 * as per RFC 2328 section 14 para 4 a) */
paul718e3742002-12-13 20:15:29 +00002856 if (lsa->retransmit_counter > 0)
2857 {
2858 reschedule = 1;
2859 continue;
2860 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002861
2862 /* TODO: maybe convert this function to a work-queue */
2863 if (thread_should_yield (thread))
Christian Franke4de8bf02013-02-20 10:00:52 +00002864 {
2865 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);
Christian Frankee387dfd2014-04-28 08:04:58 +00002866 route_unlock_node(rn); /* route_top/route_next */
Christian Franke4de8bf02013-02-20 10:00:52 +00002867 return 0;
2868 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002869
paul718e3742002-12-13 20:15:29 +00002870 /* Remove LSA from the LSDB */
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04002871 if (IS_LSA_SELF (lsa))
paul718e3742002-12-13 20:15:29 +00002872 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
Denis Ovsienkoad8d4802011-12-02 20:02:40 +04002873 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-originated: ",
paul7ddf1d62003-10-13 09:06:46 +00002874 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002875
2876 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002877 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002878 lsa->data->type, inet_ntoa (lsa->data->id));
2879
Paul Jakmac363d382010-01-24 22:42:13 +00002880 if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))
paul7ddf1d62003-10-13 09:06:46 +00002881 {
2882 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
David Lampartereed3c482015-03-03 08:51:53 +01002883 zlog_debug ("originating new lsa for lsa 0x%p\n", (void *)lsa);
Paul Jakmac363d382010-01-24 22:42:13 +00002884 ospf_lsa_refresh (ospf, lsa);
paul7ddf1d62003-10-13 09:06:46 +00002885 }
2886
paul718e3742002-12-13 20:15:29 +00002887 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002888 if (lsa->lsdb)
2889 {
2890 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2891 ospf_lsdb_delete (lsa->lsdb, lsa);
2892 }
2893 else
2894 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2895 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002896 }
2897
2898 /* A MaxAge LSA must be removed immediately from the router's link
2899 state database as soon as both a) it is no longer contained on any
2900 neighbor Link state retransmission lists and b) none of the router's
2901 neighbors are in states Exchange or Loading. */
2902 if (reschedule)
Paul Jakma02d942c2010-01-24 23:36:20 +00002903 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2904 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002905
2906 return 0;
2907}
2908
paul718e3742002-12-13 20:15:29 +00002909void
paul68980082003-03-25 05:07:42 +00002910ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002911{
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002912 struct route_node *rn;
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002913 struct prefix_ptr lsa_prefix;
paul718e3742002-12-13 20:15:29 +00002914
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002915 lsa_prefix.family = 0;
2916 lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
2917 lsa_prefix.prefix = (uintptr_t) lsa;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002918
2919 if ((rn = route_node_lookup(ospf->maxage_lsa,
2920 (struct prefix *)&lsa_prefix)))
paul718e3742002-12-13 20:15:29 +00002921 {
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002922 if (rn->info == lsa)
2923 {
2924 UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
2925 ospf_lsa_unlock (&lsa); /* maxage_lsa */
2926 rn->info = NULL;
Christian Franke8afee5c2014-04-28 08:04:59 +00002927 route_unlock_node (rn); /* unlock node because lsa is deleted */
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002928 }
Christian Franke8afee5c2014-04-28 08:04:59 +00002929 route_unlock_node (rn); /* route_node_lookup */
paul718e3742002-12-13 20:15:29 +00002930 }
2931}
2932
Paul Jakma02d942c2010-01-24 23:36:20 +00002933/* Add LSA onto the MaxAge list, and schedule for removal.
2934 * This does *not* lead to the LSA being flooded, that must be taken
2935 * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
2936 * function).
2937 */
paul718e3742002-12-13 20:15:29 +00002938void
paul68980082003-03-25 05:07:42 +00002939ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002940{
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002941 struct prefix_ptr lsa_prefix;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002942 struct route_node *rn;
2943
paul718e3742002-12-13 20:15:29 +00002944 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2945 and schedule the MaxAge LSA remover. */
Stephen Hemminger3106a032009-08-06 12:58:05 -07002946 if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
paul718e3742002-12-13 20:15:29 +00002947 {
2948 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002949 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
David Lampartereed3c482015-03-03 08:51:53 +01002950 lsa->data->type, inet_ntoa (lsa->data->id), (void *)lsa);
paul718e3742002-12-13 20:15:29 +00002951 return;
2952 }
2953
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002954 lsa_prefix.family = 0;
2955 lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
2956 lsa_prefix.prefix = (uintptr_t) lsa;
2957
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002958 if ((rn = route_node_get (ospf->maxage_lsa,
2959 (struct prefix *)&lsa_prefix)) != NULL)
2960 {
2961 if (rn->info != NULL)
2962 {
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002963 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2964 zlog_debug ("LSA[%s]: found LSA (%p) in table for LSA %p %d",
David Lampartereed3c482015-03-03 08:51:53 +01002965 dump_lsa_key (lsa), rn->info, (void *)lsa,
2966 lsa_prefix.prefixlen);
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002967 route_unlock_node (rn);
2968 }
2969 else
2970 {
2971 rn->info = ospf_lsa_lock(lsa);
2972 SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
2973 }
2974 }
2975 else
2976 {
2977 zlog_err("Unable to allocate memory for maxage lsa\n");
2978 assert(0);
2979 }
paul718e3742002-12-13 20:15:29 +00002980
2981 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002982 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002983
Paul Jakma02d942c2010-01-24 23:36:20 +00002984 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2985 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002986}
2987
paul4dadc292005-05-06 21:37:42 +00002988static int
paul68980082003-03-25 05:07:42 +00002989ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002990{
paul718e3742002-12-13 20:15:29 +00002991 /* Stay away from any Local Translated Type-7 LSAs */
2992 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2993 return 0;
paul718e3742002-12-13 20:15:29 +00002994
2995 if (IS_LSA_MAXAGE (lsa))
2996 /* Self-originated LSAs should NOT time-out instead,
2997 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00002998 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00002999 {
3000 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003001 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003002
3003 switch (lsa->data->type)
3004 {
paul718e3742002-12-13 20:15:29 +00003005#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00003006 case OSPF_OPAQUE_LINK_LSA:
3007 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003008 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003009 /*
3010 * As a general rule, whenever network topology has changed
3011 * (due to an LSA removal in this case), routing recalculation
3012 * should be triggered. However, this is not true for opaque
3013 * LSAs. Even if an opaque LSA instance is going to be removed
3014 * from the routing domain, it does not mean a change in network
3015 * topology, and thus, routing recalculation is not needed here.
3016 */
3017 break;
paul718e3742002-12-13 20:15:29 +00003018#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00003019 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003020 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003021 ospf_ase_incremental_update (ospf, lsa);
3022 break;
paul718e3742002-12-13 20:15:29 +00003023 default:
Paul Jakmab6eef002014-10-09 14:19:51 +01003024 ospf_spf_calculate_schedule (ospf, SPF_FLAG_MAXAGE);
paul68980082003-03-25 05:07:42 +00003025 break;
paul718e3742002-12-13 20:15:29 +00003026 }
paul68980082003-03-25 05:07:42 +00003027 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003028 }
3029
Paul Jakmac363d382010-01-24 22:42:13 +00003030 if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa))
3031 if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30)
3032 printf ("Eek! Shouldn't happen!\n");
3033
paul718e3742002-12-13 20:15:29 +00003034 return 0;
3035}
3036
3037/* Periodical check of MaxAge LSA. */
3038int
paul68980082003-03-25 05:07:42 +00003039ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003040{
paul68980082003-03-25 05:07:42 +00003041 struct ospf *ospf = THREAD_ARG (thread);
3042 struct route_node *rn;
3043 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003044 struct ospf_area *area;
3045 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003046
paul68980082003-03-25 05:07:42 +00003047 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003048
paul1eb8ef22005-04-07 07:30:20 +00003049 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003050 {
paul68980082003-03-25 05:07:42 +00003051 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3052 ospf_lsa_maxage_walker_remover (ospf, lsa);
3053 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3054 ospf_lsa_maxage_walker_remover (ospf, lsa);
3055 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3056 ospf_lsa_maxage_walker_remover (ospf, lsa);
3057 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3058 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003059#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003060 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3061 ospf_lsa_maxage_walker_remover (ospf, lsa);
3062 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3063 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003064#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003065 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3066 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003067 }
3068
paul4fb949e2003-05-10 20:06:51 +00003069 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003070 if (ospf->lsdb)
3071 {
3072 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3073 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003074#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003075 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3076 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003077#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003078 }
paul718e3742002-12-13 20:15:29 +00003079
paul68980082003-03-25 05:07:42 +00003080 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3081 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003082 return 0;
3083}
3084
paul68980082003-03-25 05:07:42 +00003085struct ospf_lsa *
3086ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3087 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003088{
paul68980082003-03-25 05:07:42 +00003089 struct ospf_lsa *lsa;
3090 struct in_addr mask, id;
3091 struct lsa_header_mask
3092 {
3093 struct lsa_header header;
3094 struct in_addr mask;
3095 } *hmask;
paul718e3742002-12-13 20:15:29 +00003096
paul68980082003-03-25 05:07:42 +00003097 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3098 if (lsa == NULL)
3099 return NULL;
paul718e3742002-12-13 20:15:29 +00003100
paul68980082003-03-25 05:07:42 +00003101 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003102
paul68980082003-03-25 05:07:42 +00003103 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003104
paul68980082003-03-25 05:07:42 +00003105 if (mask.s_addr != hmask->mask.s_addr)
3106 {
3107 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3108 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3109 if (!lsa)
3110 return NULL;
3111 }
paul718e3742002-12-13 20:15:29 +00003112
paul68980082003-03-25 05:07:42 +00003113 return lsa;
paul718e3742002-12-13 20:15:29 +00003114}
3115
3116struct ospf_lsa *
3117ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3118 struct in_addr id, struct in_addr adv_router)
3119{
paule05fba42003-04-13 20:20:53 +00003120 struct ospf *ospf = ospf_lookup();
3121 assert(ospf);
3122
paul718e3742002-12-13 20:15:29 +00003123 switch (type)
3124 {
3125 case OSPF_ROUTER_LSA:
3126 case OSPF_NETWORK_LSA:
3127 case OSPF_SUMMARY_LSA:
3128 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003129 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003130#ifdef HAVE_OPAQUE_LSA
3131 case OSPF_OPAQUE_LINK_LSA:
3132 case OSPF_OPAQUE_AREA_LSA:
3133#endif /* HAVE_OPAQUE_LSA */
3134 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003135 case OSPF_AS_EXTERNAL_LSA:
3136#ifdef HAVE_OPAQUE_LSA
3137 case OSPF_OPAQUE_AS_LSA:
3138#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003139 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003140 default:
3141 break;
3142 }
3143
3144 return NULL;
3145}
3146
3147struct ospf_lsa *
3148ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3149 struct in_addr id)
3150{
3151 struct ospf_lsa *lsa;
3152 struct route_node *rn;
3153
3154 switch (type)
3155 {
3156 case OSPF_ROUTER_LSA:
3157 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003158 case OSPF_NETWORK_LSA:
3159 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3160 if ((lsa = rn->info))
3161 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3162 {
3163 route_unlock_node (rn);
3164 return lsa;
3165 }
3166 break;
3167 case OSPF_SUMMARY_LSA:
3168 case OSPF_ASBR_SUMMARY_LSA:
3169 /* Currently not used. */
3170 assert (1);
3171 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003172 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003173 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003174#ifdef HAVE_OPAQUE_LSA
3175 case OSPF_OPAQUE_LINK_LSA:
3176 case OSPF_OPAQUE_AREA_LSA:
3177 case OSPF_OPAQUE_AS_LSA:
3178 /* Currently not used. */
3179 break;
3180#endif /* HAVE_OPAQUE_LSA */
3181 default:
3182 break;
3183 }
3184
3185 return NULL;
3186}
3187
3188struct ospf_lsa *
3189ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3190{
3191 struct ospf_lsa *match;
3192
3193#ifdef HAVE_OPAQUE_LSA
3194 /*
3195 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3196 * is redefined to have two subfields; opaque-type and opaque-id.
3197 * However, it is harmless to treat the two sub fields together, as if
3198 * they two were forming a unique LSA-ID.
3199 */
3200#endif /* HAVE_OPAQUE_LSA */
3201
3202 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3203
3204 if (match == NULL)
3205 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003206 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003207 lsah->type, inet_ntoa (lsah->id));
3208
3209 return match;
3210}
3211
3212/* return +n, l1 is more recent.
3213 return -n, l2 is more recent.
3214 return 0, l1 and l2 is identical. */
3215int
3216ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3217{
3218 int r;
3219 int x, y;
3220
3221 if (l1 == NULL && l2 == NULL)
3222 return 0;
3223 if (l1 == NULL)
3224 return -1;
3225 if (l2 == NULL)
3226 return 1;
3227
3228 /* compare LS sequence number. */
3229 x = (int) ntohl (l1->data->ls_seqnum);
3230 y = (int) ntohl (l2->data->ls_seqnum);
3231 if (x > y)
3232 return 1;
3233 if (x < y)
3234 return -1;
3235
3236 /* compare LS checksum. */
3237 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3238 if (r)
3239 return r;
3240
3241 /* compare LS age. */
3242 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3243 return 1;
3244 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3245 return -1;
3246
3247 /* compare LS age with MaxAgeDiff. */
3248 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3249 return -1;
3250 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3251 return 1;
3252
3253 /* LSAs are identical. */
3254 return 0;
3255}
3256
3257/* If two LSAs are different, return 1, otherwise return 0. */
3258int
3259ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3260{
3261 char *p1, *p2;
3262 assert (l1);
3263 assert (l2);
3264 assert (l1->data);
3265 assert (l2->data);
3266
3267 if (l1->data->options != l2->data->options)
3268 return 1;
3269
3270 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3271 return 1;
3272
3273 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3274 return 1;
3275
3276 if (l1->data->length != l2->data->length)
3277 return 1;
3278
3279 if (l1->data->length == 0)
3280 return 1;
3281
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02003282 if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
3283 return 1; /* May be a stale LSA in the LSBD */
3284
pauld1825832003-04-03 01:27:01 +00003285 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003286
3287 p1 = (char *) l1->data;
3288 p2 = (char *) l2->data;
3289
3290 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3291 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3292 return 1;
3293
3294 return 0;
3295}
3296
3297#ifdef ORIGINAL_CODING
3298void
3299ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3300 struct ospf_lsa *self,
3301 struct ospf_lsa *new)
3302{
3303 u_int32_t seqnum;
3304
3305 /* Adjust LS Sequence Number. */
3306 seqnum = ntohl (new->data->ls_seqnum) + 1;
3307 self->data->ls_seqnum = htonl (seqnum);
3308
3309 /* Recalculate LSA checksum. */
3310 ospf_lsa_checksum (self->data);
3311
3312 /* Reflooding LSA. */
3313 /* RFC2328 Section 13.3
3314 On non-broadcast networks, separate Link State Update
3315 packets must be sent, as unicasts, to each adjacent neighbor
3316 (i.e., those in state Exchange or greater). The destination
3317 IP addresses for these packets are the neighbors' IP
3318 addresses. */
3319 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3320 {
3321 struct route_node *rn;
3322 struct ospf_neighbor *onbr;
3323
3324 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3325 if ((onbr = rn->info) != NULL)
3326 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3327 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3328 }
3329 else
3330 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3331
3332 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003333 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003334 self->data->type, inet_ntoa (self->data->id));
3335}
3336#else /* ORIGINAL_CODING */
3337static int
paul68980082003-03-25 05:07:42 +00003338ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003339{
3340 if (lsa == NULL || !IS_LSA_SELF (lsa))
3341 return 0;
3342
3343 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003344 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 +00003345
3346 /* Force given lsa's age to MaxAge. */
3347 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3348
3349 switch (lsa->data->type)
3350 {
3351#ifdef HAVE_OPAQUE_LSA
Paul Jakma02d942c2010-01-24 23:36:20 +00003352 /* Opaque wants to be notified of flushes */
paul718e3742002-12-13 20:15:29 +00003353 case OSPF_OPAQUE_LINK_LSA:
3354 case OSPF_OPAQUE_AREA_LSA:
3355 case OSPF_OPAQUE_AS_LSA:
3356 ospf_opaque_lsa_refresh (lsa);
3357 break;
3358#endif /* HAVE_OPAQUE_LSA */
3359 default:
Paul Jakmadfbd5172010-04-14 10:32:12 +01003360 ospf_refresher_unregister_lsa (ospf, lsa);
Paul Jakma02d942c2010-01-24 23:36:20 +00003361 ospf_lsa_flush (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003362 break;
3363 }
3364
3365 return 0;
3366}
3367
3368void
paul68980082003-03-25 05:07:42 +00003369ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003370{
paul1eb8ef22005-04-07 07:30:20 +00003371 struct listnode *node, *nnode;
3372 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003373 struct ospf_area *area;
3374 struct ospf_interface *oi;
3375 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003376 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003377 int need_to_flush_ase = 0;
3378
paul1eb8ef22005-04-07 07:30:20 +00003379 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003380 {
paul718e3742002-12-13 20:15:29 +00003381 if ((lsa = area->router_lsa_self) != NULL)
3382 {
3383 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003384 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3385 lsa->data->type, inet_ntoa (lsa->data->id));
3386
3387 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003388 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003389 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003390 area->router_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003391 }
3392
paul1eb8ef22005-04-07 07:30:20 +00003393 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003394 {
paul718e3742002-12-13 20:15:29 +00003395 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003396 && oi->state == ISM_DR
3397 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003398 {
3399 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003400 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3401 lsa->data->type, inet_ntoa (lsa->data->id));
3402
3403 ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003404 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003405 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003406 oi->network_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003407 }
3408
3409 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3410 && area->external_routing == OSPF_AREA_DEFAULT)
3411 need_to_flush_ase = 1;
3412 }
3413
paul68980082003-03-25 05:07:42 +00003414 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3415 ospf_lsa_flush_schedule (ospf, lsa);
3416 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3417 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003418#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003419 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3420 ospf_lsa_flush_schedule (ospf, lsa);
3421 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3422 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003423#endif /* HAVE_OPAQUE_LSA */
3424 }
3425
3426 if (need_to_flush_ase)
3427 {
paul68980082003-03-25 05:07:42 +00003428 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3429 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003430#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003431 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3432 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003433#endif /* HAVE_OPAQUE_LSA */
3434 }
3435
3436 /*
3437 * Make sure that the MaxAge LSA remover is executed immediately,
3438 * without conflicting to other threads.
3439 */
paul68980082003-03-25 05:07:42 +00003440 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003441 {
paul68980082003-03-25 05:07:42 +00003442 OSPF_TIMER_OFF (ospf->t_maxage);
3443 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003444 }
3445
3446 return;
3447}
3448#endif /* ORIGINAL_CODING */
3449
3450/* If there is self-originated LSA, then return 1, otherwise return 0. */
3451/* An interface-independent version of ospf_lsa_is_self_originated */
3452int
paul68980082003-03-25 05:07:42 +00003453ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003454{
hasso52dc7ee2004-09-23 19:18:23 +00003455 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003456 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003457
3458 /* This LSA is already checked. */
3459 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003460 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003461
3462 /* Make sure LSA is self-checked. */
3463 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3464
3465 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003466 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003467 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3468
3469 /* LSA is router-LSA. */
3470 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003471 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003472 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3473
3474 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3475 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003476 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003477 {
paul718e3742002-12-13 20:15:29 +00003478 /* Ignore virtual link. */
3479 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3480 if (oi->address->family == AF_INET)
3481 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3482 {
3483 /* to make it easier later */
3484 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003485 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003486 }
3487 }
3488
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003489 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003490}
3491
3492/* Get unique Link State ID. */
3493struct in_addr
paul68980082003-03-25 05:07:42 +00003494ospf_lsa_unique_id (struct ospf *ospf,
3495 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003496{
3497 struct ospf_lsa *lsa;
3498 struct in_addr mask, id;
3499
3500 id = p->prefix;
3501
3502 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003503 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003504 if (lsa)
3505 {
3506 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3507 if (ip_masklen (al->mask) == p->prefixlen)
3508 {
3509 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003510 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003511 "Can't get Link State ID for %s/%d",
3512 inet_ntoa (p->prefix), p->prefixlen);
3513 /* id.s_addr = 0; */
3514 id.s_addr = 0xffffffff;
3515 return id;
3516 }
3517 /* Masklen differs, then apply wildcard mask to Link State ID. */
3518 else
3519 {
3520 masklen2ip (p->prefixlen, &mask);
3521
3522 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003523 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3524 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003525 if (lsa)
3526 {
3527 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003528 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003529 "Can't get Link State ID for %s/%d",
3530 inet_ntoa (p->prefix), p->prefixlen);
3531 /* id.s_addr = 0; */
3532 id.s_addr = 0xffffffff;
3533 return id;
3534 }
3535 }
3536 }
3537
3538 return id;
3539}
3540
David Lamparter6b0655a2014-06-04 06:53:35 +02003541
Paul Jakma70461d72006-05-12 22:57:57 +00003542#define LSA_ACTION_FLOOD_AREA 1
3543#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003544
3545struct lsa_action
3546{
3547 u_char action;
3548 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003549 struct ospf_lsa *lsa;
3550};
3551
paul4dadc292005-05-06 21:37:42 +00003552static int
paul718e3742002-12-13 20:15:29 +00003553ospf_lsa_action (struct thread *t)
3554{
3555 struct lsa_action *data;
3556
3557 data = THREAD_ARG (t);
3558
3559 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003560 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003561 data->action);
3562
3563 switch (data->action)
3564 {
paul718e3742002-12-13 20:15:29 +00003565 case LSA_ACTION_FLOOD_AREA:
3566 ospf_flood_through_area (data->area, NULL, data->lsa);
3567 break;
paul718e3742002-12-13 20:15:29 +00003568 case LSA_ACTION_FLUSH_AREA:
3569 ospf_lsa_flush_area (data->lsa, data->area);
3570 break;
paul718e3742002-12-13 20:15:29 +00003571 }
3572
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003573 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003574 XFREE (MTYPE_OSPF_MESSAGE, data);
3575 return 0;
3576}
3577
3578void
3579ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3580{
3581 struct lsa_action *data;
3582
Stephen Hemminger393deb92008-08-18 14:13:29 -07003583 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003584 data->action = LSA_ACTION_FLOOD_AREA;
3585 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003586 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003587
3588 thread_add_event (master, ospf_lsa_action, data, 0);
3589}
3590
3591void
3592ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3593{
3594 struct lsa_action *data;
3595
Stephen Hemminger393deb92008-08-18 14:13:29 -07003596 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003597 data->action = LSA_ACTION_FLUSH_AREA;
3598 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003599 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003600
3601 thread_add_event (master, ospf_lsa_action, data, 0);
3602}
3603
David Lamparter6b0655a2014-06-04 06:53:35 +02003604
paul718e3742002-12-13 20:15:29 +00003605/* LSA Refreshment functions. */
Paul Jakmac363d382010-01-24 22:42:13 +00003606struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00003607ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003608{
3609 struct external_info *ei;
Paul Jakmac363d382010-01-24 22:42:13 +00003610 struct ospf_lsa *new = NULL;
paul718e3742002-12-13 20:15:29 +00003611 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003612 assert (IS_LSA_SELF (lsa));
Paul Jakma66349742010-04-13 22:33:54 +01003613 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003614
3615 switch (lsa->data->type)
3616 {
3617 /* Router and Network LSAs are processed differently. */
3618 case OSPF_ROUTER_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003619 new = ospf_router_lsa_refresh (lsa);
3620 break;
paul718e3742002-12-13 20:15:29 +00003621 case OSPF_NETWORK_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003622 new = ospf_network_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003623 break;
3624 case OSPF_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003625 new = ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003626 break;
3627 case OSPF_ASBR_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003628 new = ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003629 break;
3630 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003631 /* Translated from NSSA Type-5s are refreshed when
3632 * from refresh of Type-7 - do not refresh these directly.
3633 */
3634 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3635 break;
paul718e3742002-12-13 20:15:29 +00003636 ei = ospf_external_info_check (lsa);
3637 if (ei)
Paul Jakmac363d382010-01-24 22:42:13 +00003638 new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003639 else
pauld4a53d52003-07-12 21:30:57 +00003640 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003641 break;
3642#ifdef HAVE_OPAQUE_LSA
3643 case OSPF_OPAQUE_LINK_LSA:
3644 case OSPF_OPAQUE_AREA_LSA:
3645 case OSPF_OPAQUE_AS_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003646 new = ospf_opaque_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003647 break;
pauld7480322003-05-16 17:31:51 +00003648#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003649 default:
3650 break;
paul718e3742002-12-13 20:15:29 +00003651 }
Paul Jakmac363d382010-01-24 22:42:13 +00003652 return new;
paul718e3742002-12-13 20:15:29 +00003653}
3654
3655void
paul68980082003-03-25 05:07:42 +00003656ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003657{
3658 u_int16_t index, current_index;
3659
Paul Jakma66349742010-04-13 22:33:54 +01003660 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003661 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003662
3663 if (lsa->refresh_list < 0)
3664 {
3665 int delay;
3666
3667 if (LS_AGE (lsa) == 0 &&
3668 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3669 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3670 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3671 else
3672 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3673 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3674 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3675
3676 if (delay < 0)
3677 delay = 0;
3678
Paul Jakmac363d382010-01-24 22:42:13 +00003679 current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL)
3680 - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003681
3682 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
Paul Jakmac363d382010-01-24 22:42:13 +00003683 % (OSPF_LSA_REFRESHER_SLOTS);
paul718e3742002-12-13 20:15:29 +00003684
3685 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003686 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003687 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003688 if (!ospf->lsa_refresh_queue.qs[index])
3689 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003690 listnode_add (ospf->lsa_refresh_queue.qs[index],
3691 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003692 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003693 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003694 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003695 "setting refresh_list on lsa %p (slod %d)",
David Lampartereed3c482015-03-03 08:51:53 +01003696 inet_ntoa (lsa->data->id), (void *)lsa, index);
paul718e3742002-12-13 20:15:29 +00003697 }
3698}
3699
3700void
paul68980082003-03-25 05:07:42 +00003701ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003702{
Paul Jakma66349742010-04-13 22:33:54 +01003703 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003704 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003705 if (lsa->refresh_list >= 0)
3706 {
hasso52dc7ee2004-09-23 19:18:23 +00003707 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003708 listnode_delete (refresh_list, lsa);
3709 if (!listcount (refresh_list))
3710 {
3711 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003712 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003713 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003714 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003715 lsa->refresh_list = -1;
3716 }
3717}
3718
3719int
3720ospf_lsa_refresh_walker (struct thread *t)
3721{
hasso52dc7ee2004-09-23 19:18:23 +00003722 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003723 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003724 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003725 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003726 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003727 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003728
3729 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003730 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003731
3732
paul68980082003-03-25 05:07:42 +00003733 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003734
ajs9dbc7972005-03-13 19:27:22 +00003735 /* Note: if clock has jumped backwards, then time change could be negative,
3736 so we are careful to cast the expression to unsigned before taking
3737 modulus. */
paul68980082003-03-25 05:07:42 +00003738 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003739 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakmac363d382010-01-24 22:42:13 +00003740 (quagga_time (NULL) - ospf->lsa_refresher_started)
3741 / OSPF_LSA_REFRESHER_GRANULARITY))
3742 % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003743
3744 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003745 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003746 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003747
paul68980082003-03-25 05:07:42 +00003748 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003749 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3750 {
3751 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003752 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003753 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003754
paul68980082003-03-25 05:07:42 +00003755 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003756
Paul Jakma66349742010-04-13 22:33:54 +01003757 assert (i >= 0);
3758
paul68980082003-03-25 05:07:42 +00003759 ospf->lsa_refresh_queue.qs [i] = NULL;
3760
paul718e3742002-12-13 20:15:29 +00003761 if (refresh_list)
3762 {
paul1eb8ef22005-04-07 07:30:20 +00003763 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003764 {
paul718e3742002-12-13 20:15:29 +00003765 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003766 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
David Lampartereed3c482015-03-03 08:51:53 +01003767 "refresh lsa %p (slot %d)",
3768 inet_ntoa (lsa->data->id), (void *)lsa, i);
3769
Paul Jakma66349742010-04-13 22:33:54 +01003770 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003771 list_delete_node (refresh_list, node);
paul718e3742002-12-13 20:15:29 +00003772 lsa->refresh_list = -1;
3773 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003774 }
3775 list_free (refresh_list);
3776 }
3777 }
3778
paul68980082003-03-25 05:07:42 +00003779 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3780 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003781 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003782
paul1eb8ef22005-04-07 07:30:20 +00003783 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
Paul Jakma66349742010-04-13 22:33:54 +01003784 {
3785 ospf_lsa_refresh (ospf, lsa);
3786 assert (lsa->lock > 0);
3787 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
3788 }
paul718e3742002-12-13 20:15:29 +00003789
3790 list_delete (lsa_to_refresh);
3791
3792 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003793 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003794
3795 return 0;
3796}
3797