blob: e62a4e7b91488fd7d0a6d55d2230dba2a73652da [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,
ajs5339cfd2005-09-19 13:28:05 +00002209 unsigned int 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#ifdef HAVE_OPAQUE_LSA
2598 case OSPF_OPAQUE_AS_LSA:
paul68980082003-03-25 05:07:42 +00002599 ospf_ls_retransmit_delete_nbr_as (ospf, old);
paul718e3742002-12-13 20:15:29 +00002600 break;
paul69310a62005-05-11 18:09:59 +00002601#endif /* HAVE_OPAQUE_LSA */
pauld7480322003-05-16 17:31:51 +00002602 case OSPF_AS_NSSA_LSA:
2603 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2604 ospf_ase_unregister_external_lsa (old, ospf);
hassobeebba72004-06-20 21:00:27 +00002605 break;
paul718e3742002-12-13 20:15:29 +00002606 default:
paul68980082003-03-25 05:07:42 +00002607 ospf_ls_retransmit_delete_nbr_area (old->area, old);
paul718e3742002-12-13 20:15:29 +00002608 break;
2609 }
2610
paul68980082003-03-25 05:07:42 +00002611 ospf_lsa_maxage_delete (ospf, old);
paul718e3742002-12-13 20:15:29 +00002612 ospf_lsa_discard (old);
2613}
2614
paul718e3742002-12-13 20:15:29 +00002615struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00002616ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2617 struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002618{
2619 struct ospf_lsa *new = NULL;
2620 struct ospf_lsa *old = NULL;
2621 struct ospf_lsdb *lsdb = NULL;
2622 int rt_recalc;
2623
2624 /* Set LSDB. */
2625 switch (lsa->data->type)
2626 {
paulf2c80652002-12-13 21:44:27 +00002627 /* kevinm */
2628 case OSPF_AS_NSSA_LSA:
2629 if (lsa->area)
2630 lsdb = lsa->area->lsdb;
2631 else
paul68980082003-03-25 05:07:42 +00002632 lsdb = ospf->lsdb;
paulf2c80652002-12-13 21:44:27 +00002633 break;
paul718e3742002-12-13 20:15:29 +00002634 case OSPF_AS_EXTERNAL_LSA:
2635#ifdef HAVE_OPAQUE_LSA
2636 case OSPF_OPAQUE_AS_LSA:
2637#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00002638 lsdb = ospf->lsdb;
paul718e3742002-12-13 20:15:29 +00002639 break;
2640 default:
2641 lsdb = lsa->area->lsdb;
2642 break;
2643 }
2644
paul718e3742002-12-13 20:15:29 +00002645 assert (lsdb);
2646
2647 /* RFC 2328 13.2. Installing LSAs in the database
2648
2649 Installing a new LSA in the database, either as the result of
2650 flooding or a newly self-originated LSA, may cause the OSPF
2651 routing table structure to be recalculated. The contents of the
2652 new LSA should be compared to the old instance, if present. If
2653 there is no difference, there is no need to recalculate the
2654 routing table. When comparing an LSA to its previous instance,
2655 the following are all considered to be differences in contents:
2656
2657 o The LSA's Options field has changed.
2658
2659 o One of the LSA instances has LS age set to MaxAge, and
2660 the other does not.
2661
2662 o The length field in the LSA header has changed.
2663
2664 o The body of the LSA (i.e., anything outside the 20-byte
2665 LSA header) has changed. Note that this excludes changes
2666 in LS Sequence Number and LS Checksum.
2667
2668 */
2669 /* Look up old LSA and determine if any SPF calculation or incremental
2670 update is needed */
2671 old = ospf_lsdb_lookup (lsdb, lsa);
2672
2673 /* Do comparision and record if recalc needed. */
2674 rt_recalc = 0;
2675 if ( old == NULL || ospf_lsa_different(old, lsa))
2676 rt_recalc = 1;
2677
paul7ddf1d62003-10-13 09:06:46 +00002678 /*
2679 Sequence number check (Section 14.1 of rfc 2328)
2680 "Premature aging is used when it is time for a self-originated
2681 LSA's sequence number field to wrap. At this point, the current
2682 LSA instance (having LS sequence number MaxSequenceNumber) must
2683 be prematurely aged and flushed from the routing domain before a
2684 new instance with sequence number equal to InitialSequenceNumber
2685 can be originated. "
2686 */
2687
Paul Jakmac2b478d2006-03-30 14:16:11 +00002688 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
paul7ddf1d62003-10-13 09:06:46 +00002689 {
2690 if (ospf_lsa_is_self_originated(ospf, lsa))
2691 {
paul0c2be262004-05-31 14:16:54 +00002692 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2693
2694 if (!IS_LSA_MAXAGE(lsa))
paul7ddf1d62003-10-13 09:06:46 +00002695 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2696 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2697
2698 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2699 {
ajse588f212004-12-08 18:12:06 +00002700 zlog_debug ("ospf_lsa_install() Premature Aging "
Paul Jakmac363d382010-01-24 22:42:13 +00002701 "lsa 0x%p, seqnum 0x%x",
David Lampartereed3c482015-03-03 08:51:53 +01002702 (void *)lsa, ntohl(lsa->data->ls_seqnum));
paul7ddf1d62003-10-13 09:06:46 +00002703 ospf_lsa_header_dump (lsa->data);
2704 }
2705 }
2706 else
2707 {
2708 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2709 {
ajse588f212004-12-08 18:12:06 +00002710 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
paul7ddf1d62003-10-13 09:06:46 +00002711 "that was not self originated. Ignoring\n");
2712 ospf_lsa_header_dump (lsa->data);
2713 }
2714 return old;
2715 }
2716 }
2717
paul718e3742002-12-13 20:15:29 +00002718 /* discard old LSA from LSDB */
2719 if (old != NULL)
paul68980082003-03-25 05:07:42 +00002720 ospf_discard_from_db (ospf, lsdb, lsa);
paul718e3742002-12-13 20:15:29 +00002721
paul718e3742002-12-13 20:15:29 +00002722 /* Calculate Checksum if self-originated?. */
2723 if (IS_LSA_SELF (lsa))
2724 ospf_lsa_checksum (lsa->data);
2725
hassofe71a972004-12-22 16:16:02 +00002726 /* Insert LSA to LSDB. */
2727 ospf_lsdb_add (lsdb, lsa);
2728 lsa->lsdb = lsdb;
2729
paul718e3742002-12-13 20:15:29 +00002730 /* Do LSA specific installation process. */
2731 switch (lsa->data->type)
2732 {
2733 case OSPF_ROUTER_LSA:
paul68980082003-03-25 05:07:42 +00002734 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002735 break;
2736 case OSPF_NETWORK_LSA:
2737 assert (oi);
paul68980082003-03-25 05:07:42 +00002738 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002739 break;
2740 case OSPF_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002741 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002742 break;
2743 case OSPF_ASBR_SUMMARY_LSA:
paul68980082003-03-25 05:07:42 +00002744 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002745 break;
2746 case OSPF_AS_EXTERNAL_LSA:
paul68980082003-03-25 05:07:42 +00002747 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
paul718e3742002-12-13 20:15:29 +00002748 break;
2749#ifdef HAVE_OPAQUE_LSA
2750 case OSPF_OPAQUE_LINK_LSA:
paul09e4efd2003-01-18 00:12:02 +00002751 if (IS_LSA_SELF (lsa))
paul68980082003-03-25 05:07:42 +00002752 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
paul09e4efd2003-01-18 00:12:02 +00002753 else
Andrew Certain0798cee2012-12-04 13:43:42 -08002754 {
2755 /* Incoming "oi" for this LSA has set at LSUpd reception. */
2756 }
paul09e4efd2003-01-18 00:12:02 +00002757 /* Fallthrough */
paul718e3742002-12-13 20:15:29 +00002758 case OSPF_OPAQUE_AREA_LSA:
2759 case OSPF_OPAQUE_AS_LSA:
2760 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2761 break;
2762#endif /* HAVE_OPAQUE_LSA */
pauld4a53d52003-07-12 21:30:57 +00002763 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00002764 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
pauld4a53d52003-07-12 21:30:57 +00002765 default: /* type-6,8,9....nothing special */
paul718e3742002-12-13 20:15:29 +00002766 break;
2767 }
2768
2769 if (new == NULL)
2770 return new; /* Installation failed, cannot proceed further -- endo. */
2771
2772 /* Debug logs. */
2773 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2774 {
2775 char area_str[INET_ADDRSTRLEN];
2776
2777 switch (lsa->data->type)
2778 {
2779 case OSPF_AS_EXTERNAL_LSA:
2780#ifdef HAVE_OPAQUE_LSA
2781 case OSPF_OPAQUE_AS_LSA:
2782#endif /* HAVE_OPAQUE_LSA */
hassobeebba72004-06-20 21:00:27 +00002783 case OSPF_AS_NSSA_LSA:
ajse588f212004-12-08 18:12:06 +00002784 zlog_debug ("LSA[%s]: Install %s",
paul718e3742002-12-13 20:15:29 +00002785 dump_lsa_key (new),
2786 LOOKUP (ospf_lsa_type_msg, new->data->type));
2787 break;
2788 default:
2789 strcpy (area_str, inet_ntoa (new->area->area_id));
ajse588f212004-12-08 18:12:06 +00002790 zlog_debug ("LSA[%s]: Install %s to Area %s",
paul718e3742002-12-13 20:15:29 +00002791 dump_lsa_key (new),
2792 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2793 break;
2794 }
2795 }
2796
paul7ddf1d62003-10-13 09:06:46 +00002797 /*
2798 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2799 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2800 */
Dinesh G Dutte0630cb2013-01-07 10:12:52 -08002801 if (IS_LSA_MAXAGE (new))
paul718e3742002-12-13 20:15:29 +00002802 {
paul7ddf1d62003-10-13 09:06:46 +00002803 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
ajse588f212004-12-08 18:12:06 +00002804 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
David Lampartereed3c482015-03-03 08:51:53 +01002805 new->data->type,
2806 inet_ntoa (new->data->id),
2807 (void *)lsa);
Dinesh G Dutte0630cb2013-01-07 10:12:52 -08002808 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00002809 }
2810
2811 return new;
2812}
2813
David Lamparter6b0655a2014-06-04 06:53:35 +02002814
Christian Franke4c14b7f2013-02-20 10:00:54 +00002815int
paul68980082003-03-25 05:07:42 +00002816ospf_check_nbr_status (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00002817{
paul1eb8ef22005-04-07 07:30:20 +00002818 struct listnode *node, *nnode;
2819 struct ospf_interface *oi;
2820
2821 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
paul718e3742002-12-13 20:15:29 +00002822 {
paul718e3742002-12-13 20:15:29 +00002823 struct route_node *rn;
2824 struct ospf_neighbor *nbr;
2825
2826 if (ospf_if_is_enable (oi))
2827 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2828 if ((nbr = rn->info) != NULL)
2829 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2830 {
2831 route_unlock_node (rn);
2832 return 0;
2833 }
2834 }
2835
2836 return 1;
2837}
2838
David Lamparter6b0655a2014-06-04 06:53:35 +02002839
paul718e3742002-12-13 20:15:29 +00002840
paul4dadc292005-05-06 21:37:42 +00002841static int
paul718e3742002-12-13 20:15:29 +00002842ospf_maxage_lsa_remover (struct thread *thread)
2843{
paul68980082003-03-25 05:07:42 +00002844 struct ospf *ospf = THREAD_ARG (thread);
paul1eb8ef22005-04-07 07:30:20 +00002845 struct ospf_lsa *lsa;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002846 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00002847 int reschedule = 0;
2848
paul68980082003-03-25 05:07:42 +00002849 ospf->t_maxage = NULL;
paul718e3742002-12-13 20:15:29 +00002850
2851 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002852 zlog_debug ("LSA[MaxAge]: remover Start");
paul718e3742002-12-13 20:15:29 +00002853
paul68980082003-03-25 05:07:42 +00002854 reschedule = !ospf_check_nbr_status (ospf);
paul718e3742002-12-13 20:15:29 +00002855
2856 if (!reschedule)
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002857 for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn))
paul718e3742002-12-13 20:15:29 +00002858 {
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002859 if ((lsa = rn->info) == NULL)
2860 {
2861 continue;
2862 }
2863
Christian Franke4de8bf02013-02-20 10:00:52 +00002864 /* There is at least one neighbor from which we still await an ack
2865 * for that LSA, so we are not allowed to remove it from our lsdb yet
2866 * as per RFC 2328 section 14 para 4 a) */
paul718e3742002-12-13 20:15:29 +00002867 if (lsa->retransmit_counter > 0)
2868 {
2869 reschedule = 1;
2870 continue;
2871 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002872
2873 /* TODO: maybe convert this function to a work-queue */
2874 if (thread_should_yield (thread))
Christian Franke4de8bf02013-02-20 10:00:52 +00002875 {
2876 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0);
Christian Frankee387dfd2014-04-28 08:04:58 +00002877 route_unlock_node(rn); /* route_top/route_next */
Christian Franke4de8bf02013-02-20 10:00:52 +00002878 return 0;
2879 }
Paul Jakma94b6bfd2010-01-09 14:11:02 +00002880
paul718e3742002-12-13 20:15:29 +00002881 /* Remove LSA from the LSDB */
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04002882 if (IS_LSA_SELF (lsa))
paul718e3742002-12-13 20:15:29 +00002883 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
Denis Ovsienkoad8d4802011-12-02 20:02:40 +04002884 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-originated: ",
paul7ddf1d62003-10-13 09:06:46 +00002885 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
paul718e3742002-12-13 20:15:29 +00002886
2887 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002888 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
paul718e3742002-12-13 20:15:29 +00002889 lsa->data->type, inet_ntoa (lsa->data->id));
2890
Paul Jakmac363d382010-01-24 22:42:13 +00002891 if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))
paul7ddf1d62003-10-13 09:06:46 +00002892 {
2893 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
David Lampartereed3c482015-03-03 08:51:53 +01002894 zlog_debug ("originating new lsa for lsa 0x%p\n", (void *)lsa);
Paul Jakmac363d382010-01-24 22:42:13 +00002895 ospf_lsa_refresh (ospf, lsa);
paul7ddf1d62003-10-13 09:06:46 +00002896 }
2897
paul718e3742002-12-13 20:15:29 +00002898 /* Remove from lsdb. */
Paul Jakmaac904de2006-06-15 12:04:57 +00002899 if (lsa->lsdb)
2900 {
2901 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2902 ospf_lsdb_delete (lsa->lsdb, lsa);
2903 }
2904 else
2905 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2906 lsa->data->type, inet_ntoa (lsa->data->id));
paul718e3742002-12-13 20:15:29 +00002907 }
2908
2909 /* A MaxAge LSA must be removed immediately from the router's link
2910 state database as soon as both a) it is no longer contained on any
2911 neighbor Link state retransmission lists and b) none of the router's
2912 neighbors are in states Exchange or Loading. */
2913 if (reschedule)
Paul Jakma02d942c2010-01-24 23:36:20 +00002914 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2915 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002916
2917 return 0;
2918}
2919
paul718e3742002-12-13 20:15:29 +00002920void
paul68980082003-03-25 05:07:42 +00002921ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002922{
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002923 struct route_node *rn;
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002924 struct prefix_ptr lsa_prefix;
paul718e3742002-12-13 20:15:29 +00002925
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002926 lsa_prefix.family = 0;
2927 lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
2928 lsa_prefix.prefix = (uintptr_t) lsa;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002929
2930 if ((rn = route_node_lookup(ospf->maxage_lsa,
2931 (struct prefix *)&lsa_prefix)))
paul718e3742002-12-13 20:15:29 +00002932 {
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002933 if (rn->info == lsa)
2934 {
2935 UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
2936 ospf_lsa_unlock (&lsa); /* maxage_lsa */
2937 rn->info = NULL;
Christian Franke8afee5c2014-04-28 08:04:59 +00002938 route_unlock_node (rn); /* unlock node because lsa is deleted */
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002939 }
Christian Franke8afee5c2014-04-28 08:04:59 +00002940 route_unlock_node (rn); /* route_node_lookup */
paul718e3742002-12-13 20:15:29 +00002941 }
2942}
2943
Paul Jakma02d942c2010-01-24 23:36:20 +00002944/* Add LSA onto the MaxAge list, and schedule for removal.
2945 * This does *not* lead to the LSA being flooded, that must be taken
2946 * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this
2947 * function).
2948 */
paul718e3742002-12-13 20:15:29 +00002949void
paul68980082003-03-25 05:07:42 +00002950ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00002951{
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002952 struct prefix_ptr lsa_prefix;
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002953 struct route_node *rn;
2954
paul718e3742002-12-13 20:15:29 +00002955 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2956 and schedule the MaxAge LSA remover. */
Stephen Hemminger3106a032009-08-06 12:58:05 -07002957 if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
paul718e3742002-12-13 20:15:29 +00002958 {
2959 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002960 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
David Lampartereed3c482015-03-03 08:51:53 +01002961 lsa->data->type, inet_ntoa (lsa->data->id), (void *)lsa);
paul718e3742002-12-13 20:15:29 +00002962 return;
2963 }
2964
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002965 lsa_prefix.family = 0;
2966 lsa_prefix.prefixlen = sizeof(lsa_prefix.prefix) * CHAR_BIT;
2967 lsa_prefix.prefix = (uintptr_t) lsa;
2968
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002969 if ((rn = route_node_get (ospf->maxage_lsa,
2970 (struct prefix *)&lsa_prefix)) != NULL)
2971 {
2972 if (rn->info != NULL)
2973 {
Pradosh Mohapatrab4b359a2014-04-28 10:58:06 +00002974 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
2975 zlog_debug ("LSA[%s]: found LSA (%p) in table for LSA %p %d",
David Lampartereed3c482015-03-03 08:51:53 +01002976 dump_lsa_key (lsa), rn->info, (void *)lsa,
2977 lsa_prefix.prefixlen);
Dinesh Dutt91e6a0e2012-12-04 10:46:37 -08002978 route_unlock_node (rn);
2979 }
2980 else
2981 {
2982 rn->info = ospf_lsa_lock(lsa);
2983 SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
2984 }
2985 }
2986 else
2987 {
2988 zlog_err("Unable to allocate memory for maxage lsa\n");
2989 assert(0);
2990 }
paul718e3742002-12-13 20:15:29 +00002991
2992 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00002993 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00002994
Paul Jakma02d942c2010-01-24 23:36:20 +00002995 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover,
2996 ospf->maxage_delay);
paul718e3742002-12-13 20:15:29 +00002997}
2998
paul4dadc292005-05-06 21:37:42 +00002999static int
paul68980082003-03-25 05:07:42 +00003000ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003001{
paul718e3742002-12-13 20:15:29 +00003002 /* Stay away from any Local Translated Type-7 LSAs */
3003 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3004 return 0;
paul718e3742002-12-13 20:15:29 +00003005
3006 if (IS_LSA_MAXAGE (lsa))
3007 /* Self-originated LSAs should NOT time-out instead,
3008 they're flushed and submitted to the max_age list explicitly. */
paul68980082003-03-25 05:07:42 +00003009 if (!ospf_lsa_is_self_originated (ospf, lsa))
paul718e3742002-12-13 20:15:29 +00003010 {
3011 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
ajse588f212004-12-08 18:12:06 +00003012 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
paul718e3742002-12-13 20:15:29 +00003013
3014 switch (lsa->data->type)
3015 {
paul718e3742002-12-13 20:15:29 +00003016#ifdef HAVE_OPAQUE_LSA
paul37163d62003-02-03 18:40:56 +00003017 case OSPF_OPAQUE_LINK_LSA:
3018 case OSPF_OPAQUE_AREA_LSA:
paul718e3742002-12-13 20:15:29 +00003019 case OSPF_OPAQUE_AS_LSA:
paul09e4efd2003-01-18 00:12:02 +00003020 /*
3021 * As a general rule, whenever network topology has changed
3022 * (due to an LSA removal in this case), routing recalculation
3023 * should be triggered. However, this is not true for opaque
3024 * LSAs. Even if an opaque LSA instance is going to be removed
3025 * from the routing domain, it does not mean a change in network
3026 * topology, and thus, routing recalculation is not needed here.
3027 */
3028 break;
paul718e3742002-12-13 20:15:29 +00003029#endif /* HAVE_OPAQUE_LSA */
paul09e4efd2003-01-18 00:12:02 +00003030 case OSPF_AS_EXTERNAL_LSA:
hassobeebba72004-06-20 21:00:27 +00003031 case OSPF_AS_NSSA_LSA:
paul68980082003-03-25 05:07:42 +00003032 ospf_ase_incremental_update (ospf, lsa);
3033 break;
paul718e3742002-12-13 20:15:29 +00003034 default:
Paul Jakmab6eef002014-10-09 14:19:51 +01003035 ospf_spf_calculate_schedule (ospf, SPF_FLAG_MAXAGE);
paul68980082003-03-25 05:07:42 +00003036 break;
paul718e3742002-12-13 20:15:29 +00003037 }
paul68980082003-03-25 05:07:42 +00003038 ospf_lsa_maxage (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003039 }
3040
Paul Jakmac363d382010-01-24 22:42:13 +00003041 if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa))
3042 if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30)
3043 printf ("Eek! Shouldn't happen!\n");
3044
paul718e3742002-12-13 20:15:29 +00003045 return 0;
3046}
3047
3048/* Periodical check of MaxAge LSA. */
3049int
paul68980082003-03-25 05:07:42 +00003050ospf_lsa_maxage_walker (struct thread *thread)
paul718e3742002-12-13 20:15:29 +00003051{
paul68980082003-03-25 05:07:42 +00003052 struct ospf *ospf = THREAD_ARG (thread);
3053 struct route_node *rn;
3054 struct ospf_lsa *lsa;
paul1eb8ef22005-04-07 07:30:20 +00003055 struct ospf_area *area;
3056 struct listnode *node, *nnode;
paul718e3742002-12-13 20:15:29 +00003057
paul68980082003-03-25 05:07:42 +00003058 ospf->t_maxage_walker = NULL;
paul718e3742002-12-13 20:15:29 +00003059
paul1eb8ef22005-04-07 07:30:20 +00003060 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003061 {
paul68980082003-03-25 05:07:42 +00003062 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3063 ospf_lsa_maxage_walker_remover (ospf, lsa);
3064 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3065 ospf_lsa_maxage_walker_remover (ospf, lsa);
3066 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3067 ospf_lsa_maxage_walker_remover (ospf, lsa);
3068 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3069 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003070#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003071 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3072 ospf_lsa_maxage_walker_remover (ospf, lsa);
3073 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3074 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003075#endif /* HAVE_OPAQUE_LSA */
paul4fb949e2003-05-10 20:06:51 +00003076 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3077 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003078 }
3079
paul4fb949e2003-05-10 20:06:51 +00003080 /* for AS-external-LSAs. */
paul68980082003-03-25 05:07:42 +00003081 if (ospf->lsdb)
3082 {
3083 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3084 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003085#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003086 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3087 ospf_lsa_maxage_walker_remover (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003088#endif /* HAVE_OPAQUE_LSA */
paul68980082003-03-25 05:07:42 +00003089 }
paul718e3742002-12-13 20:15:29 +00003090
paul68980082003-03-25 05:07:42 +00003091 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3092 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
paul718e3742002-12-13 20:15:29 +00003093 return 0;
3094}
3095
paul68980082003-03-25 05:07:42 +00003096struct ospf_lsa *
3097ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3098 struct prefix_ipv4 *p, struct in_addr router_id)
paul718e3742002-12-13 20:15:29 +00003099{
paul68980082003-03-25 05:07:42 +00003100 struct ospf_lsa *lsa;
3101 struct in_addr mask, id;
3102 struct lsa_header_mask
3103 {
3104 struct lsa_header header;
3105 struct in_addr mask;
3106 } *hmask;
paul718e3742002-12-13 20:15:29 +00003107
paul68980082003-03-25 05:07:42 +00003108 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3109 if (lsa == NULL)
3110 return NULL;
paul718e3742002-12-13 20:15:29 +00003111
paul68980082003-03-25 05:07:42 +00003112 masklen2ip (p->prefixlen, &mask);
paul718e3742002-12-13 20:15:29 +00003113
paul68980082003-03-25 05:07:42 +00003114 hmask = (struct lsa_header_mask *) lsa->data;
paul718e3742002-12-13 20:15:29 +00003115
paul68980082003-03-25 05:07:42 +00003116 if (mask.s_addr != hmask->mask.s_addr)
3117 {
3118 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3119 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3120 if (!lsa)
3121 return NULL;
3122 }
paul718e3742002-12-13 20:15:29 +00003123
paul68980082003-03-25 05:07:42 +00003124 return lsa;
paul718e3742002-12-13 20:15:29 +00003125}
3126
3127struct ospf_lsa *
3128ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3129 struct in_addr id, struct in_addr adv_router)
3130{
paule05fba42003-04-13 20:20:53 +00003131 struct ospf *ospf = ospf_lookup();
3132 assert(ospf);
3133
paul718e3742002-12-13 20:15:29 +00003134 switch (type)
3135 {
3136 case OSPF_ROUTER_LSA:
3137 case OSPF_NETWORK_LSA:
3138 case OSPF_SUMMARY_LSA:
3139 case OSPF_ASBR_SUMMARY_LSA:
paul718e3742002-12-13 20:15:29 +00003140 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003141#ifdef HAVE_OPAQUE_LSA
3142 case OSPF_OPAQUE_LINK_LSA:
3143 case OSPF_OPAQUE_AREA_LSA:
3144#endif /* HAVE_OPAQUE_LSA */
3145 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003146 case OSPF_AS_EXTERNAL_LSA:
3147#ifdef HAVE_OPAQUE_LSA
3148 case OSPF_OPAQUE_AS_LSA:
3149#endif /* HAVE_OPAQUE_LSA */
paule05fba42003-04-13 20:20:53 +00003150 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
paul718e3742002-12-13 20:15:29 +00003151 default:
3152 break;
3153 }
3154
3155 return NULL;
3156}
3157
3158struct ospf_lsa *
3159ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3160 struct in_addr id)
3161{
3162 struct ospf_lsa *lsa;
3163 struct route_node *rn;
3164
3165 switch (type)
3166 {
3167 case OSPF_ROUTER_LSA:
3168 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003169 case OSPF_NETWORK_LSA:
3170 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3171 if ((lsa = rn->info))
3172 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3173 {
3174 route_unlock_node (rn);
3175 return lsa;
3176 }
3177 break;
3178 case OSPF_SUMMARY_LSA:
3179 case OSPF_ASBR_SUMMARY_LSA:
3180 /* Currently not used. */
3181 assert (1);
3182 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
paul718e3742002-12-13 20:15:29 +00003183 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003184 case OSPF_AS_NSSA_LSA:
paul718e3742002-12-13 20:15:29 +00003185#ifdef HAVE_OPAQUE_LSA
3186 case OSPF_OPAQUE_LINK_LSA:
3187 case OSPF_OPAQUE_AREA_LSA:
3188 case OSPF_OPAQUE_AS_LSA:
3189 /* Currently not used. */
3190 break;
3191#endif /* HAVE_OPAQUE_LSA */
3192 default:
3193 break;
3194 }
3195
3196 return NULL;
3197}
3198
3199struct ospf_lsa *
3200ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3201{
3202 struct ospf_lsa *match;
3203
3204#ifdef HAVE_OPAQUE_LSA
3205 /*
3206 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3207 * is redefined to have two subfields; opaque-type and opaque-id.
3208 * However, it is harmless to treat the two sub fields together, as if
3209 * they two were forming a unique LSA-ID.
3210 */
3211#endif /* HAVE_OPAQUE_LSA */
3212
3213 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3214
3215 if (match == NULL)
3216 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003217 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
paul718e3742002-12-13 20:15:29 +00003218 lsah->type, inet_ntoa (lsah->id));
3219
3220 return match;
3221}
3222
3223/* return +n, l1 is more recent.
3224 return -n, l2 is more recent.
3225 return 0, l1 and l2 is identical. */
3226int
3227ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3228{
3229 int r;
3230 int x, y;
3231
3232 if (l1 == NULL && l2 == NULL)
3233 return 0;
3234 if (l1 == NULL)
3235 return -1;
3236 if (l2 == NULL)
3237 return 1;
3238
3239 /* compare LS sequence number. */
3240 x = (int) ntohl (l1->data->ls_seqnum);
3241 y = (int) ntohl (l2->data->ls_seqnum);
3242 if (x > y)
3243 return 1;
3244 if (x < y)
3245 return -1;
3246
3247 /* compare LS checksum. */
3248 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3249 if (r)
3250 return r;
3251
3252 /* compare LS age. */
3253 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3254 return 1;
3255 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3256 return -1;
3257
3258 /* compare LS age with MaxAgeDiff. */
3259 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3260 return -1;
3261 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3262 return 1;
3263
3264 /* LSAs are identical. */
3265 return 0;
3266}
3267
3268/* If two LSAs are different, return 1, otherwise return 0. */
3269int
3270ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3271{
3272 char *p1, *p2;
3273 assert (l1);
3274 assert (l2);
3275 assert (l1->data);
3276 assert (l2->data);
3277
3278 if (l1->data->options != l2->data->options)
3279 return 1;
3280
3281 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3282 return 1;
3283
3284 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3285 return 1;
3286
3287 if (l1->data->length != l2->data->length)
3288 return 1;
3289
3290 if (l1->data->length == 0)
3291 return 1;
3292
Joakim Tjernlund5996e0d2009-07-27 12:42:35 +02003293 if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
3294 return 1; /* May be a stale LSA in the LSBD */
3295
pauld1825832003-04-03 01:27:01 +00003296 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
paul718e3742002-12-13 20:15:29 +00003297
3298 p1 = (char *) l1->data;
3299 p2 = (char *) l2->data;
3300
3301 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3302 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3303 return 1;
3304
3305 return 0;
3306}
3307
3308#ifdef ORIGINAL_CODING
3309void
3310ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3311 struct ospf_lsa *self,
3312 struct ospf_lsa *new)
3313{
3314 u_int32_t seqnum;
3315
3316 /* Adjust LS Sequence Number. */
3317 seqnum = ntohl (new->data->ls_seqnum) + 1;
3318 self->data->ls_seqnum = htonl (seqnum);
3319
3320 /* Recalculate LSA checksum. */
3321 ospf_lsa_checksum (self->data);
3322
3323 /* Reflooding LSA. */
3324 /* RFC2328 Section 13.3
3325 On non-broadcast networks, separate Link State Update
3326 packets must be sent, as unicasts, to each adjacent neighbor
3327 (i.e., those in state Exchange or greater). The destination
3328 IP addresses for these packets are the neighbors' IP
3329 addresses. */
3330 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3331 {
3332 struct route_node *rn;
3333 struct ospf_neighbor *onbr;
3334
3335 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3336 if ((onbr = rn->info) != NULL)
3337 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3338 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3339 }
3340 else
3341 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3342
3343 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003344 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
paul718e3742002-12-13 20:15:29 +00003345 self->data->type, inet_ntoa (self->data->id));
3346}
3347#else /* ORIGINAL_CODING */
3348static int
paul68980082003-03-25 05:07:42 +00003349ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003350{
3351 if (lsa == NULL || !IS_LSA_SELF (lsa))
3352 return 0;
3353
3354 if (IS_DEBUG_OSPF_EVENT)
ajse588f212004-12-08 18:12:06 +00003355 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 +00003356
3357 /* Force given lsa's age to MaxAge. */
3358 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3359
3360 switch (lsa->data->type)
3361 {
3362#ifdef HAVE_OPAQUE_LSA
Paul Jakma02d942c2010-01-24 23:36:20 +00003363 /* Opaque wants to be notified of flushes */
paul718e3742002-12-13 20:15:29 +00003364 case OSPF_OPAQUE_LINK_LSA:
3365 case OSPF_OPAQUE_AREA_LSA:
3366 case OSPF_OPAQUE_AS_LSA:
3367 ospf_opaque_lsa_refresh (lsa);
3368 break;
3369#endif /* HAVE_OPAQUE_LSA */
3370 default:
Paul Jakmadfbd5172010-04-14 10:32:12 +01003371 ospf_refresher_unregister_lsa (ospf, lsa);
Paul Jakma02d942c2010-01-24 23:36:20 +00003372 ospf_lsa_flush (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003373 break;
3374 }
3375
3376 return 0;
3377}
3378
3379void
paul68980082003-03-25 05:07:42 +00003380ospf_flush_self_originated_lsas_now (struct ospf *ospf)
paul718e3742002-12-13 20:15:29 +00003381{
paul1eb8ef22005-04-07 07:30:20 +00003382 struct listnode *node, *nnode;
3383 struct listnode *node2, *nnode2;
paul718e3742002-12-13 20:15:29 +00003384 struct ospf_area *area;
3385 struct ospf_interface *oi;
3386 struct ospf_lsa *lsa;
paul68980082003-03-25 05:07:42 +00003387 struct route_node *rn;
paul718e3742002-12-13 20:15:29 +00003388 int need_to_flush_ase = 0;
3389
paul1eb8ef22005-04-07 07:30:20 +00003390 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
paul718e3742002-12-13 20:15:29 +00003391 {
paul718e3742002-12-13 20:15:29 +00003392 if ((lsa = area->router_lsa_self) != NULL)
3393 {
3394 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003395 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3396 lsa->data->type, inet_ntoa (lsa->data->id));
3397
3398 ospf_refresher_unregister_lsa (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003399 ospf_lsa_flush_area (lsa, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003400 ospf_lsa_unlock (&area->router_lsa_self);
paul718e3742002-12-13 20:15:29 +00003401 area->router_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003402 }
3403
paul1eb8ef22005-04-07 07:30:20 +00003404 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
paul718e3742002-12-13 20:15:29 +00003405 {
paul718e3742002-12-13 20:15:29 +00003406 if ((lsa = oi->network_lsa_self) != NULL
paul1eb8ef22005-04-07 07:30:20 +00003407 && oi->state == ISM_DR
3408 && oi->full_nbrs > 0)
paul718e3742002-12-13 20:15:29 +00003409 {
3410 if (IS_DEBUG_OSPF_EVENT)
Paul Jakmadfbd5172010-04-14 10:32:12 +01003411 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
3412 lsa->data->type, inet_ntoa (lsa->data->id));
3413
3414 ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003415 ospf_lsa_flush_area (oi->network_lsa_self, area);
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003416 ospf_lsa_unlock (&oi->network_lsa_self);
paul718e3742002-12-13 20:15:29 +00003417 oi->network_lsa_self = NULL;
paul718e3742002-12-13 20:15:29 +00003418 }
3419
3420 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3421 && area->external_routing == OSPF_AREA_DEFAULT)
3422 need_to_flush_ase = 1;
3423 }
3424
paul68980082003-03-25 05:07:42 +00003425 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3426 ospf_lsa_flush_schedule (ospf, lsa);
3427 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3428 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003429#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003430 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3431 ospf_lsa_flush_schedule (ospf, lsa);
3432 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3433 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003434#endif /* HAVE_OPAQUE_LSA */
3435 }
3436
3437 if (need_to_flush_ase)
3438 {
paul68980082003-03-25 05:07:42 +00003439 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3440 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003441#ifdef HAVE_OPAQUE_LSA
paul68980082003-03-25 05:07:42 +00003442 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3443 ospf_lsa_flush_schedule (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003444#endif /* HAVE_OPAQUE_LSA */
3445 }
3446
3447 /*
3448 * Make sure that the MaxAge LSA remover is executed immediately,
3449 * without conflicting to other threads.
3450 */
paul68980082003-03-25 05:07:42 +00003451 if (ospf->t_maxage != NULL)
paul718e3742002-12-13 20:15:29 +00003452 {
paul68980082003-03-25 05:07:42 +00003453 OSPF_TIMER_OFF (ospf->t_maxage);
3454 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
paul718e3742002-12-13 20:15:29 +00003455 }
3456
3457 return;
3458}
3459#endif /* ORIGINAL_CODING */
3460
3461/* If there is self-originated LSA, then return 1, otherwise return 0. */
3462/* An interface-independent version of ospf_lsa_is_self_originated */
3463int
paul68980082003-03-25 05:07:42 +00003464ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003465{
hasso52dc7ee2004-09-23 19:18:23 +00003466 struct listnode *node;
paul1eb8ef22005-04-07 07:30:20 +00003467 struct ospf_interface *oi;
paul718e3742002-12-13 20:15:29 +00003468
3469 /* This LSA is already checked. */
3470 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003471 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003472
3473 /* Make sure LSA is self-checked. */
3474 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3475
3476 /* AdvRouter and Router ID is the same. */
paul68980082003-03-25 05:07:42 +00003477 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003478 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3479
3480 /* LSA is router-LSA. */
3481 else if (lsa->data->type == OSPF_ROUTER_LSA &&
paul68980082003-03-25 05:07:42 +00003482 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
paul718e3742002-12-13 20:15:29 +00003483 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3484
3485 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3486 else if (lsa->data->type == OSPF_NETWORK_LSA)
paul1eb8ef22005-04-07 07:30:20 +00003487 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
paul718e3742002-12-13 20:15:29 +00003488 {
paul718e3742002-12-13 20:15:29 +00003489 /* Ignore virtual link. */
3490 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3491 if (oi->address->family == AF_INET)
3492 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3493 {
3494 /* to make it easier later */
3495 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003496 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003497 }
3498 }
3499
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003500 return IS_LSA_SELF (lsa);
paul718e3742002-12-13 20:15:29 +00003501}
3502
3503/* Get unique Link State ID. */
3504struct in_addr
paul68980082003-03-25 05:07:42 +00003505ospf_lsa_unique_id (struct ospf *ospf,
3506 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
paul718e3742002-12-13 20:15:29 +00003507{
3508 struct ospf_lsa *lsa;
3509 struct in_addr mask, id;
3510
3511 id = p->prefix;
3512
3513 /* Check existence of LSA instance. */
paul68980082003-03-25 05:07:42 +00003514 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003515 if (lsa)
3516 {
3517 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3518 if (ip_masklen (al->mask) == p->prefixlen)
3519 {
3520 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003521 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003522 "Can't get Link State ID for %s/%d",
3523 inet_ntoa (p->prefix), p->prefixlen);
3524 /* id.s_addr = 0; */
3525 id.s_addr = 0xffffffff;
3526 return id;
3527 }
3528 /* Masklen differs, then apply wildcard mask to Link State ID. */
3529 else
3530 {
3531 masklen2ip (p->prefixlen, &mask);
3532
3533 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
paul68980082003-03-25 05:07:42 +00003534 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3535 id, ospf->router_id);
paul718e3742002-12-13 20:15:29 +00003536 if (lsa)
3537 {
3538 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
ajse588f212004-12-08 18:12:06 +00003539 zlog_debug ("ospf_lsa_unique_id(): "
paul718e3742002-12-13 20:15:29 +00003540 "Can't get Link State ID for %s/%d",
3541 inet_ntoa (p->prefix), p->prefixlen);
3542 /* id.s_addr = 0; */
3543 id.s_addr = 0xffffffff;
3544 return id;
3545 }
3546 }
3547 }
3548
3549 return id;
3550}
3551
David Lamparter6b0655a2014-06-04 06:53:35 +02003552
Paul Jakma70461d72006-05-12 22:57:57 +00003553#define LSA_ACTION_FLOOD_AREA 1
3554#define LSA_ACTION_FLUSH_AREA 2
paul718e3742002-12-13 20:15:29 +00003555
3556struct lsa_action
3557{
3558 u_char action;
3559 struct ospf_area *area;
paul718e3742002-12-13 20:15:29 +00003560 struct ospf_lsa *lsa;
3561};
3562
paul4dadc292005-05-06 21:37:42 +00003563static int
paul718e3742002-12-13 20:15:29 +00003564ospf_lsa_action (struct thread *t)
3565{
3566 struct lsa_action *data;
3567
3568 data = THREAD_ARG (t);
3569
3570 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
ajse588f212004-12-08 18:12:06 +00003571 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
paul718e3742002-12-13 20:15:29 +00003572 data->action);
3573
3574 switch (data->action)
3575 {
paul718e3742002-12-13 20:15:29 +00003576 case LSA_ACTION_FLOOD_AREA:
3577 ospf_flood_through_area (data->area, NULL, data->lsa);
3578 break;
paul718e3742002-12-13 20:15:29 +00003579 case LSA_ACTION_FLUSH_AREA:
3580 ospf_lsa_flush_area (data->lsa, data->area);
3581 break;
paul718e3742002-12-13 20:15:29 +00003582 }
3583
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003584 ospf_lsa_unlock (&data->lsa); /* Message */
paul718e3742002-12-13 20:15:29 +00003585 XFREE (MTYPE_OSPF_MESSAGE, data);
3586 return 0;
3587}
3588
3589void
3590ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3591{
3592 struct lsa_action *data;
3593
Stephen Hemminger393deb92008-08-18 14:13:29 -07003594 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003595 data->action = LSA_ACTION_FLOOD_AREA;
3596 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003597 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
paul718e3742002-12-13 20:15:29 +00003598
3599 thread_add_event (master, ospf_lsa_action, data, 0);
3600}
3601
3602void
3603ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3604{
3605 struct lsa_action *data;
3606
Stephen Hemminger393deb92008-08-18 14:13:29 -07003607 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
paul718e3742002-12-13 20:15:29 +00003608 data->action = LSA_ACTION_FLUSH_AREA;
3609 data->area = area;
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003610 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
paul718e3742002-12-13 20:15:29 +00003611
3612 thread_add_event (master, ospf_lsa_action, data, 0);
3613}
3614
David Lamparter6b0655a2014-06-04 06:53:35 +02003615
paul718e3742002-12-13 20:15:29 +00003616/* LSA Refreshment functions. */
Paul Jakmac363d382010-01-24 22:42:13 +00003617struct ospf_lsa *
paul68980082003-03-25 05:07:42 +00003618ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003619{
3620 struct external_info *ei;
Paul Jakmac363d382010-01-24 22:42:13 +00003621 struct ospf_lsa *new = NULL;
paul718e3742002-12-13 20:15:29 +00003622 assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003623 assert (IS_LSA_SELF (lsa));
Paul Jakma66349742010-04-13 22:33:54 +01003624 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003625
3626 switch (lsa->data->type)
3627 {
3628 /* Router and Network LSAs are processed differently. */
3629 case OSPF_ROUTER_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003630 new = ospf_router_lsa_refresh (lsa);
3631 break;
paul718e3742002-12-13 20:15:29 +00003632 case OSPF_NETWORK_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003633 new = ospf_network_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003634 break;
3635 case OSPF_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003636 new = ospf_summary_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003637 break;
3638 case OSPF_ASBR_SUMMARY_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003639 new = ospf_summary_asbr_lsa_refresh (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003640 break;
3641 case OSPF_AS_EXTERNAL_LSA:
pauld4a53d52003-07-12 21:30:57 +00003642 /* Translated from NSSA Type-5s are refreshed when
3643 * from refresh of Type-7 - do not refresh these directly.
3644 */
3645 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3646 break;
paul718e3742002-12-13 20:15:29 +00003647 ei = ospf_external_info_check (lsa);
3648 if (ei)
Paul Jakmac363d382010-01-24 22:42:13 +00003649 new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
paul718e3742002-12-13 20:15:29 +00003650 else
pauld4a53d52003-07-12 21:30:57 +00003651 ospf_lsa_flush_as (ospf, lsa);
paul718e3742002-12-13 20:15:29 +00003652 break;
3653#ifdef HAVE_OPAQUE_LSA
3654 case OSPF_OPAQUE_LINK_LSA:
3655 case OSPF_OPAQUE_AREA_LSA:
3656 case OSPF_OPAQUE_AS_LSA:
Paul Jakmac363d382010-01-24 22:42:13 +00003657 new = ospf_opaque_lsa_refresh (lsa);
paul718e3742002-12-13 20:15:29 +00003658 break;
pauld7480322003-05-16 17:31:51 +00003659#endif /* HAVE_OPAQUE_LSA */
paul718e3742002-12-13 20:15:29 +00003660 default:
3661 break;
paul718e3742002-12-13 20:15:29 +00003662 }
Paul Jakmac363d382010-01-24 22:42:13 +00003663 return new;
paul718e3742002-12-13 20:15:29 +00003664}
3665
3666void
paul68980082003-03-25 05:07:42 +00003667ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003668{
3669 u_int16_t index, current_index;
3670
Paul Jakma66349742010-04-13 22:33:54 +01003671 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003672 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003673
3674 if (lsa->refresh_list < 0)
3675 {
3676 int delay;
3677
3678 if (LS_AGE (lsa) == 0 &&
3679 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3680 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3681 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3682 else
3683 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3684 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3685 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3686
3687 if (delay < 0)
3688 delay = 0;
3689
Paul Jakmac363d382010-01-24 22:42:13 +00003690 current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL)
3691 - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
paul718e3742002-12-13 20:15:29 +00003692
3693 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
Paul Jakmac363d382010-01-24 22:42:13 +00003694 % (OSPF_LSA_REFRESHER_SLOTS);
paul718e3742002-12-13 20:15:29 +00003695
3696 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003697 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
pauld4a53d52003-07-12 21:30:57 +00003698 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
paul68980082003-03-25 05:07:42 +00003699 if (!ospf->lsa_refresh_queue.qs[index])
3700 ospf->lsa_refresh_queue.qs[index] = list_new ();
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003701 listnode_add (ospf->lsa_refresh_queue.qs[index],
3702 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003703 lsa->refresh_list = index;
paulf2c80652002-12-13 21:44:27 +00003704 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003705 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
pauld4a53d52003-07-12 21:30:57 +00003706 "setting refresh_list on lsa %p (slod %d)",
David Lampartereed3c482015-03-03 08:51:53 +01003707 inet_ntoa (lsa->data->id), (void *)lsa, index);
paul718e3742002-12-13 20:15:29 +00003708 }
3709}
3710
3711void
paul68980082003-03-25 05:07:42 +00003712ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
paul718e3742002-12-13 20:15:29 +00003713{
Paul Jakma66349742010-04-13 22:33:54 +01003714 assert (lsa->lock > 0);
Denis Ovsienkoce3cdcf2011-10-24 18:17:09 +04003715 assert (IS_LSA_SELF (lsa));
paul718e3742002-12-13 20:15:29 +00003716 if (lsa->refresh_list >= 0)
3717 {
hasso52dc7ee2004-09-23 19:18:23 +00003718 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
paul718e3742002-12-13 20:15:29 +00003719 listnode_delete (refresh_list, lsa);
3720 if (!listcount (refresh_list))
3721 {
3722 list_free (refresh_list);
paul68980082003-03-25 05:07:42 +00003723 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
paul718e3742002-12-13 20:15:29 +00003724 }
Paul Jakma1fe6ed32006-07-26 09:37:26 +00003725 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
paul718e3742002-12-13 20:15:29 +00003726 lsa->refresh_list = -1;
3727 }
3728}
3729
3730int
3731ospf_lsa_refresh_walker (struct thread *t)
3732{
hasso52dc7ee2004-09-23 19:18:23 +00003733 struct list *refresh_list;
paul1eb8ef22005-04-07 07:30:20 +00003734 struct listnode *node, *nnode;
paul68980082003-03-25 05:07:42 +00003735 struct ospf *ospf = THREAD_ARG (t);
paul1eb8ef22005-04-07 07:30:20 +00003736 struct ospf_lsa *lsa;
paul718e3742002-12-13 20:15:29 +00003737 int i;
hasso52dc7ee2004-09-23 19:18:23 +00003738 struct list *lsa_to_refresh = list_new ();
paul718e3742002-12-13 20:15:29 +00003739
3740 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003741 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
paul718e3742002-12-13 20:15:29 +00003742
3743
paul68980082003-03-25 05:07:42 +00003744 i = ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003745
ajs9dbc7972005-03-13 19:27:22 +00003746 /* Note: if clock has jumped backwards, then time change could be negative,
3747 so we are careful to cast the expression to unsigned before taking
3748 modulus. */
paul68980082003-03-25 05:07:42 +00003749 ospf->lsa_refresh_queue.index =
ajs9dbc7972005-03-13 19:27:22 +00003750 ((unsigned long)(ospf->lsa_refresh_queue.index +
Paul Jakmac363d382010-01-24 22:42:13 +00003751 (quagga_time (NULL) - ospf->lsa_refresher_started)
3752 / OSPF_LSA_REFRESHER_GRANULARITY))
3753 % OSPF_LSA_REFRESHER_SLOTS;
paul718e3742002-12-13 20:15:29 +00003754
3755 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003756 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
paul68980082003-03-25 05:07:42 +00003757 ospf->lsa_refresh_queue.index);
paul718e3742002-12-13 20:15:29 +00003758
paul68980082003-03-25 05:07:42 +00003759 for (;i != ospf->lsa_refresh_queue.index;
paul718e3742002-12-13 20:15:29 +00003760 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3761 {
3762 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003763 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
pauld4a53d52003-07-12 21:30:57 +00003764 "refresh index %d", i);
paul718e3742002-12-13 20:15:29 +00003765
paul68980082003-03-25 05:07:42 +00003766 refresh_list = ospf->lsa_refresh_queue.qs [i];
paul718e3742002-12-13 20:15:29 +00003767
Paul Jakma66349742010-04-13 22:33:54 +01003768 assert (i >= 0);
3769
paul68980082003-03-25 05:07:42 +00003770 ospf->lsa_refresh_queue.qs [i] = NULL;
3771
paul718e3742002-12-13 20:15:29 +00003772 if (refresh_list)
3773 {
paul1eb8ef22005-04-07 07:30:20 +00003774 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
paul718e3742002-12-13 20:15:29 +00003775 {
paul718e3742002-12-13 20:15:29 +00003776 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003777 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
David Lampartereed3c482015-03-03 08:51:53 +01003778 "refresh lsa %p (slot %d)",
3779 inet_ntoa (lsa->data->id), (void *)lsa, i);
3780
Paul Jakma66349742010-04-13 22:33:54 +01003781 assert (lsa->lock > 0);
paul718e3742002-12-13 20:15:29 +00003782 list_delete_node (refresh_list, node);
paul718e3742002-12-13 20:15:29 +00003783 lsa->refresh_list = -1;
3784 listnode_add (lsa_to_refresh, lsa);
paul718e3742002-12-13 20:15:29 +00003785 }
3786 list_free (refresh_list);
3787 }
3788 }
3789
paul68980082003-03-25 05:07:42 +00003790 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3791 ospf, ospf->lsa_refresh_interval);
Paul Jakma2518efd2006-08-27 06:49:29 +00003792 ospf->lsa_refresher_started = quagga_time (NULL);
paul718e3742002-12-13 20:15:29 +00003793
paul1eb8ef22005-04-07 07:30:20 +00003794 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
Paul Jakma66349742010-04-13 22:33:54 +01003795 {
3796 ospf_lsa_refresh (ospf, lsa);
3797 assert (lsa->lock > 0);
3798 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
3799 }
paul718e3742002-12-13 20:15:29 +00003800
3801 list_delete (lsa_to_refresh);
3802
3803 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
ajse588f212004-12-08 18:12:06 +00003804 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
paul718e3742002-12-13 20:15:29 +00003805
3806 return 0;
3807}
3808