blob: 634bc4351a4353356de4f2f3201e1ebc8ccc738f [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;
paul779adb02006-01-18 15:07:38 +0000627 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
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
1652 /* Put route tag -- This value should be introduced from configuration. */
1653 stream_putl (s, 0);
1654}
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;
2166 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2167 }
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);
2554 }
2555 }
pauld7480322003-05-16 17:31:51 +00002556
pauld4a53d52003-07-12 21:30:57 +00002557 /* Register self-originated LSA to refresh queue.
paul8fc0f642003-07-13 01:36:06 +00002558 * Leave Translated LSAs alone if NSSA is enabled
pauld4a53d52003-07-12 21:30:57 +00002559 */
hassobeebba72004-06-20 21:00:27 +00002560 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
paul68980082003-03-25 05:07:42 +00002561 ospf_refresher_register_lsa (ospf, new);
paul718e3742002-12-13 20:15:29 +00002562
2563 return new;
2564}
2565
2566void
paul68980082003-03-25 05:07:42 +00002567ospf_discard_from_db (struct ospf *ospf,
2568 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002569{
2570 struct ospf_lsa *old;
2571
Paul Jakmaac904de2006-06-15 12:04:57 +00002572 if (!lsdb)
2573 {
2574 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2575 if (!lsa)
2576 zlog_warn ("%s: and NULL LSA!", __func__);
2577 else
2578 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2579 lsa->data->type, inet_ntoa (lsa->data->id));
2580 return;
2581 }
2582
paul718e3742002-12-13 20:15:29 +00002583 old = ospf_lsdb_lookup (lsdb, lsa);
2584
2585 if (!old)
2586 return;
2587
2588 if (old->refresh_list >= 0)
paul68980082003-03-25 05:07:42 +00002589 ospf_refresher_unregister_lsa (ospf, old);
paul718e3742002-12-13 20:15:29 +00002590
2591 switch (old->data->type)
2592 {
2593 case OSPF_AS_EXTERNAL_LSA:
paul69310a62005-05-11 18:09:59 +00002594 ospf_ase_unregister_external_lsa (old, ospf);
2595 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2596 break;
paul718e3742002-12-13 20:15:29 +00002597 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002598 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002599 break;
pauld7480322003-05-16 17:31:51 +00002600 case OSPF_AS_NSSA_LSA:
2601 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2602 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002603 break;
paul718e3742002-12-13 20:15:29 +00002604 default:
paul68980082003-03-25 05:07:42 +00002605 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002606 break;
2607 }
2608
paul68980082003-03-25 05:07:42 +00002609 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002610 ospf_lsa_discard (old);
2611}
2612
paul718e3742002-12-13 20:15:29 +00002613struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002614ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2615 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002616{
2617 struct ospf_lsa *new = NULL;
2618 struct ospf_lsa *old = NULL;
2619 struct ospf_lsdb *lsdb = NULL;
2620 int rt_recalc;
2621
2622 /* Set LSDB. */
2623 switch (lsa->data->type)
2624 {
paulf2c80652002-12-13 21:44:27 +00002625 /* kevinm */
2626 case OSPF_AS_NSSA_LSA:
2627 if (lsa->area)
2628 lsdb = lsa->area->lsdb;
2629 else
paul68980082003-03-25 05:07:42 +00002630 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002631 break;
paul718e3742002-12-13 20:15:29 +00002632 case OSPF_AS_EXTERNAL_LSA:
paul718e3742002-12-13 20:15:29 +00002633 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002634 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002635 break;
2636 default:
2637 lsdb = lsa->area->lsdb;
2638 break;
2639 }
2640
paul718e3742002-12-13 20:15:29 +00002641 assert (lsdb);
2642
2643 /* RFC 2328 13.2. Installing LSAs in the database
2644
2645 Installing a new LSA in the database, either as the result of
2646 flooding or a newly self-originated LSA, may cause the OSPF
2647 routing table structure to be recalculated. The contents of the
2648 new LSA should be compared to the old instance, if present. If
2649 there is no difference, there is no need to recalculate the
2650 routing table. When comparing an LSA to its previous instance,
2651 the following are all considered to be differences in contents:
2652
2653 o The LSA's Options field has changed.
2654
2655 o One of the LSA instances has LS age set to MaxAge, and
2656 the other does not.
2657
2658 o The length field in the LSA header has changed.
2659
2660 o The body of the LSA (i.e., anything outside the 20-byte
2661 LSA header) has changed. Note that this excludes changes
2662 in LS Sequence Number and LS Checksum.
2663
2664 */
2665 /* Look up old LSA and determine if any SPF calculation or incremental
2666 update is needed */
2667 old = ospf_lsdb_lookup (lsdb, lsa);
2668
2669 /* Do comparision and record if recalc needed. */
2670 rt_recalc = 0;
2671 if ( old == NULL || ospf_lsa_different(old, lsa))
2672 rt_recalc = 1;
2673
paul7ddf1d62003-10-13 09:06:46 +00002674 /*
2675 Sequence number check (Section 14.1 of rfc 2328)
2676 "Premature aging is used when it is time for a self-originated
2677 LSA's sequence number field to wrap. At this point, the current
2678 LSA instance (having LS sequence number MaxSequenceNumber) must
2679 be prematurely aged and flushed from the routing domain before a
2680 new instance with sequence number equal to InitialSequenceNumber
2681 can be originated. "
2682 */
2683
Paul Jakmac2b478d2006-03-30 14:16:11 +00002684 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002685 {
2686 if (ospf_lsa_is_self_originated(ospf, lsa))
2687 {
paul0c2be262004-05-31 14:16:54 +00002688 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2689
2690 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002691 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2692 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2693
2694 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2695 {
ajse588f212004-12-08 18:12:06 +00002696 zlog_debug ("ospf_lsa_install() Premature Aging "
Paul Jakmac363d382010-01-24 22:42:13 +00002697 "lsa 0x%p, seqnum 0x%x",
David Lampartereed3c482015-03-03 08:51:53 +01002698 (void *)lsa, ntohl(lsa->data->ls_seqnum));
paul7ddf1d62003-10-13 09:06:46 +00002699 ospf_lsa_header_dump (lsa->data);
2700 }
2701 }
2702 else
2703 {
2704 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2705 {
ajse588f212004-12-08 18:12:06 +00002706 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002707 "that was not self originated. Ignoring\n");
2708 ospf_lsa_header_dump (lsa->data);
2709 }
2710 return old;
2711 }
2712 }
2713
paul718e3742002-12-13 20:15:29 +00002714 /* discard old LSA from LSDB */
2715 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002716 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002717
paul718e3742002-12-13 20:15:29 +00002718 /* Calculate Checksum if self-originated?. */
2719 if (IS_LSA_SELF (lsa))
2720 ospf_lsa_checksum (lsa->data);
2721
hassofe71a972004-12-22 16:16:02 +00002722 /* Insert LSA to LSDB. */
2723 ospf_lsdb_add (lsdb, lsa);
2724 lsa->lsdb = lsdb;
2725
paul718e3742002-12-13 20:15:29 +00002726 /* Do LSA specific installation process. */
2727 switch (lsa->data->type)
2728 {
2729 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002730 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002731 break;
2732 case OSPF_NETWORK_LSA:
2733 assert (oi);
paul68980082003-03-25 05:07:42 +00002734 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002735 break;
2736 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002737 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002738 break;
2739 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002740 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002741 break;
2742 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002743 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002744 break;
paul718e3742002-12-13 20:15:29 +00002745 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002746 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002747 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002748 else
Andrew Certain0798cee2012-12-04 13:43:42 -08002749 {
2750 /* Incoming "oi" for this LSA has set at LSUpd reception. */
2751 }
paul09e4efd2003-01-18 00:12:02 +00002752 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002753 case OSPF_OPAQUE_AREA_LSA:
2754 case OSPF_OPAQUE_AS_LSA:
2755 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2756 break;
pauld4a53d52003-07-12 21:30:57 +00002757 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002758 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002759 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002760 break;
2761 }
2762
2763 if (new == NULL)
2764 return new; /* Installation failed, cannot proceed further -- endo. */
2765
2766 /* Debug logs. */
2767 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2768 {
2769 char area_str[INET_ADDRSTRLEN];
2770
2771 switch (lsa->data->type)
2772 {
2773 case OSPF_AS_EXTERNAL_LSA:
paul718e3742002-12-13 20:15:29 +00002774 case OSPF_OPAQUE_AS_LSA:
hassobeebba72004-06-20 21:00:27 +00002775 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002776 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002777 dump_lsa_key (new),
2778 LOOKUP (ospf_lsa_type_msg, new->data->type));
2779 break;
2780 default:
2781 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002782 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002783 dump_lsa_key (new),
2784 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2785 break;
2786 }
2787 }
2788
paul7ddf1d62003-10-13 09:06:46 +00002789 /*
2790 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2791 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2792 */
Dinesh G Dutte0630cb2013-01-07 10:12:52 -08002793 if (IS_LSA_MAXAGE (new))
paul718e3742002-12-13 20:15:29 +00002794 {
paul7ddf1d62003-10-13 09:06:46 +00002795 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002796 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
David Lampartereed3c482015-03-03 08:51:53 +01002797 new->data->type,
2798 inet_ntoa (new->data->id),
2799 (void *)lsa);
Dinesh G Dutte0630cb2013-01-07 10:12:52 -08002800 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002801 }
2802
2803 return new;
2804}
2805
David Lamparter6b0655a2014-06-04 06:53:35 +02002806
Christian Franke4c14b7f2013-02-20 10:00:54 +00002807int
paul68980082003-03-25 05:07:42 +00002808ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002809{
paul1eb8ef22005-04-07 07:30:20 +00002810 struct listnode *node, *nnode;
2811 struct ospf_interface *oi;
2812
2813 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002814 {
paul718e3742002-12-13 20:15:29 +00002815 struct route_node *rn;
2816 struct ospf_neighbor *nbr;
2817
2818 if (ospf_if_is_enable (oi))
2819 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2820 if ((nbr = rn->info) != NULL)
2821 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2822 {
2823 route_unlock_node (rn);
2824 return 0;
2825 }
2826 }
2827
2828 return 1;
2829}
2830
David Lamparter6b0655a2014-06-04 06:53:35 +02002831
paul718e3742002-12-13 20:15:29 +00002832
paul4dadc292005-05-06 21:37:42 +00002833static int
paul718e3742002-12-13 20:15:29 +00002834ospf_maxage_lsa_remover (struct thread *thread)
2835{
paul68980082003-03-25 05:07:42 +00002836 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002837 struct ospf_lsa *lsa;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002838 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00002839 int reschedule = 0;
2840
paul68980082003-03-25 05:07:42 +00002841 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002842
2843 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002844 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002845
paul68980082003-03-25 05:07:42 +00002846 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002847
2848 if (!reschedule)
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002849 for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn))
paul718e3742002-12-13 20:15:29 +00002850 {
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002851 if ((lsa = rn->info) == NULL)
2852 {
2853 continue;
2854 }
2855
Christian Franke4de8bf02013-02-20 10:00:52 +00002856 /* There is at least one neighbor from which we still await an ack
2857 * for that LSA, so we are not allowed to remove it from our lsdb yet
2858 * as per RFC 2328 section 14 para 4 a) */
paul718e3742002-12-13 20:15:29 +00002859 if (lsa->retransmit_counter > 0)
2860 {
2861 reschedule = 1;
2862 continue;
2863 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002864
2865 /* TODO: maybe convert this function to a work-queue */
2866 if (thread_should_yield (thread))
Christian Franke4de8bf02013-02-20 10:00:52 +00002867 {
2868 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);
Christian Frankee387dfd2014-04-28 08:04:58 +00002869 route_unlock_node(rn); /* route_top/route_next */
Christian Franke4de8bf02013-02-20 10:00:52 +00002870 return 0;
2871 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002872
paul718e3742002-12-13 20:15:29 +00002873 /* Remove LSA from the LSDB */
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04002874 if (IS_LSA_SELF (lsa))
paul718e3742002-12-13 20:15:29 +00002875 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
Denis Ovsienkoad8d4802011-12-02 20:02:40 +04002876 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-originated: ",
paul7ddf1d62003-10-13 09:06:46 +00002877 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002878
2879 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002880 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002881 lsa->data->type, inet_ntoa (lsa->data->id));
2882
Paul Jakmac363d382010-01-24 22:42:13 +00002883 if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))
paul7ddf1d62003-10-13 09:06:46 +00002884 {
2885 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
David Lampartereed3c482015-03-03 08:51:53 +01002886 zlog_debug ("originating new lsa for lsa 0x%p\n", (void *)lsa);
Paul Jakmac363d382010-01-24 22:42:13 +00002887 ospf_lsa_refresh (ospf, lsa);
paul7ddf1d62003-10-13 09:06:46 +00002888 }
2889
paul718e3742002-12-13 20:15:29 +00002890 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002891 if (lsa->lsdb)
2892 {
2893 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2894 ospf_lsdb_delete (lsa->lsdb, lsa);
2895 }
2896 else
2897 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2898 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002899 }
2900
2901 /* A MaxAge LSA must be removed immediately from the router's link
2902 state database as soon as both a) it is no longer contained on any
2903 neighbor Link state retransmission lists and b) none of the router's
2904 neighbors are in states Exchange or Loading. */
2905 if (reschedule)
Paul Jakma02d942c2010-01-24 23:36:20 +00002906 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2907 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002908
2909 return 0;
2910}
2911
paul718e3742002-12-13 20:15:29 +00002912void
paul68980082003-03-25 05:07:42 +00002913ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002914{
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002915 struct route_node *rn;
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002916 struct prefix_ptr lsa_prefix;
paul718e3742002-12-13 20:15:29 +00002917
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002918 lsa_prefix.family = 0;
2919 lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
2920 lsa_prefix.prefix = (uintptr_t) lsa;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002921
2922 if ((rn = route_node_lookup(ospf->maxage_lsa,
2923 (struct prefix *)&lsa_prefix)))
paul718e3742002-12-13 20:15:29 +00002924 {
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002925 if (rn->info == lsa)
2926 {
2927 UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
2928 ospf_lsa_unlock (&lsa); /* maxage_lsa */
2929 rn->info = NULL;
Christian Franke8afee5c2014-04-28 08:04:59 +00002930 route_unlock_node (rn); /* unlock node because lsa is deleted */
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002931 }
Christian Franke8afee5c2014-04-28 08:04:59 +00002932 route_unlock_node (rn); /* route_node_lookup */
paul718e3742002-12-13 20:15:29 +00002933 }
2934}
2935
Paul Jakma02d942c2010-01-24 23:36:20 +00002936/* Add LSA onto the MaxAge list, and schedule for removal.
2937 * This does *not* lead to the LSA being flooded, that must be taken
2938 * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
2939 * function).
2940 */
paul718e3742002-12-13 20:15:29 +00002941void
paul68980082003-03-25 05:07:42 +00002942ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002943{
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002944 struct prefix_ptr lsa_prefix;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002945 struct route_node *rn;
2946
paul718e3742002-12-13 20:15:29 +00002947 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2948 and schedule the MaxAge LSA remover. */
Stephen Hemminger3106a032009-08-06 12:58:05 -07002949 if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
paul718e3742002-12-13 20:15:29 +00002950 {
2951 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002952 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
David Lampartereed3c482015-03-03 08:51:53 +01002953 lsa->data->type, inet_ntoa (lsa->data->id), (void *)lsa);
paul718e3742002-12-13 20:15:29 +00002954 return;
2955 }
2956
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002957 lsa_prefix.family = 0;
2958 lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
2959 lsa_prefix.prefix = (uintptr_t) lsa;
2960
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002961 if ((rn = route_node_get (ospf->maxage_lsa,
2962 (struct prefix *)&lsa_prefix)) != NULL)
2963 {
2964 if (rn->info != NULL)
2965 {
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002966 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2967 zlog_debug ("LSA[%s]: found LSA (%p) in table for LSA %p %d",
David Lampartereed3c482015-03-03 08:51:53 +01002968 dump_lsa_key (lsa), rn->info, (void *)lsa,
2969 lsa_prefix.prefixlen);
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002970 route_unlock_node (rn);
2971 }
2972 else
2973 {
2974 rn->info = ospf_lsa_lock(lsa);
2975 SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
2976 }
2977 }
2978 else
2979 {
2980 zlog_err("Unable to allocate memory for maxage lsa\n");
2981 assert(0);
2982 }
paul718e3742002-12-13 20:15:29 +00002983
2984 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002985 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002986
Paul Jakma02d942c2010-01-24 23:36:20 +00002987 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2988 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002989}
2990
paul4dadc292005-05-06 21:37:42 +00002991static int
paul68980082003-03-25 05:07:42 +00002992ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002993{
paul718e3742002-12-13 20:15:29 +00002994 /* Stay away from any Local Translated Type-7 LSAs */
2995 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
2996 return 0;
paul718e3742002-12-13 20:15:29 +00002997
2998 if (IS_LSA_MAXAGE (lsa))
2999 /* Self-originated LSAs should NOT time-out instead,
3000 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00003001 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003002 {
3003 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003004 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003005
3006 switch (lsa->data->type)
3007 {
paul37163d62003-02-03 18:40:56 +00003008 case OSPF_OPAQUE_LINK_LSA:
3009 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003010 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003011 /*
3012 * As a general rule, whenever network topology has changed
3013 * (due to an LSA removal in this case), routing recalculation
3014 * should be triggered. However, this is not true for opaque
3015 * LSAs. Even if an opaque LSA instance is going to be removed
3016 * from the routing domain, it does not mean a change in network
3017 * topology, and thus, routing recalculation is not needed here.
3018 */
3019 break;
paul09e4efd2003-01-18 00:12:02 +00003020 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003021 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003022 ospf_ase_incremental_update (ospf, lsa);
3023 break;
paul718e3742002-12-13 20:15:29 +00003024 default:
Paul Jakmab6eef002014-10-09 14:19:51 +01003025 ospf_spf_calculate_schedule (ospf, SPF_FLAG_MAXAGE);
paul68980082003-03-25 05:07:42 +00003026 break;
paul718e3742002-12-13 20:15:29 +00003027 }
paul68980082003-03-25 05:07:42 +00003028 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003029 }
3030
Paul Jakmac363d382010-01-24 22:42:13 +00003031 if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa))
3032 if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30)
3033 printf ("Eek! Shouldn't happen!\n");
3034
paul718e3742002-12-13 20:15:29 +00003035 return 0;
3036}
3037
3038/* Periodical check of MaxAge LSA. */
3039int
paul68980082003-03-25 05:07:42 +00003040ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003041{
paul68980082003-03-25 05:07:42 +00003042 struct ospf *ospf = THREAD_ARG (thread);
3043 struct route_node *rn;
3044 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003045 struct ospf_area *area;
3046 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003047
paul68980082003-03-25 05:07:42 +00003048 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003049
paul1eb8ef22005-04-07 07:30:20 +00003050 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003051 {
paul68980082003-03-25 05:07:42 +00003052 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3053 ospf_lsa_maxage_walker_remover (ospf, lsa);
3054 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3055 ospf_lsa_maxage_walker_remover (ospf, lsa);
3056 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3057 ospf_lsa_maxage_walker_remover (ospf, lsa);
3058 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3059 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul68980082003-03-25 05:07:42 +00003060 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3061 ospf_lsa_maxage_walker_remover (ospf, lsa);
3062 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3063 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul4fb949e2003-05-10 20:06:51 +00003064 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3065 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003066 }
3067
paul4fb949e2003-05-10 20:06:51 +00003068 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003069 if (ospf->lsdb)
3070 {
3071 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3072 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul68980082003-03-25 05:07:42 +00003073 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3074 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul68980082003-03-25 05:07:42 +00003075 }
paul718e3742002-12-13 20:15:29 +00003076
paul68980082003-03-25 05:07:42 +00003077 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3078 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003079 return 0;
3080}
3081
paul68980082003-03-25 05:07:42 +00003082struct ospf_lsa *
3083ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3084 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003085{
paul68980082003-03-25 05:07:42 +00003086 struct ospf_lsa *lsa;
3087 struct in_addr mask, id;
3088 struct lsa_header_mask
3089 {
3090 struct lsa_header header;
3091 struct in_addr mask;
3092 } *hmask;
paul718e3742002-12-13 20:15:29 +00003093
paul68980082003-03-25 05:07:42 +00003094 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3095 if (lsa == NULL)
3096 return NULL;
paul718e3742002-12-13 20:15:29 +00003097
paul68980082003-03-25 05:07:42 +00003098 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003099
paul68980082003-03-25 05:07:42 +00003100 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003101
paul68980082003-03-25 05:07:42 +00003102 if (mask.s_addr != hmask->mask.s_addr)
3103 {
3104 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3105 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3106 if (!lsa)
3107 return NULL;
3108 }
paul718e3742002-12-13 20:15:29 +00003109
paul68980082003-03-25 05:07:42 +00003110 return lsa;
paul718e3742002-12-13 20:15:29 +00003111}
3112
3113struct ospf_lsa *
3114ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3115 struct in_addr id, struct in_addr adv_router)
3116{
paule05fba42003-04-13 20:20:53 +00003117 struct ospf *ospf = ospf_lookup();
3118 assert(ospf);
3119
paul718e3742002-12-13 20:15:29 +00003120 switch (type)
3121 {
3122 case OSPF_ROUTER_LSA:
3123 case OSPF_NETWORK_LSA:
3124 case OSPF_SUMMARY_LSA:
3125 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003126 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003127 case OSPF_OPAQUE_LINK_LSA:
3128 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003129 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003130 case OSPF_AS_EXTERNAL_LSA:
paul718e3742002-12-13 20:15:29 +00003131 case OSPF_OPAQUE_AS_LSA:
paule05fba42003-04-13 20:20:53 +00003132 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003133 default:
3134 break;
3135 }
3136
3137 return NULL;
3138}
3139
3140struct ospf_lsa *
3141ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3142 struct in_addr id)
3143{
3144 struct ospf_lsa *lsa;
3145 struct route_node *rn;
3146
3147 switch (type)
3148 {
3149 case OSPF_ROUTER_LSA:
3150 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003151 case OSPF_NETWORK_LSA:
3152 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3153 if ((lsa = rn->info))
3154 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3155 {
3156 route_unlock_node (rn);
3157 return lsa;
3158 }
3159 break;
3160 case OSPF_SUMMARY_LSA:
3161 case OSPF_ASBR_SUMMARY_LSA:
3162 /* Currently not used. */
3163 assert (1);
3164 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003165 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003166 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003167 case OSPF_OPAQUE_LINK_LSA:
3168 case OSPF_OPAQUE_AREA_LSA:
3169 case OSPF_OPAQUE_AS_LSA:
3170 /* Currently not used. */
3171 break;
paul718e3742002-12-13 20:15:29 +00003172 default:
3173 break;
3174 }
3175
3176 return NULL;
3177}
3178
3179struct ospf_lsa *
3180ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3181{
3182 struct ospf_lsa *match;
3183
paul718e3742002-12-13 20:15:29 +00003184 /*
3185 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3186 * is redefined to have two subfields; opaque-type and opaque-id.
3187 * However, it is harmless to treat the two sub fields together, as if
3188 * they two were forming a unique LSA-ID.
3189 */
paul718e3742002-12-13 20:15:29 +00003190
3191 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3192
3193 if (match == NULL)
3194 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003195 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003196 lsah->type, inet_ntoa (lsah->id));
3197
3198 return match;
3199}
3200
3201/* return +n, l1 is more recent.
3202 return -n, l2 is more recent.
3203 return 0, l1 and l2 is identical. */
3204int
3205ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3206{
3207 int r;
3208 int x, y;
3209
3210 if (l1 == NULL && l2 == NULL)
3211 return 0;
3212 if (l1 == NULL)
3213 return -1;
3214 if (l2 == NULL)
3215 return 1;
3216
3217 /* compare LS sequence number. */
3218 x = (int) ntohl (l1->data->ls_seqnum);
3219 y = (int) ntohl (l2->data->ls_seqnum);
3220 if (x > y)
3221 return 1;
3222 if (x < y)
3223 return -1;
3224
3225 /* compare LS checksum. */
3226 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3227 if (r)
3228 return r;
3229
3230 /* compare LS age. */
3231 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3232 return 1;
3233 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3234 return -1;
3235
3236 /* compare LS age with MaxAgeDiff. */
3237 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3238 return -1;
3239 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3240 return 1;
3241
3242 /* LSAs are identical. */
3243 return 0;
3244}
3245
3246/* If two LSAs are different, return 1, otherwise return 0. */
3247int
3248ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3249{
3250 char *p1, *p2;
3251 assert (l1);
3252 assert (l2);
3253 assert (l1->data);
3254 assert (l2->data);
3255
3256 if (l1->data->options != l2->data->options)
3257 return 1;
3258
3259 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3260 return 1;
3261
3262 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3263 return 1;
3264
3265 if (l1->data->length != l2->data->length)
3266 return 1;
3267
3268 if (l1->data->length == 0)
3269 return 1;
3270
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02003271 if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
3272 return 1; /* May be a stale LSA in the LSBD */
3273
pauld1825832003-04-03 01:27:01 +00003274 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003275
3276 p1 = (char *) l1->data;
3277 p2 = (char *) l2->data;
3278
3279 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3280 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3281 return 1;
3282
3283 return 0;
3284}
3285
3286#ifdef ORIGINAL_CODING
3287void
3288ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3289 struct ospf_lsa *self,
3290 struct ospf_lsa *new)
3291{
3292 u_int32_t seqnum;
3293
3294 /* Adjust LS Sequence Number. */
3295 seqnum = ntohl (new->data->ls_seqnum) + 1;
3296 self->data->ls_seqnum = htonl (seqnum);
3297
3298 /* Recalculate LSA checksum. */
3299 ospf_lsa_checksum (self->data);
3300
3301 /* Reflooding LSA. */
3302 /* RFC2328 Section 13.3
3303 On non-broadcast networks, separate Link State Update
3304 packets must be sent, as unicasts, to each adjacent neighbor
3305 (i.e., those in state Exchange or greater). The destination
3306 IP addresses for these packets are the neighbors' IP
3307 addresses. */
3308 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3309 {
3310 struct route_node *rn;
3311 struct ospf_neighbor *onbr;
3312
3313 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3314 if ((onbr = rn->info) != NULL)
3315 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3316 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3317 }
3318 else
3319 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3320
3321 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003322 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003323 self->data->type, inet_ntoa (self->data->id));
3324}
3325#else /* ORIGINAL_CODING */
3326static int
paul68980082003-03-25 05:07:42 +00003327ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003328{
3329 if (lsa == NULL || !IS_LSA_SELF (lsa))
3330 return 0;
3331
3332 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003333 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 +00003334
3335 /* Force given lsa's age to MaxAge. */
3336 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3337
3338 switch (lsa->data->type)
3339 {
Paul Jakma02d942c2010-01-24 23:36:20 +00003340 /* Opaque wants to be notified of flushes */
paul718e3742002-12-13 20:15:29 +00003341 case OSPF_OPAQUE_LINK_LSA:
3342 case OSPF_OPAQUE_AREA_LSA:
3343 case OSPF_OPAQUE_AS_LSA:
3344 ospf_opaque_lsa_refresh (lsa);
3345 break;
paul718e3742002-12-13 20:15:29 +00003346 default:
Paul Jakmadfbd5172010-04-14 10:32:12 +01003347 ospf_refresher_unregister_lsa (ospf, lsa);
Paul Jakma02d942c2010-01-24 23:36:20 +00003348 ospf_lsa_flush (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003349 break;
3350 }
3351
3352 return 0;
3353}
3354
3355void
paul68980082003-03-25 05:07:42 +00003356ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003357{
paul1eb8ef22005-04-07 07:30:20 +00003358 struct listnode *node, *nnode;
3359 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003360 struct ospf_area *area;
3361 struct ospf_interface *oi;
3362 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003363 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003364 int need_to_flush_ase = 0;
3365
paul1eb8ef22005-04-07 07:30:20 +00003366 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003367 {
paul718e3742002-12-13 20:15:29 +00003368 if ((lsa = area->router_lsa_self) != NULL)
3369 {
3370 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003371 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3372 lsa->data->type, inet_ntoa (lsa->data->id));
3373
3374 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003375 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003376 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003377 area->router_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003378 }
3379
paul1eb8ef22005-04-07 07:30:20 +00003380 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003381 {
paul718e3742002-12-13 20:15:29 +00003382 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003383 && oi->state == ISM_DR
3384 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003385 {
3386 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003387 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3388 lsa->data->type, inet_ntoa (lsa->data->id));
3389
3390 ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003391 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003392 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003393 oi->network_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003394 }
3395
3396 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3397 && area->external_routing == OSPF_AREA_DEFAULT)
3398 need_to_flush_ase = 1;
3399 }
3400
paul68980082003-03-25 05:07:42 +00003401 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3402 ospf_lsa_flush_schedule (ospf, lsa);
3403 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3404 ospf_lsa_flush_schedule (ospf, lsa);
paul68980082003-03-25 05:07:42 +00003405 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3406 ospf_lsa_flush_schedule (ospf, lsa);
3407 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3408 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003409 }
3410
3411 if (need_to_flush_ase)
3412 {
paul68980082003-03-25 05:07:42 +00003413 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3414 ospf_lsa_flush_schedule (ospf, lsa);
paul68980082003-03-25 05:07:42 +00003415 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3416 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003417 }
3418
3419 /*
3420 * Make sure that the MaxAge LSA remover is executed immediately,
3421 * without conflicting to other threads.
3422 */
paul68980082003-03-25 05:07:42 +00003423 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003424 {
paul68980082003-03-25 05:07:42 +00003425 OSPF_TIMER_OFF (ospf->t_maxage);
3426 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003427 }
3428
3429 return;
3430}
3431#endif /* ORIGINAL_CODING */
3432
3433/* If there is self-originated LSA, then return 1, otherwise return 0. */
3434/* An interface-independent version of ospf_lsa_is_self_originated */
3435int
paul68980082003-03-25 05:07:42 +00003436ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003437{
hasso52dc7ee2004-09-23 19:18:23 +00003438 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003439 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003440
3441 /* This LSA is already checked. */
3442 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003443 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003444
3445 /* Make sure LSA is self-checked. */
3446 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3447
3448 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003449 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003450 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3451
3452 /* LSA is router-LSA. */
3453 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003454 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003455 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3456
3457 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3458 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003459 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003460 {
paul718e3742002-12-13 20:15:29 +00003461 /* Ignore virtual link. */
3462 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3463 if (oi->address->family == AF_INET)
3464 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3465 {
3466 /* to make it easier later */
3467 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003468 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003469 }
3470 }
3471
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003472 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003473}
3474
3475/* Get unique Link State ID. */
3476struct in_addr
paul68980082003-03-25 05:07:42 +00003477ospf_lsa_unique_id (struct ospf *ospf,
3478 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003479{
3480 struct ospf_lsa *lsa;
3481 struct in_addr mask, id;
3482
3483 id = p->prefix;
3484
3485 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003486 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003487 if (lsa)
3488 {
3489 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3490 if (ip_masklen (al->mask) == p->prefixlen)
3491 {
3492 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003493 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003494 "Can't get Link State ID for %s/%d",
3495 inet_ntoa (p->prefix), p->prefixlen);
3496 /* id.s_addr = 0; */
3497 id.s_addr = 0xffffffff;
3498 return id;
3499 }
3500 /* Masklen differs, then apply wildcard mask to Link State ID. */
3501 else
3502 {
3503 masklen2ip (p->prefixlen, &mask);
3504
3505 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003506 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3507 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003508 if (lsa)
3509 {
3510 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003511 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003512 "Can't get Link State ID for %s/%d",
3513 inet_ntoa (p->prefix), p->prefixlen);
3514 /* id.s_addr = 0; */
3515 id.s_addr = 0xffffffff;
3516 return id;
3517 }
3518 }
3519 }
3520
3521 return id;
3522}
3523
David Lamparter6b0655a2014-06-04 06:53:35 +02003524
Paul Jakma70461d72006-05-12 22:57:57 +00003525#define LSA_ACTION_FLOOD_AREA 1
3526#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003527
3528struct lsa_action
3529{
3530 u_char action;
3531 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003532 struct ospf_lsa *lsa;
3533};
3534
paul4dadc292005-05-06 21:37:42 +00003535static int
paul718e3742002-12-13 20:15:29 +00003536ospf_lsa_action (struct thread *t)
3537{
3538 struct lsa_action *data;
3539
3540 data = THREAD_ARG (t);
3541
3542 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003543 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003544 data->action);
3545
3546 switch (data->action)
3547 {
paul718e3742002-12-13 20:15:29 +00003548 case LSA_ACTION_FLOOD_AREA:
3549 ospf_flood_through_area (data->area, NULL, data->lsa);
3550 break;
paul718e3742002-12-13 20:15:29 +00003551 case LSA_ACTION_FLUSH_AREA:
3552 ospf_lsa_flush_area (data->lsa, data->area);
3553 break;
paul718e3742002-12-13 20:15:29 +00003554 }
3555
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003556 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003557 XFREE (MTYPE_OSPF_MESSAGE, data);
3558 return 0;
3559}
3560
3561void
3562ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3563{
3564 struct lsa_action *data;
3565
Stephen Hemminger393deb92008-08-18 14:13:29 -07003566 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003567 data->action = LSA_ACTION_FLOOD_AREA;
3568 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003569 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003570
3571 thread_add_event (master, ospf_lsa_action, data, 0);
3572}
3573
3574void
3575ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3576{
3577 struct lsa_action *data;
3578
Stephen Hemminger393deb92008-08-18 14:13:29 -07003579 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003580 data->action = LSA_ACTION_FLUSH_AREA;
3581 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003582 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003583
3584 thread_add_event (master, ospf_lsa_action, data, 0);
3585}
3586
David Lamparter6b0655a2014-06-04 06:53:35 +02003587
paul718e3742002-12-13 20:15:29 +00003588/* LSA Refreshment functions. */
Paul Jakmac363d382010-01-24 22:42:13 +00003589struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00003590ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003591{
3592 struct external_info *ei;
Paul Jakmac363d382010-01-24 22:42:13 +00003593 struct ospf_lsa *new = NULL;
paul718e3742002-12-13 20:15:29 +00003594 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003595 assert (IS_LSA_SELF (lsa));
Paul Jakma66349742010-04-13 22:33:54 +01003596 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003597
3598 switch (lsa->data->type)
3599 {
3600 /* Router and Network LSAs are processed differently. */
3601 case OSPF_ROUTER_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003602 new = ospf_router_lsa_refresh (lsa);
3603 break;
paul718e3742002-12-13 20:15:29 +00003604 case OSPF_NETWORK_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003605 new = ospf_network_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003606 break;
3607 case OSPF_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003608 new = ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003609 break;
3610 case OSPF_ASBR_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003611 new = ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003612 break;
3613 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003614 /* Translated from NSSA Type-5s are refreshed when
3615 * from refresh of Type-7 - do not refresh these directly.
3616 */
3617 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3618 break;
paul718e3742002-12-13 20:15:29 +00003619 ei = ospf_external_info_check (lsa);
3620 if (ei)
Paul Jakmac363d382010-01-24 22:42:13 +00003621 new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003622 else
pauld4a53d52003-07-12 21:30:57 +00003623 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003624 break;
paul718e3742002-12-13 20:15:29 +00003625 case OSPF_OPAQUE_LINK_LSA:
3626 case OSPF_OPAQUE_AREA_LSA:
3627 case OSPF_OPAQUE_AS_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003628 new = ospf_opaque_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003629 break;
3630 default:
3631 break;
paul718e3742002-12-13 20:15:29 +00003632 }
Paul Jakmac363d382010-01-24 22:42:13 +00003633 return new;
paul718e3742002-12-13 20:15:29 +00003634}
3635
3636void
paul68980082003-03-25 05:07:42 +00003637ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003638{
3639 u_int16_t index, current_index;
3640
Paul Jakma66349742010-04-13 22:33:54 +01003641 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003642 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003643
3644 if (lsa->refresh_list < 0)
3645 {
3646 int delay;
3647
3648 if (LS_AGE (lsa) == 0 &&
3649 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3650 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3651 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3652 else
3653 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3654 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3655 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3656
3657 if (delay < 0)
3658 delay = 0;
3659
Paul Jakmac363d382010-01-24 22:42:13 +00003660 current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL)
3661 - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003662
3663 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
Paul Jakmac363d382010-01-24 22:42:13 +00003664 % (OSPF_LSA_REFRESHER_SLOTS);
paul718e3742002-12-13 20:15:29 +00003665
3666 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003667 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003668 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003669 if (!ospf->lsa_refresh_queue.qs[index])
3670 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003671 listnode_add (ospf->lsa_refresh_queue.qs[index],
3672 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003673 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003674 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003675 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003676 "setting refresh_list on lsa %p (slod %d)",
David Lampartereed3c482015-03-03 08:51:53 +01003677 inet_ntoa (lsa->data->id), (void *)lsa, index);
paul718e3742002-12-13 20:15:29 +00003678 }
3679}
3680
3681void
paul68980082003-03-25 05:07:42 +00003682ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003683{
Paul Jakma66349742010-04-13 22:33:54 +01003684 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003685 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003686 if (lsa->refresh_list >= 0)
3687 {
hasso52dc7ee2004-09-23 19:18:23 +00003688 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003689 listnode_delete (refresh_list, lsa);
3690 if (!listcount (refresh_list))
3691 {
3692 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003693 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003694 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003695 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003696 lsa->refresh_list = -1;
3697 }
3698}
3699
3700int
3701ospf_lsa_refresh_walker (struct thread *t)
3702{
hasso52dc7ee2004-09-23 19:18:23 +00003703 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003704 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003705 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003706 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003707 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003708 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003709
3710 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003711 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003712
3713
paul68980082003-03-25 05:07:42 +00003714 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003715
ajs9dbc7972005-03-13 19:27:22 +00003716 /* Note: if clock has jumped backwards, then time change could be negative,
3717 so we are careful to cast the expression to unsigned before taking
3718 modulus. */
paul68980082003-03-25 05:07:42 +00003719 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003720 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakmac363d382010-01-24 22:42:13 +00003721 (quagga_time (NULL) - ospf->lsa_refresher_started)
3722 / OSPF_LSA_REFRESHER_GRANULARITY))
3723 % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003724
3725 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003726 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003727 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003728
paul68980082003-03-25 05:07:42 +00003729 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003730 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3731 {
3732 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003733 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003734 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003735
paul68980082003-03-25 05:07:42 +00003736 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003737
Paul Jakma66349742010-04-13 22:33:54 +01003738 assert (i >= 0);
3739
paul68980082003-03-25 05:07:42 +00003740 ospf->lsa_refresh_queue.qs [i] = NULL;
3741
paul718e3742002-12-13 20:15:29 +00003742 if (refresh_list)
3743 {
paul1eb8ef22005-04-07 07:30:20 +00003744 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003745 {
paul718e3742002-12-13 20:15:29 +00003746 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003747 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
David Lampartereed3c482015-03-03 08:51:53 +01003748 "refresh lsa %p (slot %d)",
3749 inet_ntoa (lsa->data->id), (void *)lsa, i);
3750
Paul Jakma66349742010-04-13 22:33:54 +01003751 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003752 list_delete_node (refresh_list, node);
paul718e3742002-12-13 20:15:29 +00003753 lsa->refresh_list = -1;
3754 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003755 }
3756 list_free (refresh_list);
3757 }
3758 }
3759
paul68980082003-03-25 05:07:42 +00003760 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3761 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003762 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003763
paul1eb8ef22005-04-07 07:30:20 +00003764 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
Paul Jakma66349742010-04-13 22:33:54 +01003765 {
3766 ospf_lsa_refresh (ospf, lsa);
3767 assert (lsa->lock > 0);
3768 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
3769 }
paul718e3742002-12-13 20:15:29 +00003770
3771 list_delete (lsa_to_refresh);
3772
3773 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003774 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003775
3776 return 0;
3777}
3778