]> git.proxmox.com Git - mirror_frr.git/blame - ospfd/ospf_lsa.c
ospfd: use IS_LSA_SELF() where appropriate
[mirror_frr.git] / ospfd / ospf_lsa.c
CommitLineData
718e3744 1/*
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() */
6a270cd9 35#include "checksum.h"
718e3744 36
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
53\f
54u_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
64\f
65struct timeval
66tv_adjust (struct timeval a)
67{
68 while (a.tv_usec >= 1000000)
69 {
70 a.tv_usec -= 1000000;
71 a.tv_sec++;
72 }
73
74 while (a.tv_usec < 0)
75 {
76 a.tv_usec += 1000000;
77 a.tv_sec--;
78 }
79
80 return a;
81}
82
83int
84tv_ceil (struct timeval a)
85{
86 a = tv_adjust (a);
87
88 return (a.tv_usec ? a.tv_sec + 1 : a.tv_sec);
89}
90
91int
92tv_floor (struct timeval a)
93{
94 a = tv_adjust (a);
95
96 return a.tv_sec;
97}
98
99struct timeval
100int2tv (int a)
101{
102 struct timeval ret;
103
104 ret.tv_sec = a;
105 ret.tv_usec = 0;
106
107 return ret;
108}
109
110struct timeval
111tv_add (struct timeval a, struct timeval b)
112{
113 struct timeval ret;
114
115 ret.tv_sec = a.tv_sec + b.tv_sec;
116 ret.tv_usec = a.tv_usec + b.tv_usec;
117
118 return tv_adjust (ret);
119}
120
121struct timeval
122tv_sub (struct timeval a, struct timeval b)
123{
124 struct timeval ret;
125
126 ret.tv_sec = a.tv_sec - b.tv_sec;
127 ret.tv_usec = a.tv_usec - b.tv_usec;
128
129 return tv_adjust (ret);
130}
131
132int
133tv_cmp (struct timeval a, struct timeval b)
134{
135 return (a.tv_sec == b.tv_sec ?
136 a.tv_usec - b.tv_usec : a.tv_sec - b.tv_sec);
137}
138
139int
140ospf_lsa_refresh_delay (struct ospf_lsa *lsa)
141{
142 struct timeval delta, now;
143 int delay = 0;
144
2518efd1 145 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
718e3744 146 delta = tv_sub (now, lsa->tv_orig);
147
148 if (tv_cmp (delta, int2tv (OSPF_MIN_LS_INTERVAL)) < 0)
149 {
150 delay = tv_ceil (tv_sub (int2tv (OSPF_MIN_LS_INTERVAL), delta));
151
152 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 153 zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
718e3744 154 lsa->data->type, inet_ntoa (lsa->data->id), delay);
155
156 assert (delay > 0);
157 }
158
159 return delay;
160}
161
162\f
163int
164get_age (struct ospf_lsa *lsa)
165{
166 int age;
718e3744 167
2518efd1
PJ
168 age = ntohs (lsa->data->ls_age)
169 + tv_floor (tv_sub (recent_relative_time (), lsa->tv_recv));
718e3744 170
171 return age;
172}
173
174\f
175/* Fletcher Checksum -- Refer to RFC1008. */
718e3744 176
6a270cd9
JD
177/* All the offsets are zero-based. The offsets in the RFC1008 are
178 one-based. */
718e3744 179u_int16_t
180ospf_lsa_checksum (struct lsa_header *lsa)
181{
6a270cd9
JD
182 u_char *buffer = (u_char *) &lsa->options;
183 int options_offset = buffer - (u_char *) &lsa->ls_age; /* should be 2 */
718e3744 184
6a270cd9
JD
185 /* Skip the AGE field */
186 u_int16_t len = ntohs(lsa->length) - options_offset;
718e3744 187
6a270cd9
JD
188 /* Checksum offset starts from "options" field, not the beginning of the
189 lsa_header struct. The offset is 14, rather than 16. */
190 int checksum_offset = (u_char *) &lsa->checksum - buffer;
718e3744 191
6a270cd9 192 return fletcher_checksum(buffer, len, checksum_offset);
718e3744 193}
194
195
196\f
197/* Create OSPF LSA. */
198struct ospf_lsa *
199ospf_lsa_new ()
200{
201 struct ospf_lsa *new;
202
203 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
718e3744 204
205 new->flags = 0;
206 new->lock = 1;
207 new->retransmit_counter = 0;
2518efd1 208 new->tv_recv = recent_relative_time ();
718e3744 209 new->tv_orig = new->tv_recv;
210 new->refresh_list = -1;
211
212 return new;
213}
214
215/* Duplicate OSPF LSA. */
216struct ospf_lsa *
217ospf_lsa_dup (struct ospf_lsa *lsa)
218{
219 struct ospf_lsa *new;
220
221 if (lsa == NULL)
222 return NULL;
223
224 new = XCALLOC (MTYPE_OSPF_LSA, sizeof (struct ospf_lsa));
225
226 memcpy (new, lsa, sizeof (struct ospf_lsa));
227 UNSET_FLAG (new->flags, OSPF_LSA_DISCARD);
228 new->lock = 1;
229 new->retransmit_counter = 0;
230 new->data = ospf_lsa_data_dup (lsa->data);
231
f2c80652 232 /* kevinm: Clear the refresh_list, otherwise there are going
233 to be problems when we try to remove the LSA from the
234 queue (which it's not a member of.)
235 XXX: Should we add the LSA to the refresh_list queue? */
236 new->refresh_list = -1;
237
238 if (IS_DEBUG_OSPF (lsa, LSA))
e588f21f 239 zlog_debug ("LSA: duplicated %p (new: %p)", lsa, new);
f2c80652 240
718e3744 241 return new;
242}
243
244/* Free OSPF LSA. */
245void
246ospf_lsa_free (struct ospf_lsa *lsa)
247{
248 assert (lsa->lock == 0);
249
250 if (IS_DEBUG_OSPF (lsa, LSA))
e588f21f 251 zlog_debug ("LSA: freed %p", lsa);
718e3744 252
253 /* Delete LSA data. */
254 if (lsa->data != NULL)
255 ospf_lsa_data_free (lsa->data);
256
257 assert (lsa->refresh_list < 0);
258
259 memset (lsa, 0, sizeof (struct ospf_lsa));
260 XFREE (MTYPE_OSPF_LSA, lsa);
261}
262
263/* Lock LSA. */
264struct ospf_lsa *
265ospf_lsa_lock (struct ospf_lsa *lsa)
266{
267 lsa->lock++;
268 return lsa;
269}
270
271/* Unlock LSA. */
272void
1fe6ed38 273ospf_lsa_unlock (struct ospf_lsa **lsa)
718e3744 274{
275 /* This is sanity check. */
1fe6ed38 276 if (!lsa || !*lsa)
718e3744 277 return;
278
1fe6ed38 279 (*lsa)->lock--;
718e3744 280
1fe6ed38 281 assert ((*lsa)->lock >= 0);
718e3744 282
1fe6ed38 283 if ((*lsa)->lock == 0)
718e3744 284 {
1fe6ed38
PJ
285 assert (CHECK_FLAG ((*lsa)->flags, OSPF_LSA_DISCARD));
286 ospf_lsa_free (*lsa);
287 *lsa = NULL;
718e3744 288 }
289}
290
291/* Check discard flag. */
292void
293ospf_lsa_discard (struct ospf_lsa *lsa)
294{
295 if (!CHECK_FLAG (lsa->flags, OSPF_LSA_DISCARD))
296 {
297 SET_FLAG (lsa->flags, OSPF_LSA_DISCARD);
1fe6ed38 298 ospf_lsa_unlock (&lsa);
718e3744 299 }
300}
301
302/* Create LSA data. */
303struct lsa_header *
304ospf_lsa_data_new (size_t size)
305{
393deb9b 306 return XCALLOC (MTYPE_OSPF_LSA_DATA, size);
718e3744 307}
308
309/* Duplicate LSA data. */
310struct lsa_header *
311ospf_lsa_data_dup (struct lsa_header *lsah)
312{
313 struct lsa_header *new;
314
315 new = ospf_lsa_data_new (ntohs (lsah->length));
316 memcpy (new, lsah, ntohs (lsah->length));
317
318 return new;
319}
320
321/* Free LSA data. */
322void
323ospf_lsa_data_free (struct lsa_header *lsah)
324{
325 if (IS_DEBUG_OSPF (lsa, LSA))
e588f21f 326 zlog_debug ("LSA[Type%d:%s]: data freed %p",
718e3744 327 lsah->type, inet_ntoa (lsah->id), lsah);
328
329 XFREE (MTYPE_OSPF_LSA_DATA, lsah);
330}
331
332\f
333/* LSA general functions. */
334
335const char *
336dump_lsa_key (struct ospf_lsa *lsa)
337{
338 static char buf[] = {
52dc7ee6 339 "Type255,id(255.255.255.255),ar(255.255.255.255)"
718e3744 340 };
341 struct lsa_header *lsah;
342
343 if (lsa != NULL && (lsah = lsa->data) != NULL)
344 {
345 char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
346 strcpy (id, inet_ntoa (lsah->id));
347 strcpy (ar, inet_ntoa (lsah->adv_router));
348
349 sprintf (buf, "Type%d,id(%s),ar(%s)", lsah->type, id, ar);
350 }
351 else
352 strcpy (buf, "NULL");
353
354 return buf;
355}
356
357u_int32_t
358lsa_seqnum_increment (struct ospf_lsa *lsa)
359{
360 u_int32_t seqnum;
361
362 seqnum = ntohl (lsa->data->ls_seqnum) + 1;
363
364 return htonl (seqnum);
365}
366
367void
368lsa_header_set (struct stream *s, u_char options,
68980084 369 u_char type, struct in_addr id, struct in_addr router_id)
718e3744 370{
371 struct lsa_header *lsah;
372
373 lsah = (struct lsa_header *) STREAM_DATA (s);
374
375 lsah->ls_age = htons (0);
376 lsah->options = options;
377 lsah->type = type;
378 lsah->id = id;
68980084 379 lsah->adv_router = router_id;
718e3744 380 lsah->ls_seqnum = htonl (OSPF_INITIAL_SEQUENCE_NUMBER);
381
9985f83c 382 stream_forward_endp (s, OSPF_LSA_HEADER_SIZE);
718e3744 383}
384\f
68980084 385
718e3744 386/* router-LSA related functions. */
387/* Get router-LSA flags. */
4dadc291 388static u_char
718e3744 389router_lsa_flags (struct ospf_area *area)
390{
391 u_char flags;
392
68980084 393 flags = area->ospf->flags;
718e3744 394
395 /* Set virtual link flag. */
396 if (ospf_full_virtual_nbrs (area))
397 SET_FLAG (flags, ROUTER_LSA_VIRTUAL);
398 else
399 /* Just sanity check */
400 UNSET_FLAG (flags, ROUTER_LSA_VIRTUAL);
401
402 /* Set Shortcut ABR behabiour flag. */
403 UNSET_FLAG (flags, ROUTER_LSA_SHORTCUT);
68980084 404 if (area->ospf->abr_type == OSPF_ABR_SHORTCUT)
718e3744 405 if (!OSPF_IS_AREA_BACKBONE (area))
406 if ((area->shortcut_configured == OSPF_SHORTCUT_DEFAULT &&
68980084 407 area->ospf->backbone == NULL) ||
718e3744 408 area->shortcut_configured == OSPF_SHORTCUT_ENABLE)
409 SET_FLAG (flags, ROUTER_LSA_SHORTCUT);
410
411 /* ASBR can't exit in stub area. */
fc787e87 412 if (area->external_routing == OSPF_AREA_STUB)
942b6c19 413 UNSET_FLAG (flags, ROUTER_LSA_EXTERNAL);
414 /* If ASBR set External flag */
415 else if (IS_OSPF_ASBR (area->ospf))
416 SET_FLAG (flags, ROUTER_LSA_EXTERNAL);
417
418 /* Set ABR dependent flags */
419 if (IS_OSPF_ABR (area->ospf))
420 {
421 SET_FLAG (flags, ROUTER_LSA_BORDER);
942b6c19 422 /* If Area is NSSA and we are both ABR and unconditional translator,
d4a53d58 423 * set Nt bit to inform other routers.
942b6c19 424 */
d4a53d58 425 if ( (area->external_routing == OSPF_AREA_NSSA)
426 && (area->NSSATranslatorRole == OSPF_NSSA_ROLE_ALWAYS))
427 SET_FLAG (flags, ROUTER_LSA_NT);
942b6c19 428 }
718e3744 429 return flags;
430}
431
432/* Lookup neighbor other than myself.
433 And check neighbor count,
434 Point-to-Point link must have only 1 neighbor. */
435struct ospf_neighbor *
68980084 436ospf_nbr_lookup_ptop (struct ospf_interface *oi)
718e3744 437{
718e3744 438 struct ospf_neighbor *nbr = NULL;
68980084 439 struct route_node *rn;
718e3744 440
441 /* Search neighbor, there must be one of two nbrs. */
68980084 442 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
443 if ((nbr = rn->info))
444 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
718e3744 445 if (nbr->state == NSM_Full)
68980084 446 {
447 route_unlock_node (rn);
448 break;
449 }
718e3744 450
451 /* PtoP link must have only 1 neighbor. */
68980084 452 if (ospf_nbr_count (oi, 0) > 1)
718e3744 453 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
454
455 return nbr;
456}
457
88d6cf37 458/* Determine cost of link, taking RFC3137 stub-router support into
459 * consideration
460 */
461static u_int16_t
462ospf_link_cost (struct ospf_interface *oi)
463{
464 /* RFC3137 stub router support */
465 if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
466 return oi->output_cost;
467 else
468 return OSPF_OUTPUT_COST_INFINITE;
469}
470
718e3744 471/* Set a link information. */
779adb01 472static char
718e3744 473link_info_set (struct stream *s, struct in_addr id,
474 struct in_addr data, u_char type, u_char tos, u_int16_t cost)
475{
779adb01 476 /* LSA stream is initially allocated to OSPF_MAX_LSA_SIZE, suits
477 * vast majority of cases. Some rare routers with lots of links need more.
478 * we try accomodate those here.
479 */
480 if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE)
481 {
482 size_t ret = OSPF_MAX_LSA_SIZE;
483
484 /* Can we enlarge the stream still? */
485 if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE)
486 {
487 /* we futz the size here for simplicity, really we need to account
488 * for just:
489 * IP Header - (sizeof (struct ip))
490 * OSPF Header - OSPF_HEADER_SIZE
491 * LSA Header - OSPF_LSA_HEADER_SIZE
492 * MD5 auth data, if MD5 is configured - OSPF_AUTH_MD5_SIZE.
493 *
494 * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
495 */
496 ret = stream_resize (s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
497 }
498
499 if (ret == OSPF_MAX_LSA_SIZE)
500 {
5372510d 501 zlog_warn ("%s: Out of space in LSA stream, left %zd, size %zd",
779adb01 502 __func__, STREAM_REMAIN (s), STREAM_SIZE (s));
503 return 0;
504 }
505 }
506
718e3744 507 /* TOS based routing is not supported. */
508 stream_put_ipv4 (s, id.s_addr); /* Link ID. */
509 stream_put_ipv4 (s, data.s_addr); /* Link Data. */
510 stream_putc (s, type); /* Link Type. */
511 stream_putc (s, tos); /* TOS = 0. */
512 stream_putw (s, cost); /* Link Cost. */
779adb01 513
514 return 1;
718e3744 515}
516
e4529636 517/* Describe Point-to-Point link (Section 12.4.1.1). */
4dadc291 518static int
718e3744 519lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi)
520{
521 int links = 0;
522 struct ospf_neighbor *nbr;
523 struct in_addr id, mask;
88d6cf37 524 u_int16_t cost = ospf_link_cost (oi);
718e3744 525
526 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 527 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
718e3744 528
68980084 529 if ((nbr = ospf_nbr_lookup_ptop (oi)))
718e3744 530 if (nbr->state == NSM_Full)
531 {
532 /* For unnumbered point-to-point networks, the Link Data field
533 should specify the interface's MIB-II ifIndex value. */
779adb01 534 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
535 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
718e3744 536 }
537
e4529636
AS
538 /* Regardless of the state of the neighboring router, we must
539 add a Type 3 link (stub network).
540 N.B. Options 1 & 2 share basically the same logic. */
541 masklen2ip (oi->address->prefixlen, &mask);
542 id.s_addr = CONNECTED_PREFIX(oi->connected)->u.prefix4.s_addr & mask.s_addr;
543 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
544 oi->output_cost);
718e3744 545 return links;
546}
547
548/* Describe Broadcast Link. */
4dadc291 549static int
718e3744 550lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi)
551{
552 struct ospf_neighbor *dr;
553 struct in_addr id, mask;
88d6cf37 554 u_int16_t cost = ospf_link_cost (oi);
555
718e3744 556 /* Describe Type 3 Link. */
557 if (oi->state == ISM_Waiting)
558 {
559 masklen2ip (oi->address->prefixlen, &mask);
560 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
779adb01 561 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
562 oi->output_cost);
718e3744 563 }
564
565 dr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi));
566 /* Describe Type 2 link. */
567 if (dr && (dr->state == NSM_Full ||
568 IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))) &&
68980084 569 ospf_nbr_count (oi, NSM_Full) > 0)
718e3744 570 {
779adb01 571 return link_info_set (s, DR (oi), oi->address->u.prefix4,
572 LSA_LINK_TYPE_TRANSIT, 0, cost);
718e3744 573 }
574 /* Describe type 3 link. */
575 else
576 {
577 masklen2ip (oi->address->prefixlen, &mask);
578 id.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
779adb01 579 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0,
580 oi->output_cost);
718e3744 581 }
718e3744 582}
583
4dadc291 584static int
718e3744 585lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi)
586{
587 struct in_addr id, mask;
88d6cf37 588
718e3744 589 /* Describe Type 3 Link. */
590 if (oi->state != ISM_Loopback)
591 return 0;
592
593 mask.s_addr = 0xffffffff;
594 id.s_addr = oi->address->u.prefix4.s_addr;
779adb01 595 return link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, oi->output_cost);
718e3744 596}
597
598/* Describe Virtual Link. */
4dadc291 599static int
718e3744 600lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi)
601{
602 struct ospf_neighbor *nbr;
88d6cf37 603 u_int16_t cost = ospf_link_cost (oi);
718e3744 604
718e3744 605 if (oi->state == ISM_PointToPoint)
68980084 606 if ((nbr = ospf_nbr_lookup_ptop (oi)))
718e3744 607 if (nbr->state == NSM_Full)
608 {
779adb01 609 return link_info_set (s, nbr->router_id, oi->address->u.prefix4,
610 LSA_LINK_TYPE_VIRTUALLINK, 0, cost);
718e3744 611 }
612
613 return 0;
614}
615
616#define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
617
7afa08da 618/* this function add for support point-to-multipoint ,see rfc2328
61912.4.1.4.*/
620/* from "edward rrr" <edward_rrr@hotmail.com>
621 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
4dadc291 622static int
68980084 623lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi)
7afa08da 624{
625 int links = 0;
626 struct route_node *rn;
627 struct ospf_neighbor *nbr = NULL;
628 struct in_addr id, mask;
88d6cf37 629 u_int16_t cost = ospf_link_cost (oi);
7afa08da 630
631 mask.s_addr = 0xffffffff;
632 id.s_addr = oi->address->u.prefix4.s_addr;
779adb01 633 links += link_info_set (s, id, mask, LSA_LINK_TYPE_STUB, 0, 0);
7afa08da 634
1cc8f762 635 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 636 zlog_debug ("PointToMultipoint: running ptomultip_set");
7afa08da 637
638 /* Search neighbor, */
639 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
640 if ((nbr = rn->info) != NULL)
641 /* Ignore myself. */
68980084 642 if (!IPV4_ADDR_SAME (&nbr->router_id, &oi->ospf->router_id))
7afa08da 643 if (nbr->state == NSM_Full)
644
645 {
779adb01 646 links += link_info_set (s, nbr->router_id, oi->address->u.prefix4,
647 LSA_LINK_TYPE_POINTOPOINT, 0, cost);
1cc8f762 648 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 649 zlog_debug ("PointToMultipoint: set link to %s",
1cc8f762 650 inet_ntoa(oi->address->u.prefix4));
7afa08da 651 }
652
653 return links;
7afa08da 654}
655
718e3744 656/* Set router-LSA link information. */
4dadc291 657static int
718e3744 658router_lsa_link_set (struct stream *s, struct ospf_area *area)
659{
52dc7ee6 660 struct listnode *node;
1eb8ef25 661 struct ospf_interface *oi;
718e3744 662 int links = 0;
663
1eb8ef25 664 for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
718e3744 665 {
718e3744 666 struct interface *ifp = oi->ifp;
667
668 /* Check interface is up, OSPF is enable. */
2e3b2e47 669 if (if_is_operative (ifp))
718e3744 670 {
671 if (oi->state != ISM_Down)
672 {
673 /* Describe each link. */
674 switch (oi->type)
675 {
676 case OSPF_IFTYPE_POINTOPOINT:
677 links += lsa_link_ptop_set (s, oi);
678 break;
679 case OSPF_IFTYPE_BROADCAST:
680 links += lsa_link_broadcast_set (s, oi);
681 break;
682 case OSPF_IFTYPE_NBMA:
683 links += lsa_link_nbma_set (s, oi);
684 break;
685 case OSPF_IFTYPE_POINTOMULTIPOINT:
68980084 686 links += lsa_link_ptomp_set (s, oi);
718e3744 687 break;
688 case OSPF_IFTYPE_VIRTUALLINK:
689 links += lsa_link_virtuallink_set (s, oi);
690 break;
691 case OSPF_IFTYPE_LOOPBACK:
692 links += lsa_link_loopback_set (s, oi);
693 }
694 }
695 }
696 }
697
698 return links;
699}
700
701/* Set router-LSA body. */
4dadc291 702static void
718e3744 703ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area)
704{
705 unsigned long putp;
706 u_int16_t cnt;
707
708 /* Set flags. */
709 stream_putc (s, router_lsa_flags (area));
710
711 /* Set Zero fields. */
712 stream_putc (s, 0);
713
714 /* Keep pointer to # links. */
9985f83c 715 putp = stream_get_endp(s);
718e3744 716
717 /* Forward word */
718 stream_putw(s, 0);
719
720 /* Set all link information. */
721 cnt = router_lsa_link_set (s, area);
722
723 /* Set # of links here. */
724 stream_putw_at (s, putp, cnt);
725}
88d6cf37 726\f
727static int
728ospf_stub_router_timer (struct thread *t)
729{
730 struct ospf_area *area = THREAD_ARG (t);
731
732 area->t_stub_router = NULL;
733
734 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
735
736 /* clear stub route state and generate router-lsa refresh, don't
737 * clobber an administratively set stub-router state though.
738 */
739 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
740 return 0;
741
742 UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
743
744 ospf_router_lsa_timer_add (area);
745
746 return 0;
747}
718e3744 748
88d6cf37 749inline static void
750ospf_stub_router_check (struct ospf_area *area)
751{
752 /* area must either be administratively configured to be stub
753 * or startup-time stub-router must be configured and we must in a pre-stub
754 * state.
755 */
756 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))
757 {
758 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
759 return;
760 }
761
762 /* not admin-stubbed, check whether startup stubbing is configured and
763 * whether it's not been done yet
764 */
765 if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED))
766 return;
767
768 if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED)
769 {
770 /* stub-router is hence done forever for this area, even if someone
771 * tries configure it (take effect next restart).
772 */
773 SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED);
774 return;
775 }
776
777 /* startup stub-router configured and not yet done */
778 SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED);
779
780 OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer,
781 area->ospf->stub_router_startup_time);
782}
783\f
718e3744 784/* Create new router-LSA. */
4dadc291 785static struct ospf_lsa *
718e3744 786ospf_router_lsa_new (struct ospf_area *area)
787{
68980084 788 struct ospf *ospf = area->ospf;
718e3744 789 struct stream *s;
790 struct lsa_header *lsah;
791 struct ospf_lsa *new;
792 int length;
793
794 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 795 zlog_debug ("LSA[Type1]: Create router-LSA instance");
718e3744 796
88d6cf37 797 /* check whether stub-router is desired, and if this is the first
798 * router LSA.
799 */
800 ospf_stub_router_check (area);
801
718e3744 802 /* Create a stream for LSA. */
803 s = stream_new (OSPF_MAX_LSA_SIZE);
718e3744 804 /* Set LSA common header fields. */
d4a53d58 805 lsa_header_set (s, LSA_OPTIONS_GET (area) | LSA_OPTIONS_NSSA_GET (area),
d4a53d58 806 OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
718e3744 807
808 /* Set router-LSA body fields. */
809 ospf_router_lsa_body_set (s, area);
810
811 /* Set length. */
812 length = stream_get_endp (s);
779adb01 813 lsah = (struct lsa_header *) STREAM_DATA (s);
718e3744 814 lsah->length = htons (length);
815
816 /* Now, create OSPF LSA instance. */
c24d602e 817 if ( (new = ospf_lsa_new ()) == NULL)
818 {
819 zlog_err ("%s: Unable to create new lsa", __func__);
820 return NULL;
821 }
822
718e3744 823 new->area = area;
f6543138 824 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
718e3744 825
826 /* Copy LSA data to store, discard stream. */
827 new->data = ospf_lsa_data_new (length);
828 memcpy (new->data, lsah, length);
829 stream_free (s);
830
831 return new;
832}
833
834/* Originate Router-LSA. */
88d6cf37 835static struct ospf_lsa *
718e3744 836ospf_router_lsa_originate (struct ospf_area *area)
837{
838 struct ospf_lsa *new;
88d6cf37 839
718e3744 840 /* Create new router-LSA instance. */
c24d602e 841 if ( (new = ospf_router_lsa_new (area)) == NULL)
842 {
843 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
844 return NULL;
845 }
718e3744 846
847 /* Sanity check. */
848 if (new->data->adv_router.s_addr == 0)
849 {
850 if (IS_DEBUG_OSPF_EVENT)
e588f21f 851 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
718e3744 852 ospf_lsa_discard (new);
853 return NULL;
854 }
855
856 /* Install LSA to LSDB. */
68980084 857 new = ospf_lsa_install (area->ospf, NULL, new);
718e3744 858
859 /* Update LSA origination count. */
68980084 860 area->ospf->lsa_originate_count++;
718e3744 861
862 /* Flooding new LSA through area. */
863 ospf_flood_through_area (area, NULL, new);
864
865 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
866 {
e588f21f 867 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
718e3744 868 new->data->type, inet_ntoa (new->data->id), new);
869 ospf_lsa_header_dump (new->data);
870 }
871
872 return new;
873}
874
875/* Refresh router-LSA. */
4dadc291 876static struct ospf_lsa *
718e3744 877ospf_router_lsa_refresh (struct ospf_lsa *lsa)
878{
879 struct ospf_area *area = lsa->area;
880 struct ospf_lsa *new;
881
882 /* Sanity check. */
883 assert (lsa->data);
884
885 /* Delete LSA from neighbor retransmit-list. */
68980084 886 ospf_ls_retransmit_delete_nbr_area (area, lsa);
718e3744 887
888 /* Create new router-LSA instance. */
c24d602e 889 if ( (new = ospf_router_lsa_new (area)) == NULL)
890 {
891 zlog_err ("%s: ospf_router_lsa_new returned NULL", __func__);
892 return NULL;
893 }
894
718e3744 895 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
896
68980084 897 ospf_lsa_install (area->ospf, NULL, new);
718e3744 898
899 /* Flood LSA through area. */
900 ospf_flood_through_area (area, NULL, new);
901
902 /* Debug logging. */
903 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
904 {
e588f21f 905 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
718e3744 906 new->data->type, inet_ntoa (new->data->id));
907 ospf_lsa_header_dump (new->data);
908 }
909
910 return NULL;
911}
912
4dadc291 913static int
718e3744 914ospf_router_lsa_timer (struct thread *t)
915{
916 struct ospf_area *area;
917
918 if (IS_DEBUG_OSPF_EVENT)
e588f21f 919 zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
718e3744 920
921 area = THREAD_ARG (t);
922 area->t_router_lsa_self = NULL;
923
924 /* Now refresh router-LSA. */
925 if (area->router_lsa_self)
926 ospf_router_lsa_refresh (area->router_lsa_self);
927 /* Newly originate router-LSA. */
928 else
929 ospf_router_lsa_originate (area);
930
931 return 0;
932}
933
934void
935ospf_router_lsa_timer_add (struct ospf_area *area)
936{
937 /* Keep area's self-originated router-LSA. */
938 struct ospf_lsa *lsa = area->router_lsa_self;
939
940 /* Cancel previously scheduled router-LSA timer. */
941 if (area->t_router_lsa_self)
942 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 943 zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
718e3744 944
945 OSPF_TIMER_OFF (area->t_router_lsa_self);
946
947 /* If router-LSA is originated previously, check the interval time. */
948 if (lsa)
949 {
950 int delay;
951 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
952 {
953 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
954 ospf_router_lsa_timer, delay);
955 return;
956 }
957 }
958
959 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 960 zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
718e3744 961
962 /* Immediately refresh router-LSA. */
963 OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0);
964}
965
966int
68980084 967ospf_router_lsa_update_timer (struct thread *thread)
718e3744 968{
68980084 969 struct ospf *ospf = THREAD_ARG (thread);
1eb8ef25 970 struct listnode *node, *nnode;
971 struct ospf_area *area;
718e3744 972
973 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 974 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
718e3744 975
68980084 976 ospf->t_router_lsa_update = NULL;
718e3744 977
1eb8ef25 978 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
718e3744 979 {
718e3744 980 struct ospf_lsa *lsa = area->router_lsa_self;
981 struct router_lsa *rl;
eb1ce605 982 const char *area_str;
718e3744 983
984 /* Keep Area ID string. */
985 area_str = AREA_NAME (area);
986
987 /* If LSA not exist in this Area, originate new. */
988 if (lsa == NULL)
989 {
990 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 991 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str);
718e3744 992
993 ospf_router_lsa_originate (area);
994 }
995 /* If router-ID is changed, Link ID must change.
996 First flush old LSA, then originate new. */
68980084 997 else if (!IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
718e3744 998 {
999 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1000 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
718e3744 1001 lsa->data->type, inet_ntoa (lsa->data->id), area_str);
1002 ospf_lsa_flush_area (lsa, area);
1fe6ed38 1003 ospf_lsa_unlock (&area->router_lsa_self);
718e3744 1004 area->router_lsa_self = NULL;
1005
1006 /* Refresh router-LSA, (not install) and flood through area. */
1007 ospf_router_lsa_timer_add (area);
1008 }
1009 else
1010 {
1011 rl = (struct router_lsa *) lsa->data;
1012 /* Refresh router-LSA, (not install) and flood through area. */
68980084 1013 if (rl->flags != ospf->flags)
718e3744 1014 ospf_router_lsa_timer_add (area);
1015 }
1016 }
1017
1018 return 0;
1019}
1020
1021\f
1022/* network-LSA related functions. */
1023/* Originate Network-LSA. */
4dadc291 1024static void
718e3744 1025ospf_network_lsa_body_set (struct stream *s, struct ospf_interface *oi)
1026{
1027 struct in_addr mask;
1028 struct route_node *rn;
1029 struct ospf_neighbor *nbr;
1030
1031 masklen2ip (oi->address->prefixlen, &mask);
1032 stream_put_ipv4 (s, mask.s_addr);
1033
1034 /* The network-LSA lists those routers that are fully adjacent to
1035 the Designated Router; each fully adjacent router is identified by
1036 its OSPF Router ID. The Designated Router includes itself in this
1037 list. RFC2328, Section 12.4.2 */
1038
1039 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
1040 if ((nbr = rn->info) != NULL)
1041 if (nbr->state == NSM_Full || nbr == oi->nbr_self)
1042 stream_put_ipv4 (s, nbr->router_id.s_addr);
1043}
1044
4dadc291 1045static struct ospf_lsa *
718e3744 1046ospf_network_lsa_new (struct ospf_interface *oi)
1047{
1048 struct stream *s;
1049 struct ospf_lsa *new;
1050 struct lsa_header *lsah;
1051 int length;
1052
1053 /* If there are no neighbours on this network (the net is stub),
1054 the router does not originate network-LSA (see RFC 12.4.2) */
1055 if (oi->full_nbrs == 0)
1056 return NULL;
1057
1058 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1059 zlog_debug ("LSA[Type2]: Create network-LSA instance");
718e3744 1060
1061 /* Create new stream for LSA. */
1062 s = stream_new (OSPF_MAX_LSA_SIZE);
1063 lsah = (struct lsa_header *) STREAM_DATA (s);
1064
1065 lsa_header_set (s, (OPTIONS (oi) | LSA_OPTIONS_GET (oi->area)),
68980084 1066 OSPF_NETWORK_LSA, DR (oi), oi->ospf->router_id);
718e3744 1067
1068 /* Set network-LSA body fields. */
1069 ospf_network_lsa_body_set (s, oi);
1070
1071 /* Set length. */
1072 length = stream_get_endp (s);
1073 lsah->length = htons (length);
1074
1075 /* Create OSPF LSA instance. */
c24d602e 1076 if ( (new = ospf_lsa_new ()) == NULL)
1077 {
1078 zlog_err ("%s: ospf_lsa_new returned NULL", __func__);
1079 return NULL;
1080 }
1081
718e3744 1082 new->area = oi->area;
f6543138 1083 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
718e3744 1084
1085 /* Copy LSA to store. */
1086 new->data = ospf_lsa_data_new (length);
1087 memcpy (new->data, lsah, length);
1088 stream_free (s);
1089
1090 return new;
1091}
1092
1093/* Originate network-LSA. */
4dadc291 1094static struct ospf_lsa *
718e3744 1095ospf_network_lsa_originate (struct ospf_interface *oi)
1096{
1097 struct ospf_lsa *new;
1098
1099 /* Create new network-LSA instance. */
1100 new = ospf_network_lsa_new (oi);
1101 if (new == NULL)
1102 return NULL;
1103
1104 /* Install LSA to LSDB. */
68980084 1105 new = ospf_lsa_install (oi->ospf, oi, new);
718e3744 1106
1107 /* Update LSA origination count. */
68980084 1108 oi->ospf->lsa_originate_count++;
718e3744 1109
1110 /* Flooding new LSA through area. */
1111 ospf_flood_through_area (oi->area, NULL, new);
1112
1113 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1114 {
e588f21f 1115 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
718e3744 1116 new->data->type, inet_ntoa (new->data->id), new);
1117 ospf_lsa_header_dump (new->data);
1118 }
1119
1120 return new;
1121}
1122
1123int
1124ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)
1125{
1126 struct ospf_area *area = lsa->area;
1127 struct ospf_lsa *new;
1128
1129 assert (lsa->data);
1130
1131 /* Delete LSA from neighbor retransmit-list. */
68980084 1132 ospf_ls_retransmit_delete_nbr_area (area, lsa);
718e3744 1133
1134 /* Create new network-LSA instance. */
1135 new = ospf_network_lsa_new (oi);
1136 if (new == NULL)
1137 return -1;
1138 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
1139
68980084 1140 ospf_lsa_install (area->ospf, oi, new);
718e3744 1141
1142 /* Flood LSA through aera. */
1143 ospf_flood_through_area (area, NULL, new);
1144
1145 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1146 {
e588f21f 1147 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
718e3744 1148 new->data->type, inet_ntoa (new->data->id));
1149 ospf_lsa_header_dump (new->data);
1150 }
1151
1152 return 0;
1153}
1154
4dadc291 1155static int
718e3744 1156ospf_network_lsa_refresh_timer (struct thread *t)
1157{
1158 struct ospf_interface *oi;
1159
1160 oi = THREAD_ARG (t);
1161 oi->t_network_lsa_self = NULL;
1162
1163 if (oi->network_lsa_self)
1164 /* Now refresh network-LSA. */
1165 ospf_network_lsa_refresh (oi->network_lsa_self, oi);
1166 else
1167 /* Newly create network-LSA. */
1168 ospf_network_lsa_originate (oi);
1169
1170 return 0;
1171}
1172
1173void
1174ospf_network_lsa_timer_add (struct ospf_interface *oi)
1175{
1176 /* Keep interface's self-originated network-LSA. */
1177 struct ospf_lsa *lsa = oi->network_lsa_self;
1178
1179 /* Cancel previously schedules network-LSA timer. */
1180 if (oi->t_network_lsa_self)
1181 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1182 zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
718e3744 1183 OSPF_TIMER_OFF (oi->t_network_lsa_self);
1184
1185 /* If network-LSA is originated previously, check the interval time. */
1186 if (lsa)
1187 {
1188 int delay;
1189 if ((delay = ospf_lsa_refresh_delay (lsa)) > 0)
1190 {
1191 oi->t_network_lsa_self =
1192 thread_add_timer (master, ospf_network_lsa_refresh_timer,
1193 oi, delay);
1194 return;
1195 }
1196 }
1197
1198 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1199 zlog_debug ("Scheduling network-LSA origination right away");
718e3744 1200
1201 /* Immediately refresh network-LSA. */
1202 oi->t_network_lsa_self =
1203 thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0);
1204}
1205
1206\f
4dadc291 1207static void
718e3744 1208stream_put_ospf_metric (struct stream *s, u_int32_t metric_value)
1209{
1210 u_int32_t metric;
1211 char *mp;
1212
1213 /* Put 0 metric. TOS metric is not supported. */
1214 metric = htonl (metric_value);
1215 mp = (char *) &metric;
1216 mp++;
1217 stream_put (s, mp, 3);
1218}
1219
1220/* summary-LSA related functions. */
4dadc291 1221static void
718e3744 1222ospf_summary_lsa_body_set (struct stream *s, struct prefix *p,
1223 u_int32_t metric)
1224{
1225 struct in_addr mask;
1226
1227 masklen2ip (p->prefixlen, &mask);
1228
1229 /* Put Network Mask. */
1230 stream_put_ipv4 (s, mask.s_addr);
1231
1232 /* Set # TOS. */
1233 stream_putc (s, (u_char) 0);
1234
1235 /* Set metric. */
1236 stream_put_ospf_metric (s, metric);
1237}
1238
4dadc291 1239static struct ospf_lsa *
718e3744 1240ospf_summary_lsa_new (struct ospf_area *area, struct prefix *p,
1241 u_int32_t metric, struct in_addr id)
1242{
1243 struct stream *s;
1244 struct ospf_lsa *new;
1245 struct lsa_header *lsah;
1246 int length;
1247
c24d602e 1248 if (id.s_addr == 0xffffffff)
1249 {
1250 /* Maybe Link State ID not available. */
1251 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1252 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1253 OSPF_SUMMARY_LSA);
1254 return NULL;
1255 }
1256
718e3744 1257 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1258 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
718e3744 1259
1260 /* Create new stream for LSA. */
1261 s = stream_new (OSPF_MAX_LSA_SIZE);
1262 lsah = (struct lsa_header *) STREAM_DATA (s);
1263
68980084 1264 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_SUMMARY_LSA,
1265 id, area->ospf->router_id);
718e3744 1266
1267 /* Set summary-LSA body fields. */
1268 ospf_summary_lsa_body_set (s, p, metric);
1269
1270 /* Set length. */
1271 length = stream_get_endp (s);
1272 lsah->length = htons (length);
1273
1274 /* Create OSPF LSA instance. */
1275 new = ospf_lsa_new ();
1276 new->area = area;
f6543138 1277 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
718e3744 1278
1279 /* Copy LSA to store. */
1280 new->data = ospf_lsa_data_new (length);
1281 memcpy (new->data, lsah, length);
1282 stream_free (s);
1283
1284 return new;
1285}
1286
1287/* Originate Summary-LSA. */
1288struct ospf_lsa *
1289ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1290 struct ospf_area *area)
1291{
1292 struct ospf_lsa *new;
1293 struct in_addr id;
1294
68980084 1295 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
718e3744 1296
c24d602e 1297 if (id.s_addr == 0xffffffff)
1298 {
1299 /* Maybe Link State ID not available. */
1300 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1301 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1302 OSPF_SUMMARY_LSA);
1303 return NULL;
1304 }
1305
718e3744 1306 /* Create new summary-LSA instance. */
c24d602e 1307 if ( !(new = ospf_summary_lsa_new (area, (struct prefix *) p, metric, id)))
1308 return NULL;
718e3744 1309
1310 /* Instlal LSA to LSDB. */
68980084 1311 new = ospf_lsa_install (area->ospf, NULL, new);
718e3744 1312
1313 /* Update LSA origination count. */
68980084 1314 area->ospf->lsa_originate_count++;
718e3744 1315
1316 /* Flooding new LSA through area. */
1317 ospf_flood_through_area (area, NULL, new);
1318
1319 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1320 {
e588f21f 1321 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
718e3744 1322 new->data->type, inet_ntoa (new->data->id), new);
1323 ospf_lsa_header_dump (new->data);
1324 }
1325
1326 return new;
1327}
1328
1329struct ospf_lsa*
68980084 1330ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 1331{
1332 struct ospf_lsa *new;
1333 struct summary_lsa *sl;
1334 struct prefix p;
1335
1336 /* Sanity check. */
1337 assert (lsa->data);
1338
1339 sl = (struct summary_lsa *)lsa->data;
1340 p.prefixlen = ip_masklen (sl->mask);
1341 new = ospf_summary_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1342 sl->header.id);
c24d602e 1343
1344 if (!new)
1345 return NULL;
1346
718e3744 1347 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
718e3744 1348
68980084 1349 ospf_lsa_install (ospf, NULL, new);
718e3744 1350
1351 /* Flood LSA through AS. */
1352 ospf_flood_through_area (new->area, NULL, new);
1353
1354 /* Debug logging. */
1355 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1356 {
e588f21f 1357 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
718e3744 1358 new->data->type, inet_ntoa (new->data->id));
1359 ospf_lsa_header_dump (new->data);
1360 }
1361
1362 return new;
1363}
1364
1365\f
1366/* summary-ASBR-LSA related functions. */
4dadc291 1367static void
718e3744 1368ospf_summary_asbr_lsa_body_set (struct stream *s, struct prefix *p,
1369 u_int32_t metric)
1370{
1371 struct in_addr mask;
1372
1373 masklen2ip (p->prefixlen, &mask);
1374
1375 /* Put Network Mask. */
1376 stream_put_ipv4 (s, mask.s_addr);
1377
1378 /* Set # TOS. */
1379 stream_putc (s, (u_char) 0);
1380
1381 /* Set metric. */
1382 stream_put_ospf_metric (s, metric);
1383}
1384
4dadc291 1385static struct ospf_lsa *
718e3744 1386ospf_summary_asbr_lsa_new (struct ospf_area *area, struct prefix *p,
1387 u_int32_t metric, struct in_addr id)
1388{
1389 struct stream *s;
1390 struct ospf_lsa *new;
1391 struct lsa_header *lsah;
1392 int length;
1393
c24d602e 1394 if (id.s_addr == 0xffffffff)
1395 {
1396 /* Maybe Link State ID not available. */
1397 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1398 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1399 OSPF_ASBR_SUMMARY_LSA);
1400 return NULL;
1401 }
1402
718e3744 1403 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1404 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
718e3744 1405
1406 /* Create new stream for LSA. */
1407 s = stream_new (OSPF_MAX_LSA_SIZE);
1408 lsah = (struct lsa_header *) STREAM_DATA (s);
1409
68980084 1410 lsa_header_set (s, LSA_OPTIONS_GET (area), OSPF_ASBR_SUMMARY_LSA,
1411 id, area->ospf->router_id);
718e3744 1412
1413 /* Set summary-LSA body fields. */
1414 ospf_summary_asbr_lsa_body_set (s, p, metric);
1415
1416 /* Set length. */
1417 length = stream_get_endp (s);
1418 lsah->length = htons (length);
1419
1420 /* Create OSPF LSA instance. */
1421 new = ospf_lsa_new ();
1422 new->area = area;
f6543138 1423 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
718e3744 1424
1425 /* Copy LSA to store. */
1426 new->data = ospf_lsa_data_new (length);
1427 memcpy (new->data, lsah, length);
1428 stream_free (s);
1429
1430 return new;
1431}
1432
1433/* Originate summary-ASBR-LSA. */
1434struct ospf_lsa *
1435ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,
1436 struct ospf_area *area)
1437{
1438 struct ospf_lsa *new;
1439 struct in_addr id;
1440
68980084 1441 id = ospf_lsa_unique_id (area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA, p);
718e3744 1442
c24d602e 1443 if (id.s_addr == 0xffffffff)
1444 {
1445 /* Maybe Link State ID not available. */
1446 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1447 zlog_debug ("LSA[Type%d]: Link ID not available, can't originate",
1448 OSPF_ASBR_SUMMARY_LSA);
1449 return NULL;
1450 }
1451
718e3744 1452 /* Create new summary-LSA instance. */
1453 new = ospf_summary_asbr_lsa_new (area, (struct prefix *) p, metric, id);
c24d602e 1454 if (!new)
1455 return NULL;
718e3744 1456
1457 /* Install LSA to LSDB. */
68980084 1458 new = ospf_lsa_install (area->ospf, NULL, new);
718e3744 1459
1460 /* Update LSA origination count. */
68980084 1461 area->ospf->lsa_originate_count++;
718e3744 1462
1463 /* Flooding new LSA through area. */
1464 ospf_flood_through_area (area, NULL, new);
1465
1466 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1467 {
e588f21f 1468 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
718e3744 1469 new->data->type, inet_ntoa (new->data->id), new);
1470 ospf_lsa_header_dump (new->data);
1471 }
1472
1473 return new;
1474}
1475
1476struct ospf_lsa*
68980084 1477ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 1478{
1479 struct ospf_lsa *new;
1480 struct summary_lsa *sl;
1481 struct prefix p;
1482
1483 /* Sanity check. */
1484 assert (lsa->data);
1485
1486 sl = (struct summary_lsa *)lsa->data;
1487 p.prefixlen = ip_masklen (sl->mask);
1488 new = ospf_summary_asbr_lsa_new (lsa->area, &p, GET_METRIC (sl->metric),
1489 sl->header.id);
c24d602e 1490 if (!new)
1491 return NULL;
718e3744 1492
1493 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
718e3744 1494
68980084 1495 ospf_lsa_install (ospf, NULL, new);
718e3744 1496
1497 /* Flood LSA through area. */
1498 ospf_flood_through_area (new->area, NULL, new);
1499
1500 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
1501 {
e588f21f 1502 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
718e3744 1503 new->data->type, inet_ntoa (new->data->id));
1504 ospf_lsa_header_dump (new->data);
1505 }
1506
1507 return new;
1508}
1509
1510/* AS-external-LSA related functions. */
1511
1512/* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1513 is connected, else 0*/
4dadc291 1514static struct in_addr
68980084 1515ospf_external_lsa_nexthop_get (struct ospf *ospf, struct in_addr nexthop)
718e3744 1516{
1517 struct in_addr fwd;
1518 struct prefix nh;
1eb8ef25 1519 struct listnode *node;
1520 struct ospf_interface *oi;
718e3744 1521
1522 fwd.s_addr = 0;
1523
1524 if (!nexthop.s_addr)
1525 return fwd;
1526
1527 /* Check whether nexthop is covered by OSPF network. */
1528 nh.family = AF_INET;
1529 nh.u.prefix4 = nexthop;
1530 nh.prefixlen = IPV4_MAX_BITLEN;
4ca15d4a
PJ
1531
1532 /* XXX/SCALE: If there were a lot of oi's on an ifp, then it'd be
1533 * better to make use of the per-ifp table of ois.
1534 */
1eb8ef25 1535 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
1536 if (if_is_operative (oi->ifp))
1537 if (oi->address->family == AF_INET)
1538 if (prefix_match (oi->address, &nh))
1539 return nexthop;
718e3744 1540
1541 return fwd;
1542}
1543
718e3744 1544/* NSSA-external-LSA related functions. */
1545
1546/* Get 1st IP connection for Forward Addr */
4dadc291 1547
718e3744 1548struct in_addr
1549ospf_get_ip_from_ifp (struct ospf_interface *oi)
1550{
1551 struct in_addr fwd;
1552
1553 fwd.s_addr = 0;
1554
2e3b2e47 1555 if (if_is_operative (oi->ifp))
718e3744 1556 return oi->address->u.prefix4;
1557
1558 return fwd;
1559}
1560
1561/* Get 1st IP connection for Forward Addr */
1562struct in_addr
f2c80652 1563ospf_get_nssa_ip (struct ospf_area *area)
718e3744 1564{
1565 struct in_addr fwd;
f2c80652 1566 struct in_addr best_default;
1eb8ef25 1567 struct listnode *node;
1568 struct ospf_interface *oi;
718e3744 1569
1570 fwd.s_addr = 0;
f2c80652 1571 best_default.s_addr = 0;
718e3744 1572
1eb8ef25 1573 for (ALL_LIST_ELEMENTS_RO (area->ospf->oiflist, node, oi))
718e3744 1574 {
2e3b2e47 1575 if (if_is_operative (oi->ifp))
718e3744 1576 if (oi->area->external_routing == OSPF_AREA_NSSA)
68980084 1577 if (oi->address && oi->address->family == AF_INET)
1578 {
1579 if (best_default.s_addr == 0)
1580 best_default = oi->address->u.prefix4;
1581 if (oi->area == area)
1582 return oi->address->u.prefix4;
f2c80652 1583 }
718e3744 1584 }
f2c80652 1585 if (best_default.s_addr != 0)
1586 return best_default;
718e3744 1587
68980084 1588 if (best_default.s_addr != 0)
1589 return best_default;
1590
718e3744 1591 return fwd;
1592}
beebba75 1593
718e3744 1594#define DEFAULT_DEFAULT_METRIC 20
1595#define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1596#define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1597
1598#define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1599
1600int
68980084 1601metric_type (struct ospf *ospf, u_char src)
718e3744 1602{
68980084 1603 return (ospf->dmetric[src].type < 0 ?
1604 DEFAULT_METRIC_TYPE : ospf->dmetric[src].type);
718e3744 1605}
1606
1607int
68980084 1608metric_value (struct ospf *ospf, u_char src)
718e3744 1609{
68980084 1610 if (ospf->dmetric[src].value < 0)
718e3744 1611 {
1612 if (src == DEFAULT_ROUTE)
1613 {
68980084 1614 if (ospf->default_originate == DEFAULT_ORIGINATE_ZEBRA)
718e3744 1615 return DEFAULT_DEFAULT_ORIGINATE_METRIC;
1616 else
1617 return DEFAULT_DEFAULT_ALWAYS_METRIC;
1618 }
68980084 1619 else if (ospf->default_metric < 0)
718e3744 1620 return DEFAULT_DEFAULT_METRIC;
1621 else
68980084 1622 return ospf->default_metric;
718e3744 1623 }
1624
68980084 1625 return ospf->dmetric[src].value;
718e3744 1626}
1627
1628/* Set AS-external-LSA body. */
4dadc291 1629static void
68980084 1630ospf_external_lsa_body_set (struct stream *s, struct external_info *ei,
1631 struct ospf *ospf)
718e3744 1632{
1633 struct prefix_ipv4 *p = &ei->p;
1634 struct in_addr mask, fwd_addr;
1635 u_int32_t mvalue;
1636 int mtype;
1637 int type;
1638
1639 /* Put Network Mask. */
1640 masklen2ip (p->prefixlen, &mask);
1641 stream_put_ipv4 (s, mask.s_addr);
1642
1643 /* If prefix is default, specify DEFAULT_ROUTE. */
1644 type = is_prefix_default (&ei->p) ? DEFAULT_ROUTE : ei->type;
1645
1646 mtype = (ROUTEMAP_METRIC_TYPE (ei) != -1) ?
68980084 1647 ROUTEMAP_METRIC_TYPE (ei) : metric_type (ospf, type);
718e3744 1648
1649 mvalue = (ROUTEMAP_METRIC (ei) != -1) ?
68980084 1650 ROUTEMAP_METRIC (ei) : metric_value (ospf, type);
718e3744 1651
1652 /* Put type of external metric. */
1653 stream_putc (s, (mtype == EXTERNAL_METRIC_TYPE_2 ? 0x80 : 0));
1654
1655 /* Put 0 metric. TOS metric is not supported. */
1656 stream_put_ospf_metric (s, mvalue);
1657
1658 /* Get forwarding address to nexthop if on the Connection List, else 0. */
68980084 1659 fwd_addr = ospf_external_lsa_nexthop_get (ospf, ei->nexthop);
718e3744 1660
1661 /* Put forwarding address. */
1662 stream_put_ipv4 (s, fwd_addr.s_addr);
1663
1664 /* Put route tag -- This value should be introduced from configuration. */
1665 stream_putl (s, 0);
1666}
1667
1668/* Create new external-LSA. */
4dadc291 1669static struct ospf_lsa *
68980084 1670ospf_external_lsa_new (struct ospf *ospf,
1671 struct external_info *ei, struct in_addr *old_id)
718e3744 1672{
1673 struct stream *s;
1674 struct lsa_header *lsah;
1675 struct ospf_lsa *new;
1676 struct in_addr id;
1677 int length;
1678
1679 if (ei == NULL)
1680 {
1681 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1682 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
718e3744 1683 return NULL;
1684 }
1685
1686 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1687 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
718e3744 1688
1689 /* If old Link State ID is specified, refresh LSA with same ID. */
1690 if (old_id)
1691 id = *old_id;
1692 /* Get Link State with unique ID. */
1693 else
1694 {
68980084 1695 id = ospf_lsa_unique_id (ospf, ospf->lsdb, OSPF_AS_EXTERNAL_LSA, &ei->p);
718e3744 1696 if (id.s_addr == 0xffffffff)
1697 {
1698 /* Maybe Link State ID not available. */
1699 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 1700 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
718e3744 1701 return NULL;
1702 }
1703 }
1704
1705 /* Create new stream for LSA. */
1706 s = stream_new (OSPF_MAX_LSA_SIZE);
1707 lsah = (struct lsa_header *) STREAM_DATA (s);
1708
1709 /* Set LSA common header fields. */
68980084 1710 lsa_header_set (s, OSPF_OPTION_E, OSPF_AS_EXTERNAL_LSA,
1711 id, ospf->router_id);
718e3744 1712
1713 /* Set AS-external-LSA body fields. */
68980084 1714 ospf_external_lsa_body_set (s, ei, ospf);
718e3744 1715
1716 /* Set length. */
1717 length = stream_get_endp (s);
1718 lsah->length = htons (length);
1719
1720 /* Now, create OSPF LSA instance. */
1721 new = ospf_lsa_new ();
1722 new->area = NULL;
f6543138 1723 SET_FLAG (new->flags, OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
718e3744 1724
1725 /* Copy LSA data to store, discard stream. */
1726 new->data = ospf_lsa_data_new (length);
1727 memcpy (new->data, lsah, length);
1728 stream_free (s);
1729
1730 return new;
1731}
1732
718e3744 1733/* As Type-7 */
4dadc291 1734static void
68980084 1735ospf_install_flood_nssa (struct ospf *ospf,
1736 struct ospf_lsa *lsa, struct external_info *ei)
718e3744 1737{
d4a53d58 1738 struct ospf_lsa *new;
68980084 1739 struct as_external_lsa *extlsa;
1eb8ef25 1740 struct ospf_area *area;
1741 struct listnode *node, *nnode;
718e3744 1742
d4a53d58 1743 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1744 * which originated from an NSSA area. In which case it should not be
1745 * flooded back to NSSA areas.
1746 */
1747 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
1748 return;
1749
718e3744 1750 /* NSSA Originate or Refresh (If anyNSSA)
1751
1752 LSA is self-originated. And just installed as Type-5.
1753 Additionally, install as Type-7 LSDB for every attached NSSA.
1754
1755 P-Bit controls which ABR performs translation to outside world; If
1756 we are an ABR....do not set the P-bit, because we send the Type-5,
1757 not as the ABR Translator, but as the ASBR owner within the AS!
1758
1759 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1760 elected ABR Translator will see the P-bit, Translate, and re-flood.
1761
1762 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1763 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1764
1eb8ef25 1765 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
68980084 1766 {
0c14ad88 1767 /* Don't install Type-7 LSA's into nonNSSA area */
1768 if (area->external_routing != OSPF_AREA_NSSA)
1769 continue;
718e3744 1770
68980084 1771 /* make lsa duplicate, lock=1 */
d4a53d58 1772 new = ospf_lsa_dup (lsa);
1773 new->area = area;
1774 new->data->type = OSPF_AS_NSSA_LSA;
718e3744 1775
68980084 1776 /* set P-bit if not ABR */
020709f9 1777 if (! IS_OSPF_ABR (ospf))
68980084 1778 {
d4a53d58 1779 SET_FLAG(new->data->options, OSPF_OPTION_NP);
68980084 1780
1781 /* set non-zero FWD ADDR
1782
1783 draft-ietf-ospf-nssa-update-09.txt
1784
1785 if the network between the NSSA AS boundary router and the
1786 adjacent AS is advertised into OSPF as an internal OSPF route,
1787 the forwarding address should be the next op address as is cu
1788 currently done with type-5 LSAs. If the intervening network is
1789 not adversited into OSPF as an internal OSPF route and the
1790 type-7 LSA's P-bit is set a forwarding address should be
1791 selected from one of the router's active OSPF inteface addresses
1792 which belong to the NSSA. If no such addresses exist, then
1793 no type-7 LSA's with the P-bit set should originate from this
1794 router. */
1795
d4a53d58 1796 /* kevinm: not updating lsa anymore, just new */
1797 extlsa = (struct as_external_lsa *)(new->data);
68980084 1798
1799 if (extlsa->e[0].fwd_addr.s_addr == 0)
1800 extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); /* this NSSA area in ifp */
718e3744 1801
d748032f 1802 if (extlsa->e[0].fwd_addr.s_addr == 0)
1803 {
1804 if (IS_DEBUG_OSPF_NSSA)
e588f21f 1805 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
1fe6ed38 1806 ospf_lsa_discard (new);
d748032f 1807 return;
1808 }
f2c80652 1809 }
718e3744 1810
68980084 1811 /* install also as Type-7 */
d4a53d58 1812 ospf_lsa_install (ospf, NULL, new); /* Remove Old, Lock New = 2 */
68980084 1813
1814 /* will send each copy, lock=2+n */
d4a53d58 1815 ospf_flood_through_as (ospf, NULL, new); /* all attached NSSA's, no AS/STUBs */
1816 }
1817}
1818
4dadc291 1819static struct ospf_lsa *
d4a53d58 1820ospf_lsa_translated_nssa_new (struct ospf *ospf,
1821 struct ospf_lsa *type7)
1822{
1823
1824 struct ospf_lsa *new;
1825 struct as_external_lsa *ext, *extnew;
1826 struct external_info ei;
1827
1828 ext = (struct as_external_lsa *)(type7->data);
1829
1830 /* need external_info struct, fill in bare minimum */
1831 ei.p.family = AF_INET;
1832 ei.p.prefix = type7->data->id;
1833 ei.p.prefixlen = ip_masklen (ext->mask);
1834 ei.type = ZEBRA_ROUTE_OSPF;
1835 ei.nexthop = ext->header.adv_router;
1836 ei.route_map_set.metric = -1;
1837 ei.route_map_set.metric_type = -1;
1838 ei.tag = 0;
1839
1840 if ( (new = ospf_external_lsa_new (ospf, &ei, &type7->data->id)) == NULL)
1841 {
1842 if (IS_DEBUG_OSPF_NSSA)
e588f21f 1843 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
d4a53d58 1844 "Translated Type-5 for %s",
1845 inet_ntoa (ei.p.prefix));
1846 return NULL;
1847 }
1848
1849 extnew = (struct as_external_lsa *)(new->data);
1850
1851 /* copy over Type-7 data to new */
1852 extnew->e[0].tos = ext->e[0].tos;
1853 extnew->e[0].route_tag = ext->e[0].route_tag;
1854 extnew->e[0].fwd_addr.s_addr = ext->e[0].fwd_addr.s_addr;
1855 new->data->ls_seqnum = type7->data->ls_seqnum;
1856
1857 /* add translated flag, checksum and lock new lsa */
1858 SET_FLAG (new->flags, OSPF_LSA_LOCAL_XLT); /* Translated from 7 */
d4a53d58 1859 new = ospf_lsa_lock (new);
1860
1861 return new;
1862}
1863
d4a53d58 1864/* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1865struct ospf_lsa *
1866ospf_translated_nssa_originate (struct ospf *ospf, struct ospf_lsa *type7)
1867{
1868 struct ospf_lsa *new;
1869 struct as_external_lsa *extnew;
1870
1871 /* we cant use ospf_external_lsa_originate() as we need to set
1872 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1873 */
1874
1875 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1876 {
1877 if (IS_DEBUG_OSPF_NSSA)
e588f21f 1878 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
d4a53d58 1879 "Type-7, Id %s, to Type-5",
1880 inet_ntoa (type7->data->id));
1881 return NULL;
1882 }
1883
1884 extnew = (struct as_external_lsa *)new;
1885
1886 if (IS_DEBUG_OSPF_NSSA)
1887 {
e588f21f 1888 zlog_debug ("ospf_translated_nssa_originate(): "
d4a53d58 1889 "translated Type 7, installed:");
1890 ospf_lsa_header_dump (new->data);
e588f21f 1891 zlog_debug (" Network mask: %d",ip_masklen (extnew->mask));
1892 zlog_debug (" Forward addr: %s", inet_ntoa (extnew->e[0].fwd_addr));
d4a53d58 1893 }
1894
1895 if ( (new = ospf_lsa_install (ospf, NULL, new)) == NULL)
1896 {
1897 if (IS_DEBUG_OSPF_NSSA);
e588f21f 1898 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
d4a53d58 1899 "Could not install LSA "
1900 "id %s", inet_ntoa (type7->data->id));
1901 return NULL;
1902 }
1903
1904 ospf->lsa_originate_count++;
1905 ospf_flood_through_as (ospf, NULL, new);
1906
1907 return new;
1908}
1909
1910/* Refresh Translated from NSSA AS-external-LSA. */
1911struct ospf_lsa *
1912ospf_translated_nssa_refresh (struct ospf *ospf, struct ospf_lsa *type7,
1913 struct ospf_lsa *type5)
1914{
1915 struct ospf_lsa *new = NULL;
1916
1917 /* Sanity checks. */
1918 assert (type7 || type5);
ae128056 1919 if (!(type7 || type5))
e54e6e57 1920 return NULL;
d4a53d58 1921 if (type7)
1922 assert (type7->data);
1923 if (type5)
1924 assert (type5->data);
1925 assert (ospf->anyNSSA);
1926
1927 /* get required data according to what has been given */
1928 if (type7 && type5 == NULL)
1929 {
1930 /* find the translated Type-5 for this Type-7 */
1931 struct as_external_lsa *ext = (struct as_external_lsa *)(type7->data);
1932 struct prefix_ipv4 p =
1933 {
1934 .prefix = type7->data->id,
1935 .prefixlen = ip_masklen (ext->mask),
1936 .family = AF_INET,
1937 };
1938
1939 type5 = ospf_external_info_find_lsa (ospf, &p);
1940 }
1941 else if (type5 && type7 == NULL)
1942 {
1943 /* find the type-7 from which supplied type-5 was translated,
1944 * ie find first type-7 with same LSA Id.
1945 */
1eb8ef25 1946 struct listnode *ln, *lnn;
d4a53d58 1947 struct route_node *rn;
1948 struct ospf_lsa *lsa;
1949 struct ospf_area *area;
1950
1eb8ef25 1951 for (ALL_LIST_ELEMENTS (ospf->areas, ln, lnn, area))
d4a53d58 1952 {
1953 if (area->external_routing != OSPF_AREA_NSSA
1954 && !type7)
1955 continue;
1956
1957 LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
1958 {
1959 if (lsa->data->id.s_addr == type5->data->id.s_addr)
1960 {
1961 type7 = lsa;
1962 break;
1963 }
1964 }
1965 }
68980084 1966 }
d4a53d58 1967
1968 /* do we have type7? */
1969 if (!type7)
1970 {
1971 if (IS_DEBUG_OSPF_NSSA)
e588f21f 1972 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
d4a53d58 1973 "Type-5 LSA Id %s",
e54e6e57 1974 inet_ntoa (type5->data->id));
d4a53d58 1975 return NULL;
1976 }
1977
1978 /* do we have valid translated type5? */
1979 if (type5 == NULL || !CHECK_FLAG (type5->flags, OSPF_LSA_LOCAL_XLT) )
1980 {
1981 if (IS_DEBUG_OSPF_NSSA)
e588f21f 1982 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
d4a53d58 1983 "found for Type-7 with Id %s",
1984 inet_ntoa (type7->data->id));
1985 return NULL;
1986 }
1987
1988 /* Delete LSA from neighbor retransmit-list. */
1989 ospf_ls_retransmit_delete_nbr_as (ospf, type5);
1990
1991 /* create new translated LSA */
1992 if ( (new = ospf_lsa_translated_nssa_new (ospf, type7)) == NULL)
1993 {
1994 if (IS_DEBUG_OSPF_NSSA)
e588f21f 1995 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
d4a53d58 1996 "Type-7 for %s to Type-5",
1997 inet_ntoa (type7->data->id));
1998 return NULL;
1999 }
2000
2001 if ( !(new = ospf_lsa_install (ospf, NULL, new)) )
2002 {
2003 if (IS_DEBUG_OSPF_NSSA)
e588f21f 2004 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
d4a53d58 2005 "translated LSA, Id %s",
5db95bc2 2006 inet_ntoa (type7->data->id));
d4a53d58 2007 return NULL;
2008 }
2009
2010 /* Flood LSA through area. */
2011 ospf_flood_through_as (ospf, NULL, new);
2012
2013 return new;
718e3744 2014}
718e3744 2015
2016int
2017is_prefix_default (struct prefix_ipv4 *p)
2018{
2019 struct prefix_ipv4 q;
2020
2021 q.family = AF_INET;
2022 q.prefix.s_addr = 0;
2023 q.prefixlen = 0;
2024
2025 return prefix_same ((struct prefix *) p, (struct prefix *) &q);
2026}
2027
2028/* Originate an AS-external-LSA, install and flood. */
2029struct ospf_lsa *
68980084 2030ospf_external_lsa_originate (struct ospf *ospf, struct external_info *ei)
718e3744 2031{
2032 struct ospf_lsa *new;
2033
2034 /* Added for NSSA project....
2035
2036 External LSAs are originated in ASBRs as usual, but for NSSA systems.
2037 there is the global Type-5 LSDB and a Type-7 LSDB installed for
2038 every area. The Type-7's are flooded to every IR and every ABR; We
2039 install the Type-5 LSDB so that the normal "refresh" code operates
2040 as usual, and flag them as not used during ASE calculations. The
2041 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
2042 Address of non-zero.
2043
2044 If an ABR is the elected NSSA translator, following SPF and during
2045 the ABR task it will translate all the scanned Type-7's, with P-bit
2046 ON and not-self generated, and translate to Type-5's throughout the
2047 non-NSSA/STUB AS.
2048
2049 A difference in operation depends whether this ASBR is an ABR
2050 or not. If not an ABR, the P-bit is ON, to indicate that any
2051 elected NSSA-ABR can perform its translation.
2052
2053 If an ABR, the P-bit is OFF; No ABR will perform translation and
2054 this ASBR will flood the Type-5 LSA as usual.
2055
2056 For the case where this ASBR is not an ABR, the ASE calculations
2057 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
2058 demonstrate to the user that there are LSA's that belong to any
2059 attached NSSA.
2060
2061 Finally, it just so happens that when the ABR is translating every
2062 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
2063 approved Type-5 (translated from Type-7); at the end of translation
2064 if any Translated Type-5's remain unapproved, then they must be
2065 flushed from the AS.
2066
2067 */
2068
2069 /* Check the AS-external-LSA should be originated. */
68980084 2070 if (!ospf_redistribute_check (ospf, ei, NULL))
718e3744 2071 return NULL;
2072
2073 /* Create new AS-external-LSA instance. */
68980084 2074 if ((new = ospf_external_lsa_new (ospf, ei, NULL)) == NULL)
718e3744 2075 {
2076 if (IS_DEBUG_OSPF_EVENT)
e588f21f 2077 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
718e3744 2078 inet_ntoa (ei->p.prefix));
2079 return NULL;
2080 }
2081
2082 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
68980084 2083 ospf_lsa_install (ospf, NULL, new);
718e3744 2084
2085 /* Update LSA origination count. */
68980084 2086 ospf->lsa_originate_count++;
718e3744 2087
2088 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
68980084 2089 ospf_flood_through_as (ospf, NULL, new);
718e3744 2090
718e3744 2091 /* If there is any attached NSSA, do special handling */
d4a53d58 2092 if (ospf->anyNSSA &&
2093 /* stay away from translated LSAs! */
2094 !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
68980084 2095 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood Type-7 to all NSSAs */
718e3744 2096
2097 /* Debug logging. */
2098 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2099 {
e588f21f 2100 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
718e3744 2101 new->data->type, inet_ntoa (new->data->id), new);
2102 ospf_lsa_header_dump (new->data);
2103 }
2104
2105 return new;
2106}
2107
2108/* Originate AS-external-LSA from external info with initial flag. */
2109int
68980084 2110ospf_external_lsa_originate_timer (struct thread *thread)
718e3744 2111{
68980084 2112 struct ospf *ospf = THREAD_ARG (thread);
718e3744 2113 struct route_node *rn;
2114 struct external_info *ei;
2115 struct route_table *rt;
68980084 2116 int type = THREAD_VAL (thread);
718e3744 2117
68980084 2118 ospf->t_external_lsa = NULL;
718e3744 2119
2120 /* Originate As-external-LSA from all type of distribute source. */
2121 if ((rt = EXTERNAL_INFO (type)))
2122 for (rn = route_top (rt); rn; rn = route_next (rn))
2123 if ((ei = rn->info) != NULL)
2124 if (!is_prefix_default ((struct prefix_ipv4 *)&ei->p))
68980084 2125 if (!ospf_external_lsa_originate (ospf, ei))
718e3744 2126 zlog_warn ("LSA: AS-external-LSA was not originated.");
2127
2128 return 0;
2129}
2130
4dadc291 2131static struct external_info *
020709f9 2132ospf_default_external_info (struct ospf *ospf)
718e3744 2133{
2134 int type;
2135 struct route_node *rn;
2136 struct prefix_ipv4 p;
2137
2138 p.family = AF_INET;
2139 p.prefix.s_addr = 0;
2140 p.prefixlen = 0;
2141
2142 /* First, lookup redistributed default route. */
2143 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
2144 if (EXTERNAL_INFO (type) && type != ZEBRA_ROUTE_OSPF)
2145 {
2146 rn = route_node_lookup (EXTERNAL_INFO (type), (struct prefix *) &p);
2147 if (rn != NULL)
2148 {
2149 route_unlock_node (rn);
2150 assert (rn->info);
68980084 2151 if (ospf_redistribute_check (ospf, rn->info, NULL))
718e3744 2152 return rn->info;
2153 }
2154 }
2155
2156 return NULL;
2157}
2158
2159int
68980084 2160ospf_default_originate_timer (struct thread *thread)
718e3744 2161{
718e3744 2162 struct prefix_ipv4 p;
2163 struct in_addr nexthop;
2164 struct external_info *ei;
020709f9 2165 struct ospf *ospf;
718e3744 2166
4021b60a 2167 ospf = THREAD_ARG (thread);
718e3744 2168
2169 p.family = AF_INET;
2170 p.prefix.s_addr = 0;
2171 p.prefixlen = 0;
2172
4021b60a 2173 if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS)
718e3744 2174 {
2175 /* If there is no default route via redistribute,
2176 then originate AS-external-LSA with nexthop 0 (self). */
2177 nexthop.s_addr = 0;
2178 ospf_external_info_add (DEFAULT_ROUTE, p, 0, nexthop);
2179 }
2180
020709f9 2181 if ((ei = ospf_default_external_info (ospf)))
68980084 2182 ospf_external_lsa_originate (ospf, ei);
718e3744 2183
2184 return 0;
2185}
2186
645878f1 2187/* Flush any NSSA LSAs for given prefix */
2188void
2189ospf_nssa_lsa_flush (struct ospf *ospf, struct prefix_ipv4 *p)
2190{
1eb8ef25 2191 struct listnode *node, *nnode;
645878f1 2192 struct ospf_lsa *lsa;
2193 struct ospf_area *area;
2194
1eb8ef25 2195 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
645878f1 2196 {
1eb8ef25 2197 if (area->external_routing == OSPF_AREA_NSSA)
d748032f 2198 {
2199 if (!(lsa = ospf_lsa_lookup (area, OSPF_AS_NSSA_LSA, p->prefix,
2200 ospf->router_id)))
2201 {
2202 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 2203 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
d748032f 2204 inet_ntoa (p->prefix), p->prefixlen);
2205 continue;
2206 }
2207 ospf_ls_retransmit_delete_nbr_area (area, lsa);
2208 if (!IS_LSA_MAXAGE (lsa))
2209 {
2210 ospf_refresher_unregister_lsa (ospf, lsa);
2211 ospf_lsa_flush_area (lsa, area);
2212 }
2213 }
645878f1 2214 }
2215}
645878f1 2216
718e3744 2217/* Flush an AS-external-LSA from LSDB and routing domain. */
2218void
68980084 2219ospf_external_lsa_flush (struct ospf *ospf,
2220 u_char type, struct prefix_ipv4 *p,
5339cfdb 2221 unsigned int ifindex /*, struct in_addr nexthop */)
718e3744 2222{
2223 struct ospf_lsa *lsa;
2224
2225 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 2226 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
718e3744 2227 inet_ntoa (p->prefix), p->prefixlen);
2228
2229 /* First lookup LSA from LSDB. */
68980084 2230 if (!(lsa = ospf_external_info_find_lsa (ospf, p)))
718e3744 2231 {
2232 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 2233 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
718e3744 2234 inet_ntoa (p->prefix), p->prefixlen);
2235 return;
2236 }
beebba75 2237
d4a53d58 2238 /* If LSA is selforiginated, not a translated LSA, and there is
2239 * NSSA area, flush Type-7 LSA's at first.
2240 */
2241 if (IS_LSA_SELF(lsa) && (ospf->anyNSSA)
2242 && !(CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT)))
d748032f 2243 ospf_nssa_lsa_flush (ospf, p);
718e3744 2244
2245 /* Sweep LSA from Link State Retransmit List. */
68980084 2246 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
718e3744 2247
2248 /* There must be no self-originated LSA in rtrs_external. */
2249#if 0
2250 /* Remove External route from Zebra. */
2251 ospf_zebra_delete ((struct prefix_ipv4 *) p, &nexthop);
2252#endif
2253
2254 if (!IS_LSA_MAXAGE (lsa))
2255 {
2256 /* Unregister LSA from Refresh queue. */
68980084 2257 ospf_refresher_unregister_lsa (ospf, lsa);
718e3744 2258
2259 /* Flush AS-external-LSA through AS. */
68980084 2260 ospf_lsa_flush_as (ospf, lsa);
718e3744 2261 }
2262
2263 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 2264 zlog_debug ("ospf_external_lsa_flush(): stop");
718e3744 2265}
2266
2267void
68980084 2268ospf_external_lsa_refresh_default (struct ospf *ospf)
718e3744 2269{
2270 struct prefix_ipv4 p;
2271 struct external_info *ei;
2272 struct ospf_lsa *lsa;
2273
2274 p.family = AF_INET;
2275 p.prefixlen = 0;
2276 p.prefix.s_addr = 0;
2277
020709f9 2278 ei = ospf_default_external_info (ospf);
68980084 2279 lsa = ospf_external_info_find_lsa (ospf, &p);
718e3744 2280
2281 if (ei)
2282 {
2283 if (lsa)
2284 {
2285 if (IS_DEBUG_OSPF_EVENT)
e588f21f 2286 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa);
68980084 2287 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
718e3744 2288 }
2289 else
2290 {
2291 if (IS_DEBUG_OSPF_EVENT)
e588f21f 2292 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
68980084 2293 ospf_external_lsa_originate (ospf, ei);
718e3744 2294 }
2295 }
2296 else
2297 {
2298 if (lsa)
2299 {
2300 if (IS_DEBUG_OSPF_EVENT)
e588f21f 2301 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
68980084 2302 ospf_lsa_flush_as (ospf, lsa);
718e3744 2303 }
2304 }
2305}
2306
2307void
68980084 2308ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)
718e3744 2309{
2310 struct route_node *rn;
2311 struct external_info *ei;
2312
2313 if (type != DEFAULT_ROUTE)
2314 if (EXTERNAL_INFO(type))
2315 /* Refresh each redistributed AS-external-LSAs. */
2316 for (rn = route_top (EXTERNAL_INFO (type)); rn; rn = route_next (rn))
2317 if ((ei = rn->info))
2318 if (!is_prefix_default (&ei->p))
2319 {
2320 struct ospf_lsa *lsa;
2321
68980084 2322 if ((lsa = ospf_external_info_find_lsa (ospf, &ei->p)))
2323 ospf_external_lsa_refresh (ospf, lsa, ei, force);
718e3744 2324 else
68980084 2325 ospf_external_lsa_originate (ospf, ei);
718e3744 2326 }
2327}
2328
2329/* Refresh AS-external-LSA. */
2330void
68980084 2331ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,
718e3744 2332 struct external_info *ei, int force)
2333{
2334 struct ospf_lsa *new;
2335 int changed;
2336
2337 /* Check the AS-external-LSA should be originated. */
68980084 2338 if (!ospf_redistribute_check (ospf, ei, &changed))
718e3744 2339 {
d4a53d58 2340 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 2341 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
d4a53d58 2342 "redist check fail",
2343 lsa->data->type, inet_ntoa (lsa->data->id));
68980084 2344 ospf_external_lsa_flush (ospf, ei->type, &ei->p,
5339cfdb 2345 ei->ifindex /*, ei->nexthop */);
718e3744 2346 return;
2347 }
2348
2349 if (!changed && !force)
d4a53d58 2350 {
2351 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 2352 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
d4a53d58 2353 lsa->data->type, inet_ntoa (lsa->data->id));
2354 return;
2355 }
718e3744 2356
2357 /* Delete LSA from neighbor retransmit-list. */
68980084 2358 ospf_ls_retransmit_delete_nbr_as (ospf, lsa);
718e3744 2359
2360 /* Unregister AS-external-LSA from refresh-list. */
68980084 2361 ospf_refresher_unregister_lsa (ospf, lsa);
718e3744 2362
68980084 2363 new = ospf_external_lsa_new (ospf, ei, &lsa->data->id);
718e3744 2364
2365 if (new == NULL)
2366 {
2367 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 2368 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,
718e3744 2369 inet_ntoa (lsa->data->id));
2370 return;
2371 }
2372
2373 new->data->ls_seqnum = lsa_seqnum_increment (lsa);
2374
68980084 2375 ospf_lsa_install (ospf, NULL, new); /* As type-5. */
718e3744 2376
2377 /* Flood LSA through AS. */
68980084 2378 ospf_flood_through_as (ospf, NULL, new);
718e3744 2379
718e3744 2380 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
d4a53d58 2381 if (ospf->anyNSSA && !(CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT)))
68980084 2382 ospf_install_flood_nssa (ospf, new, ei); /* Install/Flood per new rules */
718e3744 2383
d4a53d58 2384 /* Register self-originated LSA to refresh queue.
2385 * Translated LSAs should not be registered, but refreshed upon
2386 * refresh of the Type-7
2387 */
2388 if ( !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT) )
2389 ospf_refresher_register_lsa (ospf, new);
718e3744 2390
2391 /* Debug logging. */
2392 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2393 {
e588f21f 2394 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
d4a53d58 2395 new->data->type, inet_ntoa (new->data->id));
718e3744 2396 ospf_lsa_header_dump (new->data);
2397 }
2398
2399 return;
2400}
2401
2402\f
2403/* LSA installation functions. */
2404
2405/* Install router-LSA to an area. */
4dadc291 2406static struct ospf_lsa *
68980084 2407ospf_router_lsa_install (struct ospf *ospf,
2408 struct ospf_lsa *new, int rt_recalc)
718e3744 2409{
2410 struct ospf_area *area = new->area;
2411
2412 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2413 The entire routing table must be recalculated, starting with
2414 the shortest path calculations for each area (not just the
2415 area whose link-state database has changed).
2416 */
718e3744 2417
5996e0df 2418 if (IS_LSA_SELF (new))
718e3744 2419 {
5996e0df
JT
2420
2421 /* Only install LSA if it is originated/refreshed by us.
2422 * If LSA was received by flooding, the RECEIVED flag is set so do
2423 * not link the LSA */
2424 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2425 return new; /* ignore stale LSA */
2426
718e3744 2427 /* Set router-LSA refresh timer. */
2428 OSPF_TIMER_OFF (area->t_router_lsa_self);
2429 OSPF_AREA_TIMER_ON (area->t_router_lsa_self,
d4a53d58 2430 ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME);
5996e0df 2431
718e3744 2432 /* Set self-originated router-LSA. */
1fe6ed38 2433 ospf_lsa_unlock (&area->router_lsa_self);
718e3744 2434 area->router_lsa_self = ospf_lsa_lock (new);
2435
718e3744 2436 }
5996e0df
JT
2437 if (rt_recalc)
2438 ospf_spf_calculate_schedule (ospf);
718e3744 2439
2440 return new;
2441}
2442
2443#define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2444 if (!(T)) \
2445 (T) = thread_add_timer (master, (F), oi, (V))
2446
2447/* Install network-LSA to an area. */
4dadc291 2448static struct ospf_lsa *
68980084 2449ospf_network_lsa_install (struct ospf *ospf,
2450 struct ospf_interface *oi,
718e3744 2451 struct ospf_lsa *new,
2452 int rt_recalc)
2453{
2454
2455 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2456 The entire routing table must be recalculated, starting with
2457 the shortest path calculations for each area (not just the
2458 area whose link-state database has changed).
2459 */
5996e0df 2460 if (IS_LSA_SELF (new))
718e3744 2461 {
5996e0df
JT
2462 /* We supposed that when LSA is originated by us, we pass the int
2463 for which it was originated. If LSA was received by flooding,
2464 the RECEIVED flag is set, so we do not link the LSA to the int. */
2465 if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))
2466 return new; /* ignore stale LSA */
2467
718e3744 2468 /* Set LSRefresh timer. */
2469 OSPF_TIMER_OFF (oi->t_network_lsa_self);
2470
2471 OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self,
2472 ospf_network_lsa_refresh_timer,
2473 OSPF_LS_REFRESH_TIME);
2474
1fe6ed38 2475 ospf_lsa_unlock (&oi->network_lsa_self);
718e3744 2476 oi->network_lsa_self = ospf_lsa_lock (new);
2477 }
5996e0df
JT
2478 if (rt_recalc)
2479 ospf_spf_calculate_schedule (ospf);
718e3744 2480
2481 return new;
2482}
2483
2484/* Install summary-LSA to an area. */
4dadc291 2485static struct ospf_lsa *
68980084 2486ospf_summary_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2487 int rt_recalc)
718e3744 2488{
718e3744 2489 if (rt_recalc && !IS_LSA_SELF (new))
2490 {
2491 /* RFC 2328 Section 13.2 Summary-LSAs
2492 The best route to the destination described by the summary-
2493 LSA must be recalculated (see Section 16.5). If this
2494 destination is an AS boundary router, it may also be
2495 necessary to re-examine all the AS-external-LSAs.
2496 */
2497
2498#if 0
2499 /* This doesn't exist yet... */
2500 ospf_summary_incremental_update(new); */
2501#else /* #if 0 */
68980084 2502 ospf_spf_calculate_schedule (ospf);
718e3744 2503#endif /* #if 0 */
2504
2505 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
e588f21f 2506 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
718e3744 2507 }
2508
2509 if (IS_LSA_SELF (new))
68980084 2510 ospf_refresher_register_lsa (ospf, new);
718e3744 2511
2512 return new;
2513}
2514
2515/* Install ASBR-summary-LSA to an area. */
4dadc291 2516static struct ospf_lsa *
68980084 2517ospf_summary_asbr_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2518 int rt_recalc)
718e3744 2519{
2520 if (rt_recalc && !IS_LSA_SELF (new))
2521 {
2522 /* RFC 2328 Section 13.2 Summary-LSAs
2523 The best route to the destination described by the summary-
2524 LSA must be recalculated (see Section 16.5). If this
2525 destination is an AS boundary router, it may also be
2526 necessary to re-examine all the AS-external-LSAs.
2527 */
2528#if 0
2529 /* These don't exist yet... */
2530 ospf_summary_incremental_update(new);
2531 /* Isn't this done by the above call?
2532 - RFC 2328 Section 16.5 implies it should be */
2533 /* ospf_ase_calculate_schedule(); */
2534#else /* #if 0 */
68980084 2535 ospf_spf_calculate_schedule (ospf);
718e3744 2536#endif /* #if 0 */
2537 }
2538
2539 /* register LSA to refresh-list. */
2540 if (IS_LSA_SELF (new))
68980084 2541 ospf_refresher_register_lsa (ospf, new);
718e3744 2542
2543 return new;
2544}
2545
2546/* Install AS-external-LSA. */
4dadc291 2547static struct ospf_lsa *
68980084 2548ospf_external_lsa_install (struct ospf *ospf, struct ospf_lsa *new,
2549 int rt_recalc)
718e3744 2550{
68980084 2551 ospf_ase_register_external_lsa (new, ospf);
718e3744 2552 /* If LSA is not self-originated, calculate an external route. */
2553 if (rt_recalc)
2554 {
2555 /* RFC 2328 Section 13.2 AS-external-LSAs
2556 The best route to the destination described by the AS-
2557 external-LSA must be recalculated (see Section 16.6).
2558 */
2559
2560 if (!IS_LSA_SELF (new))
d4a53d58 2561 ospf_ase_incremental_update (ospf, new);
718e3744 2562 }
2563
d4a53d58 2564 if (new->data->type == OSPF_AS_NSSA_LSA)
2565 {
2566 /* There is no point to register selforiginate Type-7 LSA for
2567 * refreshing. We rely on refreshing Type-5 LSA's
2568 */
2569 if (IS_LSA_SELF (new))
2570 return new;
2571 else
2572 {
2573 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2574 * New translations will be taken care of by the abr_task.
2575 */
2576 ospf_translated_nssa_refresh (ospf, new, NULL);
2577 }
2578 }
d748032f 2579
d4a53d58 2580 /* Register self-originated LSA to refresh queue.
8fc0f64b 2581 * Leave Translated LSAs alone if NSSA is enabled
d4a53d58 2582 */
beebba75 2583 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags, OSPF_LSA_LOCAL_XLT ) )
68980084 2584 ospf_refresher_register_lsa (ospf, new);
718e3744 2585
2586 return new;
2587}
2588
2589void
68980084 2590ospf_discard_from_db (struct ospf *ospf,
2591 struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)
718e3744 2592{
2593 struct ospf_lsa *old;
2594
ac904dec
PJ
2595 if (!lsdb)
2596 {
2597 zlog_warn ("%s: Called with NULL lsdb!", __func__);
2598 if (!lsa)
2599 zlog_warn ("%s: and NULL LSA!", __func__);
2600 else
2601 zlog_warn ("LSA[Type%d:%s]: not associated with LSDB!",
2602 lsa->data->type, inet_ntoa (lsa->data->id));
2603 return;
2604 }
2605
718e3744 2606 old = ospf_lsdb_lookup (lsdb, lsa);
2607
2608 if (!old)
2609 return;
2610
2611 if (old->refresh_list >= 0)
68980084 2612 ospf_refresher_unregister_lsa (ospf, old);
718e3744 2613
2614 switch (old->data->type)
2615 {
2616 case OSPF_AS_EXTERNAL_LSA:
69310a67 2617 ospf_ase_unregister_external_lsa (old, ospf);
2618 ospf_ls_retransmit_delete_nbr_as (ospf, old);
2619 break;
718e3744 2620#ifdef HAVE_OPAQUE_LSA
2621 case OSPF_OPAQUE_AS_LSA:
68980084 2622 ospf_ls_retransmit_delete_nbr_as (ospf, old);
718e3744 2623 break;
69310a67 2624#endif /* HAVE_OPAQUE_LSA */
d748032f 2625 case OSPF_AS_NSSA_LSA:
2626 ospf_ls_retransmit_delete_nbr_area (old->area, old);
2627 ospf_ase_unregister_external_lsa (old, ospf);
beebba75 2628 break;
718e3744 2629 default:
68980084 2630 ospf_ls_retransmit_delete_nbr_area (old->area, old);
718e3744 2631 break;
2632 }
2633
68980084 2634 ospf_lsa_maxage_delete (ospf, old);
718e3744 2635 ospf_lsa_discard (old);
2636}
2637
718e3744 2638struct ospf_lsa *
68980084 2639ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,
2640 struct ospf_lsa *lsa)
718e3744 2641{
2642 struct ospf_lsa *new = NULL;
2643 struct ospf_lsa *old = NULL;
2644 struct ospf_lsdb *lsdb = NULL;
2645 int rt_recalc;
2646
2647 /* Set LSDB. */
2648 switch (lsa->data->type)
2649 {
f2c80652 2650 /* kevinm */
2651 case OSPF_AS_NSSA_LSA:
2652 if (lsa->area)
2653 lsdb = lsa->area->lsdb;
2654 else
68980084 2655 lsdb = ospf->lsdb;
f2c80652 2656 break;
718e3744 2657 case OSPF_AS_EXTERNAL_LSA:
2658#ifdef HAVE_OPAQUE_LSA
2659 case OSPF_OPAQUE_AS_LSA:
2660#endif /* HAVE_OPAQUE_LSA */
68980084 2661 lsdb = ospf->lsdb;
718e3744 2662 break;
2663 default:
2664 lsdb = lsa->area->lsdb;
2665 break;
2666 }
2667
718e3744 2668 assert (lsdb);
2669
2670 /* RFC 2328 13.2. Installing LSAs in the database
2671
2672 Installing a new LSA in the database, either as the result of
2673 flooding or a newly self-originated LSA, may cause the OSPF
2674 routing table structure to be recalculated. The contents of the
2675 new LSA should be compared to the old instance, if present. If
2676 there is no difference, there is no need to recalculate the
2677 routing table. When comparing an LSA to its previous instance,
2678 the following are all considered to be differences in contents:
2679
2680 o The LSA's Options field has changed.
2681
2682 o One of the LSA instances has LS age set to MaxAge, and
2683 the other does not.
2684
2685 o The length field in the LSA header has changed.
2686
2687 o The body of the LSA (i.e., anything outside the 20-byte
2688 LSA header) has changed. Note that this excludes changes
2689 in LS Sequence Number and LS Checksum.
2690
2691 */
2692 /* Look up old LSA and determine if any SPF calculation or incremental
2693 update is needed */
2694 old = ospf_lsdb_lookup (lsdb, lsa);
2695
2696 /* Do comparision and record if recalc needed. */
2697 rt_recalc = 0;
2698 if ( old == NULL || ospf_lsa_different(old, lsa))
2699 rt_recalc = 1;
2700
7ddf1d6e 2701 /*
2702 Sequence number check (Section 14.1 of rfc 2328)
2703 "Premature aging is used when it is time for a self-originated
2704 LSA's sequence number field to wrap. At this point, the current
2705 LSA instance (having LS sequence number MaxSequenceNumber) must
2706 be prematurely aged and flushed from the routing domain before a
2707 new instance with sequence number equal to InitialSequenceNumber
2708 can be originated. "
2709 */
2710
c2b478d7 2711 if (ntohl(lsa->data->ls_seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER)
7ddf1d6e 2712 {
2713 if (ospf_lsa_is_self_originated(ospf, lsa))
2714 {
0c2be26c 2715 lsa->data->ls_seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
2716
2717 if (!IS_LSA_MAXAGE(lsa))
7ddf1d6e 2718 lsa->flags |= OSPF_LSA_PREMATURE_AGE;
2719 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
2720
2721 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
2722 {
e588f21f 2723 zlog_debug ("ospf_lsa_install() Premature Aging "
7ddf1d6e 2724 "lsa 0x%lx", (u_long)lsa);
2725 ospf_lsa_header_dump (lsa->data);
2726 }
2727 }
2728 else
2729 {
2730 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
2731 {
e588f21f 2732 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
7ddf1d6e 2733 "that was not self originated. Ignoring\n");
2734 ospf_lsa_header_dump (lsa->data);
2735 }
2736 return old;
2737 }
2738 }
2739
718e3744 2740 /* discard old LSA from LSDB */
2741 if (old != NULL)
68980084 2742 ospf_discard_from_db (ospf, lsdb, lsa);
718e3744 2743
718e3744 2744 /* Calculate Checksum if self-originated?. */
2745 if (IS_LSA_SELF (lsa))
2746 ospf_lsa_checksum (lsa->data);
2747
fe71a97d 2748 /* Insert LSA to LSDB. */
2749 ospf_lsdb_add (lsdb, lsa);
2750 lsa->lsdb = lsdb;
2751
718e3744 2752 /* Do LSA specific installation process. */
2753 switch (lsa->data->type)
2754 {
2755 case OSPF_ROUTER_LSA:
68980084 2756 new = ospf_router_lsa_install (ospf, lsa, rt_recalc);
718e3744 2757 break;
2758 case OSPF_NETWORK_LSA:
2759 assert (oi);
68980084 2760 new = ospf_network_lsa_install (ospf, oi, lsa, rt_recalc);
718e3744 2761 break;
2762 case OSPF_SUMMARY_LSA:
68980084 2763 new = ospf_summary_lsa_install (ospf, lsa, rt_recalc);
718e3744 2764 break;
2765 case OSPF_ASBR_SUMMARY_LSA:
68980084 2766 new = ospf_summary_asbr_lsa_install (ospf, lsa, rt_recalc);
718e3744 2767 break;
2768 case OSPF_AS_EXTERNAL_LSA:
68980084 2769 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
718e3744 2770 break;
2771#ifdef HAVE_OPAQUE_LSA
2772 case OSPF_OPAQUE_LINK_LSA:
09e4efdc 2773 if (IS_LSA_SELF (lsa))
68980084 2774 lsa->oi = oi; /* Specify outgoing ospf-interface for this LSA. */
09e4efdc 2775 else
68980084 2776 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
09e4efdc 2777 /* Fallthrough */
718e3744 2778 case OSPF_OPAQUE_AREA_LSA:
2779 case OSPF_OPAQUE_AS_LSA:
2780 new = ospf_opaque_lsa_install (lsa, rt_recalc);
2781 break;
2782#endif /* HAVE_OPAQUE_LSA */
d4a53d58 2783 case OSPF_AS_NSSA_LSA:
68980084 2784 new = ospf_external_lsa_install (ospf, lsa, rt_recalc);
d4a53d58 2785 default: /* type-6,8,9....nothing special */
718e3744 2786 break;
2787 }
2788
2789 if (new == NULL)
2790 return new; /* Installation failed, cannot proceed further -- endo. */
2791
2792 /* Debug logs. */
2793 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
2794 {
2795 char area_str[INET_ADDRSTRLEN];
2796
2797 switch (lsa->data->type)
2798 {
2799 case OSPF_AS_EXTERNAL_LSA:
2800#ifdef HAVE_OPAQUE_LSA
2801 case OSPF_OPAQUE_AS_LSA:
2802#endif /* HAVE_OPAQUE_LSA */
beebba75 2803 case OSPF_AS_NSSA_LSA:
e588f21f 2804 zlog_debug ("LSA[%s]: Install %s",
718e3744 2805 dump_lsa_key (new),
2806 LOOKUP (ospf_lsa_type_msg, new->data->type));
2807 break;
2808 default:
2809 strcpy (area_str, inet_ntoa (new->area->area_id));
e588f21f 2810 zlog_debug ("LSA[%s]: Install %s to Area %s",
718e3744 2811 dump_lsa_key (new),
2812 LOOKUP (ospf_lsa_type_msg, new->data->type), area_str);
2813 break;
2814 }
2815 }
2816
7ddf1d6e 2817 /*
2818 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2819 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2820 */
2821 if ((lsa->flags & OSPF_LSA_PREMATURE_AGE) ||
2822 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
718e3744 2823 {
7ddf1d6e 2824 if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
e588f21f 2825 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
0c2be26c 2826 new->data->type,
2827 inet_ntoa (new->data->id),
2828 lsa);
68980084 2829 ospf_lsa_maxage (ospf, lsa);
718e3744 2830 }
2831
2832 return new;
2833}
2834
2835\f
4dadc291 2836static int
68980084 2837ospf_check_nbr_status (struct ospf *ospf)
718e3744 2838{
1eb8ef25 2839 struct listnode *node, *nnode;
2840 struct ospf_interface *oi;
2841
2842 for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi))
718e3744 2843 {
718e3744 2844 struct route_node *rn;
2845 struct ospf_neighbor *nbr;
2846
2847 if (ospf_if_is_enable (oi))
2848 for (rn = route_top (oi->nbrs); rn; rn = route_next (rn))
2849 if ((nbr = rn->info) != NULL)
2850 if (nbr->state == NSM_Exchange || nbr->state == NSM_Loading)
2851 {
2852 route_unlock_node (rn);
2853 return 0;
2854 }
2855 }
2856
2857 return 1;
2858}
2859
2860\f
2861#ifdef ORIGINAL_CODING
2862/* This function flood the maxaged LSA to DR. */
2863void
2864ospf_maxage_flood (struct ospf_lsa *lsa)
2865{
2866 switch (lsa->data->type)
2867 {
2868 case OSPF_ROUTER_LSA:
2869 case OSPF_NETWORK_LSA:
2870 case OSPF_SUMMARY_LSA:
2871 case OSPF_ASBR_SUMMARY_LSA:
718e3744 2872 case OSPF_AS_NSSA_LSA:
718e3744 2873#ifdef HAVE_OPAQUE_LSA
2874 case OSPF_OPAQUE_LINK_LSA:
2875 case OSPF_OPAQUE_AREA_LSA:
2876#endif /* HAVE_OPAQUE_LSA */
2877 ospf_flood_through_area (lsa->area, NULL, lsa);
2878 break;
2879 case OSPF_AS_EXTERNAL_LSA:
2880#ifdef HAVE_OPAQUE_LSA
2881 case OSPF_OPAQUE_AS_LSA:
2882#endif /* HAVE_OPAQUE_LSA */
2883 ospf_flood_through_as (NULL, lsa);
2884 break;
2885 default:
2886 break;
2887 }
2888}
2889#endif /* ORIGINAL_CODING */
2890
4dadc291 2891static int
718e3744 2892ospf_maxage_lsa_remover (struct thread *thread)
2893{
68980084 2894 struct ospf *ospf = THREAD_ARG (thread);
1eb8ef25 2895 struct ospf_lsa *lsa;
2896 struct listnode *node, *nnode;
718e3744 2897 int reschedule = 0;
2898
68980084 2899 ospf->t_maxage = NULL;
718e3744 2900
2901 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 2902 zlog_debug ("LSA[MaxAge]: remover Start");
718e3744 2903
68980084 2904 reschedule = !ospf_check_nbr_status (ospf);
718e3744 2905
2906 if (!reschedule)
1eb8ef25 2907 for (ALL_LIST_ELEMENTS (ospf->maxage_lsa, node, nnode, lsa))
718e3744 2908 {
718e3744 2909 if (lsa->retransmit_counter > 0)
2910 {
2911 reschedule = 1;
2912 continue;
2913 }
2914
2915 /* Remove LSA from the LSDB */
f6247bf2 2916 if (IS_LSA_SELF (lsa))
718e3744 2917 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 2918 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
7ddf1d6e 2919 lsa->data->type, inet_ntoa (lsa->data->id), (u_long)lsa);
718e3744 2920
2921 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 2922 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
718e3744 2923 lsa->data->type, inet_ntoa (lsa->data->id));
2924
2925 /* Flood max age LSA. */
2926#ifdef ORIGINAL_CODING
2927 ospf_maxage_flood (lsa);
2928#else /* ORIGINAL_CODING */
68980084 2929 ospf_flood_through (ospf, NULL, lsa);
718e3744 2930#endif /* ORIGINAL_CODING */
2931
7ddf1d6e 2932 if (lsa->flags & OSPF_LSA_PREMATURE_AGE)
2933 {
2934 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 2935 zlog_debug ("originating new router lsa for lsa 0x%lx \n",
7ddf1d6e 2936 (u_long)lsa);
2937 ospf_router_lsa_originate(lsa->area);
2938 }
2939
718e3744 2940 /* Remove from lsdb. */
ac904dec
PJ
2941 if (lsa->lsdb)
2942 {
2943 ospf_discard_from_db (ospf, lsa->lsdb, lsa);
2944 ospf_lsdb_delete (lsa->lsdb, lsa);
2945 }
2946 else
2947 zlog_warn ("%s: LSA[Type%d:%s]: No associated LSDB!", __func__,
2948 lsa->data->type, inet_ntoa (lsa->data->id));
718e3744 2949 }
2950
2951 /* A MaxAge LSA must be removed immediately from the router's link
2952 state database as soon as both a) it is no longer contained on any
2953 neighbor Link state retransmission lists and b) none of the router's
2954 neighbors are in states Exchange or Loading. */
2955 if (reschedule)
68980084 2956 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
718e3744 2957
2958 return 0;
2959}
2960
718e3744 2961void
68980084 2962ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 2963{
52dc7ee6 2964 struct listnode *n;
718e3744 2965
68980084 2966 if ((n = listnode_lookup (ospf->maxage_lsa, lsa)))
718e3744 2967 {
68980084 2968 list_delete_node (ospf->maxage_lsa, n);
3106a032 2969 UNSET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
1fe6ed38 2970 ospf_lsa_unlock (&lsa); /* maxage_lsa */
718e3744 2971 }
2972}
2973
2974void
68980084 2975ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 2976{
2977 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2978 and schedule the MaxAge LSA remover. */
3106a032 2979 if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE))
718e3744 2980 {
2981 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 2982 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
718e3744 2983 lsa->data->type, inet_ntoa (lsa->data->id), lsa);
2984 return;
2985 }
2986
68980084 2987 listnode_add (ospf->maxage_lsa, ospf_lsa_lock (lsa));
3106a032 2988 SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
718e3744 2989
2990 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 2991 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa));
718e3744 2992
68980084 2993 OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2);
718e3744 2994}
2995
4dadc291 2996static int
68980084 2997ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 2998{
718e3744 2999 /* Stay away from any Local Translated Type-7 LSAs */
3000 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3001 return 0;
718e3744 3002
3003 if (IS_LSA_MAXAGE (lsa))
3004 /* Self-originated LSAs should NOT time-out instead,
3005 they're flushed and submitted to the max_age list explicitly. */
68980084 3006 if (!ospf_lsa_is_self_originated (ospf, lsa))
718e3744 3007 {
3008 if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))
e588f21f 3009 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa));
718e3744 3010
3011 switch (lsa->data->type)
3012 {
718e3744 3013#ifdef HAVE_OPAQUE_LSA
37163d6d 3014 case OSPF_OPAQUE_LINK_LSA:
3015 case OSPF_OPAQUE_AREA_LSA:
718e3744 3016 case OSPF_OPAQUE_AS_LSA:
09e4efdc 3017 /*
3018 * As a general rule, whenever network topology has changed
3019 * (due to an LSA removal in this case), routing recalculation
3020 * should be triggered. However, this is not true for opaque
3021 * LSAs. Even if an opaque LSA instance is going to be removed
3022 * from the routing domain, it does not mean a change in network
3023 * topology, and thus, routing recalculation is not needed here.
3024 */
3025 break;
718e3744 3026#endif /* HAVE_OPAQUE_LSA */
09e4efdc 3027 case OSPF_AS_EXTERNAL_LSA:
beebba75 3028 case OSPF_AS_NSSA_LSA:
68980084 3029 ospf_ase_incremental_update (ospf, lsa);
3030 break;
718e3744 3031 default:
68980084 3032 ospf_spf_calculate_schedule (ospf);
3033 break;
718e3744 3034 }
68980084 3035 ospf_lsa_maxage (ospf, lsa);
718e3744 3036 }
3037
3038 return 0;
3039}
3040
3041/* Periodical check of MaxAge LSA. */
3042int
68980084 3043ospf_lsa_maxage_walker (struct thread *thread)
718e3744 3044{
68980084 3045 struct ospf *ospf = THREAD_ARG (thread);
3046 struct route_node *rn;
3047 struct ospf_lsa *lsa;
1eb8ef25 3048 struct ospf_area *area;
3049 struct listnode *node, *nnode;
718e3744 3050
68980084 3051 ospf->t_maxage_walker = NULL;
718e3744 3052
1eb8ef25 3053 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
718e3744 3054 {
68980084 3055 LSDB_LOOP (ROUTER_LSDB (area), rn, lsa)
3056 ospf_lsa_maxage_walker_remover (ospf, lsa);
3057 LSDB_LOOP (NETWORK_LSDB (area), rn, lsa)
3058 ospf_lsa_maxage_walker_remover (ospf, lsa);
3059 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3060 ospf_lsa_maxage_walker_remover (ospf, lsa);
3061 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3062 ospf_lsa_maxage_walker_remover (ospf, lsa);
718e3744 3063#ifdef HAVE_OPAQUE_LSA
68980084 3064 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3065 ospf_lsa_maxage_walker_remover (ospf, lsa);
3066 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3067 ospf_lsa_maxage_walker_remover (ospf, lsa);
718e3744 3068#endif /* HAVE_OPAQUE_LSA */
4fb949e3 3069 LSDB_LOOP (NSSA_LSDB (area), rn, lsa)
3070 ospf_lsa_maxage_walker_remover (ospf, lsa);
718e3744 3071 }
3072
4fb949e3 3073 /* for AS-external-LSAs. */
68980084 3074 if (ospf->lsdb)
3075 {
3076 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3077 ospf_lsa_maxage_walker_remover (ospf, lsa);
718e3744 3078#ifdef HAVE_OPAQUE_LSA
68980084 3079 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3080 ospf_lsa_maxage_walker_remover (ospf, lsa);
718e3744 3081#endif /* HAVE_OPAQUE_LSA */
68980084 3082 }
718e3744 3083
68980084 3084 OSPF_TIMER_ON (ospf->t_maxage_walker, ospf_lsa_maxage_walker,
3085 OSPF_LSA_MAXAGE_CHECK_INTERVAL);
718e3744 3086 return 0;
3087}
3088
68980084 3089struct ospf_lsa *
3090ospf_lsa_lookup_by_prefix (struct ospf_lsdb *lsdb, u_char type,
3091 struct prefix_ipv4 *p, struct in_addr router_id)
718e3744 3092{
68980084 3093 struct ospf_lsa *lsa;
3094 struct in_addr mask, id;
3095 struct lsa_header_mask
3096 {
3097 struct lsa_header header;
3098 struct in_addr mask;
3099 } *hmask;
718e3744 3100
68980084 3101 lsa = ospf_lsdb_lookup_by_id (lsdb, type, p->prefix, router_id);
3102 if (lsa == NULL)
3103 return NULL;
718e3744 3104
68980084 3105 masklen2ip (p->prefixlen, &mask);
718e3744 3106
68980084 3107 hmask = (struct lsa_header_mask *) lsa->data;
718e3744 3108
68980084 3109 if (mask.s_addr != hmask->mask.s_addr)
3110 {
3111 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
3112 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, router_id);
3113 if (!lsa)
3114 return NULL;
3115 }
718e3744 3116
68980084 3117 return lsa;
718e3744 3118}
3119
3120struct ospf_lsa *
3121ospf_lsa_lookup (struct ospf_area *area, u_int32_t type,
3122 struct in_addr id, struct in_addr adv_router)
3123{
e05fba43 3124 struct ospf *ospf = ospf_lookup();
3125 assert(ospf);
3126
718e3744 3127 switch (type)
3128 {
3129 case OSPF_ROUTER_LSA:
3130 case OSPF_NETWORK_LSA:
3131 case OSPF_SUMMARY_LSA:
3132 case OSPF_ASBR_SUMMARY_LSA:
718e3744 3133 case OSPF_AS_NSSA_LSA:
718e3744 3134#ifdef HAVE_OPAQUE_LSA
3135 case OSPF_OPAQUE_LINK_LSA:
3136 case OSPF_OPAQUE_AREA_LSA:
3137#endif /* HAVE_OPAQUE_LSA */
3138 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, adv_router);
718e3744 3139 case OSPF_AS_EXTERNAL_LSA:
3140#ifdef HAVE_OPAQUE_LSA
3141 case OSPF_OPAQUE_AS_LSA:
3142#endif /* HAVE_OPAQUE_LSA */
e05fba43 3143 return ospf_lsdb_lookup_by_id (ospf->lsdb, type, id, adv_router);
718e3744 3144 default:
3145 break;
3146 }
3147
3148 return NULL;
3149}
3150
3151struct ospf_lsa *
3152ospf_lsa_lookup_by_id (struct ospf_area *area, u_int32_t type,
3153 struct in_addr id)
3154{
3155 struct ospf_lsa *lsa;
3156 struct route_node *rn;
3157
3158 switch (type)
3159 {
3160 case OSPF_ROUTER_LSA:
3161 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
718e3744 3162 case OSPF_NETWORK_LSA:
3163 for (rn = route_top (NETWORK_LSDB (area)); rn; rn = route_next (rn))
3164 if ((lsa = rn->info))
3165 if (IPV4_ADDR_SAME (&lsa->data->id, &id))
3166 {
3167 route_unlock_node (rn);
3168 return lsa;
3169 }
3170 break;
3171 case OSPF_SUMMARY_LSA:
3172 case OSPF_ASBR_SUMMARY_LSA:
3173 /* Currently not used. */
3174 assert (1);
3175 return ospf_lsdb_lookup_by_id (area->lsdb, type, id, id);
718e3744 3176 case OSPF_AS_EXTERNAL_LSA:
d4a53d58 3177 case OSPF_AS_NSSA_LSA:
718e3744 3178#ifdef HAVE_OPAQUE_LSA
3179 case OSPF_OPAQUE_LINK_LSA:
3180 case OSPF_OPAQUE_AREA_LSA:
3181 case OSPF_OPAQUE_AS_LSA:
3182 /* Currently not used. */
3183 break;
3184#endif /* HAVE_OPAQUE_LSA */
3185 default:
3186 break;
3187 }
3188
3189 return NULL;
3190}
3191
3192struct ospf_lsa *
3193ospf_lsa_lookup_by_header (struct ospf_area *area, struct lsa_header *lsah)
3194{
3195 struct ospf_lsa *match;
3196
3197#ifdef HAVE_OPAQUE_LSA
3198 /*
3199 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3200 * is redefined to have two subfields; opaque-type and opaque-id.
3201 * However, it is harmless to treat the two sub fields together, as if
3202 * they two were forming a unique LSA-ID.
3203 */
3204#endif /* HAVE_OPAQUE_LSA */
3205
3206 match = ospf_lsa_lookup (area, lsah->type, lsah->id, lsah->adv_router);
3207
3208 if (match == NULL)
3209 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
e588f21f 3210 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
718e3744 3211 lsah->type, inet_ntoa (lsah->id));
3212
3213 return match;
3214}
3215
3216/* return +n, l1 is more recent.
3217 return -n, l2 is more recent.
3218 return 0, l1 and l2 is identical. */
3219int
3220ospf_lsa_more_recent (struct ospf_lsa *l1, struct ospf_lsa *l2)
3221{
3222 int r;
3223 int x, y;
3224
3225 if (l1 == NULL && l2 == NULL)
3226 return 0;
3227 if (l1 == NULL)
3228 return -1;
3229 if (l2 == NULL)
3230 return 1;
3231
3232 /* compare LS sequence number. */
3233 x = (int) ntohl (l1->data->ls_seqnum);
3234 y = (int) ntohl (l2->data->ls_seqnum);
3235 if (x > y)
3236 return 1;
3237 if (x < y)
3238 return -1;
3239
3240 /* compare LS checksum. */
3241 r = ntohs (l1->data->checksum) - ntohs (l2->data->checksum);
3242 if (r)
3243 return r;
3244
3245 /* compare LS age. */
3246 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3247 return 1;
3248 else if (!IS_LSA_MAXAGE (l1) && IS_LSA_MAXAGE (l2))
3249 return -1;
3250
3251 /* compare LS age with MaxAgeDiff. */
3252 if (LS_AGE (l1) - LS_AGE (l2) > OSPF_LSA_MAXAGE_DIFF)
3253 return -1;
3254 else if (LS_AGE (l2) - LS_AGE (l1) > OSPF_LSA_MAXAGE_DIFF)
3255 return 1;
3256
3257 /* LSAs are identical. */
3258 return 0;
3259}
3260
3261/* If two LSAs are different, return 1, otherwise return 0. */
3262int
3263ospf_lsa_different (struct ospf_lsa *l1, struct ospf_lsa *l2)
3264{
3265 char *p1, *p2;
3266 assert (l1);
3267 assert (l2);
3268 assert (l1->data);
3269 assert (l2->data);
3270
3271 if (l1->data->options != l2->data->options)
3272 return 1;
3273
3274 if (IS_LSA_MAXAGE (l1) && !IS_LSA_MAXAGE (l2))
3275 return 1;
3276
3277 if (IS_LSA_MAXAGE (l2) && !IS_LSA_MAXAGE (l1))
3278 return 1;
3279
3280 if (l1->data->length != l2->data->length)
3281 return 1;
3282
3283 if (l1->data->length == 0)
3284 return 1;
3285
5996e0df
JT
3286 if (CHECK_FLAG ((l1->flags ^ l2->flags), OSPF_LSA_RECEIVED))
3287 return 1; /* May be a stale LSA in the LSBD */
3288
d1825830 3289 assert ( ntohs(l1->data->length) > OSPF_LSA_HEADER_SIZE);
718e3744 3290
3291 p1 = (char *) l1->data;
3292 p2 = (char *) l2->data;
3293
3294 if (memcmp (p1 + OSPF_LSA_HEADER_SIZE, p2 + OSPF_LSA_HEADER_SIZE,
3295 ntohs( l1->data->length ) - OSPF_LSA_HEADER_SIZE) != 0)
3296 return 1;
3297
3298 return 0;
3299}
3300
3301#ifdef ORIGINAL_CODING
3302void
3303ospf_lsa_flush_self_originated (struct ospf_neighbor *nbr,
3304 struct ospf_lsa *self,
3305 struct ospf_lsa *new)
3306{
3307 u_int32_t seqnum;
3308
3309 /* Adjust LS Sequence Number. */
3310 seqnum = ntohl (new->data->ls_seqnum) + 1;
3311 self->data->ls_seqnum = htonl (seqnum);
3312
3313 /* Recalculate LSA checksum. */
3314 ospf_lsa_checksum (self->data);
3315
3316 /* Reflooding LSA. */
3317 /* RFC2328 Section 13.3
3318 On non-broadcast networks, separate Link State Update
3319 packets must be sent, as unicasts, to each adjacent neighbor
3320 (i.e., those in state Exchange or greater). The destination
3321 IP addresses for these packets are the neighbors' IP
3322 addresses. */
3323 if (nbr->oi->type == OSPF_IFTYPE_NBMA)
3324 {
3325 struct route_node *rn;
3326 struct ospf_neighbor *onbr;
3327
3328 for (rn = route_top (nbr->oi->nbrs); rn; rn = route_next (rn))
3329 if ((onbr = rn->info) != NULL)
3330 if (onbr != nbr->oi->nbr_self && onbr->status >= NSM_Exchange)
3331 ospf_ls_upd_send_lsa (onbr, self, OSPF_SEND_PACKET_DIRECT);
3332 }
3333 else
3334 ospf_ls_upd_send_lsa (nbr, self, OSPF_SEND_PACKET_INDIRECT);
3335
3336 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 3337 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
718e3744 3338 self->data->type, inet_ntoa (self->data->id));
3339}
3340#else /* ORIGINAL_CODING */
3341static int
68980084 3342ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 3343{
3344 if (lsa == NULL || !IS_LSA_SELF (lsa))
3345 return 0;
3346
3347 if (IS_DEBUG_OSPF_EVENT)
e588f21f 3348 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
718e3744 3349
3350 /* Force given lsa's age to MaxAge. */
3351 lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
3352
3353 switch (lsa->data->type)
3354 {
3355#ifdef HAVE_OPAQUE_LSA
3356 case OSPF_OPAQUE_LINK_LSA:
3357 case OSPF_OPAQUE_AREA_LSA:
3358 case OSPF_OPAQUE_AS_LSA:
3359 ospf_opaque_lsa_refresh (lsa);
3360 break;
3361#endif /* HAVE_OPAQUE_LSA */
3362 default:
68980084 3363 ospf_lsa_maxage (ospf, lsa);
718e3744 3364 break;
3365 }
3366
3367 return 0;
3368}
3369
3370void
68980084 3371ospf_flush_self_originated_lsas_now (struct ospf *ospf)
718e3744 3372{
1eb8ef25 3373 struct listnode *node, *nnode;
3374 struct listnode *node2, *nnode2;
718e3744 3375 struct ospf_area *area;
3376 struct ospf_interface *oi;
3377 struct ospf_lsa *lsa;
68980084 3378 struct route_node *rn;
718e3744 3379 int need_to_flush_ase = 0;
3380
1eb8ef25 3381 for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
718e3744 3382 {
718e3744 3383 if ((lsa = area->router_lsa_self) != NULL)
3384 {
3385 if (IS_DEBUG_OSPF_EVENT)
e588f21f 3386 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
718e3744 3387
3388 ospf_lsa_flush_area (lsa, area);
1fe6ed38 3389 ospf_lsa_unlock (&area->router_lsa_self);
718e3744 3390 area->router_lsa_self = NULL;
3391 OSPF_TIMER_OFF (area->t_router_lsa_self);
3392 }
3393
1eb8ef25 3394 for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
718e3744 3395 {
718e3744 3396 if ((lsa = oi->network_lsa_self) != NULL
1eb8ef25 3397 && oi->state == ISM_DR
3398 && oi->full_nbrs > 0)
718e3744 3399 {
3400 if (IS_DEBUG_OSPF_EVENT)
e588f21f 3401 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id));
718e3744 3402
3403 ospf_lsa_flush_area (oi->network_lsa_self, area);
1fe6ed38 3404 ospf_lsa_unlock (&oi->network_lsa_self);
718e3744 3405 oi->network_lsa_self = NULL;
3406 OSPF_TIMER_OFF (oi->t_network_lsa_self);
3407 }
3408
3409 if (oi->type != OSPF_IFTYPE_VIRTUALLINK
3410 && area->external_routing == OSPF_AREA_DEFAULT)
3411 need_to_flush_ase = 1;
3412 }
3413
68980084 3414 LSDB_LOOP (SUMMARY_LSDB (area), rn, lsa)
3415 ospf_lsa_flush_schedule (ospf, lsa);
3416 LSDB_LOOP (ASBR_SUMMARY_LSDB (area), rn, lsa)
3417 ospf_lsa_flush_schedule (ospf, lsa);
718e3744 3418#ifdef HAVE_OPAQUE_LSA
68980084 3419 LSDB_LOOP (OPAQUE_LINK_LSDB (area), rn, lsa)
3420 ospf_lsa_flush_schedule (ospf, lsa);
3421 LSDB_LOOP (OPAQUE_AREA_LSDB (area), rn, lsa)
3422 ospf_lsa_flush_schedule (ospf, lsa);
718e3744 3423#endif /* HAVE_OPAQUE_LSA */
3424 }
3425
3426 if (need_to_flush_ase)
3427 {
68980084 3428 LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa)
3429 ospf_lsa_flush_schedule (ospf, lsa);
718e3744 3430#ifdef HAVE_OPAQUE_LSA
68980084 3431 LSDB_LOOP (OPAQUE_AS_LSDB (ospf), rn, lsa)
3432 ospf_lsa_flush_schedule (ospf, lsa);
718e3744 3433#endif /* HAVE_OPAQUE_LSA */
3434 }
3435
3436 /*
3437 * Make sure that the MaxAge LSA remover is executed immediately,
3438 * without conflicting to other threads.
3439 */
68980084 3440 if (ospf->t_maxage != NULL)
718e3744 3441 {
68980084 3442 OSPF_TIMER_OFF (ospf->t_maxage);
3443 thread_execute (master, ospf_maxage_lsa_remover, ospf, 0);
718e3744 3444 }
3445
3446 return;
3447}
3448#endif /* ORIGINAL_CODING */
3449
3450/* If there is self-originated LSA, then return 1, otherwise return 0. */
3451/* An interface-independent version of ospf_lsa_is_self_originated */
3452int
68980084 3453ospf_lsa_is_self_originated (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 3454{
52dc7ee6 3455 struct listnode *node;
1eb8ef25 3456 struct ospf_interface *oi;
718e3744 3457
3458 /* This LSA is already checked. */
3459 if (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED))
f6247bf2 3460 return IS_LSA_SELF (lsa);
718e3744 3461
3462 /* Make sure LSA is self-checked. */
3463 SET_FLAG (lsa->flags, OSPF_LSA_SELF_CHECKED);
3464
3465 /* AdvRouter and Router ID is the same. */
68980084 3466 if (IPV4_ADDR_SAME (&lsa->data->adv_router, &ospf->router_id))
718e3744 3467 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3468
3469 /* LSA is router-LSA. */
3470 else if (lsa->data->type == OSPF_ROUTER_LSA &&
68980084 3471 IPV4_ADDR_SAME (&lsa->data->id, &ospf->router_id))
718e3744 3472 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
3473
3474 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3475 else if (lsa->data->type == OSPF_NETWORK_LSA)
1eb8ef25 3476 for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi))
718e3744 3477 {
718e3744 3478 /* Ignore virtual link. */
3479 if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
3480 if (oi->address->family == AF_INET)
3481 if (IPV4_ADDR_SAME (&lsa->data->id, &oi->address->u.prefix4))
3482 {
3483 /* to make it easier later */
3484 SET_FLAG (lsa->flags, OSPF_LSA_SELF);
f6247bf2 3485 return IS_LSA_SELF (lsa);
718e3744 3486 }
3487 }
3488
f6247bf2 3489 return IS_LSA_SELF (lsa);
718e3744 3490}
3491
3492/* Get unique Link State ID. */
3493struct in_addr
68980084 3494ospf_lsa_unique_id (struct ospf *ospf,
3495 struct ospf_lsdb *lsdb, u_char type, struct prefix_ipv4 *p)
718e3744 3496{
3497 struct ospf_lsa *lsa;
3498 struct in_addr mask, id;
3499
3500 id = p->prefix;
3501
3502 /* Check existence of LSA instance. */
68980084 3503 lsa = ospf_lsdb_lookup_by_id (lsdb, type, id, ospf->router_id);
718e3744 3504 if (lsa)
3505 {
3506 struct as_external_lsa *al = (struct as_external_lsa *) lsa->data;
3507 if (ip_masklen (al->mask) == p->prefixlen)
3508 {
3509 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 3510 zlog_debug ("ospf_lsa_unique_id(): "
718e3744 3511 "Can't get Link State ID for %s/%d",
3512 inet_ntoa (p->prefix), p->prefixlen);
3513 /* id.s_addr = 0; */
3514 id.s_addr = 0xffffffff;
3515 return id;
3516 }
3517 /* Masklen differs, then apply wildcard mask to Link State ID. */
3518 else
3519 {
3520 masklen2ip (p->prefixlen, &mask);
3521
3522 id.s_addr = p->prefix.s_addr | (~mask.s_addr);
68980084 3523 lsa = ospf_lsdb_lookup_by_id (ospf->lsdb, type,
3524 id, ospf->router_id);
718e3744 3525 if (lsa)
3526 {
3527 if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
e588f21f 3528 zlog_debug ("ospf_lsa_unique_id(): "
718e3744 3529 "Can't get Link State ID for %s/%d",
3530 inet_ntoa (p->prefix), p->prefixlen);
3531 /* id.s_addr = 0; */
3532 id.s_addr = 0xffffffff;
3533 return id;
3534 }
3535 }
3536 }
3537
3538 return id;
3539}
3540
3541\f
70461d79
PJ
3542#define LSA_ACTION_FLOOD_AREA 1
3543#define LSA_ACTION_FLUSH_AREA 2
718e3744 3544
3545struct lsa_action
3546{
3547 u_char action;
3548 struct ospf_area *area;
718e3744 3549 struct ospf_lsa *lsa;
3550};
3551
4dadc291 3552static int
718e3744 3553ospf_lsa_action (struct thread *t)
3554{
3555 struct lsa_action *data;
3556
3557 data = THREAD_ARG (t);
3558
3559 if (IS_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA)
e588f21f 3560 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
718e3744 3561 data->action);
3562
3563 switch (data->action)
3564 {
718e3744 3565 case LSA_ACTION_FLOOD_AREA:
3566 ospf_flood_through_area (data->area, NULL, data->lsa);
3567 break;
718e3744 3568 case LSA_ACTION_FLUSH_AREA:
3569 ospf_lsa_flush_area (data->lsa, data->area);
3570 break;
718e3744 3571 }
3572
1fe6ed38 3573 ospf_lsa_unlock (&data->lsa); /* Message */
718e3744 3574 XFREE (MTYPE_OSPF_MESSAGE, data);
3575 return 0;
3576}
3577
3578void
3579ospf_schedule_lsa_flood_area (struct ospf_area *area, struct ospf_lsa *lsa)
3580{
3581 struct lsa_action *data;
3582
393deb9b 3583 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
718e3744 3584 data->action = LSA_ACTION_FLOOD_AREA;
3585 data->area = area;
1fe6ed38 3586 data->lsa = ospf_lsa_lock (lsa); /* Message / Flood area */
718e3744 3587
3588 thread_add_event (master, ospf_lsa_action, data, 0);
3589}
3590
3591void
3592ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)
3593{
3594 struct lsa_action *data;
3595
393deb9b 3596 data = XCALLOC (MTYPE_OSPF_MESSAGE, sizeof (struct lsa_action));
718e3744 3597 data->action = LSA_ACTION_FLUSH_AREA;
3598 data->area = area;
1fe6ed38 3599 data->lsa = ospf_lsa_lock (lsa); /* Message / Flush area */
718e3744 3600
3601 thread_add_event (master, ospf_lsa_action, data, 0);
3602}
3603
3604\f
3605/* LSA Refreshment functions. */
4dadc291 3606static void
68980084 3607ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 3608{
3609 struct external_info *ei;
f6247bf2 3610 assert (IS_LSA_SELF (lsa));
718e3744 3611
3612 switch (lsa->data->type)
3613 {
3614 /* Router and Network LSAs are processed differently. */
3615 case OSPF_ROUTER_LSA:
3616 case OSPF_NETWORK_LSA:
3617 break;
3618 case OSPF_SUMMARY_LSA:
68980084 3619 ospf_summary_lsa_refresh (ospf, lsa);
718e3744 3620 break;
3621 case OSPF_ASBR_SUMMARY_LSA:
68980084 3622 ospf_summary_asbr_lsa_refresh (ospf, lsa);
718e3744 3623 break;
3624 case OSPF_AS_EXTERNAL_LSA:
d4a53d58 3625 /* Translated from NSSA Type-5s are refreshed when
3626 * from refresh of Type-7 - do not refresh these directly.
3627 */
3628 if (CHECK_FLAG (lsa->flags, OSPF_LSA_LOCAL_XLT))
3629 break;
718e3744 3630 ei = ospf_external_info_check (lsa);
3631 if (ei)
d4a53d58 3632 ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);
718e3744 3633 else
d4a53d58 3634 ospf_lsa_flush_as (ospf, lsa);
718e3744 3635 break;
3636#ifdef HAVE_OPAQUE_LSA
3637 case OSPF_OPAQUE_LINK_LSA:
3638 case OSPF_OPAQUE_AREA_LSA:
3639 case OSPF_OPAQUE_AS_LSA:
3640 ospf_opaque_lsa_refresh (lsa);
3641 break;
d748032f 3642#endif /* HAVE_OPAQUE_LSA */
718e3744 3643 default:
3644 break;
718e3744 3645 }
3646}
3647
3648void
68980084 3649ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 3650{
3651 u_int16_t index, current_index;
3652
f6247bf2 3653 assert (IS_LSA_SELF (lsa));
718e3744 3654
3655 if (lsa->refresh_list < 0)
3656 {
3657 int delay;
3658
3659 if (LS_AGE (lsa) == 0 &&
3660 ntohl (lsa->data->ls_seqnum) == OSPF_INITIAL_SEQUENCE_NUMBER)
3661 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3662 delay = OSPF_LS_REFRESH_SHIFT + (random () % OSPF_LS_REFRESH_TIME);
3663 else
3664 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3665 delay = OSPF_LS_REFRESH_TIME - LS_AGE (lsa) - OSPF_LS_REFRESH_JITTER
3666 + (random () % (2*OSPF_LS_REFRESH_JITTER));
3667
3668 if (delay < 0)
3669 delay = 0;
3670
68980084 3671 current_index = ospf->lsa_refresh_queue.index +
2518efd1 3672 (quagga_time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;
718e3744 3673
3674 index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY)
3675 % (OSPF_LSA_REFRESHER_SLOTS);
3676
3677 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
e588f21f 3678 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
d4a53d58 3679 inet_ntoa (lsa->data->id), LS_AGE (lsa), index);
68980084 3680 if (!ospf->lsa_refresh_queue.qs[index])
3681 ospf->lsa_refresh_queue.qs[index] = list_new ();
1fe6ed38
PJ
3682 listnode_add (ospf->lsa_refresh_queue.qs[index],
3683 ospf_lsa_lock (lsa)); /* lsa_refresh_queue */
718e3744 3684 lsa->refresh_list = index;
f2c80652 3685 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
e588f21f 3686 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
5c8d16fd 3687 "setting refresh_list on lsa %p (index %u)",
d4a53d58 3688 inet_ntoa (lsa->data->id), lsa, index);
718e3744 3689 }
3690}
3691
3692void
68980084 3693ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)
718e3744 3694{
f6247bf2 3695 assert (IS_LSA_SELF (lsa));
718e3744 3696 if (lsa->refresh_list >= 0)
3697 {
52dc7ee6 3698 struct list *refresh_list = ospf->lsa_refresh_queue.qs[lsa->refresh_list];
718e3744 3699 listnode_delete (refresh_list, lsa);
3700 if (!listcount (refresh_list))
3701 {
3702 list_free (refresh_list);
68980084 3703 ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
718e3744 3704 }
1fe6ed38 3705 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
718e3744 3706 lsa->refresh_list = -1;
3707 }
3708}
3709
3710int
3711ospf_lsa_refresh_walker (struct thread *t)
3712{
52dc7ee6 3713 struct list *refresh_list;
1eb8ef25 3714 struct listnode *node, *nnode;
68980084 3715 struct ospf *ospf = THREAD_ARG (t);
1eb8ef25 3716 struct ospf_lsa *lsa;
718e3744 3717 int i;
52dc7ee6 3718 struct list *lsa_to_refresh = list_new ();
718e3744 3719
3720 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
e588f21f 3721 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
718e3744 3722
3723
68980084 3724 i = ospf->lsa_refresh_queue.index;
718e3744 3725
9dbc7972 3726 /* Note: if clock has jumped backwards, then time change could be negative,
3727 so we are careful to cast the expression to unsigned before taking
3728 modulus. */
68980084 3729 ospf->lsa_refresh_queue.index =
9dbc7972 3730 ((unsigned long)(ospf->lsa_refresh_queue.index +
2518efd1 3731 (quagga_time (NULL) - ospf->lsa_refresher_started) /
9dbc7972 3732 OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS;
718e3744 3733
3734 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
e588f21f 3735 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
68980084 3736 ospf->lsa_refresh_queue.index);
718e3744 3737
68980084 3738 for (;i != ospf->lsa_refresh_queue.index;
718e3744 3739 i = (i + 1) % OSPF_LSA_REFRESHER_SLOTS)
3740 {
3741 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
e588f21f 3742 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
d4a53d58 3743 "refresh index %d", i);
718e3744 3744
68980084 3745 refresh_list = ospf->lsa_refresh_queue.qs [i];
718e3744 3746
68980084 3747 ospf->lsa_refresh_queue.qs [i] = NULL;
3748
718e3744 3749 if (refresh_list)
3750 {
1eb8ef25 3751 for (ALL_LIST_ELEMENTS (refresh_list, node, nnode, lsa))
718e3744 3752 {
718e3744 3753 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
e588f21f 3754 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
d4a53d58 3755 "refresh lsa %p (slot %d)",
3756 inet_ntoa (lsa->data->id), lsa, i);
718e3744 3757
3758 list_delete_node (refresh_list, node);
1fe6ed38 3759 ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */
718e3744 3760 lsa->refresh_list = -1;
3761 listnode_add (lsa_to_refresh, lsa);
718e3744 3762 }
3763 list_free (refresh_list);
3764 }
3765 }
3766
68980084 3767 ospf->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker,
3768 ospf, ospf->lsa_refresh_interval);
2518efd1 3769 ospf->lsa_refresher_started = quagga_time (NULL);
718e3744 3770
1eb8ef25 3771 for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa))
3772 ospf_lsa_refresh (ospf, lsa);
718e3744 3773
3774 list_delete (lsa_to_refresh);
3775
3776 if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))
e588f21f 3777 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");
718e3744 3778
3779 return 0;
3780}
3781