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