2 * OSPF Link State Advertisement
3 * Copyright (C) 1999, 2000 Toshiaki Takada
5 * This file is part of GNU Zebra.
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
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.
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
34 #include "sockunion.h" /* for inet_aton() */
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"
54 get_metric (u_char
*metric
)
58 m
= (m
<< 8) + metric
[1];
59 m
= (m
<< 8) + metric
[2];
65 tv_adjust (struct timeval a
)
67 while (a
.tv_usec
>= 1000000)
83 tv_ceil (struct timeval a
)
87 return (a
.tv_usec
? a
.tv_sec
+ 1 : a
.tv_sec
);
91 tv_floor (struct timeval a
)
110 tv_add (struct timeval a
, struct timeval b
)
114 ret
.tv_sec
= a
.tv_sec
+ b
.tv_sec
;
115 ret
.tv_usec
= a
.tv_usec
+ b
.tv_usec
;
117 return tv_adjust (ret
);
121 tv_sub (struct timeval a
, struct timeval b
)
125 ret
.tv_sec
= a
.tv_sec
- b
.tv_sec
;
126 ret
.tv_usec
= a
.tv_usec
- b
.tv_usec
;
128 return tv_adjust (ret
);
132 tv_cmp (struct timeval a
, struct timeval b
)
134 return (a
.tv_sec
== b
.tv_sec
?
135 a
.tv_usec
- b
.tv_usec
: a
.tv_sec
- b
.tv_sec
);
139 ospf_lsa_refresh_delay (struct ospf_lsa
*lsa
)
141 struct timeval delta
, now
;
144 gettimeofday (&now
, NULL
);
145 delta
= tv_sub (now
, lsa
->tv_orig
);
147 if (tv_cmp (delta
, int2tv (OSPF_MIN_LS_INTERVAL
)) < 0)
149 delay
= tv_ceil (tv_sub (int2tv (OSPF_MIN_LS_INTERVAL
), delta
));
151 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
152 zlog_debug ("LSA[Type%d:%s]: Refresh timer delay %d seconds",
153 lsa
->data
->type
, inet_ntoa (lsa
->data
->id
), delay
);
163 get_age (struct ospf_lsa
*lsa
)
168 gettimeofday (&now
, NULL
);
169 age
= ntohs (lsa
->data
->ls_age
) + tv_floor (tv_sub (now
, lsa
->tv_recv
));
175 /* Fletcher Checksum -- Refer to RFC1008. */
177 #define LSA_CHECKSUM_OFFSET 15
180 ospf_lsa_checksum (struct lsa_header
*lsa
)
182 u_char
*sp
, *ep
, *p
, *q
;
188 length
= ntohs (lsa
->length
) - 2;
189 sp
= (u_char
*) &lsa
->options
;
191 for (ep
= sp
+ length
; sp
< ep
; sp
= q
)
196 for (p
= sp
; p
< q
; p
++)
205 x
= ((length
- LSA_CHECKSUM_OFFSET
) * c0
- c1
) % 255;
212 /* take care endian issue. */
213 lsa
->checksum
= htons ((x
<< 8) + y
);
215 return (lsa
->checksum
);
220 /* Create OSPF LSA. */
224 struct ospf_lsa
*new;
226 new = XCALLOC (MTYPE_OSPF_LSA
, sizeof (struct ospf_lsa
));
227 memset (new, 0, sizeof (struct ospf_lsa
));
231 new->retransmit_counter
= 0;
232 gettimeofday (&new->tv_recv
, NULL
);
233 new->tv_orig
= new->tv_recv
;
234 new->refresh_list
= -1;
239 /* Duplicate OSPF LSA. */
241 ospf_lsa_dup (struct ospf_lsa
*lsa
)
243 struct ospf_lsa
*new;
248 new = XCALLOC (MTYPE_OSPF_LSA
, sizeof (struct ospf_lsa
));
250 memcpy (new, lsa
, sizeof (struct ospf_lsa
));
251 UNSET_FLAG (new->flags
, OSPF_LSA_DISCARD
);
253 new->retransmit_counter
= 0;
254 new->data
= ospf_lsa_data_dup (lsa
->data
);
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;
262 if (IS_DEBUG_OSPF (lsa
, LSA
))
263 zlog_debug ("LSA: duplicated %p (new: %p)", lsa
, new);
270 ospf_lsa_free (struct ospf_lsa
*lsa
)
272 assert (lsa
->lock
== 0);
274 if (IS_DEBUG_OSPF (lsa
, LSA
))
275 zlog_debug ("LSA: freed %p", lsa
);
277 /* Delete LSA data. */
278 if (lsa
->data
!= NULL
)
279 ospf_lsa_data_free (lsa
->data
);
281 assert (lsa
->refresh_list
< 0);
283 memset (lsa
, 0, sizeof (struct ospf_lsa
));
284 XFREE (MTYPE_OSPF_LSA
, lsa
);
289 ospf_lsa_lock (struct ospf_lsa
*lsa
)
297 ospf_lsa_unlock (struct ospf_lsa
*lsa
)
299 /* This is sanity check. */
305 assert (lsa
->lock
>= 0);
309 assert (CHECK_FLAG (lsa
->flags
, OSPF_LSA_DISCARD
));
314 /* Check discard flag. */
316 ospf_lsa_discard (struct ospf_lsa
*lsa
)
318 if (!CHECK_FLAG (lsa
->flags
, OSPF_LSA_DISCARD
))
320 SET_FLAG (lsa
->flags
, OSPF_LSA_DISCARD
);
321 ospf_lsa_unlock (lsa
);
325 /* Create LSA data. */
327 ospf_lsa_data_new (size_t size
)
329 struct lsa_header
*new;
331 new = (struct lsa_header
*) XMALLOC (MTYPE_OSPF_LSA_DATA
, size
);
332 memset (new, 0, size
);
337 /* Duplicate LSA data. */
339 ospf_lsa_data_dup (struct lsa_header
*lsah
)
341 struct lsa_header
*new;
343 new = ospf_lsa_data_new (ntohs (lsah
->length
));
344 memcpy (new, lsah
, ntohs (lsah
->length
));
351 ospf_lsa_data_free (struct lsa_header
*lsah
)
353 if (IS_DEBUG_OSPF (lsa
, LSA
))
354 zlog_debug ("LSA[Type%d:%s]: data freed %p",
355 lsah
->type
, inet_ntoa (lsah
->id
), lsah
);
357 XFREE (MTYPE_OSPF_LSA_DATA
, lsah
);
361 /* LSA general functions. */
364 dump_lsa_key (struct ospf_lsa
*lsa
)
366 static char buf
[] = {
367 "Type255,id(255.255.255.255),ar(255.255.255.255)"
369 struct lsa_header
*lsah
;
371 if (lsa
!= NULL
&& (lsah
= lsa
->data
) != NULL
)
373 char id
[INET_ADDRSTRLEN
], ar
[INET_ADDRSTRLEN
];
374 strcpy (id
, inet_ntoa (lsah
->id
));
375 strcpy (ar
, inet_ntoa (lsah
->adv_router
));
377 sprintf (buf
, "Type%d,id(%s),ar(%s)", lsah
->type
, id
, ar
);
380 strcpy (buf
, "NULL");
386 lsa_seqnum_increment (struct ospf_lsa
*lsa
)
390 seqnum
= ntohl (lsa
->data
->ls_seqnum
) + 1;
392 return htonl (seqnum
);
396 lsa_header_set (struct stream
*s
, u_char options
,
397 u_char type
, struct in_addr id
, struct in_addr router_id
)
399 struct lsa_header
*lsah
;
401 lsah
= (struct lsa_header
*) STREAM_DATA (s
);
403 lsah
->ls_age
= htons (0);
404 lsah
->options
= options
;
407 lsah
->adv_router
= router_id
;
408 lsah
->ls_seqnum
= htonl (OSPF_INITIAL_SEQUENCE_NUMBER
);
410 stream_forward_endp (s
, OSPF_LSA_HEADER_SIZE
);
414 /* router-LSA related functions. */
415 /* Get router-LSA flags. */
417 router_lsa_flags (struct ospf_area
*area
)
421 flags
= area
->ospf
->flags
;
423 /* Set virtual link flag. */
424 if (ospf_full_virtual_nbrs (area
))
425 SET_FLAG (flags
, ROUTER_LSA_VIRTUAL
);
427 /* Just sanity check */
428 UNSET_FLAG (flags
, ROUTER_LSA_VIRTUAL
);
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
);
439 /* ASBR can't exit in stub area. */
440 if (area
->external_routing
== OSPF_AREA_STUB
)
441 UNSET_FLAG (flags
, ROUTER_LSA_EXTERNAL
);
442 /* If ASBR set External flag */
443 else if (IS_OSPF_ASBR (area
->ospf
))
444 SET_FLAG (flags
, ROUTER_LSA_EXTERNAL
);
446 /* Set ABR dependent flags */
447 if (IS_OSPF_ABR (area
->ospf
))
449 SET_FLAG (flags
, ROUTER_LSA_BORDER
);
450 /* If Area is NSSA and we are both ABR and unconditional translator,
451 * set Nt bit to inform other routers.
453 if ( (area
->external_routing
== OSPF_AREA_NSSA
)
454 && (area
->NSSATranslatorRole
== OSPF_NSSA_ROLE_ALWAYS
))
455 SET_FLAG (flags
, ROUTER_LSA_NT
);
460 /* Lookup neighbor other than myself.
461 And check neighbor count,
462 Point-to-Point link must have only 1 neighbor. */
463 struct ospf_neighbor
*
464 ospf_nbr_lookup_ptop (struct ospf_interface
*oi
)
466 struct ospf_neighbor
*nbr
= NULL
;
467 struct route_node
*rn
;
469 /* Search neighbor, there must be one of two nbrs. */
470 for (rn
= route_top (oi
->nbrs
); rn
; rn
= route_next (rn
))
471 if ((nbr
= rn
->info
))
472 if (!IPV4_ADDR_SAME (&nbr
->router_id
, &oi
->ospf
->router_id
))
473 if (nbr
->state
== NSM_Full
)
475 route_unlock_node (rn
);
479 /* PtoP link must have only 1 neighbor. */
480 if (ospf_nbr_count (oi
, 0) > 1)
481 zlog_warn ("Point-to-Point link has more than 1 neighobrs.");
486 /* Set a link information. */
488 link_info_set (struct stream
*s
, struct in_addr id
,
489 struct in_addr data
, u_char type
, u_char tos
, u_int16_t cost
)
491 /* TOS based routing is not supported. */
492 stream_put_ipv4 (s
, id
.s_addr
); /* Link ID. */
493 stream_put_ipv4 (s
, data
.s_addr
); /* Link Data. */
494 stream_putc (s
, type
); /* Link Type. */
495 stream_putc (s
, tos
); /* TOS = 0. */
496 stream_putw (s
, cost
); /* Link Cost. */
499 /* Describe Point-to-Point link. */
501 lsa_link_ptop_set (struct stream
*s
, struct ospf_interface
*oi
)
504 struct ospf_neighbor
*nbr
;
505 struct in_addr id
, mask
;
507 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
508 zlog_debug ("LSA[Type1]: Set link Point-to-Point");
510 if ((nbr
= ospf_nbr_lookup_ptop (oi
)))
511 if (nbr
->state
== NSM_Full
)
513 /* For unnumbered point-to-point networks, the Link Data field
514 should specify the interface's MIB-II ifIndex value. */
515 link_info_set (s
, nbr
->router_id
, oi
->address
->u
.prefix4
,
516 LSA_LINK_TYPE_POINTOPOINT
, 0, oi
->output_cost
);
520 if (CONNECTED_DEST_HOST(oi
->connected
))
523 link_type = LSA_LINK_TYPE_STUB;
524 link_id = nbr->address.u.prefix4;
525 link_data.s_addr = 0xffffffff;
526 link_cost = o->output_cost; */
528 id
.s_addr
= oi
->connected
->destination
->u
.prefix4
.s_addr
;
529 mask
.s_addr
= 0xffffffff;
530 link_info_set (s
, id
, mask
, LSA_LINK_TYPE_STUB
, 0, oi
->output_cost
);
534 /* Option 2: We need to include link to a stub
535 network regardless of the state of the neighbor */
536 masklen2ip (oi
->address
->prefixlen
, &mask
);
537 id
.s_addr
= oi
->address
->u
.prefix4
.s_addr
& mask
.s_addr
;
538 link_info_set (s
, id
, mask
, LSA_LINK_TYPE_STUB
, 0, oi
->output_cost
);
545 /* Describe Broadcast Link. */
547 lsa_link_broadcast_set (struct stream
*s
, struct ospf_interface
*oi
)
549 struct ospf_neighbor
*dr
;
550 struct in_addr id
, mask
;
552 /* Describe Type 3 Link. */
553 if (oi
->state
== ISM_Waiting
)
555 masklen2ip (oi
->address
->prefixlen
, &mask
);
556 id
.s_addr
= oi
->address
->u
.prefix4
.s_addr
& mask
.s_addr
;
557 link_info_set (s
, id
, mask
, LSA_LINK_TYPE_STUB
, 0, oi
->output_cost
);
561 dr
= ospf_nbr_lookup_by_addr (oi
->nbrs
, &DR (oi
));
562 /* Describe Type 2 link. */
563 if (dr
&& (dr
->state
== NSM_Full
||
564 IPV4_ADDR_SAME (&oi
->address
->u
.prefix4
, &DR (oi
))) &&
565 ospf_nbr_count (oi
, NSM_Full
) > 0)
567 link_info_set (s
, DR (oi
), oi
->address
->u
.prefix4
,
568 LSA_LINK_TYPE_TRANSIT
, 0, oi
->output_cost
);
570 /* Describe type 3 link. */
573 masklen2ip (oi
->address
->prefixlen
, &mask
);
574 id
.s_addr
= oi
->address
->u
.prefix4
.s_addr
& mask
.s_addr
;
575 link_info_set (s
, id
, mask
, LSA_LINK_TYPE_STUB
, 0, oi
->output_cost
);
581 lsa_link_loopback_set (struct stream
*s
, struct ospf_interface
*oi
)
583 struct in_addr id
, mask
;
585 /* Describe Type 3 Link. */
586 if (oi
->state
!= ISM_Loopback
)
589 mask
.s_addr
= 0xffffffff;
590 id
.s_addr
= oi
->address
->u
.prefix4
.s_addr
;
591 link_info_set (s
, id
, mask
, LSA_LINK_TYPE_STUB
, 0, oi
->output_cost
);
595 /* Describe Virtual Link. */
597 lsa_link_virtuallink_set (struct stream
*s
, struct ospf_interface
*oi
)
599 struct ospf_neighbor
*nbr
;
601 if (oi
->state
== ISM_PointToPoint
)
602 if ((nbr
= ospf_nbr_lookup_ptop (oi
)))
603 if (nbr
->state
== NSM_Full
)
605 link_info_set (s
, nbr
->router_id
, oi
->address
->u
.prefix4
,
606 LSA_LINK_TYPE_VIRTUALLINK
, 0, oi
->output_cost
);
613 #define lsa_link_nbma_set(S,O) lsa_link_broadcast_set (S, O)
615 /* this function add for support point-to-multipoint ,see rfc2328
617 /* from "edward rrr" <edward_rrr@hotmail.com>
618 http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
620 lsa_link_ptomp_set (struct stream
*s
, struct ospf_interface
*oi
)
623 struct route_node
*rn
;
624 struct ospf_neighbor
*nbr
= NULL
;
625 struct in_addr id
, mask
;
627 mask
.s_addr
= 0xffffffff;
628 id
.s_addr
= oi
->address
->u
.prefix4
.s_addr
;
629 link_info_set (s
, id
, mask
, LSA_LINK_TYPE_STUB
, 0, 0);
632 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
633 zlog_debug ("PointToMultipoint: running ptomultip_set");
635 /* Search neighbor, */
636 for (rn
= route_top (oi
->nbrs
); rn
; rn
= route_next (rn
))
637 if ((nbr
= rn
->info
) != NULL
)
639 if (!IPV4_ADDR_SAME (&nbr
->router_id
, &oi
->ospf
->router_id
))
640 if (nbr
->state
== NSM_Full
)
643 link_info_set (s
, nbr
->router_id
, oi
->address
->u
.prefix4
,
644 LSA_LINK_TYPE_POINTOPOINT
, 0, oi
->output_cost
);
646 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
647 zlog_debug ("PointToMultipoint: set link to %s",
648 inet_ntoa(oi
->address
->u
.prefix4
));
654 /* Set router-LSA link information. */
656 router_lsa_link_set (struct stream
*s
, struct ospf_area
*area
)
658 struct listnode
*node
;
659 struct ospf_interface
*oi
;
662 for (ALL_LIST_ELEMENTS_RO (area
->oiflist
, node
, oi
))
664 struct interface
*ifp
= oi
->ifp
;
666 /* Check interface is up, OSPF is enable. */
667 if (if_is_operative (ifp
))
669 if (oi
->state
!= ISM_Down
)
671 /* Describe each link. */
674 case OSPF_IFTYPE_POINTOPOINT
:
675 links
+= lsa_link_ptop_set (s
, oi
);
677 case OSPF_IFTYPE_BROADCAST
:
678 links
+= lsa_link_broadcast_set (s
, oi
);
680 case OSPF_IFTYPE_NBMA
:
681 links
+= lsa_link_nbma_set (s
, oi
);
683 case OSPF_IFTYPE_POINTOMULTIPOINT
:
684 links
+= lsa_link_ptomp_set (s
, oi
);
686 case OSPF_IFTYPE_VIRTUALLINK
:
687 links
+= lsa_link_virtuallink_set (s
, oi
);
689 case OSPF_IFTYPE_LOOPBACK
:
690 links
+= lsa_link_loopback_set (s
, oi
);
699 /* Set router-LSA body. */
701 ospf_router_lsa_body_set (struct stream
*s
, struct ospf_area
*area
)
707 stream_putc (s
, router_lsa_flags (area
));
709 /* Set Zero fields. */
712 /* Keep pointer to # links. */
713 putp
= stream_get_endp(s
);
718 /* Set all link information. */
719 cnt
= router_lsa_link_set (s
, area
);
721 /* Set # of links here. */
722 stream_putw_at (s
, putp
, cnt
);
725 /* Create new router-LSA. */
726 static struct ospf_lsa
*
727 ospf_router_lsa_new (struct ospf_area
*area
)
729 struct ospf
*ospf
= area
->ospf
;
731 struct lsa_header
*lsah
;
732 struct ospf_lsa
*new;
735 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
736 zlog_debug ("LSA[Type1]: Create router-LSA instance");
738 /* Create a stream for LSA. */
739 s
= stream_new (OSPF_MAX_LSA_SIZE
);
740 lsah
= (struct lsa_header
*) STREAM_DATA (s
);
742 /* Set LSA common header fields. */
743 lsa_header_set (s
, LSA_OPTIONS_GET (area
) | LSA_OPTIONS_NSSA_GET (area
),
744 OSPF_ROUTER_LSA
, ospf
->router_id
, ospf
->router_id
);
746 /* Set router-LSA body fields. */
747 ospf_router_lsa_body_set (s
, area
);
750 length
= stream_get_endp (s
);
751 lsah
->length
= htons (length
);
753 /* Now, create OSPF LSA instance. */
754 new = ospf_lsa_new ();
756 SET_FLAG (new->flags
, OSPF_LSA_SELF
);
758 /* Copy LSA data to store, discard stream. */
759 new->data
= ospf_lsa_data_new (length
);
760 memcpy (new->data
, lsah
, length
);
766 /* Originate Router-LSA. */
768 ospf_router_lsa_originate (struct ospf_area
*area
)
770 struct ospf_lsa
*new;
772 /* Create new router-LSA instance. */
773 new = ospf_router_lsa_new (area
);
776 if (new->data
->adv_router
.s_addr
== 0)
778 if (IS_DEBUG_OSPF_EVENT
)
779 zlog_debug ("LSA[Type1]: AdvRouter is 0, discard");
780 ospf_lsa_discard (new);
784 /* Install LSA to LSDB. */
785 new = ospf_lsa_install (area
->ospf
, NULL
, new);
787 /* Update LSA origination count. */
788 area
->ospf
->lsa_originate_count
++;
790 /* Flooding new LSA through area. */
791 ospf_flood_through_area (area
, NULL
, new);
793 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
795 zlog_debug ("LSA[Type%d:%s]: Originate router-LSA %p",
796 new->data
->type
, inet_ntoa (new->data
->id
), new);
797 ospf_lsa_header_dump (new->data
);
803 /* Refresh router-LSA. */
804 static struct ospf_lsa
*
805 ospf_router_lsa_refresh (struct ospf_lsa
*lsa
)
807 struct ospf_area
*area
= lsa
->area
;
808 struct ospf_lsa
*new;
813 /* Delete LSA from neighbor retransmit-list. */
814 ospf_ls_retransmit_delete_nbr_area (area
, lsa
);
816 /* Create new router-LSA instance. */
817 new = ospf_router_lsa_new (area
);
818 new->data
->ls_seqnum
= lsa_seqnum_increment (lsa
);
820 ospf_lsa_install (area
->ospf
, NULL
, new);
822 /* Flood LSA through area. */
823 ospf_flood_through_area (area
, NULL
, new);
826 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
828 zlog_debug ("LSA[Type%d:%s]: router-LSA refresh",
829 new->data
->type
, inet_ntoa (new->data
->id
));
830 ospf_lsa_header_dump (new->data
);
837 ospf_router_lsa_timer (struct thread
*t
)
839 struct ospf_area
*area
;
841 if (IS_DEBUG_OSPF_EVENT
)
842 zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)");
844 area
= THREAD_ARG (t
);
845 area
->t_router_lsa_self
= NULL
;
847 /* Now refresh router-LSA. */
848 if (area
->router_lsa_self
)
849 ospf_router_lsa_refresh (area
->router_lsa_self
);
850 /* Newly originate router-LSA. */
852 ospf_router_lsa_originate (area
);
858 ospf_router_lsa_timer_add (struct ospf_area
*area
)
860 /* Keep area's self-originated router-LSA. */
861 struct ospf_lsa
*lsa
= area
->router_lsa_self
;
863 /* Cancel previously scheduled router-LSA timer. */
864 if (area
->t_router_lsa_self
)
865 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
866 zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer");
868 OSPF_TIMER_OFF (area
->t_router_lsa_self
);
870 /* If router-LSA is originated previously, check the interval time. */
874 if ((delay
= ospf_lsa_refresh_delay (lsa
)) > 0)
876 OSPF_AREA_TIMER_ON (area
->t_router_lsa_self
,
877 ospf_router_lsa_timer
, delay
);
882 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
883 zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away");
885 /* Immediately refresh router-LSA. */
886 OSPF_AREA_TIMER_ON (area
->t_router_lsa_self
, ospf_router_lsa_timer
, 0);
890 ospf_router_lsa_update_timer (struct thread
*thread
)
892 struct ospf
*ospf
= THREAD_ARG (thread
);
893 struct listnode
*node
, *nnode
;
894 struct ospf_area
*area
;
896 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
897 zlog_debug ("Timer[router-LSA Update]: (timer expire)");
899 ospf
->t_router_lsa_update
= NULL
;
901 for (ALL_LIST_ELEMENTS (ospf
->areas
, node
, nnode
, area
))
903 struct ospf_lsa
*lsa
= area
->router_lsa_self
;
904 struct router_lsa
*rl
;
905 const char *area_str
;
907 /* Keep Area ID string. */
908 area_str
= AREA_NAME (area
);
910 /* If LSA not exist in this Area, originate new. */
913 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
914 zlog_debug("LSA[Type1]: Create router-LSA for Area %s", area_str
);
916 ospf_router_lsa_originate (area
);
918 /* If router-ID is changed, Link ID must change.
919 First flush old LSA, then originate new. */
920 else if (!IPV4_ADDR_SAME (&lsa
->data
->id
, &ospf
->router_id
))
922 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
923 zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",
924 lsa
->data
->type
, inet_ntoa (lsa
->data
->id
), area_str
);
925 ospf_lsa_flush_area (lsa
, area
);
926 ospf_lsa_unlock (area
->router_lsa_self
);
927 area
->router_lsa_self
= NULL
;
929 /* Refresh router-LSA, (not install) and flood through area. */
930 ospf_router_lsa_timer_add (area
);
934 rl
= (struct router_lsa
*) lsa
->data
;
935 /* Refresh router-LSA, (not install) and flood through area. */
936 if (rl
->flags
!= ospf
->flags
)
937 ospf_router_lsa_timer_add (area
);
945 /* network-LSA related functions. */
946 /* Originate Network-LSA. */
948 ospf_network_lsa_body_set (struct stream
*s
, struct ospf_interface
*oi
)
951 struct route_node
*rn
;
952 struct ospf_neighbor
*nbr
;
954 masklen2ip (oi
->address
->prefixlen
, &mask
);
955 stream_put_ipv4 (s
, mask
.s_addr
);
957 /* The network-LSA lists those routers that are fully adjacent to
958 the Designated Router; each fully adjacent router is identified by
959 its OSPF Router ID. The Designated Router includes itself in this
960 list. RFC2328, Section 12.4.2 */
962 for (rn
= route_top (oi
->nbrs
); rn
; rn
= route_next (rn
))
963 if ((nbr
= rn
->info
) != NULL
)
964 if (nbr
->state
== NSM_Full
|| nbr
== oi
->nbr_self
)
965 stream_put_ipv4 (s
, nbr
->router_id
.s_addr
);
968 static struct ospf_lsa
*
969 ospf_network_lsa_new (struct ospf_interface
*oi
)
972 struct ospf_lsa
*new;
973 struct lsa_header
*lsah
;
976 /* If there are no neighbours on this network (the net is stub),
977 the router does not originate network-LSA (see RFC 12.4.2) */
978 if (oi
->full_nbrs
== 0)
981 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
982 zlog_debug ("LSA[Type2]: Create network-LSA instance");
984 /* Create new stream for LSA. */
985 s
= stream_new (OSPF_MAX_LSA_SIZE
);
986 lsah
= (struct lsa_header
*) STREAM_DATA (s
);
988 lsa_header_set (s
, (OPTIONS (oi
) | LSA_OPTIONS_GET (oi
->area
)),
989 OSPF_NETWORK_LSA
, DR (oi
), oi
->ospf
->router_id
);
991 /* Set network-LSA body fields. */
992 ospf_network_lsa_body_set (s
, oi
);
995 length
= stream_get_endp (s
);
996 lsah
->length
= htons (length
);
998 /* Create OSPF LSA instance. */
999 new = ospf_lsa_new ();
1000 new->area
= oi
->area
;
1001 SET_FLAG (new->flags
, OSPF_LSA_SELF
);
1003 /* Copy LSA to store. */
1004 new->data
= ospf_lsa_data_new (length
);
1005 memcpy (new->data
, lsah
, length
);
1011 /* Originate network-LSA. */
1012 static struct ospf_lsa
*
1013 ospf_network_lsa_originate (struct ospf_interface
*oi
)
1015 struct ospf_lsa
*new;
1017 /* Create new network-LSA instance. */
1018 new = ospf_network_lsa_new (oi
);
1022 /* Install LSA to LSDB. */
1023 new = ospf_lsa_install (oi
->ospf
, oi
, new);
1025 /* Update LSA origination count. */
1026 oi
->ospf
->lsa_originate_count
++;
1028 /* Flooding new LSA through area. */
1029 ospf_flood_through_area (oi
->area
, NULL
, new);
1031 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
1033 zlog_debug ("LSA[Type%d:%s]: Originate network-LSA %p",
1034 new->data
->type
, inet_ntoa (new->data
->id
), new);
1035 ospf_lsa_header_dump (new->data
);
1042 ospf_network_lsa_refresh (struct ospf_lsa
*lsa
, struct ospf_interface
*oi
)
1044 struct ospf_area
*area
= lsa
->area
;
1045 struct ospf_lsa
*new;
1049 /* Delete LSA from neighbor retransmit-list. */
1050 ospf_ls_retransmit_delete_nbr_area (area
, lsa
);
1052 /* Create new network-LSA instance. */
1053 new = ospf_network_lsa_new (oi
);
1056 new->data
->ls_seqnum
= lsa_seqnum_increment (lsa
);
1058 ospf_lsa_install (area
->ospf
, oi
, new);
1060 /* Flood LSA through aera. */
1061 ospf_flood_through_area (area
, NULL
, new);
1063 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
1065 zlog_debug ("LSA[Type%d:%s]: network-LSA refresh",
1066 new->data
->type
, inet_ntoa (new->data
->id
));
1067 ospf_lsa_header_dump (new->data
);
1074 ospf_network_lsa_refresh_timer (struct thread
*t
)
1076 struct ospf_interface
*oi
;
1078 oi
= THREAD_ARG (t
);
1079 oi
->t_network_lsa_self
= NULL
;
1081 if (oi
->network_lsa_self
)
1082 /* Now refresh network-LSA. */
1083 ospf_network_lsa_refresh (oi
->network_lsa_self
, oi
);
1085 /* Newly create network-LSA. */
1086 ospf_network_lsa_originate (oi
);
1092 ospf_network_lsa_timer_add (struct ospf_interface
*oi
)
1094 /* Keep interface's self-originated network-LSA. */
1095 struct ospf_lsa
*lsa
= oi
->network_lsa_self
;
1097 /* Cancel previously schedules network-LSA timer. */
1098 if (oi
->t_network_lsa_self
)
1099 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
1100 zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer");
1101 OSPF_TIMER_OFF (oi
->t_network_lsa_self
);
1103 /* If network-LSA is originated previously, check the interval time. */
1107 if ((delay
= ospf_lsa_refresh_delay (lsa
)) > 0)
1109 oi
->t_network_lsa_self
=
1110 thread_add_timer (master
, ospf_network_lsa_refresh_timer
,
1116 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
1117 zlog_debug ("Scheduling network-LSA origination right away");
1119 /* Immediately refresh network-LSA. */
1120 oi
->t_network_lsa_self
=
1121 thread_add_event (master
, ospf_network_lsa_refresh_timer
, oi
, 0);
1126 stream_put_ospf_metric (struct stream
*s
, u_int32_t metric_value
)
1131 /* Put 0 metric. TOS metric is not supported. */
1132 metric
= htonl (metric_value
);
1133 mp
= (char *) &metric
;
1135 stream_put (s
, mp
, 3);
1138 /* summary-LSA related functions. */
1140 ospf_summary_lsa_body_set (struct stream
*s
, struct prefix
*p
,
1143 struct in_addr mask
;
1145 masklen2ip (p
->prefixlen
, &mask
);
1147 /* Put Network Mask. */
1148 stream_put_ipv4 (s
, mask
.s_addr
);
1151 stream_putc (s
, (u_char
) 0);
1154 stream_put_ospf_metric (s
, metric
);
1157 static struct ospf_lsa
*
1158 ospf_summary_lsa_new (struct ospf_area
*area
, struct prefix
*p
,
1159 u_int32_t metric
, struct in_addr id
)
1162 struct ospf_lsa
*new;
1163 struct lsa_header
*lsah
;
1166 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
1167 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
1169 /* Create new stream for LSA. */
1170 s
= stream_new (OSPF_MAX_LSA_SIZE
);
1171 lsah
= (struct lsa_header
*) STREAM_DATA (s
);
1173 lsa_header_set (s
, LSA_OPTIONS_GET (area
), OSPF_SUMMARY_LSA
,
1174 id
, area
->ospf
->router_id
);
1176 /* Set summary-LSA body fields. */
1177 ospf_summary_lsa_body_set (s
, p
, metric
);
1180 length
= stream_get_endp (s
);
1181 lsah
->length
= htons (length
);
1183 /* Create OSPF LSA instance. */
1184 new = ospf_lsa_new ();
1186 SET_FLAG (new->flags
, OSPF_LSA_SELF
);
1188 /* Copy LSA to store. */
1189 new->data
= ospf_lsa_data_new (length
);
1190 memcpy (new->data
, lsah
, length
);
1196 /* Originate Summary-LSA. */
1198 ospf_summary_lsa_originate (struct prefix_ipv4
*p
, u_int32_t metric
,
1199 struct ospf_area
*area
)
1201 struct ospf_lsa
*new;
1204 id
= ospf_lsa_unique_id (area
->ospf
, area
->lsdb
, OSPF_SUMMARY_LSA
, p
);
1206 /* Create new summary-LSA instance. */
1207 new = ospf_summary_lsa_new (area
, (struct prefix
*) p
, metric
, id
);
1209 /* Instlal LSA to LSDB. */
1210 new = ospf_lsa_install (area
->ospf
, NULL
, new);
1212 /* Update LSA origination count. */
1213 area
->ospf
->lsa_originate_count
++;
1215 /* Flooding new LSA through area. */
1216 ospf_flood_through_area (area
, NULL
, new);
1218 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
1220 zlog_debug ("LSA[Type%d:%s]: Originate summary-LSA %p",
1221 new->data
->type
, inet_ntoa (new->data
->id
), new);
1222 ospf_lsa_header_dump (new->data
);
1229 ospf_summary_lsa_refresh (struct ospf
*ospf
, struct ospf_lsa
*lsa
)
1231 struct ospf_lsa
*new;
1232 struct summary_lsa
*sl
;
1238 sl
= (struct summary_lsa
*)lsa
->data
;
1239 p
.prefixlen
= ip_masklen (sl
->mask
);
1240 new = ospf_summary_lsa_new (lsa
->area
, &p
, GET_METRIC (sl
->metric
),
1243 new->data
->ls_seqnum
= lsa_seqnum_increment (lsa
);
1245 /* Re-calculate checksum. */
1246 ospf_lsa_checksum (new->data
);
1248 ospf_lsa_install (ospf
, NULL
, new);
1250 /* Flood LSA through AS. */
1251 ospf_flood_through_area (new->area
, NULL
, new);
1253 /* Debug logging. */
1254 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
1256 zlog_debug ("LSA[Type%d:%s]: summary-LSA refresh",
1257 new->data
->type
, inet_ntoa (new->data
->id
));
1258 ospf_lsa_header_dump (new->data
);
1265 /* summary-ASBR-LSA related functions. */
1267 ospf_summary_asbr_lsa_body_set (struct stream
*s
, struct prefix
*p
,
1270 struct in_addr mask
;
1272 masklen2ip (p
->prefixlen
, &mask
);
1274 /* Put Network Mask. */
1275 stream_put_ipv4 (s
, mask
.s_addr
);
1278 stream_putc (s
, (u_char
) 0);
1281 stream_put_ospf_metric (s
, metric
);
1284 static struct ospf_lsa
*
1285 ospf_summary_asbr_lsa_new (struct ospf_area
*area
, struct prefix
*p
,
1286 u_int32_t metric
, struct in_addr id
)
1289 struct ospf_lsa
*new;
1290 struct lsa_header
*lsah
;
1293 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
1294 zlog_debug ("LSA[Type3]: Create summary-LSA instance");
1296 /* Create new stream for LSA. */
1297 s
= stream_new (OSPF_MAX_LSA_SIZE
);
1298 lsah
= (struct lsa_header
*) STREAM_DATA (s
);
1300 lsa_header_set (s
, LSA_OPTIONS_GET (area
), OSPF_ASBR_SUMMARY_LSA
,
1301 id
, area
->ospf
->router_id
);
1303 /* Set summary-LSA body fields. */
1304 ospf_summary_asbr_lsa_body_set (s
, p
, metric
);
1307 length
= stream_get_endp (s
);
1308 lsah
->length
= htons (length
);
1310 /* Create OSPF LSA instance. */
1311 new = ospf_lsa_new ();
1313 SET_FLAG (new->flags
, OSPF_LSA_SELF
);
1315 /* Copy LSA to store. */
1316 new->data
= ospf_lsa_data_new (length
);
1317 memcpy (new->data
, lsah
, length
);
1323 /* Originate summary-ASBR-LSA. */
1325 ospf_summary_asbr_lsa_originate (struct prefix_ipv4
*p
, u_int32_t metric
,
1326 struct ospf_area
*area
)
1328 struct ospf_lsa
*new;
1331 id
= ospf_lsa_unique_id (area
->ospf
, area
->lsdb
, OSPF_ASBR_SUMMARY_LSA
, p
);
1333 /* Create new summary-LSA instance. */
1334 new = ospf_summary_asbr_lsa_new (area
, (struct prefix
*) p
, metric
, id
);
1336 /* Install LSA to LSDB. */
1337 new = ospf_lsa_install (area
->ospf
, NULL
, new);
1339 /* Update LSA origination count. */
1340 area
->ospf
->lsa_originate_count
++;
1342 /* Flooding new LSA through area. */
1343 ospf_flood_through_area (area
, NULL
, new);
1345 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
1347 zlog_debug ("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
1348 new->data
->type
, inet_ntoa (new->data
->id
), new);
1349 ospf_lsa_header_dump (new->data
);
1356 ospf_summary_asbr_lsa_refresh (struct ospf
*ospf
, struct ospf_lsa
*lsa
)
1358 struct ospf_lsa
*new;
1359 struct summary_lsa
*sl
;
1365 sl
= (struct summary_lsa
*)lsa
->data
;
1366 p
.prefixlen
= ip_masklen (sl
->mask
);
1367 new = ospf_summary_asbr_lsa_new (lsa
->area
, &p
, GET_METRIC (sl
->metric
),
1370 new->data
->ls_seqnum
= lsa_seqnum_increment (lsa
);
1372 /* Re-calculate checksum. */
1373 ospf_lsa_checksum (new->data
);
1375 ospf_lsa_install (ospf
, NULL
, new);
1377 /* Flood LSA through area. */
1378 ospf_flood_through_area (new->area
, NULL
, new);
1380 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
1382 zlog_debug ("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
1383 new->data
->type
, inet_ntoa (new->data
->id
));
1384 ospf_lsa_header_dump (new->data
);
1390 /* AS-external-LSA related functions. */
1392 /* Get nexthop for AS-external-LSAs. Return nexthop if its interface
1393 is connected, else 0*/
1394 static struct in_addr
1395 ospf_external_lsa_nexthop_get (struct ospf
*ospf
, struct in_addr nexthop
)
1399 struct listnode
*node
;
1400 struct ospf_interface
*oi
;
1404 if (!nexthop
.s_addr
)
1407 /* Check whether nexthop is covered by OSPF network. */
1408 nh
.family
= AF_INET
;
1409 nh
.u
.prefix4
= nexthop
;
1410 nh
.prefixlen
= IPV4_MAX_BITLEN
;
1412 for (ALL_LIST_ELEMENTS_RO (ospf
->oiflist
, node
, oi
))
1413 if (if_is_operative (oi
->ifp
))
1414 if (oi
->address
->family
== AF_INET
)
1415 if (prefix_match (oi
->address
, &nh
))
1421 /* NSSA-external-LSA related functions. */
1423 /* Get 1st IP connection for Forward Addr */
1426 ospf_get_ip_from_ifp (struct ospf_interface
*oi
)
1432 if (if_is_operative (oi
->ifp
))
1433 return oi
->address
->u
.prefix4
;
1438 /* Get 1st IP connection for Forward Addr */
1440 ospf_get_nssa_ip (struct ospf_area
*area
)
1443 struct in_addr best_default
;
1444 struct listnode
*node
;
1445 struct ospf_interface
*oi
;
1448 best_default
.s_addr
= 0;
1450 for (ALL_LIST_ELEMENTS_RO (area
->ospf
->oiflist
, node
, oi
))
1452 if (if_is_operative (oi
->ifp
))
1453 if (oi
->area
->external_routing
== OSPF_AREA_NSSA
)
1454 if (oi
->address
&& oi
->address
->family
== AF_INET
)
1456 if (best_default
.s_addr
== 0)
1457 best_default
= oi
->address
->u
.prefix4
;
1458 if (oi
->area
== area
)
1459 return oi
->address
->u
.prefix4
;
1462 if (best_default
.s_addr
!= 0)
1463 return best_default
;
1465 if (best_default
.s_addr
!= 0)
1466 return best_default
;
1471 #define DEFAULT_DEFAULT_METRIC 20
1472 #define DEFAULT_DEFAULT_ORIGINATE_METRIC 10
1473 #define DEFAULT_DEFAULT_ALWAYS_METRIC 1
1475 #define DEFAULT_METRIC_TYPE EXTERNAL_METRIC_TYPE_2
1478 metric_type (struct ospf
*ospf
, u_char src
)
1480 return (ospf
->dmetric
[src
].type
< 0 ?
1481 DEFAULT_METRIC_TYPE
: ospf
->dmetric
[src
].type
);
1485 metric_value (struct ospf
*ospf
, u_char src
)
1487 if (ospf
->dmetric
[src
].value
< 0)
1489 if (src
== DEFAULT_ROUTE
)
1491 if (ospf
->default_originate
== DEFAULT_ORIGINATE_ZEBRA
)
1492 return DEFAULT_DEFAULT_ORIGINATE_METRIC
;
1494 return DEFAULT_DEFAULT_ALWAYS_METRIC
;
1496 else if (ospf
->default_metric
< 0)
1497 return DEFAULT_DEFAULT_METRIC
;
1499 return ospf
->default_metric
;
1502 return ospf
->dmetric
[src
].value
;
1505 /* Set AS-external-LSA body. */
1507 ospf_external_lsa_body_set (struct stream
*s
, struct external_info
*ei
,
1510 struct prefix_ipv4
*p
= &ei
->p
;
1511 struct in_addr mask
, fwd_addr
;
1516 /* Put Network Mask. */
1517 masklen2ip (p
->prefixlen
, &mask
);
1518 stream_put_ipv4 (s
, mask
.s_addr
);
1520 /* If prefix is default, specify DEFAULT_ROUTE. */
1521 type
= is_prefix_default (&ei
->p
) ? DEFAULT_ROUTE
: ei
->type
;
1523 mtype
= (ROUTEMAP_METRIC_TYPE (ei
) != -1) ?
1524 ROUTEMAP_METRIC_TYPE (ei
) : metric_type (ospf
, type
);
1526 mvalue
= (ROUTEMAP_METRIC (ei
) != -1) ?
1527 ROUTEMAP_METRIC (ei
) : metric_value (ospf
, type
);
1529 /* Put type of external metric. */
1530 stream_putc (s
, (mtype
== EXTERNAL_METRIC_TYPE_2
? 0x80 : 0));
1532 /* Put 0 metric. TOS metric is not supported. */
1533 stream_put_ospf_metric (s
, mvalue
);
1535 /* Get forwarding address to nexthop if on the Connection List, else 0. */
1536 fwd_addr
= ospf_external_lsa_nexthop_get (ospf
, ei
->nexthop
);
1538 /* Put forwarding address. */
1539 stream_put_ipv4 (s
, fwd_addr
.s_addr
);
1541 /* Put route tag -- This value should be introduced from configuration. */
1545 /* Create new external-LSA. */
1546 static struct ospf_lsa
*
1547 ospf_external_lsa_new (struct ospf
*ospf
,
1548 struct external_info
*ei
, struct in_addr
*old_id
)
1551 struct lsa_header
*lsah
;
1552 struct ospf_lsa
*new;
1558 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
1559 zlog_debug ("LSA[Type5]: External info is NULL, could not originated");
1563 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
1564 zlog_debug ("LSA[Type5]: Originate AS-external-LSA instance");
1566 /* If old Link State ID is specified, refresh LSA with same ID. */
1569 /* Get Link State with unique ID. */
1572 id
= ospf_lsa_unique_id (ospf
, ospf
->lsdb
, OSPF_AS_EXTERNAL_LSA
, &ei
->p
);
1573 if (id
.s_addr
== 0xffffffff)
1575 /* Maybe Link State ID not available. */
1576 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
1577 zlog_debug ("LSA[Type5]: Link ID not available, can't originate");
1582 /* Create new stream for LSA. */
1583 s
= stream_new (OSPF_MAX_LSA_SIZE
);
1584 lsah
= (struct lsa_header
*) STREAM_DATA (s
);
1586 /* Set LSA common header fields. */
1587 lsa_header_set (s
, OSPF_OPTION_E
, OSPF_AS_EXTERNAL_LSA
,
1588 id
, ospf
->router_id
);
1590 /* Set AS-external-LSA body fields. */
1591 ospf_external_lsa_body_set (s
, ei
, ospf
);
1594 length
= stream_get_endp (s
);
1595 lsah
->length
= htons (length
);
1597 /* Now, create OSPF LSA instance. */
1598 new = ospf_lsa_new ();
1600 SET_FLAG (new->flags
, OSPF_LSA_SELF
|OSPF_LSA_APPROVED
);
1602 /* Copy LSA data to store, discard stream. */
1603 new->data
= ospf_lsa_data_new (length
);
1604 memcpy (new->data
, lsah
, length
);
1612 ospf_install_flood_nssa (struct ospf
*ospf
,
1613 struct ospf_lsa
*lsa
, struct external_info
*ei
)
1615 struct ospf_lsa
*new;
1616 struct as_external_lsa
*extlsa
;
1617 struct ospf_area
*area
;
1618 struct listnode
*node
, *nnode
;
1620 /* LSA may be a Type-5 originated via translation of a Type-7 LSA
1621 * which originated from an NSSA area. In which case it should not be
1622 * flooded back to NSSA areas.
1624 if (CHECK_FLAG (lsa
->flags
, OSPF_LSA_LOCAL_XLT
))
1627 /* NSSA Originate or Refresh (If anyNSSA)
1629 LSA is self-originated. And just installed as Type-5.
1630 Additionally, install as Type-7 LSDB for every attached NSSA.
1632 P-Bit controls which ABR performs translation to outside world; If
1633 we are an ABR....do not set the P-bit, because we send the Type-5,
1634 not as the ABR Translator, but as the ASBR owner within the AS!
1636 If we are NOT ABR, Flood through NSSA as Type-7 w/P-bit set. The
1637 elected ABR Translator will see the P-bit, Translate, and re-flood.
1639 Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to
1640 Type-5's to non-NSSA Areas. (it will also attempt a re-install) */
1642 for (ALL_LIST_ELEMENTS (ospf
->areas
, node
, nnode
, area
))
1644 /* Don't install Type-7 LSA's into nonNSSA area */
1645 if (area
->external_routing
!= OSPF_AREA_NSSA
)
1648 /* make lsa duplicate, lock=1 */
1649 new = ospf_lsa_dup (lsa
);
1651 new->data
->type
= OSPF_AS_NSSA_LSA
;
1653 /* set P-bit if not ABR */
1654 if (! IS_OSPF_ABR (ospf
))
1656 SET_FLAG(new->data
->options
, OSPF_OPTION_NP
);
1658 /* set non-zero FWD ADDR
1660 draft-ietf-ospf-nssa-update-09.txt
1662 if the network between the NSSA AS boundary router and the
1663 adjacent AS is advertised into OSPF as an internal OSPF route,
1664 the forwarding address should be the next op address as is cu
1665 currently done with type-5 LSAs. If the intervening network is
1666 not adversited into OSPF as an internal OSPF route and the
1667 type-7 LSA's P-bit is set a forwarding address should be
1668 selected from one of the router's active OSPF inteface addresses
1669 which belong to the NSSA. If no such addresses exist, then
1670 no type-7 LSA's with the P-bit set should originate from this
1673 /* kevinm: not updating lsa anymore, just new */
1674 extlsa
= (struct as_external_lsa
*)(new->data
);
1676 if (extlsa
->e
[0].fwd_addr
.s_addr
== 0)
1677 extlsa
->e
[0].fwd_addr
= ospf_get_nssa_ip(area
); /* this NSSA area in ifp */
1679 if (extlsa
->e
[0].fwd_addr
.s_addr
== 0)
1681 if (IS_DEBUG_OSPF_NSSA
)
1682 zlog_debug ("LSA[Type-7]: Could not build FWD-ADDR");
1683 ospf_lsa_discard(new);
1687 /* Re-calculate checksum. */
1688 ospf_lsa_checksum (new->data
);
1690 /* install also as Type-7 */
1691 ospf_lsa_install (ospf
, NULL
, new); /* Remove Old, Lock New = 2 */
1693 /* will send each copy, lock=2+n */
1694 ospf_flood_through_as (ospf
, NULL
, new); /* all attached NSSA's, no AS/STUBs */
1698 static struct ospf_lsa
*
1699 ospf_lsa_translated_nssa_new (struct ospf
*ospf
,
1700 struct ospf_lsa
*type7
)
1703 struct ospf_lsa
*new;
1704 struct as_external_lsa
*ext
, *extnew
;
1705 struct external_info ei
;
1707 ext
= (struct as_external_lsa
*)(type7
->data
);
1709 /* need external_info struct, fill in bare minimum */
1710 ei
.p
.family
= AF_INET
;
1711 ei
.p
.prefix
= type7
->data
->id
;
1712 ei
.p
.prefixlen
= ip_masklen (ext
->mask
);
1713 ei
.type
= ZEBRA_ROUTE_OSPF
;
1714 ei
.nexthop
= ext
->header
.adv_router
;
1715 ei
.route_map_set
.metric
= -1;
1716 ei
.route_map_set
.metric_type
= -1;
1719 if ( (new = ospf_external_lsa_new (ospf
, &ei
, &type7
->data
->id
)) == NULL
)
1721 if (IS_DEBUG_OSPF_NSSA
)
1722 zlog_debug ("ospf_nssa_translate_originate(): Could not originate "
1723 "Translated Type-5 for %s",
1724 inet_ntoa (ei
.p
.prefix
));
1728 extnew
= (struct as_external_lsa
*)(new->data
);
1730 /* copy over Type-7 data to new */
1731 extnew
->e
[0].tos
= ext
->e
[0].tos
;
1732 extnew
->e
[0].route_tag
= ext
->e
[0].route_tag
;
1733 extnew
->e
[0].fwd_addr
.s_addr
= ext
->e
[0].fwd_addr
.s_addr
;
1734 new->data
->ls_seqnum
= type7
->data
->ls_seqnum
;
1736 /* add translated flag, checksum and lock new lsa */
1737 SET_FLAG (new->flags
, OSPF_LSA_LOCAL_XLT
); /* Translated from 7 */
1738 ospf_lsa_checksum (new->data
);
1739 new = ospf_lsa_lock (new);
1744 /* compare type-5 to type-7
1745 * -1: err, 0: same, 1: different
1748 ospf_lsa_translated_nssa_compare (struct ospf_lsa
*t7
, struct ospf_lsa
*t5
)
1751 struct as_external_lsa
*e5
= (struct as_external_lsa
*)t5
,
1752 *e7
= (struct as_external_lsa
*)t7
;
1756 if (! ((t5
->data
->type
== OSPF_AS_EXTERNAL_LSA
)
1757 && (t7
->data
->type
== OSPF_AS_NSSA_LSA
)))
1760 if (t5
->data
->id
.s_addr
!= t7
->data
->id
.s_addr
)
1763 if (t5
->data
->ls_seqnum
!= t7
->data
->ls_seqnum
)
1764 return LSA_REFRESH_FORCE
;
1766 if (e5
->mask
.s_addr
!= e7
->mask
.s_addr
)
1767 return LSA_REFRESH_FORCE
;
1769 if (e5
->e
[0].fwd_addr
.s_addr
!= e7
->e
[0].fwd_addr
.s_addr
)
1770 return LSA_REFRESH_FORCE
;
1772 if (e5
->e
[0].route_tag
!= e7
->e
[0].route_tag
)
1773 return LSA_REFRESH_FORCE
;
1775 if (GET_METRIC (e5
->e
[0].metric
) != GET_METRIC (e7
->e
[0].metric
))
1776 return LSA_REFRESH_FORCE
;
1778 return LSA_REFRESH_IF_CHANGED
;
1781 /* Originate Translated Type-5 for supplied Type-7 NSSA LSA */
1783 ospf_translated_nssa_originate (struct ospf
*ospf
, struct ospf_lsa
*type7
)
1785 struct ospf_lsa
*new;
1786 struct as_external_lsa
*extnew
;
1788 /* we cant use ospf_external_lsa_originate() as we need to set
1789 * the OSPF_LSA_LOCAL_XLT flag, must originate by hand
1792 if ( (new = ospf_lsa_translated_nssa_new (ospf
, type7
)) == NULL
)
1794 if (IS_DEBUG_OSPF_NSSA
)
1795 zlog_debug ("ospf_translated_nssa_originate(): Could not translate "
1796 "Type-7, Id %s, to Type-5",
1797 inet_ntoa (type7
->data
->id
));
1801 extnew
= (struct as_external_lsa
*)new;
1803 if (IS_DEBUG_OSPF_NSSA
)
1805 zlog_debug ("ospf_translated_nssa_originate(): "
1806 "translated Type 7, installed:");
1807 ospf_lsa_header_dump (new->data
);
1808 zlog_debug (" Network mask: %d",ip_masklen (extnew
->mask
));
1809 zlog_debug (" Forward addr: %s", inet_ntoa (extnew
->e
[0].fwd_addr
));
1812 if ( (new = ospf_lsa_install (ospf
, NULL
, new)) == NULL
)
1814 if (IS_DEBUG_OSPF_NSSA
);
1815 zlog_debug ("ospf_lsa_translated_nssa_originate(): "
1816 "Could not install LSA "
1817 "id %s", inet_ntoa (type7
->data
->id
));
1821 ospf
->lsa_originate_count
++;
1822 ospf_flood_through_as (ospf
, NULL
, new);
1827 /* Refresh Translated from NSSA AS-external-LSA. */
1829 ospf_translated_nssa_refresh (struct ospf
*ospf
, struct ospf_lsa
*type7
,
1830 struct ospf_lsa
*type5
)
1832 struct ospf_lsa
*new = NULL
;
1834 /* Sanity checks. */
1835 assert (type7
|| type5
);
1837 assert (type7
->data
);
1839 assert (type5
->data
);
1840 assert (ospf
->anyNSSA
);
1842 /* get required data according to what has been given */
1843 if (type7
&& type5
== NULL
)
1845 /* find the translated Type-5 for this Type-7 */
1846 struct as_external_lsa
*ext
= (struct as_external_lsa
*)(type7
->data
);
1847 struct prefix_ipv4 p
=
1849 .prefix
= type7
->data
->id
,
1850 .prefixlen
= ip_masklen (ext
->mask
),
1854 type5
= ospf_external_info_find_lsa (ospf
, &p
);
1856 else if (type5
&& type7
== NULL
)
1858 /* find the type-7 from which supplied type-5 was translated,
1859 * ie find first type-7 with same LSA Id.
1861 struct listnode
*ln
, *lnn
;
1862 struct route_node
*rn
;
1863 struct ospf_lsa
*lsa
;
1864 struct ospf_area
*area
;
1866 for (ALL_LIST_ELEMENTS (ospf
->areas
, ln
, lnn
, area
))
1868 if (area
->external_routing
!= OSPF_AREA_NSSA
1872 LSDB_LOOP (NSSA_LSDB(area
), rn
, lsa
)
1874 if (lsa
->data
->id
.s_addr
== type5
->data
->id
.s_addr
)
1883 /* do we have type7? */
1886 if (IS_DEBUG_OSPF_NSSA
)
1887 zlog_debug ("ospf_translated_nssa_refresh(): no Type-7 found for "
1889 inet_ntoa (type7
->data
->id
));
1893 /* do we have valid translated type5? */
1894 if (type5
== NULL
|| !CHECK_FLAG (type5
->flags
, OSPF_LSA_LOCAL_XLT
) )
1896 if (IS_DEBUG_OSPF_NSSA
)
1897 zlog_debug ("ospf_translated_nssa_refresh(): No translated Type-5 "
1898 "found for Type-7 with Id %s",
1899 inet_ntoa (type7
->data
->id
));
1903 /* Delete LSA from neighbor retransmit-list. */
1904 ospf_ls_retransmit_delete_nbr_as (ospf
, type5
);
1906 /* create new translated LSA */
1907 if ( (new = ospf_lsa_translated_nssa_new (ospf
, type7
)) == NULL
)
1909 if (IS_DEBUG_OSPF_NSSA
)
1910 zlog_debug ("ospf_translated_nssa_refresh(): Could not translate "
1911 "Type-7 for %s to Type-5",
1912 inet_ntoa (type7
->data
->id
));
1916 if ( !(new = ospf_lsa_install (ospf
, NULL
, new)) )
1918 if (IS_DEBUG_OSPF_NSSA
)
1919 zlog_debug ("ospf_translated_nssa_refresh(): Could not install "
1920 "translated LSA, Id %s",
1921 inet_ntoa (new->data
->id
));
1925 /* Flood LSA through area. */
1926 ospf_flood_through_as (ospf
, NULL
, new);
1932 is_prefix_default (struct prefix_ipv4
*p
)
1934 struct prefix_ipv4 q
;
1937 q
.prefix
.s_addr
= 0;
1940 return prefix_same ((struct prefix
*) p
, (struct prefix
*) &q
);
1943 /* Originate an AS-external-LSA, install and flood. */
1945 ospf_external_lsa_originate (struct ospf
*ospf
, struct external_info
*ei
)
1947 struct ospf_lsa
*new;
1949 /* Added for NSSA project....
1951 External LSAs are originated in ASBRs as usual, but for NSSA systems.
1952 there is the global Type-5 LSDB and a Type-7 LSDB installed for
1953 every area. The Type-7's are flooded to every IR and every ABR; We
1954 install the Type-5 LSDB so that the normal "refresh" code operates
1955 as usual, and flag them as not used during ASE calculations. The
1956 Type-7 LSDB is used for calculations. Each Type-7 has a Forwarding
1957 Address of non-zero.
1959 If an ABR is the elected NSSA translator, following SPF and during
1960 the ABR task it will translate all the scanned Type-7's, with P-bit
1961 ON and not-self generated, and translate to Type-5's throughout the
1964 A difference in operation depends whether this ASBR is an ABR
1965 or not. If not an ABR, the P-bit is ON, to indicate that any
1966 elected NSSA-ABR can perform its translation.
1968 If an ABR, the P-bit is OFF; No ABR will perform translation and
1969 this ASBR will flood the Type-5 LSA as usual.
1971 For the case where this ASBR is not an ABR, the ASE calculations
1972 are based on the Type-5 LSDB; The Type-7 LSDB exists just to
1973 demonstrate to the user that there are LSA's that belong to any
1976 Finally, it just so happens that when the ABR is translating every
1977 Type-7 into Type-5, it installs it into the Type-5 LSDB as an
1978 approved Type-5 (translated from Type-7); at the end of translation
1979 if any Translated Type-5's remain unapproved, then they must be
1980 flushed from the AS.
1984 /* Check the AS-external-LSA should be originated. */
1985 if (!ospf_redistribute_check (ospf
, ei
, NULL
))
1988 /* Create new AS-external-LSA instance. */
1989 if ((new = ospf_external_lsa_new (ospf
, ei
, NULL
)) == NULL
)
1991 if (IS_DEBUG_OSPF_EVENT
)
1992 zlog_debug ("LSA[Type5:%s]: Could not originate AS-external-LSA",
1993 inet_ntoa (ei
->p
.prefix
));
1997 /* Install newly created LSA into Type-5 LSDB, lock = 1. */
1998 ospf_lsa_install (ospf
, NULL
, new);
2000 /* Update LSA origination count. */
2001 ospf
->lsa_originate_count
++;
2003 /* Flooding new LSA. only to AS (non-NSSA/STUB) */
2004 ospf_flood_through_as (ospf
, NULL
, new);
2006 /* If there is any attached NSSA, do special handling */
2007 if (ospf
->anyNSSA
&&
2008 /* stay away from translated LSAs! */
2009 !(CHECK_FLAG (new->flags
, OSPF_LSA_LOCAL_XLT
)))
2010 ospf_install_flood_nssa (ospf
, new, ei
); /* Install/Flood Type-7 to all NSSAs */
2012 /* Debug logging. */
2013 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
2015 zlog_debug ("LSA[Type%d:%s]: Originate AS-external-LSA %p",
2016 new->data
->type
, inet_ntoa (new->data
->id
), new);
2017 ospf_lsa_header_dump (new->data
);
2023 /* Originate AS-external-LSA from external info with initial flag. */
2025 ospf_external_lsa_originate_timer (struct thread
*thread
)
2027 struct ospf
*ospf
= THREAD_ARG (thread
);
2028 struct route_node
*rn
;
2029 struct external_info
*ei
;
2030 struct route_table
*rt
;
2031 int type
= THREAD_VAL (thread
);
2033 ospf
->t_external_lsa
= NULL
;
2035 /* Originate As-external-LSA from all type of distribute source. */
2036 if ((rt
= EXTERNAL_INFO (type
)))
2037 for (rn
= route_top (rt
); rn
; rn
= route_next (rn
))
2038 if ((ei
= rn
->info
) != NULL
)
2039 if (!is_prefix_default ((struct prefix_ipv4
*)&ei
->p
))
2040 if (!ospf_external_lsa_originate (ospf
, ei
))
2041 zlog_warn ("LSA: AS-external-LSA was not originated.");
2046 static struct external_info
*
2047 ospf_default_external_info (struct ospf
*ospf
)
2050 struct route_node
*rn
;
2051 struct prefix_ipv4 p
;
2054 p
.prefix
.s_addr
= 0;
2057 /* First, lookup redistributed default route. */
2058 for (type
= 0; type
<= ZEBRA_ROUTE_MAX
; type
++)
2059 if (EXTERNAL_INFO (type
) && type
!= ZEBRA_ROUTE_OSPF
)
2061 rn
= route_node_lookup (EXTERNAL_INFO (type
), (struct prefix
*) &p
);
2064 route_unlock_node (rn
);
2066 if (ospf_redistribute_check (ospf
, rn
->info
, NULL
))
2075 ospf_default_originate_timer (struct thread
*thread
)
2078 struct prefix_ipv4 p
;
2079 struct in_addr nexthop
;
2080 struct external_info
*ei
;
2083 ospf
= ospf_lookup ();
2085 /* Get originate flags. */
2086 origin
= THREAD_ARG (thread
);
2089 p
.prefix
.s_addr
= 0;
2092 if (*origin
== DEFAULT_ORIGINATE_ALWAYS
)
2094 /* If there is no default route via redistribute,
2095 then originate AS-external-LSA with nexthop 0 (self). */
2097 ospf_external_info_add (DEFAULT_ROUTE
, p
, 0, nexthop
);
2100 if ((ei
= ospf_default_external_info (ospf
)))
2101 ospf_external_lsa_originate (ospf
, ei
);
2106 /* Flush any NSSA LSAs for given prefix */
2108 ospf_nssa_lsa_flush (struct ospf
*ospf
, struct prefix_ipv4
*p
)
2110 struct listnode
*node
, *nnode
;
2111 struct ospf_lsa
*lsa
;
2112 struct ospf_area
*area
;
2114 for (ALL_LIST_ELEMENTS (ospf
->areas
, node
, nnode
, area
))
2116 if (area
->external_routing
== OSPF_AREA_NSSA
)
2118 if (!(lsa
= ospf_lsa_lookup (area
, OSPF_AS_NSSA_LSA
, p
->prefix
,
2121 if (IS_DEBUG_OSPF (lsa
, LSA_FLOODING
))
2122 zlog_debug ("LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
2123 inet_ntoa (p
->prefix
), p
->prefixlen
);
2126 ospf_ls_retransmit_delete_nbr_area (area
, lsa
);
2127 if (!IS_LSA_MAXAGE (lsa
))
2129 ospf_refresher_unregister_lsa (ospf
, lsa
);
2130 ospf_lsa_flush_area (lsa
, area
);
2136 /* Flush an AS-external-LSA from LSDB and routing domain. */
2138 ospf_external_lsa_flush (struct ospf
*ospf
,
2139 u_char type
, struct prefix_ipv4
*p
,
2140 unsigned int ifindex
/*, struct in_addr nexthop */)
2142 struct ospf_lsa
*lsa
;
2144 if (IS_DEBUG_OSPF (lsa
, LSA_FLOODING
))
2145 zlog_debug ("LSA: Flushing AS-external-LSA %s/%d",
2146 inet_ntoa (p
->prefix
), p
->prefixlen
);
2148 /* First lookup LSA from LSDB. */
2149 if (!(lsa
= ospf_external_info_find_lsa (ospf
, p
)))
2151 if (IS_DEBUG_OSPF (lsa
, LSA_FLOODING
))
2152 zlog_debug ("LSA: There is no such AS-external-LSA %s/%d in LSDB",
2153 inet_ntoa (p
->prefix
), p
->prefixlen
);
2157 /* If LSA is selforiginated, not a translated LSA, and there is
2158 * NSSA area, flush Type-7 LSA's at first.
2160 if (IS_LSA_SELF(lsa
) && (ospf
->anyNSSA
)
2161 && !(CHECK_FLAG (lsa
->flags
, OSPF_LSA_LOCAL_XLT
)))
2162 ospf_nssa_lsa_flush (ospf
, p
);
2164 /* Sweep LSA from Link State Retransmit List. */
2165 ospf_ls_retransmit_delete_nbr_as (ospf
, lsa
);
2167 /* There must be no self-originated LSA in rtrs_external. */
2169 /* Remove External route from Zebra. */
2170 ospf_zebra_delete ((struct prefix_ipv4
*) p
, &nexthop
);
2173 if (!IS_LSA_MAXAGE (lsa
))
2175 /* Unregister LSA from Refresh queue. */
2176 ospf_refresher_unregister_lsa (ospf
, lsa
);
2178 /* Flush AS-external-LSA through AS. */
2179 ospf_lsa_flush_as (ospf
, lsa
);
2182 if (IS_DEBUG_OSPF (lsa
, LSA_FLOODING
))
2183 zlog_debug ("ospf_external_lsa_flush(): stop");
2187 ospf_external_lsa_refresh_default (struct ospf
*ospf
)
2189 struct prefix_ipv4 p
;
2190 struct external_info
*ei
;
2191 struct ospf_lsa
*lsa
;
2195 p
.prefix
.s_addr
= 0;
2197 ei
= ospf_default_external_info (ospf
);
2198 lsa
= ospf_external_info_find_lsa (ospf
, &p
);
2204 if (IS_DEBUG_OSPF_EVENT
)
2205 zlog_debug ("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p", lsa
);
2206 ospf_external_lsa_refresh (ospf
, lsa
, ei
, LSA_REFRESH_FORCE
);
2210 if (IS_DEBUG_OSPF_EVENT
)
2211 zlog_debug ("LSA[Type5:0.0.0.0]: Originate AS-external-LSA");
2212 ospf_external_lsa_originate (ospf
, ei
);
2219 if (IS_DEBUG_OSPF_EVENT
)
2220 zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA");
2221 ospf_lsa_flush_as (ospf
, lsa
);
2227 ospf_external_lsa_refresh_type (struct ospf
*ospf
, u_char type
, int force
)
2229 struct route_node
*rn
;
2230 struct external_info
*ei
;
2232 if (type
!= DEFAULT_ROUTE
)
2233 if (EXTERNAL_INFO(type
))
2234 /* Refresh each redistributed AS-external-LSAs. */
2235 for (rn
= route_top (EXTERNAL_INFO (type
)); rn
; rn
= route_next (rn
))
2236 if ((ei
= rn
->info
))
2237 if (!is_prefix_default (&ei
->p
))
2239 struct ospf_lsa
*lsa
;
2241 if ((lsa
= ospf_external_info_find_lsa (ospf
, &ei
->p
)))
2242 ospf_external_lsa_refresh (ospf
, lsa
, ei
, force
);
2244 ospf_external_lsa_originate (ospf
, ei
);
2248 /* Refresh AS-external-LSA. */
2250 ospf_external_lsa_refresh (struct ospf
*ospf
, struct ospf_lsa
*lsa
,
2251 struct external_info
*ei
, int force
)
2253 struct ospf_lsa
*new;
2256 /* Check the AS-external-LSA should be originated. */
2257 if (!ospf_redistribute_check (ospf
, ei
, &changed
))
2259 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
2260 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed, "
2261 "redist check fail",
2262 lsa
->data
->type
, inet_ntoa (lsa
->data
->id
));
2263 ospf_external_lsa_flush (ospf
, ei
->type
, &ei
->p
,
2264 ei
->ifindex
/*, ei->nexthop */);
2268 if (!changed
&& !force
)
2270 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
2271 zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",
2272 lsa
->data
->type
, inet_ntoa (lsa
->data
->id
));
2276 /* Delete LSA from neighbor retransmit-list. */
2277 ospf_ls_retransmit_delete_nbr_as (ospf
, lsa
);
2279 /* Unregister AS-external-LSA from refresh-list. */
2280 ospf_refresher_unregister_lsa (ospf
, lsa
);
2282 new = ospf_external_lsa_new (ospf
, ei
, &lsa
->data
->id
);
2286 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
2287 zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa
->data
->type
,
2288 inet_ntoa (lsa
->data
->id
));
2292 new->data
->ls_seqnum
= lsa_seqnum_increment (lsa
);
2294 /* Record timestamp. */
2295 gettimeofday (&new->tv_orig
, NULL
);
2297 /* Re-calculate checksum. */
2298 ospf_lsa_checksum (new->data
);
2300 ospf_lsa_install (ospf
, NULL
, new); /* As type-5. */
2302 /* Flood LSA through AS. */
2303 ospf_flood_through_as (ospf
, NULL
, new);
2305 /* If any attached NSSA, install as Type-7, flood to all NSSA Areas */
2306 if (ospf
->anyNSSA
&& !(CHECK_FLAG (new->flags
, OSPF_LSA_LOCAL_XLT
)))
2307 ospf_install_flood_nssa (ospf
, new, ei
); /* Install/Flood per new rules */
2309 /* Register self-originated LSA to refresh queue.
2310 * Translated LSAs should not be registered, but refreshed upon
2311 * refresh of the Type-7
2313 if ( !CHECK_FLAG (new->flags
, OSPF_LSA_LOCAL_XLT
) )
2314 ospf_refresher_register_lsa (ospf
, new);
2316 /* Debug logging. */
2317 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
2319 zlog_debug ("LSA[Type%d:%s]: AS-external-LSA refresh",
2320 new->data
->type
, inet_ntoa (new->data
->id
));
2321 ospf_lsa_header_dump (new->data
);
2328 /* LSA installation functions. */
2330 /* Install router-LSA to an area. */
2331 static struct ospf_lsa
*
2332 ospf_router_lsa_install (struct ospf
*ospf
,
2333 struct ospf_lsa
*new, int rt_recalc
)
2335 struct ospf_area
*area
= new->area
;
2337 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2338 The entire routing table must be recalculated, starting with
2339 the shortest path calculations for each area (not just the
2340 area whose link-state database has changed).
2343 ospf_spf_calculate_schedule (ospf
);
2345 if (IS_LSA_SELF (new))
2347 /* Set router-LSA refresh timer. */
2348 OSPF_TIMER_OFF (area
->t_router_lsa_self
);
2349 OSPF_AREA_TIMER_ON (area
->t_router_lsa_self
,
2350 ospf_router_lsa_timer
, OSPF_LS_REFRESH_TIME
);
2352 /* Set self-originated router-LSA. */
2353 ospf_lsa_unlock (area
->router_lsa_self
);
2354 area
->router_lsa_self
= ospf_lsa_lock (new);
2356 if (IS_DEBUG_OSPF (lsa
, LSA_INSTALL
))
2357 zlog_debug("LSA[Type%d]: ID %s seq 0x%x is self-originated",
2358 new->data
->type
, inet_ntoa (new->data
->id
),
2359 ntohl(new->data
->ls_seqnum
));
2365 #define OSPF_INTERFACE_TIMER_ON(T,F,V) \
2367 (T) = thread_add_timer (master, (F), oi, (V))
2369 /* Install network-LSA to an area. */
2370 static struct ospf_lsa
*
2371 ospf_network_lsa_install (struct ospf
*ospf
,
2372 struct ospf_interface
*oi
,
2373 struct ospf_lsa
*new,
2377 /* RFC 2328 Section 13.2 Router-LSAs and network-LSAs
2378 The entire routing table must be recalculated, starting with
2379 the shortest path calculations for each area (not just the
2380 area whose link-state database has changed).
2383 ospf_spf_calculate_schedule (ospf
);
2385 /* We supposed that when LSA is originated by us, we pass the int
2386 for which it was originated. If LSA was received by flooding,
2387 the RECEIVED flag is set, so we do not link the LSA to the int. */
2388 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags
, OSPF_LSA_RECEIVED
))
2390 /* Set LSRefresh timer. */
2391 OSPF_TIMER_OFF (oi
->t_network_lsa_self
);
2393 OSPF_INTERFACE_TIMER_ON (oi
->t_network_lsa_self
,
2394 ospf_network_lsa_refresh_timer
,
2395 OSPF_LS_REFRESH_TIME
);
2397 ospf_lsa_unlock (oi
->network_lsa_self
);
2398 oi
->network_lsa_self
= ospf_lsa_lock (new);
2404 /* Install summary-LSA to an area. */
2405 static struct ospf_lsa
*
2406 ospf_summary_lsa_install (struct ospf
*ospf
, struct ospf_lsa
*new,
2409 if (rt_recalc
&& !IS_LSA_SELF (new))
2411 /* RFC 2328 Section 13.2 Summary-LSAs
2412 The best route to the destination described by the summary-
2413 LSA must be recalculated (see Section 16.5). If this
2414 destination is an AS boundary router, it may also be
2415 necessary to re-examine all the AS-external-LSAs.
2419 /* This doesn't exist yet... */
2420 ospf_summary_incremental_update(new); */
2422 ospf_spf_calculate_schedule (ospf
);
2425 if (IS_DEBUG_OSPF (lsa
, LSA_INSTALL
))
2426 zlog_debug ("ospf_summary_lsa_install(): SPF scheduled");
2429 if (IS_LSA_SELF (new))
2430 ospf_refresher_register_lsa (ospf
, new);
2435 /* Install ASBR-summary-LSA to an area. */
2436 static struct ospf_lsa
*
2437 ospf_summary_asbr_lsa_install (struct ospf
*ospf
, struct ospf_lsa
*new,
2440 if (rt_recalc
&& !IS_LSA_SELF (new))
2442 /* RFC 2328 Section 13.2 Summary-LSAs
2443 The best route to the destination described by the summary-
2444 LSA must be recalculated (see Section 16.5). If this
2445 destination is an AS boundary router, it may also be
2446 necessary to re-examine all the AS-external-LSAs.
2449 /* These don't exist yet... */
2450 ospf_summary_incremental_update(new);
2451 /* Isn't this done by the above call?
2452 - RFC 2328 Section 16.5 implies it should be */
2453 /* ospf_ase_calculate_schedule(); */
2455 ospf_spf_calculate_schedule (ospf
);
2459 /* register LSA to refresh-list. */
2460 if (IS_LSA_SELF (new))
2461 ospf_refresher_register_lsa (ospf
, new);
2466 /* Install AS-external-LSA. */
2467 static struct ospf_lsa
*
2468 ospf_external_lsa_install (struct ospf
*ospf
, struct ospf_lsa
*new,
2471 ospf_ase_register_external_lsa (new, ospf
);
2472 /* If LSA is not self-originated, calculate an external route. */
2475 /* RFC 2328 Section 13.2 AS-external-LSAs
2476 The best route to the destination described by the AS-
2477 external-LSA must be recalculated (see Section 16.6).
2480 if (!IS_LSA_SELF (new))
2481 ospf_ase_incremental_update (ospf
, new);
2484 if (new->data
->type
== OSPF_AS_NSSA_LSA
)
2486 /* There is no point to register selforiginate Type-7 LSA for
2487 * refreshing. We rely on refreshing Type-5 LSA's
2489 if (IS_LSA_SELF (new))
2493 /* Try refresh type-5 translated LSA for this LSA, if one exists.
2494 * New translations will be taken care of by the abr_task.
2496 ospf_translated_nssa_refresh (ospf
, new, NULL
);
2500 /* Register self-originated LSA to refresh queue.
2501 * Leave Translated LSAs alone if NSSA is enabled
2503 if (IS_LSA_SELF (new) && !CHECK_FLAG (new->flags
, OSPF_LSA_LOCAL_XLT
) )
2504 ospf_refresher_register_lsa (ospf
, new);
2510 ospf_discard_from_db (struct ospf
*ospf
,
2511 struct ospf_lsdb
*lsdb
, struct ospf_lsa
*lsa
)
2513 struct ospf_lsa
*old
;
2515 old
= ospf_lsdb_lookup (lsdb
, lsa
);
2520 if (old
->refresh_list
>= 0)
2521 ospf_refresher_unregister_lsa (ospf
, old
);
2523 switch (old
->data
->type
)
2525 case OSPF_AS_EXTERNAL_LSA
:
2526 ospf_ase_unregister_external_lsa (old
, ospf
);
2527 ospf_ls_retransmit_delete_nbr_as (ospf
, old
);
2529 #ifdef HAVE_OPAQUE_LSA
2530 case OSPF_OPAQUE_AS_LSA
:
2531 ospf_ls_retransmit_delete_nbr_as (ospf
, old
);
2533 #endif /* HAVE_OPAQUE_LSA */
2534 case OSPF_AS_NSSA_LSA
:
2535 ospf_ls_retransmit_delete_nbr_area (old
->area
, old
);
2536 ospf_ase_unregister_external_lsa (old
, ospf
);
2539 ospf_ls_retransmit_delete_nbr_area (old
->area
, old
);
2543 ospf_lsa_maxage_delete (ospf
, old
);
2544 ospf_lsa_discard (old
);
2548 ospf_lsa_install (struct ospf
*ospf
, struct ospf_interface
*oi
,
2549 struct ospf_lsa
*lsa
)
2551 struct ospf_lsa
*new = NULL
;
2552 struct ospf_lsa
*old
= NULL
;
2553 struct ospf_lsdb
*lsdb
= NULL
;
2557 switch (lsa
->data
->type
)
2560 case OSPF_AS_NSSA_LSA
:
2562 lsdb
= lsa
->area
->lsdb
;
2566 case OSPF_AS_EXTERNAL_LSA
:
2567 #ifdef HAVE_OPAQUE_LSA
2568 case OSPF_OPAQUE_AS_LSA
:
2569 #endif /* HAVE_OPAQUE_LSA */
2573 lsdb
= lsa
->area
->lsdb
;
2579 /* RFC 2328 13.2. Installing LSAs in the database
2581 Installing a new LSA in the database, either as the result of
2582 flooding or a newly self-originated LSA, may cause the OSPF
2583 routing table structure to be recalculated. The contents of the
2584 new LSA should be compared to the old instance, if present. If
2585 there is no difference, there is no need to recalculate the
2586 routing table. When comparing an LSA to its previous instance,
2587 the following are all considered to be differences in contents:
2589 o The LSA's Options field has changed.
2591 o One of the LSA instances has LS age set to MaxAge, and
2594 o The length field in the LSA header has changed.
2596 o The body of the LSA (i.e., anything outside the 20-byte
2597 LSA header) has changed. Note that this excludes changes
2598 in LS Sequence Number and LS Checksum.
2601 /* Look up old LSA and determine if any SPF calculation or incremental
2603 old
= ospf_lsdb_lookup (lsdb
, lsa
);
2605 /* Do comparision and record if recalc needed. */
2607 if ( old
== NULL
|| ospf_lsa_different(old
, lsa
))
2611 Sequence number check (Section 14.1 of rfc 2328)
2612 "Premature aging is used when it is time for a self-originated
2613 LSA's sequence number field to wrap. At this point, the current
2614 LSA instance (having LS sequence number MaxSequenceNumber) must
2615 be prematurely aged and flushed from the routing domain before a
2616 new instance with sequence number equal to InitialSequenceNumber
2617 can be originated. "
2620 if (ntohl(lsa
->data
->ls_seqnum
) - 1 == htonl(OSPF_MAX_SEQUENCE_NUMBER
))
2622 if (ospf_lsa_is_self_originated(ospf
, lsa
))
2624 lsa
->data
->ls_seqnum
= htonl(OSPF_MAX_SEQUENCE_NUMBER
);
2626 if (!IS_LSA_MAXAGE(lsa
))
2627 lsa
->flags
|= OSPF_LSA_PREMATURE_AGE
;
2628 lsa
->data
->ls_age
= htons (OSPF_LSA_MAXAGE
);
2630 if (IS_DEBUG_OSPF (lsa
, LSA_REFRESH
))
2632 zlog_debug ("ospf_lsa_install() Premature Aging "
2633 "lsa 0x%lx", (u_long
)lsa
);
2634 ospf_lsa_header_dump (lsa
->data
);
2639 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
2641 zlog_debug ("ospf_lsa_install() got an lsa with seq 0x80000000 "
2642 "that was not self originated. Ignoring\n");
2643 ospf_lsa_header_dump (lsa
->data
);
2649 /* discard old LSA from LSDB */
2651 ospf_discard_from_db (ospf
, lsdb
, lsa
);
2653 /* Calculate Checksum if self-originated?. */
2654 if (IS_LSA_SELF (lsa
))
2655 ospf_lsa_checksum (lsa
->data
);
2657 /* Insert LSA to LSDB. */
2658 ospf_lsdb_add (lsdb
, lsa
);
2661 /* Do LSA specific installation process. */
2662 switch (lsa
->data
->type
)
2664 case OSPF_ROUTER_LSA
:
2665 new = ospf_router_lsa_install (ospf
, lsa
, rt_recalc
);
2667 case OSPF_NETWORK_LSA
:
2669 new = ospf_network_lsa_install (ospf
, oi
, lsa
, rt_recalc
);
2671 case OSPF_SUMMARY_LSA
:
2672 new = ospf_summary_lsa_install (ospf
, lsa
, rt_recalc
);
2674 case OSPF_ASBR_SUMMARY_LSA
:
2675 new = ospf_summary_asbr_lsa_install (ospf
, lsa
, rt_recalc
);
2677 case OSPF_AS_EXTERNAL_LSA
:
2678 new = ospf_external_lsa_install (ospf
, lsa
, rt_recalc
);
2680 #ifdef HAVE_OPAQUE_LSA
2681 case OSPF_OPAQUE_LINK_LSA
:
2682 if (IS_LSA_SELF (lsa
))
2683 lsa
->oi
= oi
; /* Specify outgoing ospf-interface for this LSA. */
2685 ; /* Incoming "oi" for this LSA has set at LSUpd reception. */
2687 case OSPF_OPAQUE_AREA_LSA
:
2688 case OSPF_OPAQUE_AS_LSA
:
2689 new = ospf_opaque_lsa_install (lsa
, rt_recalc
);
2691 #endif /* HAVE_OPAQUE_LSA */
2692 case OSPF_AS_NSSA_LSA
:
2693 new = ospf_external_lsa_install (ospf
, lsa
, rt_recalc
);
2694 default: /* type-6,8,9....nothing special */
2699 return new; /* Installation failed, cannot proceed further -- endo. */
2702 if (IS_DEBUG_OSPF (lsa
, LSA_INSTALL
))
2704 char area_str
[INET_ADDRSTRLEN
];
2706 switch (lsa
->data
->type
)
2708 case OSPF_AS_EXTERNAL_LSA
:
2709 #ifdef HAVE_OPAQUE_LSA
2710 case OSPF_OPAQUE_AS_LSA
:
2711 #endif /* HAVE_OPAQUE_LSA */
2712 case OSPF_AS_NSSA_LSA
:
2713 zlog_debug ("LSA[%s]: Install %s",
2715 LOOKUP (ospf_lsa_type_msg
, new->data
->type
));
2718 strcpy (area_str
, inet_ntoa (new->area
->area_id
));
2719 zlog_debug ("LSA[%s]: Install %s to Area %s",
2721 LOOKUP (ospf_lsa_type_msg
, new->data
->type
), area_str
);
2727 If received LSA' ls_age is MaxAge, or lsa is being prematurely aged
2728 (it's getting flushed out of the area), set LSA on MaxAge LSA list.
2730 if ((lsa
->flags
& OSPF_LSA_PREMATURE_AGE
) ||
2731 (IS_LSA_MAXAGE (new) && !IS_LSA_SELF (new)))
2733 if (IS_DEBUG_OSPF (lsa
, LSA_INSTALL
))
2734 zlog_debug ("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
2736 inet_ntoa (new->data
->id
),
2738 ospf_lsa_maxage (ospf
, lsa
);
2746 ospf_check_nbr_status (struct ospf
*ospf
)
2748 struct listnode
*node
, *nnode
;
2749 struct ospf_interface
*oi
;
2751 for (ALL_LIST_ELEMENTS (ospf
->oiflist
, node
, nnode
, oi
))
2753 struct route_node
*rn
;
2754 struct ospf_neighbor
*nbr
;
2756 if (ospf_if_is_enable (oi
))
2757 for (rn
= route_top (oi
->nbrs
); rn
; rn
= route_next (rn
))
2758 if ((nbr
= rn
->info
) != NULL
)
2759 if (nbr
->state
== NSM_Exchange
|| nbr
->state
== NSM_Loading
)
2761 route_unlock_node (rn
);
2770 #ifdef ORIGINAL_CODING
2771 /* This function flood the maxaged LSA to DR. */
2773 ospf_maxage_flood (struct ospf_lsa
*lsa
)
2775 switch (lsa
->data
->type
)
2777 case OSPF_ROUTER_LSA
:
2778 case OSPF_NETWORK_LSA
:
2779 case OSPF_SUMMARY_LSA
:
2780 case OSPF_ASBR_SUMMARY_LSA
:
2781 case OSPF_AS_NSSA_LSA
:
2782 #ifdef HAVE_OPAQUE_LSA
2783 case OSPF_OPAQUE_LINK_LSA
:
2784 case OSPF_OPAQUE_AREA_LSA
:
2785 #endif /* HAVE_OPAQUE_LSA */
2786 ospf_flood_through_area (lsa
->area
, NULL
, lsa
);
2788 case OSPF_AS_EXTERNAL_LSA
:
2789 #ifdef HAVE_OPAQUE_LSA
2790 case OSPF_OPAQUE_AS_LSA
:
2791 #endif /* HAVE_OPAQUE_LSA */
2792 ospf_flood_through_as (NULL
, lsa
);
2798 #endif /* ORIGINAL_CODING */
2801 ospf_maxage_lsa_remover (struct thread
*thread
)
2803 struct ospf
*ospf
= THREAD_ARG (thread
);
2804 struct ospf_lsa
*lsa
;
2805 struct listnode
*node
, *nnode
;
2808 ospf
->t_maxage
= NULL
;
2810 if (IS_DEBUG_OSPF (lsa
, LSA_FLOODING
))
2811 zlog_debug ("LSA[MaxAge]: remover Start");
2813 reschedule
= !ospf_check_nbr_status (ospf
);
2816 for (ALL_LIST_ELEMENTS (ospf
->maxage_lsa
, node
, nnode
, lsa
))
2818 if (lsa
->retransmit_counter
> 0)
2824 /* Remove LSA from the LSDB */
2825 if (CHECK_FLAG (lsa
->flags
, OSPF_LSA_SELF
))
2826 if (IS_DEBUG_OSPF (lsa
, LSA_FLOODING
))
2827 zlog_debug ("LSA[Type%d:%s]: LSA 0x%lx is self-oririnated: ",
2828 lsa
->data
->type
, inet_ntoa (lsa
->data
->id
), (u_long
)lsa
);
2830 if (IS_DEBUG_OSPF (lsa
, LSA_FLOODING
))
2831 zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",
2832 lsa
->data
->type
, inet_ntoa (lsa
->data
->id
));
2834 /* Flood max age LSA. */
2835 #ifdef ORIGINAL_CODING
2836 ospf_maxage_flood (lsa
);
2837 #else /* ORIGINAL_CODING */
2838 ospf_flood_through (ospf
, NULL
, lsa
);
2839 #endif /* ORIGINAL_CODING */
2841 if (lsa
->flags
& OSPF_LSA_PREMATURE_AGE
)
2843 if (IS_DEBUG_OSPF (lsa
, LSA_FLOODING
))
2844 zlog_debug ("originating new router lsa for lsa 0x%lx \n",
2846 ospf_router_lsa_originate(lsa
->area
);
2849 /* Remove from lsdb. */
2850 ospf_discard_from_db (ospf
, lsa
->lsdb
, lsa
);
2851 ospf_lsdb_delete (lsa
->lsdb
, lsa
);
2854 /* A MaxAge LSA must be removed immediately from the router's link
2855 state database as soon as both a) it is no longer contained on any
2856 neighbor Link state retransmission lists and b) none of the router's
2857 neighbors are in states Exchange or Loading. */
2859 OSPF_TIMER_ON (ospf
->t_maxage
, ospf_maxage_lsa_remover
, 2);
2865 ospf_lsa_maxage_exist (struct ospf
*ospf
, struct ospf_lsa
*new)
2867 struct listnode
*node
;
2868 struct ospf_lsa
*lsa
;
2870 for (ALL_LIST_ELEMENTS_RO (ospf
->maxage_lsa
, node
, lsa
))
2878 ospf_lsa_maxage_delete (struct ospf
*ospf
, struct ospf_lsa
*lsa
)
2882 if ((n
= listnode_lookup (ospf
->maxage_lsa
, lsa
)))
2884 list_delete_node (ospf
->maxage_lsa
, n
);
2885 ospf_lsa_unlock (lsa
);
2890 ospf_lsa_maxage (struct ospf
*ospf
, struct ospf_lsa
*lsa
)
2892 /* When we saw a MaxAge LSA flooded to us, we put it on the list
2893 and schedule the MaxAge LSA remover. */
2894 if (ospf_lsa_maxage_exist (ospf
, lsa
))
2896 if (IS_DEBUG_OSPF (lsa
, LSA_FLOODING
))
2897 zlog_debug ("LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
2898 lsa
->data
->type
, inet_ntoa (lsa
->data
->id
), lsa
);
2902 listnode_add (ospf
->maxage_lsa
, ospf_lsa_lock (lsa
));
2904 if (IS_DEBUG_OSPF (lsa
, LSA_FLOODING
))
2905 zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa
));
2907 OSPF_TIMER_ON (ospf
->t_maxage
, ospf_maxage_lsa_remover
, 2);
2911 ospf_lsa_maxage_walker_remover (struct ospf
*ospf
, struct ospf_lsa
*lsa
)
2913 /* Stay away from any Local Translated Type-7 LSAs */
2914 if (CHECK_FLAG (lsa
->flags
, OSPF_LSA_LOCAL_XLT
))
2917 if (IS_LSA_MAXAGE (lsa
))
2918 /* Self-originated LSAs should NOT time-out instead,
2919 they're flushed and submitted to the max_age list explicitly. */
2920 if (!ospf_lsa_is_self_originated (ospf
, lsa
))
2922 if (IS_DEBUG_OSPF (lsa
, LSA_FLOODING
))
2923 zlog_debug("LSA[%s]: is MaxAge", dump_lsa_key (lsa
));
2925 switch (lsa
->data
->type
)
2927 #ifdef HAVE_OPAQUE_LSA
2928 case OSPF_OPAQUE_LINK_LSA
:
2929 case OSPF_OPAQUE_AREA_LSA
:
2930 case OSPF_OPAQUE_AS_LSA
:
2932 * As a general rule, whenever network topology has changed
2933 * (due to an LSA removal in this case), routing recalculation
2934 * should be triggered. However, this is not true for opaque
2935 * LSAs. Even if an opaque LSA instance is going to be removed
2936 * from the routing domain, it does not mean a change in network
2937 * topology, and thus, routing recalculation is not needed here.
2940 #endif /* HAVE_OPAQUE_LSA */
2941 case OSPF_AS_EXTERNAL_LSA
:
2942 case OSPF_AS_NSSA_LSA
:
2943 ospf_ase_incremental_update (ospf
, lsa
);
2946 ospf_spf_calculate_schedule (ospf
);
2949 ospf_lsa_maxage (ospf
, lsa
);
2955 /* Periodical check of MaxAge LSA. */
2957 ospf_lsa_maxage_walker (struct thread
*thread
)
2959 struct ospf
*ospf
= THREAD_ARG (thread
);
2960 struct route_node
*rn
;
2961 struct ospf_lsa
*lsa
;
2962 struct ospf_area
*area
;
2963 struct listnode
*node
, *nnode
;
2965 ospf
->t_maxage_walker
= NULL
;
2967 for (ALL_LIST_ELEMENTS (ospf
->areas
, node
, nnode
, area
))
2969 LSDB_LOOP (ROUTER_LSDB (area
), rn
, lsa
)
2970 ospf_lsa_maxage_walker_remover (ospf
, lsa
);
2971 LSDB_LOOP (NETWORK_LSDB (area
), rn
, lsa
)
2972 ospf_lsa_maxage_walker_remover (ospf
, lsa
);
2973 LSDB_LOOP (SUMMARY_LSDB (area
), rn
, lsa
)
2974 ospf_lsa_maxage_walker_remover (ospf
, lsa
);
2975 LSDB_LOOP (ASBR_SUMMARY_LSDB (area
), rn
, lsa
)
2976 ospf_lsa_maxage_walker_remover (ospf
, lsa
);
2977 #ifdef HAVE_OPAQUE_LSA
2978 LSDB_LOOP (OPAQUE_AREA_LSDB (area
), rn
, lsa
)
2979 ospf_lsa_maxage_walker_remover (ospf
, lsa
);
2980 LSDB_LOOP (OPAQUE_LINK_LSDB (area
), rn
, lsa
)
2981 ospf_lsa_maxage_walker_remover (ospf
, lsa
);
2982 #endif /* HAVE_OPAQUE_LSA */
2983 LSDB_LOOP (NSSA_LSDB (area
), rn
, lsa
)
2984 ospf_lsa_maxage_walker_remover (ospf
, lsa
);
2987 /* for AS-external-LSAs. */
2990 LSDB_LOOP (EXTERNAL_LSDB (ospf
), rn
, lsa
)
2991 ospf_lsa_maxage_walker_remover (ospf
, lsa
);
2992 #ifdef HAVE_OPAQUE_LSA
2993 LSDB_LOOP (OPAQUE_AS_LSDB (ospf
), rn
, lsa
)
2994 ospf_lsa_maxage_walker_remover (ospf
, lsa
);
2995 #endif /* HAVE_OPAQUE_LSA */
2998 OSPF_TIMER_ON (ospf
->t_maxage_walker
, ospf_lsa_maxage_walker
,
2999 OSPF_LSA_MAXAGE_CHECK_INTERVAL
);
3004 ospf_lsa_lookup_by_prefix (struct ospf_lsdb
*lsdb
, u_char type
,
3005 struct prefix_ipv4
*p
, struct in_addr router_id
)
3007 struct ospf_lsa
*lsa
;
3008 struct in_addr mask
, id
;
3009 struct lsa_header_mask
3011 struct lsa_header header
;
3012 struct in_addr mask
;
3015 lsa
= ospf_lsdb_lookup_by_id (lsdb
, type
, p
->prefix
, router_id
);
3019 masklen2ip (p
->prefixlen
, &mask
);
3021 hmask
= (struct lsa_header_mask
*) lsa
->data
;
3023 if (mask
.s_addr
!= hmask
->mask
.s_addr
)
3025 id
.s_addr
= p
->prefix
.s_addr
| (~mask
.s_addr
);
3026 lsa
= ospf_lsdb_lookup_by_id (lsdb
, type
, id
, router_id
);
3035 ospf_lsa_lookup (struct ospf_area
*area
, u_int32_t type
,
3036 struct in_addr id
, struct in_addr adv_router
)
3038 struct ospf
*ospf
= ospf_lookup();
3043 case OSPF_ROUTER_LSA
:
3044 case OSPF_NETWORK_LSA
:
3045 case OSPF_SUMMARY_LSA
:
3046 case OSPF_ASBR_SUMMARY_LSA
:
3047 case OSPF_AS_NSSA_LSA
:
3048 #ifdef HAVE_OPAQUE_LSA
3049 case OSPF_OPAQUE_LINK_LSA
:
3050 case OSPF_OPAQUE_AREA_LSA
:
3051 #endif /* HAVE_OPAQUE_LSA */
3052 return ospf_lsdb_lookup_by_id (area
->lsdb
, type
, id
, adv_router
);
3054 case OSPF_AS_EXTERNAL_LSA
:
3055 #ifdef HAVE_OPAQUE_LSA
3056 case OSPF_OPAQUE_AS_LSA
:
3057 #endif /* HAVE_OPAQUE_LSA */
3058 return ospf_lsdb_lookup_by_id (ospf
->lsdb
, type
, id
, adv_router
);
3068 ospf_lsa_lookup_by_id (struct ospf_area
*area
, u_int32_t type
,
3071 struct ospf_lsa
*lsa
;
3072 struct route_node
*rn
;
3076 case OSPF_ROUTER_LSA
:
3077 return ospf_lsdb_lookup_by_id (area
->lsdb
, type
, id
, id
);
3079 case OSPF_NETWORK_LSA
:
3080 for (rn
= route_top (NETWORK_LSDB (area
)); rn
; rn
= route_next (rn
))
3081 if ((lsa
= rn
->info
))
3082 if (IPV4_ADDR_SAME (&lsa
->data
->id
, &id
))
3084 route_unlock_node (rn
);
3088 case OSPF_SUMMARY_LSA
:
3089 case OSPF_ASBR_SUMMARY_LSA
:
3090 /* Currently not used. */
3092 return ospf_lsdb_lookup_by_id (area
->lsdb
, type
, id
, id
);
3094 case OSPF_AS_EXTERNAL_LSA
:
3095 case OSPF_AS_NSSA_LSA
:
3096 #ifdef HAVE_OPAQUE_LSA
3097 case OSPF_OPAQUE_LINK_LSA
:
3098 case OSPF_OPAQUE_AREA_LSA
:
3099 case OSPF_OPAQUE_AS_LSA
:
3100 /* Currently not used. */
3102 #endif /* HAVE_OPAQUE_LSA */
3111 ospf_lsa_lookup_by_header (struct ospf_area
*area
, struct lsa_header
*lsah
)
3113 struct ospf_lsa
*match
;
3115 #ifdef HAVE_OPAQUE_LSA
3117 * Strictly speaking, the LSA-ID field for Opaque-LSAs (type-9/10/11)
3118 * is redefined to have two subfields; opaque-type and opaque-id.
3119 * However, it is harmless to treat the two sub fields together, as if
3120 * they two were forming a unique LSA-ID.
3122 #endif /* HAVE_OPAQUE_LSA */
3124 match
= ospf_lsa_lookup (area
, lsah
->type
, lsah
->id
, lsah
->adv_router
);
3127 if (IS_DEBUG_OSPF (lsa
, LSA
) == OSPF_DEBUG_LSA
)
3128 zlog_debug ("LSA[Type%d:%s]: Lookup by header, NO MATCH",
3129 lsah
->type
, inet_ntoa (lsah
->id
));
3134 /* return +n, l1 is more recent.
3135 return -n, l2 is more recent.
3136 return 0, l1 and l2 is identical. */
3138 ospf_lsa_more_recent (struct ospf_lsa
*l1
, struct ospf_lsa
*l2
)
3143 if (l1
== NULL
&& l2
== NULL
)
3150 /* compare LS sequence number. */
3151 x
= (int) ntohl (l1
->data
->ls_seqnum
);
3152 y
= (int) ntohl (l2
->data
->ls_seqnum
);
3158 /* compare LS checksum. */
3159 r
= ntohs (l1
->data
->checksum
) - ntohs (l2
->data
->checksum
);
3163 /* compare LS age. */
3164 if (IS_LSA_MAXAGE (l1
) && !IS_LSA_MAXAGE (l2
))
3166 else if (!IS_LSA_MAXAGE (l1
) && IS_LSA_MAXAGE (l2
))
3169 /* compare LS age with MaxAgeDiff. */
3170 if (LS_AGE (l1
) - LS_AGE (l2
) > OSPF_LSA_MAXAGE_DIFF
)
3172 else if (LS_AGE (l2
) - LS_AGE (l1
) > OSPF_LSA_MAXAGE_DIFF
)
3175 /* LSAs are identical. */
3179 /* If two LSAs are different, return 1, otherwise return 0. */
3181 ospf_lsa_different (struct ospf_lsa
*l1
, struct ospf_lsa
*l2
)
3189 if (l1
->data
->options
!= l2
->data
->options
)
3192 if (IS_LSA_MAXAGE (l1
) && !IS_LSA_MAXAGE (l2
))
3195 if (IS_LSA_MAXAGE (l2
) && !IS_LSA_MAXAGE (l1
))
3198 if (l1
->data
->length
!= l2
->data
->length
)
3201 if (l1
->data
->length
== 0)
3204 assert ( ntohs(l1
->data
->length
) > OSPF_LSA_HEADER_SIZE
);
3206 p1
= (char *) l1
->data
;
3207 p2
= (char *) l2
->data
;
3209 if (memcmp (p1
+ OSPF_LSA_HEADER_SIZE
, p2
+ OSPF_LSA_HEADER_SIZE
,
3210 ntohs( l1
->data
->length
) - OSPF_LSA_HEADER_SIZE
) != 0)
3216 #ifdef ORIGINAL_CODING
3218 ospf_lsa_flush_self_originated (struct ospf_neighbor
*nbr
,
3219 struct ospf_lsa
*self
,
3220 struct ospf_lsa
*new)
3224 /* Adjust LS Sequence Number. */
3225 seqnum
= ntohl (new->data
->ls_seqnum
) + 1;
3226 self
->data
->ls_seqnum
= htonl (seqnum
);
3228 /* Recalculate LSA checksum. */
3229 ospf_lsa_checksum (self
->data
);
3231 /* Reflooding LSA. */
3232 /* RFC2328 Section 13.3
3233 On non-broadcast networks, separate Link State Update
3234 packets must be sent, as unicasts, to each adjacent neighbor
3235 (i.e., those in state Exchange or greater). The destination
3236 IP addresses for these packets are the neighbors' IP
3238 if (nbr
->oi
->type
== OSPF_IFTYPE_NBMA
)
3240 struct route_node
*rn
;
3241 struct ospf_neighbor
*onbr
;
3243 for (rn
= route_top (nbr
->oi
->nbrs
); rn
; rn
= route_next (rn
))
3244 if ((onbr
= rn
->info
) != NULL
)
3245 if (onbr
!= nbr
->oi
->nbr_self
&& onbr
->status
>= NSM_Exchange
)
3246 ospf_ls_upd_send_lsa (onbr
, self
, OSPF_SEND_PACKET_DIRECT
);
3249 ospf_ls_upd_send_lsa (nbr
, self
, OSPF_SEND_PACKET_INDIRECT
);
3251 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
3252 zlog_debug ("LSA[Type%d:%s]: Flush self-originated LSA",
3253 self
->data
->type
, inet_ntoa (self
->data
->id
));
3255 #else /* ORIGINAL_CODING */
3257 ospf_lsa_flush_schedule (struct ospf
*ospf
, struct ospf_lsa
*lsa
)
3259 if (lsa
== NULL
|| !IS_LSA_SELF (lsa
))
3262 if (IS_DEBUG_OSPF_EVENT
)
3263 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa
->data
->type
, inet_ntoa (lsa
->data
->id
));
3265 /* Force given lsa's age to MaxAge. */
3266 lsa
->data
->ls_age
= htons (OSPF_LSA_MAXAGE
);
3268 switch (lsa
->data
->type
)
3270 #ifdef HAVE_OPAQUE_LSA
3271 case OSPF_OPAQUE_LINK_LSA
:
3272 case OSPF_OPAQUE_AREA_LSA
:
3273 case OSPF_OPAQUE_AS_LSA
:
3274 ospf_opaque_lsa_refresh (lsa
);
3276 #endif /* HAVE_OPAQUE_LSA */
3278 ospf_lsa_maxage (ospf
, lsa
);
3286 ospf_flush_self_originated_lsas_now (struct ospf
*ospf
)
3288 struct listnode
*node
, *nnode
;
3289 struct listnode
*node2
, *nnode2
;
3290 struct ospf_area
*area
;
3291 struct ospf_interface
*oi
;
3292 struct ospf_lsa
*lsa
;
3293 struct route_node
*rn
;
3294 int need_to_flush_ase
= 0;
3296 for (ALL_LIST_ELEMENTS (ospf
->areas
, node
, nnode
, area
))
3298 if ((lsa
= area
->router_lsa_self
) != NULL
)
3300 if (IS_DEBUG_OSPF_EVENT
)
3301 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa
->data
->type
, inet_ntoa (lsa
->data
->id
));
3303 ospf_lsa_flush_area (lsa
, area
);
3304 ospf_lsa_unlock (area
->router_lsa_self
);
3305 area
->router_lsa_self
= NULL
;
3306 OSPF_TIMER_OFF (area
->t_router_lsa_self
);
3309 for (ALL_LIST_ELEMENTS (area
->oiflist
, node2
, nnode2
, oi
))
3311 if ((lsa
= oi
->network_lsa_self
) != NULL
3312 && oi
->state
== ISM_DR
3313 && oi
->full_nbrs
> 0)
3315 if (IS_DEBUG_OSPF_EVENT
)
3316 zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa
->data
->type
, inet_ntoa (lsa
->data
->id
));
3318 ospf_lsa_flush_area (oi
->network_lsa_self
, area
);
3319 ospf_lsa_unlock (oi
->network_lsa_self
);
3320 oi
->network_lsa_self
= NULL
;
3321 OSPF_TIMER_OFF (oi
->t_network_lsa_self
);
3324 if (oi
->type
!= OSPF_IFTYPE_VIRTUALLINK
3325 && area
->external_routing
== OSPF_AREA_DEFAULT
)
3326 need_to_flush_ase
= 1;
3329 LSDB_LOOP (SUMMARY_LSDB (area
), rn
, lsa
)
3330 ospf_lsa_flush_schedule (ospf
, lsa
);
3331 LSDB_LOOP (ASBR_SUMMARY_LSDB (area
), rn
, lsa
)
3332 ospf_lsa_flush_schedule (ospf
, lsa
);
3333 #ifdef HAVE_OPAQUE_LSA
3334 LSDB_LOOP (OPAQUE_LINK_LSDB (area
), rn
, lsa
)
3335 ospf_lsa_flush_schedule (ospf
, lsa
);
3336 LSDB_LOOP (OPAQUE_AREA_LSDB (area
), rn
, lsa
)
3337 ospf_lsa_flush_schedule (ospf
, lsa
);
3338 #endif /* HAVE_OPAQUE_LSA */
3341 if (need_to_flush_ase
)
3343 LSDB_LOOP (EXTERNAL_LSDB (ospf
), rn
, lsa
)
3344 ospf_lsa_flush_schedule (ospf
, lsa
);
3345 #ifdef HAVE_OPAQUE_LSA
3346 LSDB_LOOP (OPAQUE_AS_LSDB (ospf
), rn
, lsa
)
3347 ospf_lsa_flush_schedule (ospf
, lsa
);
3348 #endif /* HAVE_OPAQUE_LSA */
3352 * Make sure that the MaxAge LSA remover is executed immediately,
3353 * without conflicting to other threads.
3355 if (ospf
->t_maxage
!= NULL
)
3357 OSPF_TIMER_OFF (ospf
->t_maxage
);
3358 thread_execute (master
, ospf_maxage_lsa_remover
, ospf
, 0);
3363 #endif /* ORIGINAL_CODING */
3365 /* If there is self-originated LSA, then return 1, otherwise return 0. */
3366 /* An interface-independent version of ospf_lsa_is_self_originated */
3368 ospf_lsa_is_self_originated (struct ospf
*ospf
, struct ospf_lsa
*lsa
)
3370 struct listnode
*node
;
3371 struct ospf_interface
*oi
;
3373 /* This LSA is already checked. */
3374 if (CHECK_FLAG (lsa
->flags
, OSPF_LSA_SELF_CHECKED
))
3375 return CHECK_FLAG (lsa
->flags
, OSPF_LSA_SELF
);
3377 /* Make sure LSA is self-checked. */
3378 SET_FLAG (lsa
->flags
, OSPF_LSA_SELF_CHECKED
);
3380 /* AdvRouter and Router ID is the same. */
3381 if (IPV4_ADDR_SAME (&lsa
->data
->adv_router
, &ospf
->router_id
))
3382 SET_FLAG (lsa
->flags
, OSPF_LSA_SELF
);
3384 /* LSA is router-LSA. */
3385 else if (lsa
->data
->type
== OSPF_ROUTER_LSA
&&
3386 IPV4_ADDR_SAME (&lsa
->data
->id
, &ospf
->router_id
))
3387 SET_FLAG (lsa
->flags
, OSPF_LSA_SELF
);
3389 /* LSA is network-LSA. Compare Link ID with all interfaces. */
3390 else if (lsa
->data
->type
== OSPF_NETWORK_LSA
)
3391 for (ALL_LIST_ELEMENTS_RO (ospf
->oiflist
, node
, oi
))
3393 /* Ignore virtual link. */
3394 if (oi
->type
!= OSPF_IFTYPE_VIRTUALLINK
)
3395 if (oi
->address
->family
== AF_INET
)
3396 if (IPV4_ADDR_SAME (&lsa
->data
->id
, &oi
->address
->u
.prefix4
))
3398 /* to make it easier later */
3399 SET_FLAG (lsa
->flags
, OSPF_LSA_SELF
);
3400 return CHECK_FLAG (lsa
->flags
, OSPF_LSA_SELF
);
3404 return CHECK_FLAG (lsa
->flags
, OSPF_LSA_SELF
);
3407 /* Get unique Link State ID. */
3409 ospf_lsa_unique_id (struct ospf
*ospf
,
3410 struct ospf_lsdb
*lsdb
, u_char type
, struct prefix_ipv4
*p
)
3412 struct ospf_lsa
*lsa
;
3413 struct in_addr mask
, id
;
3417 /* Check existence of LSA instance. */
3418 lsa
= ospf_lsdb_lookup_by_id (lsdb
, type
, id
, ospf
->router_id
);
3421 struct as_external_lsa
*al
= (struct as_external_lsa
*) lsa
->data
;
3422 if (ip_masklen (al
->mask
) == p
->prefixlen
)
3424 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
3425 zlog_debug ("ospf_lsa_unique_id(): "
3426 "Can't get Link State ID for %s/%d",
3427 inet_ntoa (p
->prefix
), p
->prefixlen
);
3428 /* id.s_addr = 0; */
3429 id
.s_addr
= 0xffffffff;
3432 /* Masklen differs, then apply wildcard mask to Link State ID. */
3435 masklen2ip (p
->prefixlen
, &mask
);
3437 id
.s_addr
= p
->prefix
.s_addr
| (~mask
.s_addr
);
3438 lsa
= ospf_lsdb_lookup_by_id (ospf
->lsdb
, type
,
3439 id
, ospf
->router_id
);
3442 if (IS_DEBUG_OSPF (lsa
, LSA_GENERATE
))
3443 zlog_debug ("ospf_lsa_unique_id(): "
3444 "Can't get Link State ID for %s/%d",
3445 inet_ntoa (p
->prefix
), p
->prefixlen
);
3446 /* id.s_addr = 0; */
3447 id
.s_addr
= 0xffffffff;
3457 #define LSA_ACTION_ORIGN_RTR 1
3458 #define LSA_ACTION_ORIGN_NET 2
3459 #define LSA_ACTION_FLOOD_AREA 3
3460 #define LSA_ACTION_FLOOD_AS 4
3461 #define LSA_ACTION_FLUSH_AREA 5
3462 #define LSA_ACTION_FLUSH_AS 6
3467 struct ospf_area
*area
;
3468 struct ospf_interface
*oi
;
3469 struct ospf_lsa
*lsa
;
3473 ospf_lsa_action (struct thread
*t
)
3475 struct lsa_action
*data
;
3478 ospf
= ospf_lookup ();
3480 data
= THREAD_ARG (t
);
3482 if (IS_DEBUG_OSPF (lsa
, LSA
) == OSPF_DEBUG_LSA
)
3483 zlog_debug ("LSA[Action]: Performing scheduled LSA action: %d",
3486 switch (data
->action
)
3488 case LSA_ACTION_ORIGN_RTR
:
3489 ospf_router_lsa_refresh (data
->area
->router_lsa_self
);
3491 case LSA_ACTION_ORIGN_NET
:
3492 ospf_network_lsa_originate (data
->oi
);
3494 case LSA_ACTION_FLOOD_AREA
:
3495 ospf_flood_through_area (data
->area
, NULL
, data
->lsa
);
3497 case LSA_ACTION_FLOOD_AS
:
3498 ospf_flood_through_as (ospf
, NULL
, data
->lsa
);
3500 case LSA_ACTION_FLUSH_AREA
:
3501 ospf_lsa_flush_area (data
->lsa
, data
->area
);
3503 case LSA_ACTION_FLUSH_AS
:
3504 ospf_lsa_flush_as (ospf
, data
->lsa
);
3508 ospf_lsa_unlock (data
->lsa
);
3509 XFREE (MTYPE_OSPF_MESSAGE
, data
);
3514 ospf_schedule_lsa_flood_area (struct ospf_area
*area
, struct ospf_lsa
*lsa
)
3516 struct lsa_action
*data
;
3518 data
= XMALLOC (MTYPE_OSPF_MESSAGE
, sizeof (struct lsa_action
));
3519 memset (data
, 0, sizeof (struct lsa_action
));
3521 data
->action
= LSA_ACTION_FLOOD_AREA
;
3523 data
->lsa
= ospf_lsa_lock (lsa
);
3525 thread_add_event (master
, ospf_lsa_action
, data
, 0);
3529 ospf_schedule_lsa_flush_area (struct ospf_area
*area
, struct ospf_lsa
*lsa
)
3531 struct lsa_action
*data
;
3533 data
= XMALLOC (MTYPE_OSPF_MESSAGE
, sizeof (struct lsa_action
));
3534 memset (data
, 0, sizeof (struct lsa_action
));
3536 data
->action
= LSA_ACTION_FLUSH_AREA
;
3538 data
->lsa
= ospf_lsa_lock (lsa
);
3540 thread_add_event (master
, ospf_lsa_action
, data
, 0);
3544 /* LSA Refreshment functions. */
3546 ospf_lsa_refresh (struct ospf
*ospf
, struct ospf_lsa
*lsa
)
3548 struct external_info
*ei
;
3549 assert (CHECK_FLAG (lsa
->flags
, OSPF_LSA_SELF
));
3551 switch (lsa
->data
->type
)
3553 /* Router and Network LSAs are processed differently. */
3554 case OSPF_ROUTER_LSA
:
3555 case OSPF_NETWORK_LSA
:
3557 case OSPF_SUMMARY_LSA
:
3558 ospf_summary_lsa_refresh (ospf
, lsa
);
3560 case OSPF_ASBR_SUMMARY_LSA
:
3561 ospf_summary_asbr_lsa_refresh (ospf
, lsa
);
3563 case OSPF_AS_EXTERNAL_LSA
:
3564 /* Translated from NSSA Type-5s are refreshed when
3565 * from refresh of Type-7 - do not refresh these directly.
3567 if (CHECK_FLAG (lsa
->flags
, OSPF_LSA_LOCAL_XLT
))
3569 ei
= ospf_external_info_check (lsa
);
3571 ospf_external_lsa_refresh (ospf
, lsa
, ei
, LSA_REFRESH_FORCE
);
3573 ospf_lsa_flush_as (ospf
, lsa
);
3575 #ifdef HAVE_OPAQUE_LSA
3576 case OSPF_OPAQUE_LINK_LSA
:
3577 case OSPF_OPAQUE_AREA_LSA
:
3578 case OSPF_OPAQUE_AS_LSA
:
3579 ospf_opaque_lsa_refresh (lsa
);
3581 #endif /* HAVE_OPAQUE_LSA */
3588 ospf_refresher_register_lsa (struct ospf
*ospf
, struct ospf_lsa
*lsa
)
3590 u_int16_t index
, current_index
;
3592 assert (CHECK_FLAG (lsa
->flags
, OSPF_LSA_SELF
));
3594 if (lsa
->refresh_list
< 0)
3598 if (LS_AGE (lsa
) == 0 &&
3599 ntohl (lsa
->data
->ls_seqnum
) == OSPF_INITIAL_SEQUENCE_NUMBER
)
3600 /* Randomize first update by OSPF_LS_REFRESH_SHIFT factor */
3601 delay
= OSPF_LS_REFRESH_SHIFT
+ (random () % OSPF_LS_REFRESH_TIME
);
3603 /* Randomize another updates by +-OSPF_LS_REFRESH_JITTER factor */
3604 delay
= OSPF_LS_REFRESH_TIME
- LS_AGE (lsa
) - OSPF_LS_REFRESH_JITTER
3605 + (random () % (2*OSPF_LS_REFRESH_JITTER
));
3610 current_index
= ospf
->lsa_refresh_queue
.index
+
3611 (time (NULL
) - ospf
->lsa_refresher_started
)/OSPF_LSA_REFRESHER_GRANULARITY
;
3613 index
= (current_index
+ delay
/OSPF_LSA_REFRESHER_GRANULARITY
)
3614 % (OSPF_LSA_REFRESHER_SLOTS
);
3616 if (IS_DEBUG_OSPF (lsa
, LSA_REFRESH
))
3617 zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d",
3618 inet_ntoa (lsa
->data
->id
), LS_AGE (lsa
), index
);
3619 if (!ospf
->lsa_refresh_queue
.qs
[index
])
3620 ospf
->lsa_refresh_queue
.qs
[index
] = list_new ();
3621 listnode_add (ospf
->lsa_refresh_queue
.qs
[index
], ospf_lsa_lock (lsa
));
3622 lsa
->refresh_list
= index
;
3623 if (IS_DEBUG_OSPF (lsa
, LSA_REFRESH
))
3624 zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): "
3625 "setting refresh_list on lsa %p (slod %d)",
3626 inet_ntoa (lsa
->data
->id
), lsa
, index
);
3631 ospf_refresher_unregister_lsa (struct ospf
*ospf
, struct ospf_lsa
*lsa
)
3633 assert (CHECK_FLAG (lsa
->flags
, OSPF_LSA_SELF
));
3634 if (lsa
->refresh_list
>= 0)
3636 struct list
*refresh_list
= ospf
->lsa_refresh_queue
.qs
[lsa
->refresh_list
];
3637 listnode_delete (refresh_list
, lsa
);
3638 if (!listcount (refresh_list
))
3640 list_free (refresh_list
);
3641 ospf
->lsa_refresh_queue
.qs
[lsa
->refresh_list
] = NULL
;
3643 ospf_lsa_unlock (lsa
);
3644 lsa
->refresh_list
= -1;
3649 ospf_lsa_refresh_walker (struct thread
*t
)
3651 struct list
*refresh_list
;
3652 struct listnode
*node
, *nnode
;
3653 struct ospf
*ospf
= THREAD_ARG (t
);
3654 struct ospf_lsa
*lsa
;
3656 struct list
*lsa_to_refresh
= list_new ();
3658 if (IS_DEBUG_OSPF (lsa
, LSA_REFRESH
))
3659 zlog_debug ("LSA[Refresh]:ospf_lsa_refresh_walker(): start");
3662 i
= ospf
->lsa_refresh_queue
.index
;
3664 /* Note: if clock has jumped backwards, then time change could be negative,
3665 so we are careful to cast the expression to unsigned before taking
3667 ospf
->lsa_refresh_queue
.index
=
3668 ((unsigned long)(ospf
->lsa_refresh_queue
.index
+
3669 (time (NULL
) - ospf
->lsa_refresher_started
) /
3670 OSPF_LSA_REFRESHER_GRANULARITY
)) % OSPF_LSA_REFRESHER_SLOTS
;
3672 if (IS_DEBUG_OSPF (lsa
, LSA_REFRESH
))
3673 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d",
3674 ospf
->lsa_refresh_queue
.index
);
3676 for (;i
!= ospf
->lsa_refresh_queue
.index
;
3677 i
= (i
+ 1) % OSPF_LSA_REFRESHER_SLOTS
)
3679 if (IS_DEBUG_OSPF (lsa
, LSA_REFRESH
))
3680 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): "
3681 "refresh index %d", i
);
3683 refresh_list
= ospf
->lsa_refresh_queue
.qs
[i
];
3685 ospf
->lsa_refresh_queue
.qs
[i
] = NULL
;
3689 for (ALL_LIST_ELEMENTS (refresh_list
, node
, nnode
, lsa
))
3691 if (IS_DEBUG_OSPF (lsa
, LSA_REFRESH
))
3692 zlog_debug ("LSA[Refresh:%s]: ospf_lsa_refresh_walker(): "
3693 "refresh lsa %p (slot %d)",
3694 inet_ntoa (lsa
->data
->id
), lsa
, i
);
3696 list_delete_node (refresh_list
, node
);
3697 ospf_lsa_unlock (lsa
);
3698 lsa
->refresh_list
= -1;
3699 listnode_add (lsa_to_refresh
, lsa
);
3701 list_free (refresh_list
);
3705 ospf
->t_lsa_refresher
= thread_add_timer (master
, ospf_lsa_refresh_walker
,
3706 ospf
, ospf
->lsa_refresh_interval
);
3707 ospf
->lsa_refresher_started
= time (NULL
);
3709 for (ALL_LIST_ELEMENTS (lsa_to_refresh
, node
, nnode
, lsa
))
3710 ospf_lsa_refresh (ospf
, lsa
);
3712 list_delete (lsa_to_refresh
);
3714 if (IS_DEBUG_OSPF (lsa
, LSA_REFRESH
))
3715 zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): end");