blob: 1a21b051070b34dc261b8ce31997c56a5bd04fa1 [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
Michael Rossberg2ef762e2015-07-27 07:56:25 +0200111msec2tv (int a)
112{
113 struct timeval ret;
114
115 ret.tv_sec = 0;
116 ret.tv_usec = a * 1000;
117
118 return tv_adjust (ret);
119}
120
121struct timeval
paul718e3742002-12-13 20:15:29 +0000122tv_add (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
132struct timeval
133tv_sub (struct timeval a, struct timeval b)
134{
135 struct timeval ret;
136
137 ret.tv_sec = a.tv_sec - b.tv_sec;
138 ret.tv_usec = a.tv_usec - b.tv_usec;
139
140 return tv_adjust (ret);
141}
142
143int
144tv_cmp (struct timeval a, struct timeval b)
145{
146 return (a.tv_sec == b.tv_sec ?
147 a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
148}
149
150int
151ospf_lsa_refresh_delay (struct ospf_lsa *lsa)
152{
153 struct timeval delta, now;
154 int delay = 0;
155
Paul Jakma2518efd2006-08-27 06:49:29 +0000156 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
paul718e3742002-12-13 20:15:29 +0000157 delta = tv_sub (now, lsa->tv_orig);
158
Michael Rossberg2ef762e2015-07-27 07:56:25 +0200159 if (tv_cmp (delta, msec2tv (OSPF_MIN_LS_INTERVAL)) < 0)
paul718e3742002-12-13 20:15:29 +0000160 {
Michael Rossberg2ef762e2015-07-27 07:56:25 +0200161 delay = tv_ceil (tv_sub (msec2tv (OSPF_MIN_LS_INTERVAL), delta));
paul718e3742002-12-13 20:15:29 +0000162
163 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000164 zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
paul718e3742002-12-13 20:15:29 +0000165 lsa->data->type, inet_ntoa (lsa->data->id), delay);
166
167 assert (delay > 0);
168 }
169
170 return delay;
171}
172
David Lamparter6b0655a2014-06-04 06:53:35 +0200173
paul718e3742002-12-13 20:15:29 +0000174int
175get_age (struct ospf_lsa *lsa)
176{
177 int age;
paul718e3742002-12-13 20:15:29 +0000178
Paul Jakma2518efd2006-08-27 06:49:29 +0000179 age = ntohs (lsa->data->ls_age)
180 + tv_floor (tv_sub (recent_relative_time (), lsa->tv_recv));
paul718e3742002-12-13 20:15:29 +0000181
182 return age;
183}
184
David Lamparter6b0655a2014-06-04 06:53:35 +0200185
paul718e3742002-12-13 20:15:29 +0000186/* Fletcher Checksum -- Refer to RFC1008. */
paul718e3742002-12-13 20:15:29 +0000187
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100188/* All the offsets are zero-based. The offsets in the RFC1008 are
189 one-based. */
paul718e3742002-12-13 20:15:29 +0000190u_int16_t
191ospf_lsa_checksum (struct lsa_header *lsa)
192{
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100193 u_char *buffer = (u_char *) &lsa->options;
194 int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */
paul718e3742002-12-13 20:15:29 +0000195
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100196 /* Skip the AGE field */
197 u_int16_t len = ntohs(lsa->length) - options_offset;
paul718e3742002-12-13 20:15:29 +0000198
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100199 /* Checksum offset starts from "options" field, not the beginning of the
200 lsa_header struct. The offset is 14, rather than 16. */
201 int checksum_offset = (u_char *) &lsa->checksum - buffer;
paul718e3742002-12-13 20:15:29 +0000202
Jingjing Duan6a270cd2008-08-13 19:09:10 +0100203 return fletcher_checksum(buffer, len, checksum_offset);
paul718e3742002-12-13 20:15:29 +0000204}
205
JR Riversd8a4e422012-09-13 17:17:36 +0000206int
207ospf_lsa_checksum_valid (struct lsa_header *lsa)
208{
209 u_char *buffer = (u_char *) &lsa->options;
210 int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */
211
212 /* Skip the AGE field */
213 u_int16_t len = ntohs(lsa->length) - options_offset;
214
215 return(fletcher_checksum(buffer, len, FLETCHER_CHECKSUM_VALIDATE) == 0);
216}
217
paul718e3742002-12-13 20:15:29 +0000218
David Lamparter6b0655a2014-06-04 06:53:35 +0200219
paul718e3742002-12-13 20:15:29 +0000220/* Create OSPF LSA. */
221struct ospf_lsa *
222ospf_lsa_new ()
223{
224 struct ospf_lsa *new;
225
226 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
paul718e3742002-12-13 20:15:29 +0000227
228 new->flags = 0;
229 new->lock = 1;
230 new->retransmit_counter = 0;
Paul Jakma2518efd2006-08-27 06:49:29 +0000231 new->tv_recv = recent_relative_time ();
paul718e3742002-12-13 20:15:29 +0000232 new->tv_orig = new->tv_recv;
233 new->refresh_list = -1;
234
235 return new;
236}
237
238/* Duplicate OSPF LSA. */
239struct ospf_lsa *
240ospf_lsa_dup (struct ospf_lsa *lsa)
241{
242 struct ospf_lsa *new;
243
244 if (lsa == NULL)
245 return NULL;
246
247 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
248
249 memcpy (new, lsa, sizeof (struct ospf_lsa));
250 UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
251 new->lock = 1;
252 new->retransmit_counter = 0;
253 new->data = ospf_lsa_data_dup (lsa->data);
254
paulf2c80652002-12-13 21:44:27 +0000255 /* kevinm: Clear the refresh_list, otherwise there are going
256 to be problems when we try to remove the LSA from the
257 queue (which it's not a member of.)
258 XXX: Should we add the LSA to the refresh_list queue? */
259 new->refresh_list = -1;
260
261 if (IS_DEBUG_OSPF (lsa, LSA))
David Lampartereed3c482015-03-03 08:51:53 +0100262 zlog_debug ("LSA: duplicated %p (new: %p)", (void *)lsa, (void *)new);
paulf2c80652002-12-13 21:44:27 +0000263
paul718e3742002-12-13 20:15:29 +0000264 return new;
265}
266
267/* Free OSPF LSA. */
268void
269ospf_lsa_free (struct ospf_lsa *lsa)
270{
271 assert (lsa->lock == 0);
272
273 if (IS_DEBUG_OSPF (lsa, LSA))
David Lampartereed3c482015-03-03 08:51:53 +0100274 zlog_debug ("LSA: freed %p", (void *)lsa);
paul718e3742002-12-13 20:15:29 +0000275
276 /* Delete LSA data. */
277 if (lsa->data != NULL)
278 ospf_lsa_data_free (lsa->data);
279
280 assert (lsa->refresh_list < 0);
281
282 memset (lsa, 0, sizeof (struct ospf_lsa));
283 XFREE (MTYPE_OSPF_LSA, lsa);
284}
285
286/* Lock LSA. */
287struct ospf_lsa *
288ospf_lsa_lock (struct ospf_lsa *lsa)
289{
290 lsa->lock++;
291 return lsa;
292}
293
294/* Unlock LSA. */
295void
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000296ospf_lsa_unlock (struct ospf_lsa **lsa)
paul718e3742002-12-13 20:15:29 +0000297{
298 /* This is sanity check. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000299 if (!lsa || !*lsa)
paul718e3742002-12-13 20:15:29 +0000300 return;
301
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000302 (*lsa)->lock--;
paul718e3742002-12-13 20:15:29 +0000303
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000304 assert ((*lsa)->lock >= 0);
paul718e3742002-12-13 20:15:29 +0000305
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000306 if ((*lsa)->lock == 0)
paul718e3742002-12-13 20:15:29 +0000307 {
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000308 assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
309 ospf_lsa_free (*lsa);
310 *lsa = NULL;
paul718e3742002-12-13 20:15:29 +0000311 }
312}
313
314/* Check discard flag. */
315void
316ospf_lsa_discard (struct ospf_lsa *lsa)
317{
318 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
319 {
320 SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
Paul Jakma1fe6ed32006-07-26 09:37:26 +0000321 ospf_lsa_unlock (&lsa);
paul718e3742002-12-13 20:15:29 +0000322 }
323}
324
325/* Create LSA data. */
326struct lsa_header *
327ospf_lsa_data_new (size_t size)
328{
Stephen Hemminger393deb92008-08-18 14:13:29 -0700329 return XCALLOC (MTYPE_OSPF_LSA_DATA, size);
paul718e3742002-12-13 20:15:29 +0000330}
331
332/* Duplicate LSA data. */
333struct lsa_header *
334ospf_lsa_data_dup (struct lsa_header *lsah)
335{
336 struct lsa_header *new;
337
338 new = ospf_lsa_data_new (ntohs (lsah->length));
339 memcpy (new, lsah, ntohs (lsah->length));
340
341 return new;
342}
343
344/* Free LSA data. */
345void
346ospf_lsa_data_free (struct lsa_header *lsah)
347{
348 if (IS_DEBUG_OSPF (lsa, LSA))
ajse588f212004-12-08 18:12:06 +0000349 zlog_debug ("LSA[Type%d:%s]: data freed %p",
David Lampartereed3c482015-03-03 08:51:53 +0100350 lsah->type, inet_ntoa (lsah->id), (void *)lsah);
paul718e3742002-12-13 20:15:29 +0000351
352 XFREE (MTYPE_OSPF_LSA_DATA, lsah);
353}
354
David Lamparter6b0655a2014-06-04 06:53:35 +0200355
paul718e3742002-12-13 20:15:29 +0000356/* LSA general functions. */
357
358const char *
359dump_lsa_key (struct ospf_lsa *lsa)
360{
361 static char buf[] = {
hasso52dc7ee2004-09-23 19:18:23 +0000362 "Type255,id(255.255.255.255),ar(255.255.255.255)"
paul718e3742002-12-13 20:15:29 +0000363 };
364 struct lsa_header *lsah;
365
366 if (lsa != NULL && (lsah = lsa->data) != NULL)
367 {
368 char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
369 strcpy (id, inet_ntoa (lsah->id));
370 strcpy (ar, inet_ntoa (lsah->adv_router));
371
372 sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
373 }
374 else
375 strcpy (buf, "NULL");
376
377 return buf;
378}
379
380u_int32_t
381lsa_seqnum_increment (struct ospf_lsa *lsa)
382{
383 u_int32_t seqnum;
384
385 seqnum = ntohl (lsa->data->ls_seqnum) + 1;
386
387 return htonl (seqnum);
388}
389
390void
391lsa_header_set (struct stream *s, u_char options,
paul68980082003-03-25 05:07:42 +0000392 u_char type, struct in_addr id, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +0000393{
394 struct lsa_header *lsah;
395
396 lsah = (struct lsa_header *) STREAM_DATA (s);
397
Paul Jakma02d942c2010-01-24 23:36:20 +0000398 lsah->ls_age = htons (OSPF_LSA_INITIAL_AGE);
paul718e3742002-12-13 20:15:29 +0000399 lsah->options = options;
400 lsah->type = type;
401 lsah->id = id;
paul68980082003-03-25 05:07:42 +0000402 lsah->adv_router = router_id;
paul718e3742002-12-13 20:15:29 +0000403 lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
404
paul9985f832005-02-09 15:51:56 +0000405 stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +0000406}
David Lamparter6b0655a2014-06-04 06:53:35 +0200407
paul68980082003-03-25 05:07:42 +0000408
paul718e3742002-12-13 20:15:29 +0000409/* router-LSA related functions. */
410/* Get router-LSA flags. */
paul4dadc292005-05-06 21:37:42 +0000411static u_char
paul718e3742002-12-13 20:15:29 +0000412router_lsa_flags (struct ospf_area *area)
413{
414 u_char flags;
415
paul68980082003-03-25 05:07:42 +0000416 flags = area->ospf->flags;
paul718e3742002-12-13 20:15:29 +0000417
418 /* Set virtual link flag. */
419 if (ospf_full_virtual_nbrs (area))
420 SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
421 else
422 /* Just sanity check */
423 UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);
424
425 /* Set Shortcut ABR behabiour flag. */
426 UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
paul68980082003-03-25 05:07:42 +0000427 if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
paul718e3742002-12-13 20:15:29 +0000428 if (!OSPF_IS_AREA_BACKBONE (area))
429 if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
paul68980082003-03-25 05:07:42 +0000430 area->ospf->backbone == NULL) ||
paul718e3742002-12-13 20:15:29 +0000431 area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
432 SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
433
434 /* ASBR can't exit in stub area. */
Greg Troxelfc787e82007-08-06 15:50:20 +0000435 if (area->external_routing == OSPF_AREA_STUB)
paul942b6c12003-06-22 08:22:18 +0000436 UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
437 /* If ASBR set External flag */
438 else if (IS_OSPF_ASBR (area->ospf))
439 SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
440
441 /* Set ABR dependent flags */
442 if (IS_OSPF_ABR (area->ospf))
443 {
444 SET_FLAG (flags, ROUTER_LSA_BORDER);
paul942b6c12003-06-22 08:22:18 +0000445 /* If Area is NSSA and we are both ABR and unconditional translator,
pauld4a53d52003-07-12 21:30:57 +0000446 * set Nt bit to inform other routers.
paul942b6c12003-06-22 08:22:18 +0000447 */
pauld4a53d52003-07-12 21:30:57 +0000448 if ( (area->external_routing == OSPF_AREA_NSSA)
449 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
450 SET_FLAG (flags, ROUTER_LSA_NT);
paul942b6c12003-06-22 08:22:18 +0000451 }
paul718e3742002-12-13 20:15:29 +0000452 return flags;
453}
454
455/* Lookup neighbor other than myself.
456 And check neighbor count,
457 Point-to-Point link must have only 1 neighbor. */
458struct ospf_neighbor *
paul68980082003-03-25 05:07:42 +0000459ospf_nbr_lookup_ptop (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +0000460{
paul718e3742002-12-13 20:15:29 +0000461 struct ospf_neighbor *nbr = NULL;
paul68980082003-03-25 05:07:42 +0000462 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +0000463
464 /* Search neighbor, there must be one of two nbrs. */
paul68980082003-03-25 05:07:42 +0000465 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
466 if ((nbr = rn->info))
467 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000468 if (nbr->state == NSM_Full)
paul68980082003-03-25 05:07:42 +0000469 {
470 route_unlock_node (rn);
471 break;
472 }
paul718e3742002-12-13 20:15:29 +0000473
474 /* PtoP link must have only 1 neighbor. */
paul68980082003-03-25 05:07:42 +0000475 if (ospf_nbr_count (oi, 0) > 1)
paul718e3742002-12-13 20:15:29 +0000476 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
477
478 return nbr;
479}
480
paul88d6cf32005-10-29 12:50:09 +0000481/* Determine cost of link, taking RFC3137 stub-router support into
482 * consideration
483 */
484static u_int16_t
485ospf_link_cost (struct ospf_interface *oi)
486{
487 /* RFC3137 stub router support */
488 if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
489 return oi->output_cost;
490 else
491 return OSPF_OUTPUT_COST_INFINITE;
492}
493
paul718e3742002-12-13 20:15:29 +0000494/* Set a link information. */
paul779adb02006-01-18 15:07:38 +0000495static char
paul718e3742002-12-13 20:15:29 +0000496link_info_set (struct stream *s, struct in_addr id,
497 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
498{
paul779adb02006-01-18 15:07:38 +0000499 /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
500 * vast majority of cases. Some rare routers with lots of links need more.
501 * we try accomodate those here.
502 */
503 if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
504 {
505 size_t ret = OSPF_MAX_LSA_SIZE;
506
507 /* Can we enlarge the stream still? */
508 if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
509 {
510 /* we futz the size here for simplicity, really we need to account
511 * for just:
512 * IP Header - (sizeof (struct ip))
513 * OSPF Header - OSPF_HEADER_SIZE
514 * LSA Header - OSPF_LSA_HEADER_SIZE
515 * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
516 *
517 * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
518 */
519 ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
520 }
521
522 if (ret == OSPF_MAX_LSA_SIZE)
523 {
Paul Jakma53725102009-08-03 16:34:16 +0100524 zlog_warn ("%s: Out of space in LSA stream, left %zd, size %zd",
paul779adb02006-01-18 15:07:38 +0000525 __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
526 return 0;
527 }
528 }
529
paul718e3742002-12-13 20:15:29 +0000530 /* TOS based routing is not supported. */
531 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
532 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
533 stream_putc (s, type); /* Link Type. */
534 stream_putc (s, tos); /* TOS = 0. */
535 stream_putw (s, cost); /* Link Cost. */
paul779adb02006-01-18 15:07:38 +0000536
537 return 1;
paul718e3742002-12-13 20:15:29 +0000538}
539
Andrew J. Schorre4529632006-12-12 19:18:21 +0000540/* Describe Point-to-Point link (Section 12.4.1.1). */
paul4dadc292005-05-06 21:37:42 +0000541static int
paul718e3742002-12-13 20:15:29 +0000542lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
543{
544 int links = 0;
545 struct ospf_neighbor *nbr;
546 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000547 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000548
549 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000550 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
paul718e3742002-12-13 20:15:29 +0000551
paul68980082003-03-25 05:07:42 +0000552 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000553 if (nbr->state == NSM_Full)
554 {
555 /* For unnumbered point-to-point networks, the Link Data field
556 should specify the interface's MIB-II ifIndex value. */
paul779adb02006-01-18 15:07:38 +0000557 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
558 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000559 }
560
Andrew J. Schorre4529632006-12-12 19:18:21 +0000561 /* Regardless of the state of the neighboring router, we must
562 add a Type 3 link (stub network).
563 N.B. Options 1 & 2 share basically the same logic. */
564 masklen2ip (oi->address->prefixlen, &mask);
565 id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
566 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
567 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000568 return links;
569}
570
571/* Describe Broadcast Link. */
paul4dadc292005-05-06 21:37:42 +0000572static int
paul718e3742002-12-13 20:15:29 +0000573lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
574{
575 struct ospf_neighbor *dr;
576 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000577 u_int16_t cost = ospf_link_cost (oi);
578
paul718e3742002-12-13 20:15:29 +0000579 /* Describe Type 3 Link. */
580 if (oi->state == ISM_Waiting)
581 {
Christian Frankecbf435c2014-04-28 11:42:20 +0000582 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
583 zlog_debug ("LSA[Type1]: Interface %s is in state Waiting. "
584 "Adding stub interface", oi->ifp->name);
paul718e3742002-12-13 20:15:29 +0000585 masklen2ip (oi->address->prefixlen, &mask);
586 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000587 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
588 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000589 }
590
591 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
592 /* Describe Type 2 link. */
593 if (dr && (dr->state == NSM_Full ||
594 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
paul68980082003-03-25 05:07:42 +0000595 ospf_nbr_count (oi, NSM_Full) > 0)
paul718e3742002-12-13 20:15:29 +0000596 {
Christian Frankecbf435c2014-04-28 11:42:20 +0000597 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
598 zlog_debug ("LSA[Type1]: Interface %s has a DR. "
599 "Adding transit interface", oi->ifp->name);
paul779adb02006-01-18 15:07:38 +0000600 return link_info_set (s, DR (oi), oi->address->u.prefix4,
601 LSA_LINK_TYPE_TRANSIT, 0, cost);
paul718e3742002-12-13 20:15:29 +0000602 }
603 /* Describe type 3 link. */
604 else
605 {
Christian Frankecbf435c2014-04-28 11:42:20 +0000606 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
607 zlog_debug ("LSA[Type1]: Interface %s has no DR. "
608 "Adding stub interface", oi->ifp->name);
paul718e3742002-12-13 20:15:29 +0000609 masklen2ip (oi->address->prefixlen, &mask);
610 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
paul779adb02006-01-18 15:07:38 +0000611 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
612 oi->output_cost);
paul718e3742002-12-13 20:15:29 +0000613 }
paul718e3742002-12-13 20:15:29 +0000614}
615
paul4dadc292005-05-06 21:37:42 +0000616static int
paul718e3742002-12-13 20:15:29 +0000617lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
618{
619 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000620
paul718e3742002-12-13 20:15:29 +0000621 /* Describe Type 3 Link. */
622 if (oi->state != ISM_Loopback)
623 return 0;
624
625 mask.s_addr = 0xffffffff;
626 id.s_addr = oi->address->u.prefix4.s_addr;
kitty7bd31772016-02-18 21:33:40 -0800627 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
paul718e3742002-12-13 20:15:29 +0000628}
629
630/* Describe Virtual Link. */
paul4dadc292005-05-06 21:37:42 +0000631static int
paul718e3742002-12-13 20:15:29 +0000632lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
633{
634 struct ospf_neighbor *nbr;
paul88d6cf32005-10-29 12:50:09 +0000635 u_int16_t cost = ospf_link_cost (oi);
paul718e3742002-12-13 20:15:29 +0000636
paul718e3742002-12-13 20:15:29 +0000637 if (oi->state == ISM_PointToPoint)
paul68980082003-03-25 05:07:42 +0000638 if ((nbr = ospf_nbr_lookup_ptop (oi)))
paul718e3742002-12-13 20:15:29 +0000639 if (nbr->state == NSM_Full)
640 {
paul779adb02006-01-18 15:07:38 +0000641 return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
642 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
paul718e3742002-12-13 20:15:29 +0000643 }
644
645 return 0;
646}
647
648#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
649
paul7afa08d2002-12-13 20:59:45 +0000650/* this function add for support point-to-multipoint ,see rfc2328
65112.4.1.4.*/
652/* from "edward rrr" <edward_rrr@hotmail.com>
653 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
paul4dadc292005-05-06 21:37:42 +0000654static int
paul68980082003-03-25 05:07:42 +0000655lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
paul7afa08d2002-12-13 20:59:45 +0000656{
657 int links = 0;
658 struct route_node *rn;
659 struct ospf_neighbor *nbr = NULL;
660 struct in_addr id, mask;
paul88d6cf32005-10-29 12:50:09 +0000661 u_int16_t cost = ospf_link_cost (oi);
paul7afa08d2002-12-13 20:59:45 +0000662
663 mask.s_addr = 0xffffffff;
664 id.s_addr = oi->address->u.prefix4.s_addr;
paul779adb02006-01-18 15:07:38 +0000665 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
paul7afa08d2002-12-13 20:59:45 +0000666
paul1cc8f762003-04-05 19:34:32 +0000667 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000668 zlog_debug ("PointToMultipoint: running ptomultip_set");
paul7afa08d2002-12-13 20:59:45 +0000669
670 /* Search neighbor, */
671 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
672 if ((nbr = rn->info) != NULL)
673 /* Ignore myself. */
paul68980082003-03-25 05:07:42 +0000674 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
paul7afa08d2002-12-13 20:59:45 +0000675 if (nbr->state == NSM_Full)
676
677 {
paul779adb02006-01-18 15:07:38 +0000678 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
679 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
paul1cc8f762003-04-05 19:34:32 +0000680 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000681 zlog_debug ("PointToMultipoint: set link to %s",
paul1cc8f762003-04-05 19:34:32 +0000682 inet_ntoa(oi->address->u.prefix4));
paul7afa08d2002-12-13 20:59:45 +0000683 }
684
685 return links;
paul7afa08d2002-12-13 20:59:45 +0000686}
687
paul718e3742002-12-13 20:15:29 +0000688/* Set router-LSA link information. */
paul4dadc292005-05-06 21:37:42 +0000689static int
paul718e3742002-12-13 20:15:29 +0000690router_lsa_link_set (struct stream *s, struct ospf_area *area)
691{
hasso52dc7ee2004-09-23 19:18:23 +0000692 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +0000693 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +0000694 int links = 0;
695
paul1eb8ef22005-04-07 07:30:20 +0000696 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +0000697 {
paul718e3742002-12-13 20:15:29 +0000698 struct interface *ifp = oi->ifp;
699
700 /* Check interface is up, OSPF is enable. */
paul2e3b2e42002-12-13 21:03:13 +0000701 if (if_is_operative (ifp))
paul718e3742002-12-13 20:15:29 +0000702 {
703 if (oi->state != ISM_Down)
704 {
Joakim Tjernlundc81ee5c2012-07-07 17:06:11 +0200705 oi->lsa_pos_beg = links;
paul718e3742002-12-13 20:15:29 +0000706 /* Describe each link. */
707 switch (oi->type)
708 {
709 case OSPF_IFTYPE_POINTOPOINT:
710 links += lsa_link_ptop_set (s, oi);
711 break;
712 case OSPF_IFTYPE_BROADCAST:
713 links += lsa_link_broadcast_set (s, oi);
714 break;
715 case OSPF_IFTYPE_NBMA:
716 links += lsa_link_nbma_set (s, oi);
717 break;
718 case OSPF_IFTYPE_POINTOMULTIPOINT:
paul68980082003-03-25 05:07:42 +0000719 links += lsa_link_ptomp_set (s, oi);
paul718e3742002-12-13 20:15:29 +0000720 break;
721 case OSPF_IFTYPE_VIRTUALLINK:
722 links += lsa_link_virtuallink_set (s, oi);
723 break;
724 case OSPF_IFTYPE_LOOPBACK:
725 links += lsa_link_loopback_set (s, oi);
726 }
Joakim Tjernlundc81ee5c2012-07-07 17:06:11 +0200727 oi->lsa_pos_end = links;
paul718e3742002-12-13 20:15:29 +0000728 }
729 }
730 }
731
732 return links;
733}
734
735/* Set router-LSA body. */
paul4dadc292005-05-06 21:37:42 +0000736static void
paul718e3742002-12-13 20:15:29 +0000737ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
738{
739 unsigned long putp;
740 u_int16_t cnt;
741
742 /* Set flags. */
743 stream_putc (s, router_lsa_flags (area));
744
745 /* Set Zero fields. */
746 stream_putc (s, 0);
747
748 /* Keep pointer to # links. */
paul9985f832005-02-09 15:51:56 +0000749 putp = stream_get_endp(s);
paul718e3742002-12-13 20:15:29 +0000750
751 /* Forward word */
752 stream_putw(s, 0);
753
754 /* Set all link information. */
755 cnt = router_lsa_link_set (s, area);
756
757 /* Set # of links here. */
758 stream_putw_at (s, putp, cnt);
759}
David Lamparter6b0655a2014-06-04 06:53:35 +0200760
paul88d6cf32005-10-29 12:50:09 +0000761static int
762ospf_stub_router_timer (struct thread *t)
763{
764 struct ospf_area *area = THREAD_ARG (t);
765
766 area->t_stub_router = NULL;
767
768 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
769
770 /* clear stub route state and generate router-lsa refresh, don't
771 * clobber an administratively set stub-router state though.
772 */
773 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
774 return 0;
775
776 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
777
Paul Jakmac363d382010-01-24 22:42:13 +0000778 ospf_router_lsa_update_area (area);
paul88d6cf32005-10-29 12:50:09 +0000779
780 return 0;
781}
paul718e3742002-12-13 20:15:29 +0000782
Paul Jakmaf63f06d2011-04-08 12:44:43 +0100783static void
paul88d6cf32005-10-29 12:50:09 +0000784ospf_stub_router_check (struct ospf_area *area)
785{
786 /* area must either be administratively configured to be stub
787 * or startup-time stub-router must be configured and we must in a pre-stub
788 * state.
789 */
790 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
791 {
792 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
793 return;
794 }
795
796 /* not admin-stubbed, check whether startup stubbing is configured and
797 * whether it's not been done yet
798 */
799 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
800 return;
801
802 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
803 {
804 /* stub-router is hence done forever for this area, even if someone
805 * tries configure it (take effect next restart).
806 */
807 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
808 return;
809 }
810
811 /* startup stub-router configured and not yet done */
812 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
813
814 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
815 area->ospf->stub_router_startup_time);
816}
David Lamparter6b0655a2014-06-04 06:53:35 +0200817
paul718e3742002-12-13 20:15:29 +0000818/* Create new router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000819static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000820ospf_router_lsa_new (struct ospf_area *area)
821{
paul68980082003-03-25 05:07:42 +0000822 struct ospf *ospf = area->ospf;
paul718e3742002-12-13 20:15:29 +0000823 struct stream *s;
824 struct lsa_header *lsah;
825 struct ospf_lsa *new;
826 int length;
827
828 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000829 zlog_debug ("LSA[Type1]: Create router-LSA instance");
paul718e3742002-12-13 20:15:29 +0000830
paul88d6cf32005-10-29 12:50:09 +0000831 /* check whether stub-router is desired, and if this is the first
832 * router LSA.
833 */
834 ospf_stub_router_check (area);
835
paul718e3742002-12-13 20:15:29 +0000836 /* Create a stream for LSA. */
837 s = stream_new (OSPF_MAX_LSA_SIZE);
paul718e3742002-12-13 20:15:29 +0000838 /* Set LSA common header fields. */
pauld4a53d52003-07-12 21:30:57 +0000839 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
pauld4a53d52003-07-12 21:30:57 +0000840 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +0000841
842 /* Set router-LSA body fields. */
843 ospf_router_lsa_body_set (s, area);
844
845 /* Set length. */
846 length = stream_get_endp (s);
paul779adb02006-01-18 15:07:38 +0000847 lsah = (struct lsa_header *) STREAM_DATA (s);
paul718e3742002-12-13 20:15:29 +0000848 lsah->length = htons (length);
849
850 /* Now, create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000851 if ( (new = ospf_lsa_new ()) == NULL)
852 {
853 zlog_err ("%s: Unable to create new lsa", __func__);
854 return NULL;
855 }
856
paul718e3742002-12-13 20:15:29 +0000857 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +0000858 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +0000859
860 /* Copy LSA data to store, discard stream. */
861 new->data = ospf_lsa_data_new (length);
862 memcpy (new->data, lsah, length);
863 stream_free (s);
864
865 return new;
866}
867
868/* Originate Router-LSA. */
paul88d6cf32005-10-29 12:50:09 +0000869static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000870ospf_router_lsa_originate (struct ospf_area *area)
871{
872 struct ospf_lsa *new;
paul88d6cf32005-10-29 12:50:09 +0000873
paul718e3742002-12-13 20:15:29 +0000874 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000875 if ( (new = ospf_router_lsa_new (area)) == NULL)
876 {
877 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
878 return NULL;
879 }
paul718e3742002-12-13 20:15:29 +0000880
881 /* Sanity check. */
882 if (new->data->adv_router.s_addr == 0)
883 {
884 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +0000885 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
paul718e3742002-12-13 20:15:29 +0000886 ospf_lsa_discard (new);
887 return NULL;
888 }
889
890 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +0000891 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000892
893 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +0000894 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +0000895
896 /* Flooding new LSA through area. */
897 ospf_flood_through_area (area, NULL, new);
898
899 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
900 {
ajse588f212004-12-08 18:12:06 +0000901 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
David Lampartereed3c482015-03-03 08:51:53 +0100902 new->data->type, inet_ntoa (new->data->id), (void *)new);
paul718e3742002-12-13 20:15:29 +0000903 ospf_lsa_header_dump (new->data);
904 }
905
906 return new;
907}
908
909/* Refresh router-LSA. */
paul4dadc292005-05-06 21:37:42 +0000910static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +0000911ospf_router_lsa_refresh (struct ospf_lsa *lsa)
912{
913 struct ospf_area *area = lsa->area;
914 struct ospf_lsa *new;
915
916 /* Sanity check. */
917 assert (lsa->data);
918
919 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +0000920 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +0000921
Paul Jakmac363d382010-01-24 22:42:13 +0000922 /* Unregister LSA from refresh-list */
923 ospf_refresher_unregister_lsa (area->ospf, lsa);
924
paul718e3742002-12-13 20:15:29 +0000925 /* Create new router-LSA instance. */
paulc24d6022005-11-20 14:54:12 +0000926 if ( (new = ospf_router_lsa_new (area)) == NULL)
927 {
928 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
929 return NULL;
930 }
931
paul718e3742002-12-13 20:15:29 +0000932 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
933
paul68980082003-03-25 05:07:42 +0000934 ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +0000935
936 /* Flood LSA through area. */
937 ospf_flood_through_area (area, NULL, new);
938
939 /* Debug logging. */
940 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
941 {
ajse588f212004-12-08 18:12:06 +0000942 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
paul718e3742002-12-13 20:15:29 +0000943 new->data->type, inet_ntoa (new->data->id));
944 ospf_lsa_header_dump (new->data);
945 }
946
947 return NULL;
948}
949
Paul Jakmac363d382010-01-24 22:42:13 +0000950int
951ospf_router_lsa_update_area (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +0000952{
paul718e3742002-12-13 20:15:29 +0000953 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmac363d382010-01-24 22:42:13 +0000954 zlog_debug ("[router-LSA]: (router-LSA area update)");
paul718e3742002-12-13 20:15:29 +0000955
956 /* Now refresh router-LSA. */
957 if (area->router_lsa_self)
Paul Jakmac363d382010-01-24 22:42:13 +0000958 ospf_lsa_refresh (area->ospf, area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +0000959 /* Newly originate router-LSA. */
960 else
961 ospf_router_lsa_originate (area);
962
963 return 0;
964}
965
paul718e3742002-12-13 20:15:29 +0000966int
Paul Jakmac363d382010-01-24 22:42:13 +0000967ospf_router_lsa_update (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +0000968{
paul1eb8ef22005-04-07 07:30:20 +0000969 struct listnode *node, *nnode;
970 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +0000971
972 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000973 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
paul718e3742002-12-13 20:15:29 +0000974
paul1eb8ef22005-04-07 07:30:20 +0000975 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +0000976 {
paul718e3742002-12-13 20:15:29 +0000977 struct ospf_lsa *lsa = area->router_lsa_self;
978 struct router_lsa *rl;
hassoeb1ce602004-10-08 08:17:22 +0000979 const char *area_str;
paul718e3742002-12-13 20:15:29 +0000980
981 /* Keep Area ID string. */
982 area_str = AREA_NAME (area);
983
984 /* If LSA not exist in this Area, originate new. */
985 if (lsa == NULL)
986 {
987 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000988 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
paul718e3742002-12-13 20:15:29 +0000989
990 ospf_router_lsa_originate (area);
991 }
992 /* If router-ID is changed, Link ID must change.
993 First flush old LSA, then originate new. */
paul68980082003-03-25 05:07:42 +0000994 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +0000995 {
996 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +0000997 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
paul718e3742002-12-13 20:15:29 +0000998 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
Paul Jakmadfbd5172010-04-14 10:32:12 +0100999 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00001000 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001001 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00001002 area->router_lsa_self = NULL;
1003
1004 /* Refresh router-LSA, (not install) and flood through area. */
Paul Jakmac363d382010-01-24 22:42:13 +00001005 ospf_router_lsa_update_area (area);
paul718e3742002-12-13 20:15:29 +00001006 }
1007 else
1008 {
1009 rl = (struct router_lsa *) lsa->data;
1010 /* Refresh router-LSA, (not install) and flood through area. */
paul68980082003-03-25 05:07:42 +00001011 if (rl->flags != ospf->flags)
Paul Jakmac363d382010-01-24 22:42:13 +00001012 ospf_router_lsa_update_area (area);
paul718e3742002-12-13 20:15:29 +00001013 }
1014 }
1015
1016 return 0;
1017}
1018
David Lamparter6b0655a2014-06-04 06:53:35 +02001019
paul718e3742002-12-13 20:15:29 +00001020/* network-LSA related functions. */
1021/* Originate Network-LSA. */
paul4dadc292005-05-06 21:37:42 +00001022static void
paul718e3742002-12-13 20:15:29 +00001023ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1024{
1025 struct in_addr mask;
1026 struct route_node *rn;
1027 struct ospf_neighbor *nbr;
1028
1029 masklen2ip (oi->address->prefixlen, &mask);
1030 stream_put_ipv4 (s, mask.s_addr);
1031
1032 /* The network-LSA lists those routers that are fully adjacent to
1033 the Designated Router; each fully adjacent router is identified by
1034 its OSPF Router ID. The Designated Router includes itself in this
1035 list. RFC2328, Section 12.4.2 */
1036
1037 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1038 if ((nbr = rn->info) != NULL)
1039 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1040 stream_put_ipv4 (s, nbr->router_id.s_addr);
1041}
1042
paul4dadc292005-05-06 21:37:42 +00001043static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001044ospf_network_lsa_new (struct ospf_interface *oi)
1045{
1046 struct stream *s;
1047 struct ospf_lsa *new;
1048 struct lsa_header *lsah;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001049 struct ospf_if_params *oip;
paul718e3742002-12-13 20:15:29 +00001050 int length;
1051
1052 /* If there are no neighbours on this network (the net is stub),
1053 the router does not originate network-LSA (see RFC 12.4.2) */
1054 if (oi->full_nbrs == 0)
1055 return NULL;
1056
1057 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001058 zlog_debug ("LSA[Type2]: Create network-LSA instance");
paul718e3742002-12-13 20:15:29 +00001059
1060 /* Create new stream for LSA. */
1061 s = stream_new (OSPF_MAX_LSA_SIZE);
1062 lsah = (struct lsa_header *) STREAM_DATA (s);
1063
1064 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
paul68980082003-03-25 05:07:42 +00001065 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001066
1067 /* Set network-LSA body fields. */
1068 ospf_network_lsa_body_set (s, oi);
1069
1070 /* Set length. */
1071 length = stream_get_endp (s);
1072 lsah->length = htons (length);
1073
1074 /* Create OSPF LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001075 if ( (new = ospf_lsa_new ()) == NULL)
1076 {
1077 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1078 return NULL;
1079 }
1080
paul718e3742002-12-13 20:15:29 +00001081 new->area = oi->area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001082 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001083
1084 /* Copy LSA to store. */
1085 new->data = ospf_lsa_data_new (length);
1086 memcpy (new->data, lsah, length);
1087 stream_free (s);
Paul Jakma7eb5b472009-10-13 16:13:13 +01001088
1089 /* Remember prior network LSA sequence numbers, even if we stop
1090 * originating one for this oi, to try avoid re-originating LSAs with a
1091 * prior sequence number, and thus speed up adjency forming & convergence.
1092 */
1093 if ((oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4)))
1094 {
1095 new->data->ls_seqnum = oip->network_lsa_seqnum;
1096 new->data->ls_seqnum = lsa_seqnum_increment (new);
1097 }
1098 else
1099 {
1100 oip = ospf_get_if_params (oi->ifp, oi->address->u.prefix4);
1101 ospf_if_update_params (oi->ifp, oi->address->u.prefix4);
1102 }
1103 oip->network_lsa_seqnum = new->data->ls_seqnum;
1104
paul718e3742002-12-13 20:15:29 +00001105 return new;
1106}
1107
1108/* Originate network-LSA. */
Paul Jakmac363d382010-01-24 22:42:13 +00001109void
1110ospf_network_lsa_update (struct ospf_interface *oi)
paul718e3742002-12-13 20:15:29 +00001111{
1112 struct ospf_lsa *new;
Paul Jakmac363d382010-01-24 22:42:13 +00001113
1114 if (oi->network_lsa_self != NULL)
1115 {
1116 ospf_lsa_refresh (oi->ospf, oi->network_lsa_self);
1117 return;
1118 }
1119
paul718e3742002-12-13 20:15:29 +00001120 /* Create new network-LSA instance. */
1121 new = ospf_network_lsa_new (oi);
1122 if (new == NULL)
Paul Jakmac363d382010-01-24 22:42:13 +00001123 return;
paul718e3742002-12-13 20:15:29 +00001124
1125 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001126 new = ospf_lsa_install (oi->ospf, oi, new);
paul718e3742002-12-13 20:15:29 +00001127
1128 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001129 oi->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001130
1131 /* Flooding new LSA through area. */
1132 ospf_flood_through_area (oi->area, NULL, new);
1133
1134 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1135 {
ajse588f212004-12-08 18:12:06 +00001136 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
David Lampartereed3c482015-03-03 08:51:53 +01001137 new->data->type, inet_ntoa (new->data->id), (void *)new);
paul718e3742002-12-13 20:15:29 +00001138 ospf_lsa_header_dump (new->data);
1139 }
1140
Paul Jakmac363d382010-01-24 22:42:13 +00001141 return;
paul718e3742002-12-13 20:15:29 +00001142}
1143
Paul Jakmac363d382010-01-24 22:42:13 +00001144static struct ospf_lsa *
1145ospf_network_lsa_refresh (struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001146{
1147 struct ospf_area *area = lsa->area;
Paul Jakmac363d382010-01-24 22:42:13 +00001148 struct ospf_lsa *new, *new2;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001149 struct ospf_if_params *oip;
Paul Jakma4dd87df2010-04-15 08:11:51 +01001150 struct ospf_interface *oi;
Paul Jakmac363d382010-01-24 22:42:13 +00001151
paul718e3742002-12-13 20:15:29 +00001152 assert (lsa->data);
Paul Jakma4dd87df2010-04-15 08:11:51 +01001153
1154 /* Retrieve the oi for the network LSA */
1155 oi = ospf_if_lookup_by_local_addr (area->ospf, NULL, lsa->data->id);
1156 if (oi == NULL)
1157 {
1158 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1159 {
1160 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh: "
1161 "no oi found, ick, ignoring.",
1162 lsa->data->type, inet_ntoa (lsa->data->id));
1163 ospf_lsa_header_dump (lsa->data);
1164 }
1165 return NULL;
1166 }
paul718e3742002-12-13 20:15:29 +00001167 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00001168 ospf_ls_retransmit_delete_nbr_area (area, lsa);
paul718e3742002-12-13 20:15:29 +00001169
Paul Jakmac363d382010-01-24 22:42:13 +00001170 /* Unregister LSA from refresh-list */
1171 ospf_refresher_unregister_lsa (area->ospf, lsa);
1172
paul718e3742002-12-13 20:15:29 +00001173 /* Create new network-LSA instance. */
1174 new = ospf_network_lsa_new (oi);
1175 if (new == NULL)
Paul Jakmac363d382010-01-24 22:42:13 +00001176 return NULL;
Paul Jakma7eb5b472009-10-13 16:13:13 +01001177
1178 oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4);
1179 assert (oip != NULL);
1180 oip->network_lsa_seqnum = new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001181
Paul Jakmac363d382010-01-24 22:42:13 +00001182 new2 = ospf_lsa_install (area->ospf, oi, new);
1183
1184 assert (new2 == new);
1185
paul718e3742002-12-13 20:15:29 +00001186 /* Flood LSA through aera. */
1187 ospf_flood_through_area (area, NULL, new);
1188
1189 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1190 {
ajse588f212004-12-08 18:12:06 +00001191 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001192 new->data->type, inet_ntoa (new->data->id));
1193 ospf_lsa_header_dump (new->data);
1194 }
1195
Paul Jakmac363d382010-01-24 22:42:13 +00001196 return new;
paul718e3742002-12-13 20:15:29 +00001197}
David Lamparter6b0655a2014-06-04 06:53:35 +02001198
paul4dadc292005-05-06 21:37:42 +00001199static void
paul718e3742002-12-13 20:15:29 +00001200stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1201{
1202 u_int32_t metric;
1203 char *mp;
1204
1205 /* Put 0 metric. TOS metric is not supported. */
1206 metric = htonl (metric_value);
1207 mp = (char *) &metric;
1208 mp++;
1209 stream_put (s, mp, 3);
1210}
1211
1212/* summary-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001213static void
paul718e3742002-12-13 20:15:29 +00001214ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1215 u_int32_t metric)
1216{
1217 struct in_addr mask;
1218
1219 masklen2ip (p->prefixlen, &mask);
1220
1221 /* Put Network Mask. */
1222 stream_put_ipv4 (s, mask.s_addr);
1223
1224 /* Set # TOS. */
1225 stream_putc (s, (u_char) 0);
1226
1227 /* Set metric. */
1228 stream_put_ospf_metric (s, metric);
1229}
1230
paul4dadc292005-05-06 21:37:42 +00001231static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001232ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1233 u_int32_t metric, struct in_addr id)
1234{
1235 struct stream *s;
1236 struct ospf_lsa *new;
1237 struct lsa_header *lsah;
1238 int length;
1239
paulc24d6022005-11-20 14:54:12 +00001240 if (id.s_addr == 0xffffffff)
1241 {
1242 /* Maybe Link State ID not available. */
1243 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1244 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1245 OSPF_SUMMARY_LSA);
1246 return NULL;
1247 }
1248
paul718e3742002-12-13 20:15:29 +00001249 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001250 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001251
1252 /* Create new stream for LSA. */
1253 s = stream_new (OSPF_MAX_LSA_SIZE);
1254 lsah = (struct lsa_header *) STREAM_DATA (s);
1255
paul68980082003-03-25 05:07:42 +00001256 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1257 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001258
1259 /* Set summary-LSA body fields. */
1260 ospf_summary_lsa_body_set (s, p, metric);
1261
1262 /* Set length. */
1263 length = stream_get_endp (s);
1264 lsah->length = htons (length);
1265
1266 /* Create OSPF LSA instance. */
1267 new = ospf_lsa_new ();
1268 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001269 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001270
1271 /* Copy LSA to store. */
1272 new->data = ospf_lsa_data_new (length);
1273 memcpy (new->data, lsah, length);
1274 stream_free (s);
1275
1276 return new;
1277}
1278
1279/* Originate Summary-LSA. */
1280struct ospf_lsa *
1281ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1282 struct ospf_area *area)
1283{
1284 struct ospf_lsa *new;
1285 struct in_addr id;
1286
paul68980082003-03-25 05:07:42 +00001287 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001288
paulc24d6022005-11-20 14:54:12 +00001289 if (id.s_addr == 0xffffffff)
1290 {
1291 /* Maybe Link State ID not available. */
1292 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1293 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1294 OSPF_SUMMARY_LSA);
1295 return NULL;
1296 }
1297
paul718e3742002-12-13 20:15:29 +00001298 /* Create new summary-LSA instance. */
paulc24d6022005-11-20 14:54:12 +00001299 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1300 return NULL;
paul718e3742002-12-13 20:15:29 +00001301
1302 /* Instlal LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001303 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001304
1305 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001306 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001307
1308 /* Flooding new LSA through area. */
1309 ospf_flood_through_area (area, NULL, new);
1310
1311 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1312 {
ajse588f212004-12-08 18:12:06 +00001313 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
David Lampartereed3c482015-03-03 08:51:53 +01001314 new->data->type, inet_ntoa (new->data->id), (void *)new);
paul718e3742002-12-13 20:15:29 +00001315 ospf_lsa_header_dump (new->data);
1316 }
1317
1318 return new;
1319}
1320
Paul Jakmac363d382010-01-24 22:42:13 +00001321static struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001322ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001323{
1324 struct ospf_lsa *new;
1325 struct summary_lsa *sl;
1326 struct prefix p;
1327
1328 /* Sanity check. */
1329 assert (lsa->data);
1330
1331 sl = (struct summary_lsa *)lsa->data;
1332 p.prefixlen = ip_masklen (sl->mask);
1333 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1334 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001335
1336 if (!new)
1337 return NULL;
1338
paul718e3742002-12-13 20:15:29 +00001339 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001340
paul68980082003-03-25 05:07:42 +00001341 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001342
1343 /* Flood LSA through AS. */
1344 ospf_flood_through_area (new->area, NULL, new);
1345
1346 /* Debug logging. */
1347 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1348 {
ajse588f212004-12-08 18:12:06 +00001349 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001350 new->data->type, inet_ntoa (new->data->id));
1351 ospf_lsa_header_dump (new->data);
1352 }
1353
1354 return new;
1355}
1356
David Lamparter6b0655a2014-06-04 06:53:35 +02001357
paul718e3742002-12-13 20:15:29 +00001358/* summary-ASBR-LSA related functions. */
paul4dadc292005-05-06 21:37:42 +00001359static void
paul718e3742002-12-13 20:15:29 +00001360ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1361 u_int32_t metric)
1362{
paul718e3742002-12-13 20:15:29 +00001363 /* Put Network Mask. */
Leonard Tracy2345a222012-12-04 11:02:35 -08001364 stream_put_ipv4 (s, (u_int32_t) 0);
paul718e3742002-12-13 20:15:29 +00001365
1366 /* Set # TOS. */
1367 stream_putc (s, (u_char) 0);
1368
1369 /* Set metric. */
1370 stream_put_ospf_metric (s, metric);
1371}
1372
paul4dadc292005-05-06 21:37:42 +00001373static struct ospf_lsa *
paul718e3742002-12-13 20:15:29 +00001374ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1375 u_int32_t metric, struct in_addr id)
1376{
1377 struct stream *s;
1378 struct ospf_lsa *new;
1379 struct lsa_header *lsah;
1380 int length;
1381
paulc24d6022005-11-20 14:54:12 +00001382 if (id.s_addr == 0xffffffff)
1383 {
1384 /* Maybe Link State ID not available. */
1385 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1386 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1387 OSPF_ASBR_SUMMARY_LSA);
1388 return NULL;
1389 }
1390
paul718e3742002-12-13 20:15:29 +00001391 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001392 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
paul718e3742002-12-13 20:15:29 +00001393
1394 /* Create new stream for LSA. */
1395 s = stream_new (OSPF_MAX_LSA_SIZE);
1396 lsah = (struct lsa_header *) STREAM_DATA (s);
1397
paul68980082003-03-25 05:07:42 +00001398 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1399 id, area->ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001400
1401 /* Set summary-LSA body fields. */
1402 ospf_summary_asbr_lsa_body_set (s, p, metric);
1403
1404 /* Set length. */
1405 length = stream_get_endp (s);
1406 lsah->length = htons (length);
1407
1408 /* Create OSPF LSA instance. */
1409 new = ospf_lsa_new ();
1410 new->area = area;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001411 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001412
1413 /* Copy LSA to store. */
1414 new->data = ospf_lsa_data_new (length);
1415 memcpy (new->data, lsah, length);
1416 stream_free (s);
1417
1418 return new;
1419}
1420
1421/* Originate summary-ASBR-LSA. */
1422struct ospf_lsa *
1423ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1424 struct ospf_area *area)
1425{
1426 struct ospf_lsa *new;
1427 struct in_addr id;
1428
paul68980082003-03-25 05:07:42 +00001429 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
paul718e3742002-12-13 20:15:29 +00001430
paulc24d6022005-11-20 14:54:12 +00001431 if (id.s_addr == 0xffffffff)
1432 {
1433 /* Maybe Link State ID not available. */
1434 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1435 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1436 OSPF_ASBR_SUMMARY_LSA);
1437 return NULL;
1438 }
1439
paul718e3742002-12-13 20:15:29 +00001440 /* Create new summary-LSA instance. */
1441 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
paulc24d6022005-11-20 14:54:12 +00001442 if (!new)
1443 return NULL;
paul718e3742002-12-13 20:15:29 +00001444
1445 /* Install LSA to LSDB. */
paul68980082003-03-25 05:07:42 +00001446 new = ospf_lsa_install (area->ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001447
1448 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00001449 area->ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00001450
1451 /* Flooding new LSA through area. */
1452 ospf_flood_through_area (area, NULL, new);
1453
1454 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1455 {
ajse588f212004-12-08 18:12:06 +00001456 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
David Lampartereed3c482015-03-03 08:51:53 +01001457 new->data->type, inet_ntoa (new->data->id), (void *)new);
paul718e3742002-12-13 20:15:29 +00001458 ospf_lsa_header_dump (new->data);
1459 }
1460
1461 return new;
1462}
1463
Paul Jakmac363d382010-01-24 22:42:13 +00001464static struct ospf_lsa*
paul68980082003-03-25 05:07:42 +00001465ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00001466{
1467 struct ospf_lsa *new;
1468 struct summary_lsa *sl;
1469 struct prefix p;
1470
1471 /* Sanity check. */
1472 assert (lsa->data);
1473
1474 sl = (struct summary_lsa *)lsa->data;
1475 p.prefixlen = ip_masklen (sl->mask);
1476 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1477 sl->header.id);
paulc24d6022005-11-20 14:54:12 +00001478 if (!new)
1479 return NULL;
paul718e3742002-12-13 20:15:29 +00001480
1481 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
paul718e3742002-12-13 20:15:29 +00001482
paul68980082003-03-25 05:07:42 +00001483 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00001484
1485 /* Flood LSA through area. */
1486 ospf_flood_through_area (new->area, NULL, new);
1487
1488 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1489 {
ajse588f212004-12-08 18:12:06 +00001490 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
paul718e3742002-12-13 20:15:29 +00001491 new->data->type, inet_ntoa (new->data->id));
1492 ospf_lsa_header_dump (new->data);
1493 }
1494
1495 return new;
1496}
1497
1498/* AS-external-LSA related functions. */
1499
1500/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1501 is connected, else 0*/
paul4dadc292005-05-06 21:37:42 +00001502static struct in_addr
paul68980082003-03-25 05:07:42 +00001503ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
paul718e3742002-12-13 20:15:29 +00001504{
1505 struct in_addr fwd;
1506 struct prefix nh;
paul1eb8ef22005-04-07 07:30:20 +00001507 struct listnode *node;
1508 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001509
1510 fwd.s_addr = 0;
1511
1512 if (!nexthop.s_addr)
1513 return fwd;
1514
1515 /* Check whether nexthop is covered by OSPF network. */
1516 nh.family = AF_INET;
1517 nh.u.prefix4 = nexthop;
1518 nh.prefixlen = IPV4_MAX_BITLEN;
Paul Jakma4ca15d42009-08-03 15:16:41 +01001519
1520 /* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be
1521 * better to make use of the per-ifp table of ois.
1522 */
paul1eb8ef22005-04-07 07:30:20 +00001523 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1524 if (if_is_operative (oi->ifp))
1525 if (oi->address->family == AF_INET)
1526 if (prefix_match (oi->address, &nh))
1527 return nexthop;
paul718e3742002-12-13 20:15:29 +00001528
1529 return fwd;
1530}
1531
paul718e3742002-12-13 20:15:29 +00001532/* NSSA-external-LSA related functions. */
1533
1534/* Get 1st IP connection for Forward Addr */
paul4dadc292005-05-06 21:37:42 +00001535
paul718e3742002-12-13 20:15:29 +00001536struct in_addr
1537ospf_get_ip_from_ifp (struct ospf_interface *oi)
1538{
1539 struct in_addr fwd;
1540
1541 fwd.s_addr = 0;
1542
paul2e3b2e42002-12-13 21:03:13 +00001543 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001544 return oi->address->u.prefix4;
1545
1546 return fwd;
1547}
1548
1549/* Get 1st IP connection for Forward Addr */
1550struct in_addr
paulf2c80652002-12-13 21:44:27 +00001551ospf_get_nssa_ip (struct ospf_area *area)
paul718e3742002-12-13 20:15:29 +00001552{
1553 struct in_addr fwd;
paulf2c80652002-12-13 21:44:27 +00001554 struct in_addr best_default;
paul1eb8ef22005-04-07 07:30:20 +00001555 struct listnode *node;
1556 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00001557
1558 fwd.s_addr = 0;
paulf2c80652002-12-13 21:44:27 +00001559 best_default.s_addr = 0;
paul718e3742002-12-13 20:15:29 +00001560
paul1eb8ef22005-04-07 07:30:20 +00001561 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00001562 {
paul2e3b2e42002-12-13 21:03:13 +00001563 if (if_is_operative (oi->ifp))
paul718e3742002-12-13 20:15:29 +00001564 if (oi->area->external_routing == OSPF_AREA_NSSA)
paul68980082003-03-25 05:07:42 +00001565 if (oi->address && oi->address->family == AF_INET)
1566 {
1567 if (best_default.s_addr == 0)
1568 best_default = oi->address->u.prefix4;
1569 if (oi->area == area)
1570 return oi->address->u.prefix4;
paulf2c80652002-12-13 21:44:27 +00001571 }
paul718e3742002-12-13 20:15:29 +00001572 }
paulf2c80652002-12-13 21:44:27 +00001573 if (best_default.s_addr != 0)
1574 return best_default;
paul718e3742002-12-13 20:15:29 +00001575
paul68980082003-03-25 05:07:42 +00001576 if (best_default.s_addr != 0)
1577 return best_default;
1578
paul718e3742002-12-13 20:15:29 +00001579 return fwd;
1580}
hassobeebba72004-06-20 21:00:27 +00001581
paul718e3742002-12-13 20:15:29 +00001582#define DEFAULT_DEFAULT_METRIC 20
1583#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1584#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1585
1586#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1587
1588int
paul68980082003-03-25 05:07:42 +00001589metric_type (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001590{
paul68980082003-03-25 05:07:42 +00001591 return (ospf->dmetric[src].type < 0 ?
1592 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
paul718e3742002-12-13 20:15:29 +00001593}
1594
1595int
paul68980082003-03-25 05:07:42 +00001596metric_value (struct ospf *ospf, u_char src)
paul718e3742002-12-13 20:15:29 +00001597{
paul68980082003-03-25 05:07:42 +00001598 if (ospf->dmetric[src].value < 0)
paul718e3742002-12-13 20:15:29 +00001599 {
1600 if (src == DEFAULT_ROUTE)
1601 {
paul68980082003-03-25 05:07:42 +00001602 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
paul718e3742002-12-13 20:15:29 +00001603 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1604 else
1605 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1606 }
paul68980082003-03-25 05:07:42 +00001607 else if (ospf->default_metric < 0)
paul718e3742002-12-13 20:15:29 +00001608 return DEFAULT_DEFAULT_METRIC;
1609 else
paul68980082003-03-25 05:07:42 +00001610 return ospf->default_metric;
paul718e3742002-12-13 20:15:29 +00001611 }
1612
paul68980082003-03-25 05:07:42 +00001613 return ospf->dmetric[src].value;
paul718e3742002-12-13 20:15:29 +00001614}
1615
1616/* Set AS-external-LSA body. */
paul4dadc292005-05-06 21:37:42 +00001617static void
paul68980082003-03-25 05:07:42 +00001618ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1619 struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00001620{
1621 struct prefix_ipv4 *p = &ei->p;
1622 struct in_addr mask, fwd_addr;
1623 u_int32_t mvalue;
1624 int mtype;
1625 int type;
1626
1627 /* Put Network Mask. */
1628 masklen2ip (p->prefixlen, &mask);
1629 stream_put_ipv4 (s, mask.s_addr);
1630
1631 /* If prefix is default, specify DEFAULT_ROUTE. */
1632 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1633
1634 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001635 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
paul718e3742002-12-13 20:15:29 +00001636
1637 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
paul68980082003-03-25 05:07:42 +00001638 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
paul718e3742002-12-13 20:15:29 +00001639
1640 /* Put type of external metric. */
1641 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1642
1643 /* Put 0 metric. TOS metric is not supported. */
1644 stream_put_ospf_metric (s, mvalue);
1645
1646 /* Get forwarding address to nexthop if on the Connection List, else 0. */
paul68980082003-03-25 05:07:42 +00001647 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
paul718e3742002-12-13 20:15:29 +00001648
1649 /* Put forwarding address. */
1650 stream_put_ipv4 (s, fwd_addr.s_addr);
1651
Paul Jakma96d10602016-07-01 14:23:45 +01001652 /* Put route tag */
Piotr Chytła2b2e38c2015-12-01 10:10:41 -05001653 stream_putl (s, ei->tag);
paul718e3742002-12-13 20:15:29 +00001654}
1655
1656/* Create new external-LSA. */
paul4dadc292005-05-06 21:37:42 +00001657static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00001658ospf_external_lsa_new (struct ospf *ospf,
1659 struct external_info *ei, struct in_addr *old_id)
paul718e3742002-12-13 20:15:29 +00001660{
1661 struct stream *s;
1662 struct lsa_header *lsah;
1663 struct ospf_lsa *new;
1664 struct in_addr id;
1665 int length;
1666
1667 if (ei == NULL)
1668 {
1669 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
Denis Ovsienkoad8d4802011-12-02 20:02:40 +04001670 zlog_debug ("LSA[Type5]: External info is NULL, can't originate");
paul718e3742002-12-13 20:15:29 +00001671 return NULL;
1672 }
1673
1674 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001675 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
paul718e3742002-12-13 20:15:29 +00001676
1677 /* If old Link State ID is specified, refresh LSA with same ID. */
1678 if (old_id)
1679 id = *old_id;
1680 /* Get Link State with unique ID. */
1681 else
1682 {
paul68980082003-03-25 05:07:42 +00001683 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
paul718e3742002-12-13 20:15:29 +00001684 if (id.s_addr == 0xffffffff)
1685 {
1686 /* Maybe Link State ID not available. */
1687 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00001688 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
paul718e3742002-12-13 20:15:29 +00001689 return NULL;
1690 }
1691 }
1692
1693 /* Create new stream for LSA. */
1694 s = stream_new (OSPF_MAX_LSA_SIZE);
1695 lsah = (struct lsa_header *) STREAM_DATA (s);
1696
1697 /* Set LSA common header fields. */
paul68980082003-03-25 05:07:42 +00001698 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1699 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00001700
1701 /* Set AS-external-LSA body fields. */
paul68980082003-03-25 05:07:42 +00001702 ospf_external_lsa_body_set (s, ei, ospf);
paul718e3742002-12-13 20:15:29 +00001703
1704 /* Set length. */
1705 length = stream_get_endp (s);
1706 lsah->length = htons (length);
1707
1708 /* Now, create OSPF LSA instance. */
1709 new = ospf_lsa_new ();
1710 new->area = NULL;
Joakim Tjernlundf6543132008-11-04 13:37:29 +00001711 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
paul718e3742002-12-13 20:15:29 +00001712
1713 /* Copy LSA data to store, discard stream. */
1714 new->data = ospf_lsa_data_new (length);
1715 memcpy (new->data, lsah, length);
1716 stream_free (s);
1717
1718 return new;
1719}
1720
paul718e3742002-12-13 20:15:29 +00001721/* As Type-7 */
paul4dadc292005-05-06 21:37:42 +00001722static void
paul68980082003-03-25 05:07:42 +00001723ospf_install_flood_nssa (struct ospf *ospf,
1724 struct ospf_lsa *lsa, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00001725{
pauld4a53d52003-07-12 21:30:57 +00001726 struct ospf_lsa *new;
paul68980082003-03-25 05:07:42 +00001727 struct as_external_lsa *extlsa;
paul1eb8ef22005-04-07 07:30:20 +00001728 struct ospf_area *area;
1729 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00001730
pauld4a53d52003-07-12 21:30:57 +00001731 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1732 * which originated from an NSSA area. In which case it should not be
1733 * flooded back to NSSA areas.
1734 */
1735 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1736 return;
1737
paul718e3742002-12-13 20:15:29 +00001738 /* NSSA Originate or Refresh (If anyNSSA)
1739
1740 LSA is self-originated. And just installed as Type-5.
1741 Additionally, install as Type-7 LSDB for every attached NSSA.
1742
1743 P-Bit controls which ABR performs translation to outside world; If
1744 we are an ABR....do not set the P-bit, because we send the Type-5,
1745 not as the ABR Translator, but as the ASBR owner within the AS!
1746
1747 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1748 elected ABR Translator will see the P-bit, Translate, and re-flood.
1749
1750 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1751 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1752
paul1eb8ef22005-04-07 07:30:20 +00001753 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul68980082003-03-25 05:07:42 +00001754 {
hasso0c14ad82003-07-03 08:36:02 +00001755 /* Don't install Type-7 LSA's into nonNSSA area */
1756 if (area->external_routing != OSPF_AREA_NSSA)
1757 continue;
paul718e3742002-12-13 20:15:29 +00001758
paul68980082003-03-25 05:07:42 +00001759 /* make lsa duplicate, lock=1 */
pauld4a53d52003-07-12 21:30:57 +00001760 new = ospf_lsa_dup (lsa);
1761 new->area = area;
1762 new->data->type = OSPF_AS_NSSA_LSA;
paul718e3742002-12-13 20:15:29 +00001763
paul68980082003-03-25 05:07:42 +00001764 /* set P-bit if not ABR */
paul020709f2003-04-04 02:44:16 +00001765 if (! IS_OSPF_ABR (ospf))
paul68980082003-03-25 05:07:42 +00001766 {
pauld4a53d52003-07-12 21:30:57 +00001767 SET_FLAG(new->data->options, OSPF_OPTION_NP);
paul68980082003-03-25 05:07:42 +00001768
1769 /* set non-zero FWD ADDR
1770
1771 draft-ietf-ospf-nssa-update-09.txt
1772
1773 if the network between the NSSA AS boundary router and the
1774 adjacent AS is advertised into OSPF as an internal OSPF route,
1775 the forwarding address should be the next op address as is cu
1776 currently done with type-5 LSAs. If the intervening network is
1777 not adversited into OSPF as an internal OSPF route and the
1778 type-7 LSA's P-bit is set a forwarding address should be
1779 selected from one of the router's active OSPF inteface addresses
1780 which belong to the NSSA. If no such addresses exist, then
1781 no type-7 LSA's with the P-bit set should originate from this
1782 router. */
1783
pauld4a53d52003-07-12 21:30:57 +00001784 /* kevinm: not updating lsa anymore, just new */
1785 extlsa = (struct as_external_lsa *)(new->data);
paul68980082003-03-25 05:07:42 +00001786
1787 if (extlsa->e[0].fwd_addr.s_addr == 0)
1788 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
paul718e3742002-12-13 20:15:29 +00001789
pauld7480322003-05-16 17:31:51 +00001790 if (extlsa->e[0].fwd_addr.s_addr == 0)
1791 {
1792 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001793 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
Paul Jakma1fe6ed32006-07-26 09:37:26 +00001794 ospf_lsa_discard (new);
pauld7480322003-05-16 17:31:51 +00001795 return;
1796 }
paulf2c80652002-12-13 21:44:27 +00001797 }
paul718e3742002-12-13 20:15:29 +00001798
paul68980082003-03-25 05:07:42 +00001799 /* install also as Type-7 */
pauld4a53d52003-07-12 21:30:57 +00001800 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
paul68980082003-03-25 05:07:42 +00001801
1802 /* will send each copy, lock=2+n */
pauld4a53d52003-07-12 21:30:57 +00001803 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
paul68980082003-03-25 05:07:42 +00001804 }
paul718e3742002-12-13 20:15:29 +00001805}
pauld4a53d52003-07-12 21:30:57 +00001806
paul4dadc292005-05-06 21:37:42 +00001807static struct ospf_lsa *
pauld4a53d52003-07-12 21:30:57 +00001808ospf_lsa_translated_nssa_new (struct ospf *ospf,
1809 struct ospf_lsa *type7)
1810{
1811
1812 struct ospf_lsa *new;
1813 struct as_external_lsa *ext, *extnew;
1814 struct external_info ei;
1815
1816 ext = (struct as_external_lsa *)(type7->data);
1817
1818 /* need external_info struct, fill in bare minimum */
1819 ei.p.family = AF_INET;
1820 ei.p.prefix = type7->data->id;
1821 ei.p.prefixlen = ip_masklen (ext->mask);
1822 ei.type = ZEBRA_ROUTE_OSPF;
1823 ei.nexthop = ext->header.adv_router;
1824 ei.route_map_set.metric = -1;
1825 ei.route_map_set.metric_type = -1;
1826 ei.tag = 0;
1827
1828 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1829 {
1830 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001831 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
pauld4a53d52003-07-12 21:30:57 +00001832 "Translated Type-5 for %s",
1833 inet_ntoa (ei.p.prefix));
1834 return NULL;
1835 }
1836
1837 extnew = (struct as_external_lsa *)(new->data);
1838
1839 /* copy over Type-7 data to new */
1840 extnew->e[0].tos = ext->e[0].tos;
1841 extnew->e[0].route_tag = ext->e[0].route_tag;
1842 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1843 new->data->ls_seqnum = type7->data->ls_seqnum;
1844
1845 /* add translated flag, checksum and lock new lsa */
1846 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
pauld4a53d52003-07-12 21:30:57 +00001847 new = ospf_lsa_lock (new);
1848
1849 return new;
1850}
1851
pauld4a53d52003-07-12 21:30:57 +00001852/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1853struct ospf_lsa *
1854ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1855{
1856 struct ospf_lsa *new;
1857 struct as_external_lsa *extnew;
1858
1859 /* we cant use ospf_external_lsa_originate() as we need to set
1860 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1861 */
1862
1863 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1864 {
1865 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001866 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001867 "Type-7, Id %s, to Type-5",
1868 inet_ntoa (type7->data->id));
1869 return NULL;
1870 }
1871
1872 extnew = (struct as_external_lsa *)new;
1873
1874 if (IS_DEBUG_OSPF_NSSA)
1875 {
ajse588f212004-12-08 18:12:06 +00001876 zlog_debug ("ospf_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001877 "translated Type 7, installed:");
1878 ospf_lsa_header_dump (new->data);
ajse588f212004-12-08 18:12:06 +00001879 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1880 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
pauld4a53d52003-07-12 21:30:57 +00001881 }
1882
1883 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1884 {
Hasso Tepper8c9ed272012-10-11 11:15:18 +00001885 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001886 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
pauld4a53d52003-07-12 21:30:57 +00001887 "Could not install LSA "
1888 "id %s", inet_ntoa (type7->data->id));
1889 return NULL;
1890 }
1891
1892 ospf->lsa_originate_count++;
1893 ospf_flood_through_as (ospf, NULL, new);
1894
1895 return new;
1896}
1897
1898/* Refresh Translated from NSSA AS-external-LSA. */
1899struct ospf_lsa *
1900ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1901 struct ospf_lsa *type5)
1902{
1903 struct ospf_lsa *new = NULL;
1904
1905 /* Sanity checks. */
1906 assert (type7 || type5);
Paul Jakmaae128052006-05-12 23:15:30 +00001907 if (!(type7 || type5))
Paul Jakmae54e6e52006-05-12 23:11:14 +00001908 return NULL;
pauld4a53d52003-07-12 21:30:57 +00001909 if (type7)
1910 assert (type7->data);
1911 if (type5)
1912 assert (type5->data);
1913 assert (ospf->anyNSSA);
1914
1915 /* get required data according to what has been given */
1916 if (type7 && type5 == NULL)
1917 {
1918 /* find the translated Type-5 for this Type-7 */
1919 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1920 struct prefix_ipv4 p =
1921 {
1922 .prefix = type7->data->id,
1923 .prefixlen = ip_masklen (ext->mask),
1924 .family = AF_INET,
1925 };
1926
1927 type5 = ospf_external_info_find_lsa (ospf, &p);
1928 }
1929 else if (type5 && type7 == NULL)
1930 {
1931 /* find the type-7 from which supplied type-5 was translated,
1932 * ie find first type-7 with same LSA Id.
1933 */
paul1eb8ef22005-04-07 07:30:20 +00001934 struct listnode *ln, *lnn;
pauld4a53d52003-07-12 21:30:57 +00001935 struct route_node *rn;
1936 struct ospf_lsa *lsa;
1937 struct ospf_area *area;
1938
paul1eb8ef22005-04-07 07:30:20 +00001939 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
pauld4a53d52003-07-12 21:30:57 +00001940 {
1941 if (area->external_routing != OSPF_AREA_NSSA
1942 && !type7)
1943 continue;
1944
1945 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
1946 {
1947 if (lsa->data->id.s_addr == type5->data->id.s_addr)
1948 {
1949 type7 = lsa;
1950 break;
1951 }
1952 }
1953 }
1954 }
1955
1956 /* do we have type7? */
1957 if (!type7)
1958 {
1959 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001960 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
pauld4a53d52003-07-12 21:30:57 +00001961 "Type-5 LSA Id %s",
Paul Jakmae54e6e52006-05-12 23:11:14 +00001962 inet_ntoa (type5->data->id));
pauld4a53d52003-07-12 21:30:57 +00001963 return NULL;
1964 }
1965
1966 /* do we have valid translated type5? */
1967 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
1968 {
1969 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001970 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
pauld4a53d52003-07-12 21:30:57 +00001971 "found for Type-7 with Id %s",
1972 inet_ntoa (type7->data->id));
1973 return NULL;
1974 }
1975
1976 /* Delete LSA from neighbor retransmit-list. */
1977 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
1978
1979 /* create new translated LSA */
1980 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1981 {
1982 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001983 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
pauld4a53d52003-07-12 21:30:57 +00001984 "Type-7 for %s to Type-5",
1985 inet_ntoa (type7->data->id));
1986 return NULL;
1987 }
1988
1989 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
1990 {
1991 if (IS_DEBUG_OSPF_NSSA)
ajse588f212004-12-08 18:12:06 +00001992 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
pauld4a53d52003-07-12 21:30:57 +00001993 "translated LSA, Id %s",
Paul Jakma5db95bc2006-07-04 13:52:29 +00001994 inet_ntoa (type7->data->id));
pauld4a53d52003-07-12 21:30:57 +00001995 return NULL;
1996 }
1997
1998 /* Flood LSA through area. */
1999 ospf_flood_through_as (ospf, NULL, new);
2000
2001 return new;
2002}
paul718e3742002-12-13 20:15:29 +00002003
2004int
2005is_prefix_default (struct prefix_ipv4 *p)
2006{
2007 struct prefix_ipv4 q;
2008
2009 q.family = AF_INET;
2010 q.prefix.s_addr = 0;
2011 q.prefixlen = 0;
2012
2013 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
2014}
2015
2016/* Originate an AS-external-LSA, install and flood. */
2017struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002018ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
paul718e3742002-12-13 20:15:29 +00002019{
2020 struct ospf_lsa *new;
2021
2022 /* Added for NSSA project....
2023
2024 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2025 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2026 every area. The Type-7's are flooded to every IR and every ABR; We
2027 install the Type-5 LSDB so that the normal "refresh" code operates
2028 as usual, and flag them as not used during ASE calculations. The
2029 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2030 Address of non-zero.
2031
2032 If an ABR is the elected NSSA translator, following SPF and during
2033 the ABR task it will translate all the scanned Type-7's, with P-bit
2034 ON and not-self generated, and translate to Type-5's throughout the
2035 non-NSSA/STUB AS.
2036
2037 A difference in operation depends whether this ASBR is an ABR
2038 or not. If not an ABR, the P-bit is ON, to indicate that any
2039 elected NSSA-ABR can perform its translation.
2040
2041 If an ABR, the P-bit is OFF; No ABR will perform translation and
2042 this ASBR will flood the Type-5 LSA as usual.
2043
2044 For the case where this ASBR is not an ABR, the ASE calculations
2045 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2046 demonstrate to the user that there are LSA's that belong to any
2047 attached NSSA.
2048
2049 Finally, it just so happens that when the ABR is translating every
2050 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2051 approved Type-5 (translated from Type-7); at the end of translation
2052 if any Translated Type-5's remain unapproved, then they must be
2053 flushed from the AS.
2054
2055 */
2056
2057 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002058 if (!ospf_redistribute_check (ospf, ei, NULL))
paul718e3742002-12-13 20:15:29 +00002059 return NULL;
2060
2061 /* Create new AS-external-LSA instance. */
paul68980082003-03-25 05:07:42 +00002062 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
paul718e3742002-12-13 20:15:29 +00002063 {
2064 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002065 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
paul718e3742002-12-13 20:15:29 +00002066 inet_ntoa (ei->p.prefix));
2067 return NULL;
2068 }
2069
2070 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
paul68980082003-03-25 05:07:42 +00002071 ospf_lsa_install (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002072
2073 /* Update LSA origination count. */
paul68980082003-03-25 05:07:42 +00002074 ospf->lsa_originate_count++;
paul718e3742002-12-13 20:15:29 +00002075
2076 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
paul68980082003-03-25 05:07:42 +00002077 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002078
paul718e3742002-12-13 20:15:29 +00002079 /* If there is any attached NSSA, do special handling */
pauld4a53d52003-07-12 21:30:57 +00002080 if (ospf->anyNSSA &&
2081 /* stay away from translated LSAs! */
2082 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002083 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
paul718e3742002-12-13 20:15:29 +00002084
2085 /* Debug logging. */
2086 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2087 {
ajse588f212004-12-08 18:12:06 +00002088 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
David Lampartereed3c482015-03-03 08:51:53 +01002089 new->data->type, inet_ntoa (new->data->id), (void *)new);
paul718e3742002-12-13 20:15:29 +00002090 ospf_lsa_header_dump (new->data);
2091 }
2092
2093 return new;
2094}
2095
2096/* Originate AS-external-LSA from external info with initial flag. */
2097int
paul68980082003-03-25 05:07:42 +00002098ospf_external_lsa_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002099{
paul68980082003-03-25 05:07:42 +00002100 struct ospf *ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002101 struct route_node *rn;
2102 struct external_info *ei;
2103 struct route_table *rt;
paul68980082003-03-25 05:07:42 +00002104 int type = THREAD_VAL (thread);
paul718e3742002-12-13 20:15:29 +00002105
paul68980082003-03-25 05:07:42 +00002106 ospf->t_external_lsa = NULL;
paul718e3742002-12-13 20:15:29 +00002107
2108 /* Originate As-external-LSA from all type of distribute source. */
2109 if ((rt = EXTERNAL_INFO (type)))
2110 for (rn = route_top (rt); rn; rn = route_next (rn))
2111 if ((ei = rn->info) != NULL)
2112 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
paul68980082003-03-25 05:07:42 +00002113 if (!ospf_external_lsa_originate (ospf, ei))
paul718e3742002-12-13 20:15:29 +00002114 zlog_warn ("LSA: AS-external-LSA was not originated.");
2115
2116 return 0;
2117}
2118
paul4dadc292005-05-06 21:37:42 +00002119static struct external_info *
paul020709f2003-04-04 02:44:16 +00002120ospf_default_external_info (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002121{
2122 int type;
2123 struct route_node *rn;
2124 struct prefix_ipv4 p;
2125
2126 p.family = AF_INET;
2127 p.prefix.s_addr = 0;
2128 p.prefixlen = 0;
2129
2130 /* First, lookup redistributed default route. */
2131 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2132 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2133 {
2134 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2135 if (rn != NULL)
2136 {
2137 route_unlock_node (rn);
2138 assert (rn->info);
paul68980082003-03-25 05:07:42 +00002139 if (ospf_redistribute_check (ospf, rn->info, NULL))
paul718e3742002-12-13 20:15:29 +00002140 return rn->info;
2141 }
2142 }
2143
2144 return NULL;
2145}
2146
2147int
paul68980082003-03-25 05:07:42 +00002148ospf_default_originate_timer (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00002149{
paul718e3742002-12-13 20:15:29 +00002150 struct prefix_ipv4 p;
2151 struct in_addr nexthop;
2152 struct external_info *ei;
paul020709f2003-04-04 02:44:16 +00002153 struct ospf *ospf;
paul718e3742002-12-13 20:15:29 +00002154
Paul Jakma4021b602006-05-12 22:55:41 +00002155 ospf = THREAD_ARG (thread);
paul718e3742002-12-13 20:15:29 +00002156
2157 p.family = AF_INET;
2158 p.prefix.s_addr = 0;
2159 p.prefixlen = 0;
2160
Paul Jakma4021b602006-05-12 22:55:41 +00002161 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
paul718e3742002-12-13 20:15:29 +00002162 {
2163 /* If there is no default route via redistribute,
2164 then originate AS-external-LSA with nexthop 0 (self). */
2165 nexthop.s_addr = 0;
Piotr Chytła2b2e38c2015-12-01 10:10:41 -05002166 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop, 0);
paul718e3742002-12-13 20:15:29 +00002167 }
2168
paul020709f2003-04-04 02:44:16 +00002169 if ((ei = ospf_default_external_info (ospf)))
paul68980082003-03-25 05:07:42 +00002170 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002171
2172 return 0;
2173}
2174
paul645878f2003-04-13 21:42:11 +00002175/* Flush any NSSA LSAs for given prefix */
2176void
2177ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2178{
paul1eb8ef22005-04-07 07:30:20 +00002179 struct listnode *node, *nnode;
paul645878f2003-04-13 21:42:11 +00002180 struct ospf_lsa *lsa;
2181 struct ospf_area *area;
2182
paul1eb8ef22005-04-07 07:30:20 +00002183 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul645878f2003-04-13 21:42:11 +00002184 {
paul1eb8ef22005-04-07 07:30:20 +00002185 if (area->external_routing == OSPF_AREA_NSSA)
pauld7480322003-05-16 17:31:51 +00002186 {
2187 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2188 ospf->router_id)))
2189 {
2190 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002191 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
pauld7480322003-05-16 17:31:51 +00002192 inet_ntoa (p->prefix), p->prefixlen);
2193 continue;
2194 }
2195 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2196 if (!IS_LSA_MAXAGE (lsa))
2197 {
2198 ospf_refresher_unregister_lsa (ospf, lsa);
2199 ospf_lsa_flush_area (lsa, area);
2200 }
2201 }
paul645878f2003-04-13 21:42:11 +00002202 }
2203}
paul645878f2003-04-13 21:42:11 +00002204
paul718e3742002-12-13 20:15:29 +00002205/* Flush an AS-external-LSA from LSDB and routing domain. */
2206void
paul68980082003-03-25 05:07:42 +00002207ospf_external_lsa_flush (struct ospf *ospf,
2208 u_char type, struct prefix_ipv4 *p,
Paul Jakma9099f9b2016-01-18 10:12:10 +00002209 ifindex_t ifindex /*, struct in_addr nexthop */)
paul718e3742002-12-13 20:15:29 +00002210{
2211 struct ospf_lsa *lsa;
2212
2213 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002214 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
paul718e3742002-12-13 20:15:29 +00002215 inet_ntoa (p->prefix), p->prefixlen);
2216
2217 /* First lookup LSA from LSDB. */
paul68980082003-03-25 05:07:42 +00002218 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
paul718e3742002-12-13 20:15:29 +00002219 {
2220 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002221 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
paul718e3742002-12-13 20:15:29 +00002222 inet_ntoa (p->prefix), p->prefixlen);
2223 return;
2224 }
hassobeebba72004-06-20 21:00:27 +00002225
pauld4a53d52003-07-12 21:30:57 +00002226 /* If LSA is selforiginated, not a translated LSA, and there is
2227 * NSSA area, flush Type-7 LSA's at first.
2228 */
2229 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2230 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
pauld7480322003-05-16 17:31:51 +00002231 ospf_nssa_lsa_flush (ospf, p);
paul718e3742002-12-13 20:15:29 +00002232
2233 /* Sweep LSA from Link State Retransmit List. */
paul68980082003-03-25 05:07:42 +00002234 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002235
2236 /* There must be no self-originated LSA in rtrs_external. */
2237#if 0
2238 /* Remove External route from Zebra. */
2239 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2240#endif
2241
2242 if (!IS_LSA_MAXAGE (lsa))
2243 {
2244 /* Unregister LSA from Refresh queue. */
paul68980082003-03-25 05:07:42 +00002245 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002246
2247 /* Flush AS-external-LSA through AS. */
paul68980082003-03-25 05:07:42 +00002248 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002249 }
2250
2251 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002252 zlog_debug ("ospf_external_lsa_flush(): stop");
paul718e3742002-12-13 20:15:29 +00002253}
2254
2255void
paul68980082003-03-25 05:07:42 +00002256ospf_external_lsa_refresh_default (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002257{
2258 struct prefix_ipv4 p;
2259 struct external_info *ei;
2260 struct ospf_lsa *lsa;
2261
2262 p.family = AF_INET;
2263 p.prefixlen = 0;
2264 p.prefix.s_addr = 0;
2265
paul020709f2003-04-04 02:44:16 +00002266 ei = ospf_default_external_info (ospf);
paul68980082003-03-25 05:07:42 +00002267 lsa = ospf_external_info_find_lsa (ospf, &p);
paul718e3742002-12-13 20:15:29 +00002268
2269 if (ei)
2270 {
2271 if (lsa)
2272 {
2273 if (IS_DEBUG_OSPF_EVENT)
David Lampartereed3c482015-03-03 08:51:53 +01002274 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p",
2275 (void *)lsa);
paul68980082003-03-25 05:07:42 +00002276 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00002277 }
2278 else
2279 {
2280 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002281 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
paul68980082003-03-25 05:07:42 +00002282 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002283 }
2284 }
2285 else
2286 {
2287 if (lsa)
2288 {
2289 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00002290 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
Paul Jakmadfbd5172010-04-14 10:32:12 +01002291 ospf_refresher_unregister_lsa (ospf, lsa);
paul68980082003-03-25 05:07:42 +00002292 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002293 }
2294 }
2295}
2296
2297void
paul68980082003-03-25 05:07:42 +00002298ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
paul718e3742002-12-13 20:15:29 +00002299{
2300 struct route_node *rn;
2301 struct external_info *ei;
2302
2303 if (type != DEFAULT_ROUTE)
2304 if (EXTERNAL_INFO(type))
2305 /* Refresh each redistributed AS-external-LSAs. */
2306 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2307 if ((ei = rn->info))
2308 if (!is_prefix_default (&ei->p))
2309 {
2310 struct ospf_lsa *lsa;
2311
paul68980082003-03-25 05:07:42 +00002312 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2313 ospf_external_lsa_refresh (ospf, lsa, ei, force);
paul718e3742002-12-13 20:15:29 +00002314 else
paul68980082003-03-25 05:07:42 +00002315 ospf_external_lsa_originate (ospf, ei);
paul718e3742002-12-13 20:15:29 +00002316 }
2317}
2318
2319/* Refresh AS-external-LSA. */
Paul Jakmac363d382010-01-24 22:42:13 +00002320struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002321ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
paul718e3742002-12-13 20:15:29 +00002322 struct external_info *ei, int force)
2323{
2324 struct ospf_lsa *new;
2325 int changed;
2326
2327 /* Check the AS-external-LSA should be originated. */
paul68980082003-03-25 05:07:42 +00002328 if (!ospf_redistribute_check (ospf, ei, &changed))
paul718e3742002-12-13 20:15:29 +00002329 {
pauld4a53d52003-07-12 21:30:57 +00002330 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002331 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
pauld4a53d52003-07-12 21:30:57 +00002332 "redist check fail",
2333 lsa->data->type, inet_ntoa (lsa->data->id));
paul68980082003-03-25 05:07:42 +00002334 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
ajs5339cfd2005-09-19 13:28:05 +00002335 ei->ifindex /*, ei->nexthop */);
Paul Jakmac363d382010-01-24 22:42:13 +00002336 return NULL;
paul718e3742002-12-13 20:15:29 +00002337 }
2338
2339 if (!changed && !force)
pauld4a53d52003-07-12 21:30:57 +00002340 {
2341 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002342 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
pauld4a53d52003-07-12 21:30:57 +00002343 lsa->data->type, inet_ntoa (lsa->data->id));
Paul Jakmac363d382010-01-24 22:42:13 +00002344 return NULL;
pauld4a53d52003-07-12 21:30:57 +00002345 }
paul718e3742002-12-13 20:15:29 +00002346
2347 /* Delete LSA from neighbor retransmit-list. */
paul68980082003-03-25 05:07:42 +00002348 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002349
2350 /* Unregister AS-external-LSA from refresh-list. */
paul68980082003-03-25 05:07:42 +00002351 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002352
paul68980082003-03-25 05:07:42 +00002353 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
paul718e3742002-12-13 20:15:29 +00002354
2355 if (new == NULL)
2356 {
2357 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00002358 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
paul718e3742002-12-13 20:15:29 +00002359 inet_ntoa (lsa->data->id));
Paul Jakmac363d382010-01-24 22:42:13 +00002360 return NULL;
paul718e3742002-12-13 20:15:29 +00002361 }
2362
2363 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2364
paul68980082003-03-25 05:07:42 +00002365 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
paul718e3742002-12-13 20:15:29 +00002366
2367 /* Flood LSA through AS. */
paul68980082003-03-25 05:07:42 +00002368 ospf_flood_through_as (ospf, NULL, new);
paul718e3742002-12-13 20:15:29 +00002369
paul718e3742002-12-13 20:15:29 +00002370 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
pauld4a53d52003-07-12 21:30:57 +00002371 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
paul68980082003-03-25 05:07:42 +00002372 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
paul718e3742002-12-13 20:15:29 +00002373
pauld4a53d52003-07-12 21:30:57 +00002374 /* Register self-originated LSA to refresh queue.
2375 * Translated LSAs should not be registered, but refreshed upon
2376 * refresh of the Type-7
2377 */
2378 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2379 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002380
2381 /* Debug logging. */
2382 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2383 {
ajse588f212004-12-08 18:12:06 +00002384 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
pauld4a53d52003-07-12 21:30:57 +00002385 new->data->type, inet_ntoa (new->data->id));
paul718e3742002-12-13 20:15:29 +00002386 ospf_lsa_header_dump (new->data);
2387 }
2388
Paul Jakmac363d382010-01-24 22:42:13 +00002389 return new;
paul718e3742002-12-13 20:15:29 +00002390}
2391
David Lamparter6b0655a2014-06-04 06:53:35 +02002392
paul718e3742002-12-13 20:15:29 +00002393/* LSA installation functions. */
2394
2395/* Install router-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002396static struct ospf_lsa *
Paul Jakmac363d382010-01-24 22:42:13 +00002397ospf_router_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2398 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002399{
2400 struct ospf_area *area = new->area;
2401
2402 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2403 The entire routing table must be recalculated, starting with
2404 the shortest path calculations for each area (not just the
2405 area whose link-state database has changed).
2406 */
paul718e3742002-12-13 20:15:29 +00002407
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002408 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002409 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002410
2411 /* Only install LSA if it is originated/refreshed by us.
2412 * If LSA was received by flooding, the RECEIVED flag is set so do
2413 * not link the LSA */
2414 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2415 return new; /* ignore stale LSA */
2416
paul718e3742002-12-13 20:15:29 +00002417 /* Set self-originated router-LSA. */
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002418 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00002419 area->router_lsa_self = ospf_lsa_lock (new);
2420
Paul Jakmac363d382010-01-24 22:42:13 +00002421 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002422 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002423 if (rt_recalc)
Paul Jakmab6eef002014-10-09 14:19:51 +01002424 ospf_spf_calculate_schedule (ospf, SPF_FLAG_ROUTER_LSA_INSTALL);
paul718e3742002-12-13 20:15:29 +00002425 return new;
2426}
2427
2428#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2429 if (!(T)) \
2430 (T) = thread_add_timer (master, (F), oi, (V))
2431
2432/* Install network-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002433static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002434ospf_network_lsa_install (struct ospf *ospf,
2435 struct ospf_interface *oi,
paul718e3742002-12-13 20:15:29 +00002436 struct ospf_lsa *new,
2437 int rt_recalc)
2438{
2439
2440 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2441 The entire routing table must be recalculated, starting with
2442 the shortest path calculations for each area (not just the
2443 area whose link-state database has changed).
2444 */
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002445 if (IS_LSA_SELF (new))
paul718e3742002-12-13 20:15:29 +00002446 {
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002447 /* We supposed that when LSA is originated by us, we pass the int
2448 for which it was originated. If LSA was received by flooding,
2449 the RECEIVED flag is set, so we do not link the LSA to the int. */
2450 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2451 return new; /* ignore stale LSA */
2452
Paul Jakma1fe6ed32006-07-26 09:37:26 +00002453 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00002454 oi->network_lsa_self = ospf_lsa_lock (new);
Paul Jakmac363d382010-01-24 22:42:13 +00002455 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002456 }
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02002457 if (rt_recalc)
Paul Jakmab6eef002014-10-09 14:19:51 +01002458 ospf_spf_calculate_schedule (ospf, SPF_FLAG_NETWORK_LSA_INSTALL);
paul718e3742002-12-13 20:15:29 +00002459
2460 return new;
2461}
2462
2463/* Install summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002464static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002465ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2466 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002467{
paul718e3742002-12-13 20:15:29 +00002468 if (rt_recalc && !IS_LSA_SELF (new))
2469 {
2470 /* RFC 2328 Section 13.2 Summary-LSAs
2471 The best route to the destination described by the summary-
2472 LSA must be recalculated (see Section 16.5). If this
2473 destination is an AS boundary router, it may also be
2474 necessary to re-examine all the AS-external-LSAs.
2475 */
2476
2477#if 0
2478 /* This doesn't exist yet... */
2479 ospf_summary_incremental_update(new); */
2480#else /* #if 0 */
Paul Jakmab6eef002014-10-09 14:19:51 +01002481 ospf_spf_calculate_schedule (ospf, SPF_FLAG_SUMMARY_LSA_INSTALL);
paul718e3742002-12-13 20:15:29 +00002482#endif /* #if 0 */
2483
paul718e3742002-12-13 20:15:29 +00002484 }
2485
2486 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002487 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002488
2489 return new;
2490}
2491
2492/* Install ASBR-summary-LSA to an area. */
paul4dadc292005-05-06 21:37:42 +00002493static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002494ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2495 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002496{
2497 if (rt_recalc && !IS_LSA_SELF (new))
2498 {
2499 /* RFC 2328 Section 13.2 Summary-LSAs
2500 The best route to the destination described by the summary-
2501 LSA must be recalculated (see Section 16.5). If this
2502 destination is an AS boundary router, it may also be
2503 necessary to re-examine all the AS-external-LSAs.
2504 */
2505#if 0
2506 /* These don't exist yet... */
2507 ospf_summary_incremental_update(new);
2508 /* Isn't this done by the above call?
2509 - RFC 2328 Section 16.5 implies it should be */
2510 /* ospf_ase_calculate_schedule(); */
2511#else /* #if 0 */
Paul Jakmab6eef002014-10-09 14:19:51 +01002512 ospf_spf_calculate_schedule (ospf, SPF_FLAG_ASBR_SUMMARY_LSA_INSTALL);
paul718e3742002-12-13 20:15:29 +00002513#endif /* #if 0 */
2514 }
2515
2516 /* register LSA to refresh-list. */
2517 if (IS_LSA_SELF (new))
paul68980082003-03-25 05:07:42 +00002518 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002519
2520 return new;
2521}
2522
2523/* Install AS-external-LSA. */
paul4dadc292005-05-06 21:37:42 +00002524static struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002525ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2526 int rt_recalc)
paul718e3742002-12-13 20:15:29 +00002527{
paul68980082003-03-25 05:07:42 +00002528 ospf_ase_register_external_lsa (new, ospf);
paul718e3742002-12-13 20:15:29 +00002529 /* If LSA is not self-originated, calculate an external route. */
2530 if (rt_recalc)
2531 {
2532 /* RFC 2328 Section 13.2 AS-external-LSAs
2533 The best route to the destination described by the AS-
2534 external-LSA must be recalculated (see Section 16.6).
2535 */
2536
2537 if (!IS_LSA_SELF (new))
pauld4a53d52003-07-12 21:30:57 +00002538 ospf_ase_incremental_update (ospf, new);
paul718e3742002-12-13 20:15:29 +00002539 }
2540
pauld4a53d52003-07-12 21:30:57 +00002541 if (new->data->type == OSPF_AS_NSSA_LSA)
2542 {
2543 /* There is no point to register selforiginate Type-7 LSA for
2544 * refreshing. We rely on refreshing Type-5 LSA's
2545 */
2546 if (IS_LSA_SELF (new))
2547 return new;
2548 else
2549 {
2550 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2551 * New translations will be taken care of by the abr_task.
2552 */
2553 ospf_translated_nssa_refresh (ospf, new, NULL);
Svata Dedic21e8b422011-12-22 18:07:15 +04002554 ospf_schedule_abr_task(ospf);
pauld4a53d52003-07-12 21:30:57 +00002555 }
2556 }
pauld7480322003-05-16 17:31:51 +00002557
pauld4a53d52003-07-12 21:30:57 +00002558 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002559 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002560 */
hassobeebba72004-06-20 21:00:27 +00002561 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002562 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002563
2564 return new;
2565}
2566
2567void
paul68980082003-03-25 05:07:42 +00002568ospf_discard_from_db (struct ospf *ospf,
2569 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002570{
2571 struct ospf_lsa *old;
2572
Paul Jakmaac904de2006-06-15 12:04:57 +00002573 if (!lsdb)
2574 {
2575 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2576 if (!lsa)
2577 zlog_warn ("%s: and NULL LSA!", __func__);
2578 else
2579 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2580 lsa->data->type, inet_ntoa (lsa->data->id));
2581 return;
2582 }
2583
paul718e3742002-12-13 20:15:29 +00002584 old = ospf_lsdb_lookup (lsdb, lsa);
2585
2586 if (!old)
2587 return;
2588
2589 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002590 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002591
2592 switch (old->data->type)
2593 {
2594 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002595 ospf_ase_unregister_external_lsa (old, ospf);
2596 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2597 break;
paul718e3742002-12-13 20:15:29 +00002598 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002599 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002600 break;
pauld7480322003-05-16 17:31:51 +00002601 case OSPF_AS_NSSA_LSA:
2602 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2603 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002604 break;
paul718e3742002-12-13 20:15:29 +00002605 default:
paul68980082003-03-25 05:07:42 +00002606 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002607 break;
2608 }
2609
paul68980082003-03-25 05:07:42 +00002610 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002611 ospf_lsa_discard (old);
2612}
2613
paul718e3742002-12-13 20:15:29 +00002614struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002615ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2616 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002617{
2618 struct ospf_lsa *new = NULL;
2619 struct ospf_lsa *old = NULL;
2620 struct ospf_lsdb *lsdb = NULL;
2621 int rt_recalc;
2622
2623 /* Set LSDB. */
2624 switch (lsa->data->type)
2625 {
paulf2c80652002-12-13 21:44:27 +00002626 /* kevinm */
2627 case OSPF_AS_NSSA_LSA:
2628 if (lsa->area)
2629 lsdb = lsa->area->lsdb;
2630 else
paul68980082003-03-25 05:07:42 +00002631 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002632 break;
paul718e3742002-12-13 20:15:29 +00002633 case OSPF_AS_EXTERNAL_LSA:
paul718e3742002-12-13 20:15:29 +00002634 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002635 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002636 break;
2637 default:
2638 lsdb = lsa->area->lsdb;
2639 break;
2640 }
2641
paul718e3742002-12-13 20:15:29 +00002642 assert (lsdb);
2643
2644 /* RFC 2328 13.2. Installing LSAs in the database
2645
2646 Installing a new LSA in the database, either as the result of
2647 flooding or a newly self-originated LSA, may cause the OSPF
2648 routing table structure to be recalculated. The contents of the
2649 new LSA should be compared to the old instance, if present. If
2650 there is no difference, there is no need to recalculate the
2651 routing table. When comparing an LSA to its previous instance,
2652 the following are all considered to be differences in contents:
2653
2654 o The LSA's Options field has changed.
2655
2656 o One of the LSA instances has LS age set to MaxAge, and
2657 the other does not.
2658
2659 o The length field in the LSA header has changed.
2660
2661 o The body of the LSA (i.e., anything outside the 20-byte
2662 LSA header) has changed. Note that this excludes changes
2663 in LS Sequence Number and LS Checksum.
2664
2665 */
2666 /* Look up old LSA and determine if any SPF calculation or incremental
2667 update is needed */
2668 old = ospf_lsdb_lookup (lsdb, lsa);
2669
2670 /* Do comparision and record if recalc needed. */
2671 rt_recalc = 0;
2672 if ( old == NULL || ospf_lsa_different(old, lsa))
2673 rt_recalc = 1;
2674
paul7ddf1d62003-10-13 09:06:46 +00002675 /*
2676 Sequence number check (Section 14.1 of rfc 2328)
2677 "Premature aging is used when it is time for a self-originated
2678 LSA's sequence number field to wrap. At this point, the current
2679 LSA instance (having LS sequence number MaxSequenceNumber) must
2680 be prematurely aged and flushed from the routing domain before a
2681 new instance with sequence number equal to InitialSequenceNumber
2682 can be originated. "
2683 */
2684
Paul Jakmac2b478d2006-03-30 14:16:11 +00002685 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002686 {
2687 if (ospf_lsa_is_self_originated(ospf, lsa))
2688 {
paul0c2be262004-05-31 14:16:54 +00002689 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2690
2691 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002692 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2693 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2694
2695 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2696 {
ajse588f212004-12-08 18:12:06 +00002697 zlog_debug ("ospf_lsa_install() Premature Aging "
Paul Jakmac363d382010-01-24 22:42:13 +00002698 "lsa 0x%p, seqnum 0x%x",
David Lampartereed3c482015-03-03 08:51:53 +01002699 (void *)lsa, ntohl(lsa->data->ls_seqnum));
paul7ddf1d62003-10-13 09:06:46 +00002700 ospf_lsa_header_dump (lsa->data);
2701 }
2702 }
2703 else
2704 {
2705 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2706 {
ajse588f212004-12-08 18:12:06 +00002707 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002708 "that was not self originated. Ignoring\n");
2709 ospf_lsa_header_dump (lsa->data);
2710 }
2711 return old;
2712 }
2713 }
2714
paul718e3742002-12-13 20:15:29 +00002715 /* discard old LSA from LSDB */
2716 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002717 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002718
paul718e3742002-12-13 20:15:29 +00002719 /* Calculate Checksum if self-originated?. */
2720 if (IS_LSA_SELF (lsa))
2721 ospf_lsa_checksum (lsa->data);
2722
hassofe71a972004-12-22 16:16:02 +00002723 /* Insert LSA to LSDB. */
2724 ospf_lsdb_add (lsdb, lsa);
2725 lsa->lsdb = lsdb;
2726
paul718e3742002-12-13 20:15:29 +00002727 /* Do LSA specific installation process. */
2728 switch (lsa->data->type)
2729 {
2730 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002731 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002732 break;
2733 case OSPF_NETWORK_LSA:
2734 assert (oi);
paul68980082003-03-25 05:07:42 +00002735 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002736 break;
2737 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002738 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002739 break;
2740 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002741 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002742 break;
2743 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002744 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002745 break;
paul718e3742002-12-13 20:15:29 +00002746 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002747 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002748 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002749 else
Andrew Certain0798cee2012-12-04 13:43:42 -08002750 {
2751 /* Incoming "oi" for this LSA has set at LSUpd reception. */
2752 }
paul09e4efd2003-01-18 00:12:02 +00002753 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002754 case OSPF_OPAQUE_AREA_LSA:
2755 case OSPF_OPAQUE_AS_LSA:
2756 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2757 break;
pauld4a53d52003-07-12 21:30:57 +00002758 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002759 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002760 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002761 break;
2762 }
2763
2764 if (new == NULL)
2765 return new; /* Installation failed, cannot proceed further -- endo. */
2766
2767 /* Debug logs. */
2768 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2769 {
2770 char area_str[INET_ADDRSTRLEN];
2771
2772 switch (lsa->data->type)
2773 {
2774 case OSPF_AS_EXTERNAL_LSA:
paul718e3742002-12-13 20:15:29 +00002775 case OSPF_OPAQUE_AS_LSA:
hassobeebba72004-06-20 21:00:27 +00002776 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002777 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002778 dump_lsa_key (new),
2779 LOOKUP (ospf_lsa_type_msg, new->data->type));
2780 break;
2781 default:
2782 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002783 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002784 dump_lsa_key (new),
2785 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2786 break;
2787 }
2788 }
2789
paul7ddf1d62003-10-13 09:06:46 +00002790 /*
2791 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2792 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2793 */
Dinesh G Dutte0630cb2013-01-07 10:12:52 -08002794 if (IS_LSA_MAXAGE (new))
paul718e3742002-12-13 20:15:29 +00002795 {
paul7ddf1d62003-10-13 09:06:46 +00002796 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002797 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
David Lampartereed3c482015-03-03 08:51:53 +01002798 new->data->type,
2799 inet_ntoa (new->data->id),
2800 (void *)lsa);
Dinesh G Dutte0630cb2013-01-07 10:12:52 -08002801 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002802 }
2803
2804 return new;
2805}
2806
David Lamparter6b0655a2014-06-04 06:53:35 +02002807
Christian Franke4c14b7f2013-02-20 10:00:54 +00002808int
paul68980082003-03-25 05:07:42 +00002809ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002810{
paul1eb8ef22005-04-07 07:30:20 +00002811 struct listnode *node, *nnode;
2812 struct ospf_interface *oi;
2813
2814 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002815 {
paul718e3742002-12-13 20:15:29 +00002816 struct route_node *rn;
2817 struct ospf_neighbor *nbr;
2818
2819 if (ospf_if_is_enable (oi))
2820 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2821 if ((nbr = rn->info) != NULL)
2822 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2823 {
2824 route_unlock_node (rn);
2825 return 0;
2826 }
2827 }
2828
2829 return 1;
2830}
2831
David Lamparter6b0655a2014-06-04 06:53:35 +02002832
paul718e3742002-12-13 20:15:29 +00002833
paul4dadc292005-05-06 21:37:42 +00002834static int
paul718e3742002-12-13 20:15:29 +00002835ospf_maxage_lsa_remover (struct thread *thread)
2836{
paul68980082003-03-25 05:07:42 +00002837 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002838 struct ospf_lsa *lsa;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002839 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00002840 int reschedule = 0;
2841
paul68980082003-03-25 05:07:42 +00002842 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002843
2844 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002845 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002846
paul68980082003-03-25 05:07:42 +00002847 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002848
2849 if (!reschedule)
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002850 for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn))
paul718e3742002-12-13 20:15:29 +00002851 {
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002852 if ((lsa = rn->info) == NULL)
2853 {
2854 continue;
2855 }
2856
Christian Franke4de8bf02013-02-20 10:00:52 +00002857 /* There is at least one neighbor from which we still await an ack
2858 * for that LSA, so we are not allowed to remove it from our lsdb yet
2859 * as per RFC 2328 section 14 para 4 a) */
paul718e3742002-12-13 20:15:29 +00002860 if (lsa->retransmit_counter > 0)
2861 {
2862 reschedule = 1;
2863 continue;
2864 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002865
2866 /* TODO: maybe convert this function to a work-queue */
2867 if (thread_should_yield (thread))
Christian Franke4de8bf02013-02-20 10:00:52 +00002868 {
2869 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);
Christian Frankee387dfd2014-04-28 08:04:58 +00002870 route_unlock_node(rn); /* route_top/route_next */
Christian Franke4de8bf02013-02-20 10:00:52 +00002871 return 0;
2872 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002873
paul718e3742002-12-13 20:15:29 +00002874 /* Remove LSA from the LSDB */
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04002875 if (IS_LSA_SELF (lsa))
paul718e3742002-12-13 20:15:29 +00002876 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
Denis Ovsienkoad8d4802011-12-02 20:02:40 +04002877 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-originated: ",
paul7ddf1d62003-10-13 09:06:46 +00002878 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002879
2880 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002881 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002882 lsa->data->type, inet_ntoa (lsa->data->id));
2883
Paul Jakmac363d382010-01-24 22:42:13 +00002884 if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))
paul7ddf1d62003-10-13 09:06:46 +00002885 {
2886 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
David Lampartereed3c482015-03-03 08:51:53 +01002887 zlog_debug ("originating new lsa for lsa 0x%p\n", (void *)lsa);
Paul Jakmac363d382010-01-24 22:42:13 +00002888 ospf_lsa_refresh (ospf, lsa);
paul7ddf1d62003-10-13 09:06:46 +00002889 }
2890
paul718e3742002-12-13 20:15:29 +00002891 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002892 if (lsa->lsdb)
2893 {
2894 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2895 ospf_lsdb_delete (lsa->lsdb, lsa);
2896 }
2897 else
2898 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2899 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002900 }
2901
2902 /* A MaxAge LSA must be removed immediately from the router's link
2903 state database as soon as both a) it is no longer contained on any
2904 neighbor Link state retransmission lists and b) none of the router's
2905 neighbors are in states Exchange or Loading. */
2906 if (reschedule)
Paul Jakma02d942c2010-01-24 23:36:20 +00002907 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2908 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002909
2910 return 0;
2911}
2912
paul718e3742002-12-13 20:15:29 +00002913void
paul68980082003-03-25 05:07:42 +00002914ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002915{
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002916 struct route_node *rn;
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002917 struct prefix_ptr lsa_prefix;
paul718e3742002-12-13 20:15:29 +00002918
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002919 lsa_prefix.family = 0;
2920 lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
2921 lsa_prefix.prefix = (uintptr_t) lsa;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002922
2923 if ((rn = route_node_lookup(ospf->maxage_lsa,
2924 (struct prefix *)&lsa_prefix)))
paul718e3742002-12-13 20:15:29 +00002925 {
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002926 if (rn->info == lsa)
2927 {
2928 UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
2929 ospf_lsa_unlock (&lsa); /* maxage_lsa */
2930 rn->info = NULL;
Christian Franke8afee5c2014-04-28 08:04:59 +00002931 route_unlock_node (rn); /* unlock node because lsa is deleted */
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002932 }
Christian Franke8afee5c2014-04-28 08:04:59 +00002933 route_unlock_node (rn); /* route_node_lookup */
paul718e3742002-12-13 20:15:29 +00002934 }
2935}
2936
Paul Jakma02d942c2010-01-24 23:36:20 +00002937/* Add LSA onto the MaxAge list, and schedule for removal.
2938 * This does *not* lead to the LSA being flooded, that must be taken
2939 * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
2940 * function).
2941 */
paul718e3742002-12-13 20:15:29 +00002942void
paul68980082003-03-25 05:07:42 +00002943ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002944{
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002945 struct prefix_ptr lsa_prefix;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002946 struct route_node *rn;
2947
paul718e3742002-12-13 20:15:29 +00002948 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2949 and schedule the MaxAge LSA remover. */
Stephen Hemminger3106a032009-08-06 12:58:05 -07002950 if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
paul718e3742002-12-13 20:15:29 +00002951 {
2952 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002953 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
David Lampartereed3c482015-03-03 08:51:53 +01002954 lsa->data->type, inet_ntoa (lsa->data->id), (void *)lsa);
paul718e3742002-12-13 20:15:29 +00002955 return;
2956 }
2957
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002958 lsa_prefix.family = 0;
2959 lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
2960 lsa_prefix.prefix = (uintptr_t) lsa;
2961
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002962 if ((rn = route_node_get (ospf->maxage_lsa,
2963 (struct prefix *)&lsa_prefix)) != NULL)
2964 {
2965 if (rn->info != NULL)
2966 {
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002967 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2968 zlog_debug ("LSA[%s]: found LSA (%p) in table for LSA %p %d",
David Lampartereed3c482015-03-03 08:51:53 +01002969 dump_lsa_key (lsa), rn->info, (void *)lsa,
2970 lsa_prefix.prefixlen);
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002971 route_unlock_node (rn);
2972 }
2973 else
2974 {
2975 rn->info = ospf_lsa_lock(lsa);
2976 SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
2977 }
2978 }
2979 else
2980 {
2981 zlog_err("Unable to allocate memory for maxage lsa\n");
2982 assert(0);
2983 }
paul718e3742002-12-13 20:15:29 +00002984
2985 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002986 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002987
Paul Jakma02d942c2010-01-24 23:36:20 +00002988 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2989 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002990}
2991
paul4dadc292005-05-06 21:37:42 +00002992static int
paul68980082003-03-25 05:07:42 +00002993ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002994{
paul718e3742002-12-13 20:15:29 +00002995 /* Stay away from any Local Translated Type-7 LSAs */
2996 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2997 return 0;
paul718e3742002-12-13 20:15:29 +00002998
2999 if (IS_LSA_MAXAGE (lsa))
3000 /* Self-originated LSAs should NOT time-out instead,
3001 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00003002 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003003 {
3004 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003005 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003006
3007 switch (lsa->data->type)
3008 {
paul37163d62003-02-03 18:40:56 +00003009 case OSPF_OPAQUE_LINK_LSA:
3010 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003011 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003012 /*
3013 * As a general rule, whenever network topology has changed
3014 * (due to an LSA removal in this case), routing recalculation
3015 * should be triggered. However, this is not true for opaque
3016 * LSAs. Even if an opaque LSA instance is going to be removed
3017 * from the routing domain, it does not mean a change in network
3018 * topology, and thus, routing recalculation is not needed here.
3019 */
3020 break;
paul09e4efd2003-01-18 00:12:02 +00003021 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003022 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003023 ospf_ase_incremental_update (ospf, lsa);
3024 break;
paul718e3742002-12-13 20:15:29 +00003025 default:
Paul Jakmab6eef002014-10-09 14:19:51 +01003026 ospf_spf_calculate_schedule (ospf, SPF_FLAG_MAXAGE);
paul68980082003-03-25 05:07:42 +00003027 break;
paul718e3742002-12-13 20:15:29 +00003028 }
paul68980082003-03-25 05:07:42 +00003029 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003030 }
3031
Paul Jakmac363d382010-01-24 22:42:13 +00003032 if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa))
3033 if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30)
3034 printf ("Eek! Shouldn't happen!\n");
3035
paul718e3742002-12-13 20:15:29 +00003036 return 0;
3037}
3038
3039/* Periodical check of MaxAge LSA. */
3040int
paul68980082003-03-25 05:07:42 +00003041ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003042{
paul68980082003-03-25 05:07:42 +00003043 struct ospf *ospf = THREAD_ARG (thread);
3044 struct route_node *rn;
3045 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003046 struct ospf_area *area;
3047 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003048
paul68980082003-03-25 05:07:42 +00003049 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003050
paul1eb8ef22005-04-07 07:30:20 +00003051 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003052 {
paul68980082003-03-25 05:07:42 +00003053 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3054 ospf_lsa_maxage_walker_remover (ospf, lsa);
3055 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3056 ospf_lsa_maxage_walker_remover (ospf, lsa);
3057 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3058 ospf_lsa_maxage_walker_remover (ospf, lsa);
3059 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3060 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul68980082003-03-25 05:07:42 +00003061 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3062 ospf_lsa_maxage_walker_remover (ospf, lsa);
3063 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3064 ospf_lsa_maxage_walker_remover (ospf, 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);
paul68980082003-03-25 05:07:42 +00003074 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3075 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul68980082003-03-25 05:07:42 +00003076 }
paul718e3742002-12-13 20:15:29 +00003077
paul68980082003-03-25 05:07:42 +00003078 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3079 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003080 return 0;
3081}
3082
paul68980082003-03-25 05:07:42 +00003083struct ospf_lsa *
3084ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3085 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003086{
paul68980082003-03-25 05:07:42 +00003087 struct ospf_lsa *lsa;
3088 struct in_addr mask, id;
3089 struct lsa_header_mask
3090 {
3091 struct lsa_header header;
3092 struct in_addr mask;
3093 } *hmask;
paul718e3742002-12-13 20:15:29 +00003094
paul68980082003-03-25 05:07:42 +00003095 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3096 if (lsa == NULL)
3097 return NULL;
paul718e3742002-12-13 20:15:29 +00003098
paul68980082003-03-25 05:07:42 +00003099 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003100
paul68980082003-03-25 05:07:42 +00003101 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003102
paul68980082003-03-25 05:07:42 +00003103 if (mask.s_addr != hmask->mask.s_addr)
3104 {
3105 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3106 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3107 if (!lsa)
3108 return NULL;
3109 }
paul718e3742002-12-13 20:15:29 +00003110
paul68980082003-03-25 05:07:42 +00003111 return lsa;
paul718e3742002-12-13 20:15:29 +00003112}
3113
3114struct ospf_lsa *
3115ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3116 struct in_addr id, struct in_addr adv_router)
3117{
paule05fba42003-04-13 20:20:53 +00003118 struct ospf *ospf = ospf_lookup();
3119 assert(ospf);
3120
paul718e3742002-12-13 20:15:29 +00003121 switch (type)
3122 {
3123 case OSPF_ROUTER_LSA:
3124 case OSPF_NETWORK_LSA:
3125 case OSPF_SUMMARY_LSA:
3126 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003127 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003128 case OSPF_OPAQUE_LINK_LSA:
3129 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003130 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003131 case OSPF_AS_EXTERNAL_LSA:
paul718e3742002-12-13 20:15:29 +00003132 case OSPF_OPAQUE_AS_LSA:
paule05fba42003-04-13 20:20:53 +00003133 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003134 default:
3135 break;
3136 }
3137
3138 return NULL;
3139}
3140
3141struct ospf_lsa *
3142ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3143 struct in_addr id)
3144{
3145 struct ospf_lsa *lsa;
3146 struct route_node *rn;
3147
3148 switch (type)
3149 {
3150 case OSPF_ROUTER_LSA:
3151 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003152 case OSPF_NETWORK_LSA:
3153 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3154 if ((lsa = rn->info))
3155 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3156 {
3157 route_unlock_node (rn);
3158 return lsa;
3159 }
3160 break;
3161 case OSPF_SUMMARY_LSA:
3162 case OSPF_ASBR_SUMMARY_LSA:
3163 /* Currently not used. */
3164 assert (1);
3165 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003166 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003167 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003168 case OSPF_OPAQUE_LINK_LSA:
3169 case OSPF_OPAQUE_AREA_LSA:
3170 case OSPF_OPAQUE_AS_LSA:
3171 /* Currently not used. */
3172 break;
paul718e3742002-12-13 20:15:29 +00003173 default:
3174 break;
3175 }
3176
3177 return NULL;
3178}
3179
3180struct ospf_lsa *
3181ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3182{
3183 struct ospf_lsa *match;
3184
paul718e3742002-12-13 20:15:29 +00003185 /*
3186 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3187 * is redefined to have two subfields; opaque-type and opaque-id.
3188 * However, it is harmless to treat the two sub fields together, as if
3189 * they two were forming a unique LSA-ID.
3190 */
paul718e3742002-12-13 20:15:29 +00003191
3192 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3193
3194 if (match == NULL)
3195 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003196 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003197 lsah->type, inet_ntoa (lsah->id));
3198
3199 return match;
3200}
3201
3202/* return +n, l1 is more recent.
3203 return -n, l2 is more recent.
3204 return 0, l1 and l2 is identical. */
3205int
3206ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3207{
3208 int r;
3209 int x, y;
3210
3211 if (l1 == NULL && l2 == NULL)
3212 return 0;
3213 if (l1 == NULL)
3214 return -1;
3215 if (l2 == NULL)
3216 return 1;
3217
3218 /* compare LS sequence number. */
3219 x = (int) ntohl (l1->data->ls_seqnum);
3220 y = (int) ntohl (l2->data->ls_seqnum);
3221 if (x > y)
3222 return 1;
3223 if (x < y)
3224 return -1;
3225
3226 /* compare LS checksum. */
3227 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3228 if (r)
3229 return r;
3230
3231 /* compare LS age. */
3232 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3233 return 1;
3234 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3235 return -1;
3236
3237 /* compare LS age with MaxAgeDiff. */
3238 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3239 return -1;
3240 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3241 return 1;
3242
3243 /* LSAs are identical. */
3244 return 0;
3245}
3246
3247/* If two LSAs are different, return 1, otherwise return 0. */
3248int
3249ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3250{
3251 char *p1, *p2;
3252 assert (l1);
3253 assert (l2);
3254 assert (l1->data);
3255 assert (l2->data);
3256
3257 if (l1->data->options != l2->data->options)
3258 return 1;
3259
3260 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3261 return 1;
3262
3263 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3264 return 1;
3265
3266 if (l1->data->length != l2->data->length)
3267 return 1;
3268
3269 if (l1->data->length == 0)
3270 return 1;
3271
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02003272 if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
3273 return 1; /* May be a stale LSA in the LSBD */
3274
pauld1825832003-04-03 01:27:01 +00003275 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003276
3277 p1 = (char *) l1->data;
3278 p2 = (char *) l2->data;
3279
3280 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3281 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3282 return 1;
3283
3284 return 0;
3285}
3286
3287#ifdef ORIGINAL_CODING
3288void
3289ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3290 struct ospf_lsa *self,
3291 struct ospf_lsa *new)
3292{
3293 u_int32_t seqnum;
3294
3295 /* Adjust LS Sequence Number. */
3296 seqnum = ntohl (new->data->ls_seqnum) + 1;
3297 self->data->ls_seqnum = htonl (seqnum);
3298
3299 /* Recalculate LSA checksum. */
3300 ospf_lsa_checksum (self->data);
3301
3302 /* Reflooding LSA. */
3303 /* RFC2328 Section 13.3
3304 On non-broadcast networks, separate Link State Update
3305 packets must be sent, as unicasts, to each adjacent neighbor
3306 (i.e., those in state Exchange or greater). The destination
3307 IP addresses for these packets are the neighbors' IP
3308 addresses. */
3309 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3310 {
3311 struct route_node *rn;
3312 struct ospf_neighbor *onbr;
3313
3314 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3315 if ((onbr = rn->info) != NULL)
3316 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3317 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3318 }
3319 else
3320 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3321
3322 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003323 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003324 self->data->type, inet_ntoa (self->data->id));
3325}
3326#else /* ORIGINAL_CODING */
3327static int
paul68980082003-03-25 05:07:42 +00003328ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003329{
3330 if (lsa == NULL || !IS_LSA_SELF (lsa))
3331 return 0;
3332
3333 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003334 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 +00003335
3336 /* Force given lsa's age to MaxAge. */
3337 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3338
3339 switch (lsa->data->type)
3340 {
Paul Jakma02d942c2010-01-24 23:36:20 +00003341 /* Opaque wants to be notified of flushes */
paul718e3742002-12-13 20:15:29 +00003342 case OSPF_OPAQUE_LINK_LSA:
3343 case OSPF_OPAQUE_AREA_LSA:
3344 case OSPF_OPAQUE_AS_LSA:
3345 ospf_opaque_lsa_refresh (lsa);
3346 break;
paul718e3742002-12-13 20:15:29 +00003347 default:
Paul Jakmadfbd5172010-04-14 10:32:12 +01003348 ospf_refresher_unregister_lsa (ospf, lsa);
Paul Jakma02d942c2010-01-24 23:36:20 +00003349 ospf_lsa_flush (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003350 break;
3351 }
3352
3353 return 0;
3354}
3355
3356void
paul68980082003-03-25 05:07:42 +00003357ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003358{
paul1eb8ef22005-04-07 07:30:20 +00003359 struct listnode *node, *nnode;
3360 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003361 struct ospf_area *area;
3362 struct ospf_interface *oi;
3363 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003364 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003365 int need_to_flush_ase = 0;
3366
paul1eb8ef22005-04-07 07:30:20 +00003367 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003368 {
paul718e3742002-12-13 20:15:29 +00003369 if ((lsa = area->router_lsa_self) != NULL)
3370 {
3371 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003372 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3373 lsa->data->type, inet_ntoa (lsa->data->id));
3374
3375 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003376 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003377 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003378 area->router_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003379 }
3380
paul1eb8ef22005-04-07 07:30:20 +00003381 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003382 {
paul718e3742002-12-13 20:15:29 +00003383 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003384 && oi->state == ISM_DR
3385 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003386 {
3387 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003388 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3389 lsa->data->type, inet_ntoa (lsa->data->id));
3390
3391 ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003392 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003393 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003394 oi->network_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003395 }
3396
3397 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3398 && area->external_routing == OSPF_AREA_DEFAULT)
3399 need_to_flush_ase = 1;
3400 }
3401
paul68980082003-03-25 05:07:42 +00003402 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3403 ospf_lsa_flush_schedule (ospf, lsa);
3404 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3405 ospf_lsa_flush_schedule (ospf, lsa);
paul68980082003-03-25 05:07:42 +00003406 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3407 ospf_lsa_flush_schedule (ospf, lsa);
3408 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3409 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003410 }
3411
3412 if (need_to_flush_ase)
3413 {
paul68980082003-03-25 05:07:42 +00003414 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3415 ospf_lsa_flush_schedule (ospf, lsa);
paul68980082003-03-25 05:07:42 +00003416 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3417 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003418 }
3419
3420 /*
3421 * Make sure that the MaxAge LSA remover is executed immediately,
3422 * without conflicting to other threads.
3423 */
paul68980082003-03-25 05:07:42 +00003424 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003425 {
paul68980082003-03-25 05:07:42 +00003426 OSPF_TIMER_OFF (ospf->t_maxage);
3427 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003428 }
3429
3430 return;
3431}
3432#endif /* ORIGINAL_CODING */
3433
3434/* If there is self-originated LSA, then return 1, otherwise return 0. */
3435/* An interface-independent version of ospf_lsa_is_self_originated */
3436int
paul68980082003-03-25 05:07:42 +00003437ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003438{
hasso52dc7ee2004-09-23 19:18:23 +00003439 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003440 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003441
3442 /* This LSA is already checked. */
3443 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003444 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003445
3446 /* Make sure LSA is self-checked. */
3447 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3448
3449 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003450 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003451 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3452
3453 /* LSA is router-LSA. */
3454 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003455 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003456 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3457
3458 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3459 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003460 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003461 {
paul718e3742002-12-13 20:15:29 +00003462 /* Ignore virtual link. */
3463 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3464 if (oi->address->family == AF_INET)
3465 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3466 {
3467 /* to make it easier later */
3468 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003469 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003470 }
3471 }
3472
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003473 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003474}
3475
3476/* Get unique Link State ID. */
3477struct in_addr
paul68980082003-03-25 05:07:42 +00003478ospf_lsa_unique_id (struct ospf *ospf,
3479 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003480{
3481 struct ospf_lsa *lsa;
3482 struct in_addr mask, id;
3483
3484 id = p->prefix;
3485
3486 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003487 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003488 if (lsa)
3489 {
3490 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3491 if (ip_masklen (al->mask) == p->prefixlen)
3492 {
3493 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003494 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003495 "Can't get Link State ID for %s/%d",
3496 inet_ntoa (p->prefix), p->prefixlen);
3497 /* id.s_addr = 0; */
3498 id.s_addr = 0xffffffff;
3499 return id;
3500 }
3501 /* Masklen differs, then apply wildcard mask to Link State ID. */
3502 else
3503 {
3504 masklen2ip (p->prefixlen, &mask);
3505
3506 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003507 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3508 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003509 if (lsa)
3510 {
3511 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003512 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003513 "Can't get Link State ID for %s/%d",
3514 inet_ntoa (p->prefix), p->prefixlen);
3515 /* id.s_addr = 0; */
3516 id.s_addr = 0xffffffff;
3517 return id;
3518 }
3519 }
3520 }
3521
3522 return id;
3523}
3524
David Lamparter6b0655a2014-06-04 06:53:35 +02003525
Paul Jakma70461d72006-05-12 22:57:57 +00003526#define LSA_ACTION_FLOOD_AREA 1
3527#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003528
3529struct lsa_action
3530{
3531 u_char action;
3532 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003533 struct ospf_lsa *lsa;
3534};
3535
paul4dadc292005-05-06 21:37:42 +00003536static int
paul718e3742002-12-13 20:15:29 +00003537ospf_lsa_action (struct thread *t)
3538{
3539 struct lsa_action *data;
3540
3541 data = THREAD_ARG (t);
3542
3543 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003544 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003545 data->action);
3546
3547 switch (data->action)
3548 {
paul718e3742002-12-13 20:15:29 +00003549 case LSA_ACTION_FLOOD_AREA:
3550 ospf_flood_through_area (data->area, NULL, data->lsa);
3551 break;
paul718e3742002-12-13 20:15:29 +00003552 case LSA_ACTION_FLUSH_AREA:
3553 ospf_lsa_flush_area (data->lsa, data->area);
3554 break;
paul718e3742002-12-13 20:15:29 +00003555 }
3556
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003557 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003558 XFREE (MTYPE_OSPF_MESSAGE, data);
3559 return 0;
3560}
3561
3562void
3563ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3564{
3565 struct lsa_action *data;
3566
Stephen Hemminger393deb92008-08-18 14:13:29 -07003567 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003568 data->action = LSA_ACTION_FLOOD_AREA;
3569 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003570 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003571
3572 thread_add_event (master, ospf_lsa_action, data, 0);
3573}
3574
3575void
3576ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3577{
3578 struct lsa_action *data;
3579
Stephen Hemminger393deb92008-08-18 14:13:29 -07003580 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003581 data->action = LSA_ACTION_FLUSH_AREA;
3582 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003583 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003584
3585 thread_add_event (master, ospf_lsa_action, data, 0);
3586}
3587
David Lamparter6b0655a2014-06-04 06:53:35 +02003588
paul718e3742002-12-13 20:15:29 +00003589/* LSA Refreshment functions. */
Paul Jakmac363d382010-01-24 22:42:13 +00003590struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00003591ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003592{
3593 struct external_info *ei;
Paul Jakmac363d382010-01-24 22:42:13 +00003594 struct ospf_lsa *new = NULL;
paul718e3742002-12-13 20:15:29 +00003595 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003596 assert (IS_LSA_SELF (lsa));
Paul Jakma66349742010-04-13 22:33:54 +01003597 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003598
3599 switch (lsa->data->type)
3600 {
3601 /* Router and Network LSAs are processed differently. */
3602 case OSPF_ROUTER_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003603 new = ospf_router_lsa_refresh (lsa);
3604 break;
paul718e3742002-12-13 20:15:29 +00003605 case OSPF_NETWORK_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003606 new = ospf_network_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003607 break;
3608 case OSPF_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003609 new = ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003610 break;
3611 case OSPF_ASBR_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003612 new = ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003613 break;
3614 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003615 /* Translated from NSSA Type-5s are refreshed when
3616 * from refresh of Type-7 - do not refresh these directly.
3617 */
3618 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3619 break;
paul718e3742002-12-13 20:15:29 +00003620 ei = ospf_external_info_check (lsa);
3621 if (ei)
Paul Jakmac363d382010-01-24 22:42:13 +00003622 new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003623 else
pauld4a53d52003-07-12 21:30:57 +00003624 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003625 break;
paul718e3742002-12-13 20:15:29 +00003626 case OSPF_OPAQUE_LINK_LSA:
3627 case OSPF_OPAQUE_AREA_LSA:
3628 case OSPF_OPAQUE_AS_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003629 new = ospf_opaque_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003630 break;
3631 default:
3632 break;
paul718e3742002-12-13 20:15:29 +00003633 }
Paul Jakmac363d382010-01-24 22:42:13 +00003634 return new;
paul718e3742002-12-13 20:15:29 +00003635}
3636
3637void
paul68980082003-03-25 05:07:42 +00003638ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003639{
3640 u_int16_t index, current_index;
3641
Paul Jakma66349742010-04-13 22:33:54 +01003642 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003643 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003644
3645 if (lsa->refresh_list < 0)
3646 {
3647 int delay;
3648
3649 if (LS_AGE (lsa) == 0 &&
3650 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3651 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3652 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3653 else
3654 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3655 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3656 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3657
3658 if (delay < 0)
3659 delay = 0;
3660
Paul Jakmac363d382010-01-24 22:42:13 +00003661 current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL)
3662 - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003663
3664 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
Paul Jakmac363d382010-01-24 22:42:13 +00003665 % (OSPF_LSA_REFRESHER_SLOTS);
paul718e3742002-12-13 20:15:29 +00003666
3667 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003668 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003669 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003670 if (!ospf->lsa_refresh_queue.qs[index])
3671 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003672 listnode_add (ospf->lsa_refresh_queue.qs[index],
3673 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003674 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003675 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003676 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003677 "setting refresh_list on lsa %p (slod %d)",
David Lampartereed3c482015-03-03 08:51:53 +01003678 inet_ntoa (lsa->data->id), (void *)lsa, index);
paul718e3742002-12-13 20:15:29 +00003679 }
3680}
3681
3682void
paul68980082003-03-25 05:07:42 +00003683ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003684{
Paul Jakma66349742010-04-13 22:33:54 +01003685 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003686 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003687 if (lsa->refresh_list >= 0)
3688 {
hasso52dc7ee2004-09-23 19:18:23 +00003689 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003690 listnode_delete (refresh_list, lsa);
3691 if (!listcount (refresh_list))
3692 {
3693 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003694 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003695 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003696 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003697 lsa->refresh_list = -1;
3698 }
3699}
3700
3701int
3702ospf_lsa_refresh_walker (struct thread *t)
3703{
hasso52dc7ee2004-09-23 19:18:23 +00003704 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003705 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003706 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003707 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003708 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003709 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003710
3711 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003712 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003713
3714
paul68980082003-03-25 05:07:42 +00003715 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003716
ajs9dbc7972005-03-13 19:27:22 +00003717 /* Note: if clock has jumped backwards, then time change could be negative,
3718 so we are careful to cast the expression to unsigned before taking
3719 modulus. */
paul68980082003-03-25 05:07:42 +00003720 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003721 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakmac363d382010-01-24 22:42:13 +00003722 (quagga_time (NULL) - ospf->lsa_refresher_started)
3723 / OSPF_LSA_REFRESHER_GRANULARITY))
3724 % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003725
3726 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003727 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003728 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003729
paul68980082003-03-25 05:07:42 +00003730 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003731 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3732 {
3733 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003734 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003735 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003736
paul68980082003-03-25 05:07:42 +00003737 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003738
Paul Jakma66349742010-04-13 22:33:54 +01003739 assert (i >= 0);
3740
paul68980082003-03-25 05:07:42 +00003741 ospf->lsa_refresh_queue.qs [i] = NULL;
3742
paul718e3742002-12-13 20:15:29 +00003743 if (refresh_list)
3744 {
paul1eb8ef22005-04-07 07:30:20 +00003745 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003746 {
paul718e3742002-12-13 20:15:29 +00003747 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003748 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
David Lampartereed3c482015-03-03 08:51:53 +01003749 "refresh lsa %p (slot %d)",
3750 inet_ntoa (lsa->data->id), (void *)lsa, i);
3751
Paul Jakma66349742010-04-13 22:33:54 +01003752 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003753 list_delete_node (refresh_list, node);
paul718e3742002-12-13 20:15:29 +00003754 lsa->refresh_list = -1;
3755 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003756 }
3757 list_free (refresh_list);
3758 }
3759 }
3760
paul68980082003-03-25 05:07:42 +00003761 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3762 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003763 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003764
paul1eb8ef22005-04-07 07:30:20 +00003765 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
Paul Jakma66349742010-04-13 22:33:54 +01003766 {
3767 ospf_lsa_refresh (ospf, lsa);
3768 assert (lsa->lock > 0);
3769 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
3770 }
paul718e3742002-12-13 20:15:29 +00003771
3772 list_delete (lsa_to_refresh);
3773
3774 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003775 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003776
3777 return 0;
3778}
3779