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