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