2 * Copyright (C) 2003 Yasuhiro Ohara
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "ospf6_proto.h"
31 #include "ospf6_lsa.h"
32 #include "ospf6_lsdb.h"
33 #include "ospf6_message.h"
34 #include "ospf6_route.h"
35 #include "ospf6_spf.h"
37 #include "ospf6_top.h"
38 #include "ospf6_area.h"
39 #include "ospf6_interface.h"
40 #include "ospf6_neighbor.h"
42 #include "ospf6_flood.h"
44 unsigned char conf_debug_ospf6_flooding
;
47 ospf6_get_scoped_lsdb (struct ospf6_lsa
*lsa
)
49 struct ospf6_lsdb
*lsdb
= NULL
;
50 switch (OSPF6_LSA_SCOPE (lsa
->header
->type
))
52 case OSPF6_SCOPE_LINKLOCAL
:
53 lsdb
= OSPF6_INTERFACE (lsa
->lsdb
->data
)->lsdb
;
55 case OSPF6_SCOPE_AREA
:
56 lsdb
= OSPF6_AREA (lsa
->lsdb
->data
)->lsdb
;
59 lsdb
= OSPF6_PROCESS (lsa
->lsdb
->data
)->lsdb
;
69 ospf6_get_scoped_lsdb_self (struct ospf6_lsa
*lsa
)
71 struct ospf6_lsdb
*lsdb_self
= NULL
;
72 switch (OSPF6_LSA_SCOPE (lsa
->header
->type
))
74 case OSPF6_SCOPE_LINKLOCAL
:
75 lsdb_self
= OSPF6_INTERFACE (lsa
->lsdb
->data
)->lsdb_self
;
77 case OSPF6_SCOPE_AREA
:
78 lsdb_self
= OSPF6_AREA (lsa
->lsdb
->data
)->lsdb_self
;
81 lsdb_self
= OSPF6_PROCESS (lsa
->lsdb
->data
)->lsdb_self
;
91 ospf6_lsa_originate (struct ospf6_lsa
*lsa
)
93 struct ospf6_lsa
*old
;
94 struct ospf6_lsdb
*lsdb_self
;
96 /* find previous LSA */
97 old
= ospf6_lsdb_lookup (lsa
->header
->type
, lsa
->header
->id
,
98 lsa
->header
->adv_router
, lsa
->lsdb
);
100 /* if the new LSA does not differ from previous,
101 suppress this update of the LSA */
102 if (old
&& ! OSPF6_LSA_IS_DIFFER (lsa
, old
))
104 if (IS_OSPF6_DEBUG_ORIGINATE_TYPE (lsa
->header
->type
))
105 zlog_debug ("Suppress updating LSA: %s", lsa
->name
);
106 ospf6_lsa_delete (lsa
);
110 /* store it in the LSDB for self-originated LSAs */
111 lsdb_self
= ospf6_get_scoped_lsdb_self (lsa
);
112 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), lsdb_self
);
115 thread_add_timer(master
, ospf6_lsa_refresh
, lsa
, OSPF_LS_REFRESH_TIME
,
118 if (IS_OSPF6_DEBUG_LSA_TYPE (lsa
->header
->type
) ||
119 IS_OSPF6_DEBUG_ORIGINATE_TYPE (lsa
->header
->type
))
121 zlog_debug ("LSA Originate:");
122 ospf6_lsa_header_print (lsa
);
125 ospf6_install_lsa (lsa
);
126 ospf6_flood (NULL
, lsa
);
130 ospf6_lsa_originate_process (struct ospf6_lsa
*lsa
,
131 struct ospf6
*process
)
133 lsa
->lsdb
= process
->lsdb
;
134 ospf6_lsa_originate (lsa
);
138 ospf6_lsa_originate_area (struct ospf6_lsa
*lsa
,
139 struct ospf6_area
*oa
)
141 lsa
->lsdb
= oa
->lsdb
;
142 ospf6_lsa_originate (lsa
);
146 ospf6_lsa_originate_interface (struct ospf6_lsa
*lsa
,
147 struct ospf6_interface
*oi
)
149 lsa
->lsdb
= oi
->lsdb
;
150 ospf6_lsa_originate (lsa
);
154 ospf6_lsa_purge (struct ospf6_lsa
*lsa
)
156 struct ospf6_lsa
*self
;
157 struct ospf6_lsdb
*lsdb_self
;
159 /* remove it from the LSDB for self-originated LSAs */
160 lsdb_self
= ospf6_get_scoped_lsdb_self (lsa
);
161 self
= ospf6_lsdb_lookup (lsa
->header
->type
, lsa
->header
->id
,
162 lsa
->header
->adv_router
, lsdb_self
);
165 THREAD_OFF (self
->expire
);
166 THREAD_OFF (self
->refresh
);
167 ospf6_lsdb_remove (self
, lsdb_self
);
170 ospf6_lsa_premature_aging (lsa
);
175 ospf6_increment_retrans_count (struct ospf6_lsa
*lsa
)
177 /* The LSA must be the original one (see the description
178 in ospf6_decrement_retrans_count () below) */
179 lsa
->retrans_count
++;
183 ospf6_decrement_retrans_count (struct ospf6_lsa
*lsa
)
185 struct ospf6_lsdb
*lsdb
;
186 struct ospf6_lsa
*orig
;
188 /* The LSA must be on the retrans-list of a neighbor. It means
189 the "lsa" is a copied one, and we have to decrement the
190 retransmission count of the original one (instead of this "lsa"'s).
191 In order to find the original LSA, first we have to find
192 appropriate LSDB that have the original LSA. */
193 lsdb
= ospf6_get_scoped_lsdb (lsa
);
195 /* Find the original LSA of which the retrans_count should be decremented */
196 orig
= ospf6_lsdb_lookup (lsa
->header
->type
, lsa
->header
->id
,
197 lsa
->header
->adv_router
, lsdb
);
200 orig
->retrans_count
--;
201 assert (orig
->retrans_count
>= 0);
205 /* RFC2328 section 13.2 Installing LSAs in the database */
207 ospf6_install_lsa (struct ospf6_lsa
*lsa
)
210 struct ospf6_lsa
*old
;
212 if (IS_OSPF6_DEBUG_LSA_TYPE (lsa
->header
->type
) ||
213 IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa
->header
->type
))
214 zlog_debug ("Install LSA: %s", lsa
->name
);
216 /* Remove the old instance from all neighbors' Link state
217 retransmission list (RFC2328 13.2 last paragraph) */
218 old
= ospf6_lsdb_lookup (lsa
->header
->type
, lsa
->header
->id
,
219 lsa
->header
->adv_router
, lsa
->lsdb
);
222 THREAD_OFF (old
->expire
);
223 THREAD_OFF (old
->refresh
);
224 ospf6_flood_clear (old
);
228 if (! OSPF6_LSA_IS_MAXAGE (lsa
)) {
230 thread_add_timer(master
, ospf6_lsa_expire
, lsa
, OSPF_LSA_MAXAGE
+ lsa
->birth
.tv_sec
- now
.tv_sec
,
236 if (OSPF6_LSA_IS_SEQWRAP(lsa
) &&
237 ! (CHECK_FLAG(lsa
->flag
,OSPF6_LSA_SEQWRAPPED
) &&
238 lsa
->header
->seqnum
== htonl(OSPF_MAX_SEQUENCE_NUMBER
)))
240 if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa
->header
->type
))
241 zlog_debug("lsa install wrapping: sequence 0x%x",
242 ntohl(lsa
->header
->seqnum
));
243 SET_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
);
244 /* in lieu of premature_aging, since we do not want to recreate this lsa
245 * and/or mess with timers etc, we just want to wrap the sequence number
246 * and reflood the lsa before continuing.
247 * NOTE: Flood needs to be called right after this function call, by the
250 lsa
->header
->seqnum
= htonl (OSPF_MAX_SEQUENCE_NUMBER
);
251 lsa
->header
->age
= htons (OSPF_LSA_MAXAGE
);
252 ospf6_lsa_checksum (lsa
->header
);
255 /* actually install */
256 lsa
->installed
= now
;
257 ospf6_lsdb_add (lsa
, lsa
->lsdb
);
262 /* RFC2740 section 3.5.2. Sending Link State Update packets */
263 /* RFC2328 section 13.3 Next step in the flooding procedure */
265 ospf6_flood_interface (struct ospf6_neighbor
*from
,
266 struct ospf6_lsa
*lsa
, struct ospf6_interface
*oi
)
268 struct listnode
*node
, *nnode
;
269 struct ospf6_neighbor
*on
;
270 struct ospf6_lsa
*req
;
271 int retrans_added
= 0;
274 if (IS_OSPF6_DEBUG_FLOODING
||
275 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa
->header
->type
))
278 zlog_debug ("Flooding on %s: %s", oi
->interface
->name
, lsa
->name
);
281 /* (1) For each neighbor */
282 for (ALL_LIST_ELEMENTS (oi
->neighbor_list
, node
, nnode
, on
))
285 zlog_debug ("To neighbor %s", on
->name
);
287 /* (a) if neighbor state < Exchange, examin next */
288 if (on
->state
< OSPF6_NEIGHBOR_EXCHANGE
)
291 zlog_debug ("Neighbor state less than ExChange, next neighbor");
295 /* (b) if neighbor not yet Full, check request-list */
296 if (on
->state
!= OSPF6_NEIGHBOR_FULL
)
299 zlog_debug ("Neighbor not yet Full");
301 req
= ospf6_lsdb_lookup (lsa
->header
->type
, lsa
->header
->id
,
302 lsa
->header
->adv_router
, on
->request_list
);
306 zlog_debug ("Not on request-list for this neighbor");
311 /* If new LSA less recent, examin next neighbor */
312 if (ospf6_lsa_compare (lsa
, req
) > 0)
315 zlog_debug ("Requesting is older, next neighbor");
319 /* If the same instance, delete from request-list and
320 examin next neighbor */
321 if (ospf6_lsa_compare (lsa
, req
) == 0)
324 zlog_debug ("Requesting the same, remove it, next neighbor");
325 if (req
== on
->last_ls_req
)
327 ospf6_lsa_unlock (req
);
328 on
->last_ls_req
= NULL
;
330 ospf6_lsdb_remove (req
, on
->request_list
);
331 ospf6_check_nbr_loading (on
);
335 /* If the new LSA is more recent, delete from request-list */
336 if (ospf6_lsa_compare (lsa
, req
) < 0)
339 zlog_debug ("Received is newer, remove requesting");
340 if (req
== on
->last_ls_req
)
342 ospf6_lsa_unlock (req
);
343 on
->last_ls_req
= NULL
;
345 ospf6_lsdb_remove (req
, on
->request_list
);
346 ospf6_check_nbr_loading (on
);
352 /* (c) If the new LSA was received from this neighbor,
353 examin next neighbor */
357 zlog_debug ("Received is from the neighbor, next neighbor");
361 /* (d) add retrans-list, schedule retransmission */
363 zlog_debug ("Add retrans-list of this neighbor");
364 ospf6_increment_retrans_count (lsa
);
365 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), on
->retrans_list
);
366 thread_add_timer(master
, ospf6_lsupdate_send_neighbor
, on
, on
->ospf6_if
->rxmt_interval
,
367 &on
->thread_send_lsupdate
);
371 /* (2) examin next interface if not added to retrans-list */
372 if (retrans_added
== 0)
375 zlog_debug ("No retransmission scheduled, next interface");
379 /* (3) If the new LSA was received on this interface,
380 and it was from DR or BDR, examin next interface */
381 if (from
&& from
->ospf6_if
== oi
&&
382 (from
->router_id
== oi
->drouter
|| from
->router_id
== oi
->bdrouter
))
385 zlog_debug ("Received is from the I/F's DR or BDR, next interface");
389 /* (4) If the new LSA was received on this interface,
390 and the interface state is BDR, examin next interface */
391 if (from
&& from
->ospf6_if
== oi
)
393 if (oi
->state
== OSPF6_INTERFACE_BDR
)
396 zlog_debug ("Received is from the I/F, itself BDR, next interface");
399 SET_FLAG(lsa
->flag
, OSPF6_LSA_FLOODBACK
);
402 /* (5) flood the LSA out the interface. */
404 zlog_debug ("Schedule flooding for the interface");
405 if ((oi
->type
== OSPF_IFTYPE_BROADCAST
) ||
406 (oi
->type
== OSPF_IFTYPE_POINTOPOINT
))
408 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), oi
->lsupdate_list
);
409 thread_add_event(master
, ospf6_lsupdate_send_interface
, oi
, 0,
410 &oi
->thread_send_lsupdate
);
414 /* reschedule retransmissions to all neighbors */
415 for (ALL_LIST_ELEMENTS (oi
->neighbor_list
, node
, nnode
, on
))
417 THREAD_OFF (on
->thread_send_lsupdate
);
418 on
->thread_send_lsupdate
= NULL
;
419 thread_add_event(master
, ospf6_lsupdate_send_neighbor
, on
, 0,
420 &on
->thread_send_lsupdate
);
426 ospf6_flood_area (struct ospf6_neighbor
*from
,
427 struct ospf6_lsa
*lsa
, struct ospf6_area
*oa
)
429 struct listnode
*node
, *nnode
;
430 struct ospf6_interface
*oi
;
432 for (ALL_LIST_ELEMENTS (oa
->if_list
, node
, nnode
, oi
))
434 if (OSPF6_LSA_SCOPE (lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
&&
435 oi
!= OSPF6_INTERFACE (lsa
->lsdb
->data
))
439 if (OSPF6_LSA_SCOPE (lsa
->header
->type
) == OSPF6_SCOPE_AS
&&
440 ospf6_is_interface_virtual_link (oi
))
444 ospf6_flood_interface (from
, lsa
, oi
);
449 ospf6_flood_process (struct ospf6_neighbor
*from
,
450 struct ospf6_lsa
*lsa
, struct ospf6
*process
)
452 struct listnode
*node
, *nnode
;
453 struct ospf6_area
*oa
;
455 for (ALL_LIST_ELEMENTS (process
->area_list
, node
, nnode
, oa
))
457 if (OSPF6_LSA_SCOPE (lsa
->header
->type
) == OSPF6_SCOPE_AREA
&&
458 oa
!= OSPF6_AREA (lsa
->lsdb
->data
))
460 if (OSPF6_LSA_SCOPE (lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
&&
461 oa
!= OSPF6_INTERFACE (lsa
->lsdb
->data
)->area
)
464 if (ntohs (lsa
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
&&
468 ospf6_flood_area (from
, lsa
, oa
);
473 ospf6_flood (struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
)
475 ospf6_flood_process (from
, lsa
, ospf6
);
479 ospf6_flood_clear_interface (struct ospf6_lsa
*lsa
, struct ospf6_interface
*oi
)
481 struct listnode
*node
, *nnode
;
482 struct ospf6_neighbor
*on
;
483 struct ospf6_lsa
*rem
;
485 for (ALL_LIST_ELEMENTS (oi
->neighbor_list
, node
, nnode
, on
))
487 rem
= ospf6_lsdb_lookup (lsa
->header
->type
, lsa
->header
->id
,
488 lsa
->header
->adv_router
, on
->retrans_list
);
489 if (rem
&& ! ospf6_lsa_compare (rem
, lsa
))
491 if (IS_OSPF6_DEBUG_FLOODING
||
492 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa
->header
->type
))
493 zlog_debug ("Remove %s from retrans_list of %s",
494 rem
->name
, on
->name
);
495 ospf6_decrement_retrans_count (rem
);
496 ospf6_lsdb_remove (rem
, on
->retrans_list
);
502 ospf6_flood_clear_area (struct ospf6_lsa
*lsa
, struct ospf6_area
*oa
)
504 struct listnode
*node
, *nnode
;
505 struct ospf6_interface
*oi
;
507 for (ALL_LIST_ELEMENTS (oa
->if_list
, node
, nnode
, oi
))
509 if (OSPF6_LSA_SCOPE (lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
&&
510 oi
!= OSPF6_INTERFACE (lsa
->lsdb
->data
))
514 if (OSPF6_LSA_SCOPE (lsa
->header
->type
) == OSPF6_SCOPE_AS
&&
515 ospf6_is_interface_virtual_link (oi
))
519 ospf6_flood_clear_interface (lsa
, oi
);
524 ospf6_flood_clear_process (struct ospf6_lsa
*lsa
, struct ospf6
*process
)
526 struct listnode
*node
, *nnode
;
527 struct ospf6_area
*oa
;
529 for (ALL_LIST_ELEMENTS (process
->area_list
, node
, nnode
, oa
))
531 if (OSPF6_LSA_SCOPE (lsa
->header
->type
) == OSPF6_SCOPE_AREA
&&
532 oa
!= OSPF6_AREA (lsa
->lsdb
->data
))
534 if (OSPF6_LSA_SCOPE (lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
&&
535 oa
!= OSPF6_INTERFACE (lsa
->lsdb
->data
)->area
)
538 if (ntohs (lsa
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
&&
542 ospf6_flood_clear_area (lsa
, oa
);
547 ospf6_flood_clear (struct ospf6_lsa
*lsa
)
549 ospf6_flood_clear_process (lsa
, ospf6
);
553 /* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
555 ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa
*lsa
, int ismore_recent
,
556 struct ospf6_neighbor
*from
)
558 struct ospf6_interface
*oi
;
561 if (IS_OSPF6_DEBUG_FLOODING
||
562 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa
->header
->type
))
565 assert (from
&& from
->ospf6_if
);
568 /* LSA is more recent than database copy, but was not flooded
569 back out receiving interface. Delayed acknowledgement sent
570 if advertisement received from Designated Router,
571 otherwide do nothing. */
572 if (ismore_recent
< 0)
574 if (oi
->drouter
== from
->router_id
)
577 zlog_debug ("Delayed acknowledgement (BDR & MoreRecent & from DR)");
578 /* Delayed acknowledgement */
579 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), oi
->lsack_list
);
580 thread_add_timer(master
, ospf6_lsack_send_interface
, oi
, 3,
581 &oi
->thread_send_lsack
);
586 zlog_debug ("No acknowledgement (BDR & MoreRecent & ! from DR)");
591 /* LSA is a duplicate, and was treated as an implied acknowledgement.
592 Delayed acknowledgement sent if advertisement received from
593 Designated Router, otherwise do nothing */
594 if (CHECK_FLAG (lsa
->flag
, OSPF6_LSA_DUPLICATE
) &&
595 CHECK_FLAG (lsa
->flag
, OSPF6_LSA_IMPLIEDACK
))
597 if (oi
->drouter
== from
->router_id
)
600 zlog_debug ("Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
601 /* Delayed acknowledgement */
602 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), oi
->lsack_list
);
603 thread_add_timer(master
, ospf6_lsack_send_interface
, oi
, 3,
604 &oi
->thread_send_lsack
);
609 zlog_debug ("No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
614 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
615 Direct acknowledgement sent */
616 if (CHECK_FLAG (lsa
->flag
, OSPF6_LSA_DUPLICATE
) &&
617 ! CHECK_FLAG (lsa
->flag
, OSPF6_LSA_IMPLIEDACK
))
620 zlog_debug ("Direct acknowledgement (BDR & Duplicate)");
621 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), from
->lsack_list
);
622 thread_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
623 &from
->thread_send_lsack
);
627 /* LSA's LS age is equal to Maxage, and there is no current instance
628 of the LSA in the link state database, and none of router's
629 neighbors are in states Exchange or Loading */
630 /* Direct acknowledgement sent, but this case is handled in
631 early of ospf6_receive_lsa () */
635 ospf6_acknowledge_lsa_allother (struct ospf6_lsa
*lsa
, int ismore_recent
,
636 struct ospf6_neighbor
*from
)
638 struct ospf6_interface
*oi
;
641 if (IS_OSPF6_DEBUG_FLOODING
||
642 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa
->header
->type
))
645 assert (from
&& from
->ospf6_if
);
648 /* LSA has been flood back out receiving interface.
649 No acknowledgement sent. */
650 if (CHECK_FLAG (lsa
->flag
, OSPF6_LSA_FLOODBACK
))
653 zlog_debug ("No acknowledgement (AllOther & FloodBack)");
657 /* LSA is more recent than database copy, but was not flooded
658 back out receiving interface. Delayed acknowledgement sent. */
659 if (ismore_recent
< 0)
662 zlog_debug ("Delayed acknowledgement (AllOther & MoreRecent)");
663 /* Delayed acknowledgement */
664 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), oi
->lsack_list
);
665 thread_add_timer(master
, ospf6_lsack_send_interface
, oi
, 3,
666 &oi
->thread_send_lsack
);
670 /* LSA is a duplicate, and was treated as an implied acknowledgement.
671 No acknowledgement sent. */
672 if (CHECK_FLAG (lsa
->flag
, OSPF6_LSA_DUPLICATE
) &&
673 CHECK_FLAG (lsa
->flag
, OSPF6_LSA_IMPLIEDACK
))
676 zlog_debug ("No acknowledgement (AllOther & Duplicate & ImpliedAck)");
680 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
681 Direct acknowledgement sent */
682 if (CHECK_FLAG (lsa
->flag
, OSPF6_LSA_DUPLICATE
) &&
683 ! CHECK_FLAG (lsa
->flag
, OSPF6_LSA_IMPLIEDACK
))
686 zlog_debug ("Direct acknowledgement (AllOther & Duplicate)");
687 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), from
->lsack_list
);
688 thread_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
689 &from
->thread_send_lsack
);
693 /* LSA's LS age is equal to Maxage, and there is no current instance
694 of the LSA in the link state database, and none of router's
695 neighbors are in states Exchange or Loading */
696 /* Direct acknowledgement sent, but this case is handled in
697 early of ospf6_receive_lsa () */
701 ospf6_acknowledge_lsa (struct ospf6_lsa
*lsa
, int ismore_recent
,
702 struct ospf6_neighbor
*from
)
704 struct ospf6_interface
*oi
;
706 assert (from
&& from
->ospf6_if
);
709 if (oi
->state
== OSPF6_INTERFACE_BDR
)
710 ospf6_acknowledge_lsa_bdrouter (lsa
, ismore_recent
, from
);
712 ospf6_acknowledge_lsa_allother (lsa
, ismore_recent
, from
);
715 /* RFC2328 section 13 (4):
716 if MaxAge LSA and if we have no instance, and no neighbor
717 is in states Exchange or Loading
718 returns 1 if match this case, else returns 0 */
720 ospf6_is_maxage_lsa_drop (struct ospf6_lsa
*lsa
, struct ospf6_neighbor
*from
)
722 struct ospf6_neighbor
*on
;
723 struct ospf6_interface
*oi
;
724 struct ospf6_area
*oa
;
725 struct ospf6
*process
= NULL
;
726 struct listnode
*i
, *j
, *k
;
729 if (! OSPF6_LSA_IS_MAXAGE (lsa
))
732 if (ospf6_lsdb_lookup (lsa
->header
->type
, lsa
->header
->id
,
733 lsa
->header
->adv_router
, lsa
->lsdb
))
736 process
= from
->ospf6_if
->area
->ospf6
;
738 for (ALL_LIST_ELEMENTS_RO (process
->area_list
, i
, oa
))
739 for (ALL_LIST_ELEMENTS_RO (oa
->if_list
, j
, oi
))
740 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, k
, on
))
741 if (on
->state
== OSPF6_NEIGHBOR_EXCHANGE
||
742 on
->state
== OSPF6_NEIGHBOR_LOADING
)
750 /* RFC2328 section 13 The Flooding Procedure */
752 ospf6_receive_lsa (struct ospf6_neighbor
*from
,
753 struct ospf6_lsa_header
*lsa_header
)
755 struct ospf6_lsa
*new = NULL
, *old
= NULL
, *rem
= NULL
;
758 unsigned int time_delta_ms
;
763 /* make lsa structure for received lsa */
764 new = ospf6_lsa_create (lsa_header
);
766 if (IS_OSPF6_DEBUG_FLOODING
||
767 IS_OSPF6_DEBUG_FLOOD_TYPE (new->header
->type
))
770 zlog_debug ("LSA Receive from %s", from
->name
);
771 ospf6_lsa_header_print (new);
774 /* (1) LSA Checksum */
775 if (! ospf6_lsa_checksum_valid (new->header
))
778 zlog_debug ("Wrong LSA Checksum, discard");
779 ospf6_lsa_delete (new);
783 /* (2) Examine the LSA's LS type.
784 RFC2470 3.5.1. Receiving Link State Update packets */
785 if (IS_AREA_STUB (from
->ospf6_if
->area
) &&
786 OSPF6_LSA_SCOPE (new->header
->type
) == OSPF6_SCOPE_AS
)
789 zlog_debug ("AS-External-LSA (or AS-scope LSA) in stub area, discard");
790 ospf6_lsa_delete (new);
794 /* (3) LSA which have reserved scope is discarded
795 RFC2470 3.5.1. Receiving Link State Update packets */
796 /* Flooding scope check. LSAs with unknown scope are discarded here.
797 Set appropriate LSDB for the LSA */
798 switch (OSPF6_LSA_SCOPE (new->header
->type
))
800 case OSPF6_SCOPE_LINKLOCAL
:
801 new->lsdb
= from
->ospf6_if
->lsdb
;
803 case OSPF6_SCOPE_AREA
:
804 new->lsdb
= from
->ospf6_if
->area
->lsdb
;
807 new->lsdb
= from
->ospf6_if
->area
->ospf6
->lsdb
;
811 zlog_debug ("LSA has reserved scope, discard");
812 ospf6_lsa_delete (new);
816 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
817 is in states Exchange or Loading */
818 if (ospf6_is_maxage_lsa_drop (new, from
))
822 zlog_debug ("Drop MaxAge LSA with direct acknowledgement.");
824 /* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */
825 ospf6_lsdb_add (ospf6_lsa_copy (new), from
->lsack_list
);
826 thread_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
827 &from
->thread_send_lsack
);
830 ospf6_lsa_delete (new);
835 /* lookup the same database copy in lsdb */
836 old
= ospf6_lsdb_lookup (new->header
->type
, new->header
->id
,
837 new->header
->adv_router
, new->lsdb
);
840 ismore_recent
= ospf6_lsa_compare (new, old
);
841 if (ntohl (new->header
->seqnum
) == ntohl (old
->header
->seqnum
))
844 zlog_debug ("Received is duplicated LSA");
845 SET_FLAG (new->flag
, OSPF6_LSA_DUPLICATE
);
849 /* if no database copy or received is more recent */
850 if (old
== NULL
|| ismore_recent
< 0)
852 /* in case we have no database copy */
855 /* (a) MinLSArrival check */
858 struct timeval now
, res
;
860 timersub (&now
, &old
->installed
, &res
);
861 time_delta_ms
= (res
.tv_sec
* 1000) + (int)(res
.tv_usec
/1000);
862 if (time_delta_ms
< from
->ospf6_if
->area
->ospf6
->lsa_minarrival
)
865 zlog_debug ("LSA can't be updated within MinLSArrival, %dms < %dms, discard",
866 time_delta_ms
, from
->ospf6_if
->area
->ospf6
->lsa_minarrival
);
867 ospf6_lsa_delete (new);
868 return; /* examin next lsa */
872 monotime(&new->received
);
875 zlog_debug ("Install, Flood, Possibly acknowledge the received LSA");
877 /* Remove older copies of this LSA from retx lists */
879 ospf6_flood_clear (old
);
881 /* (b) immediately flood and (c) remove from all retrans-list */
882 /* Prevent self-originated LSA to be flooded. this is to make
883 reoriginated instance of the LSA not to be rejected by other routers
884 due to MinLSArrival. */
885 if (new->header
->adv_router
!= from
->ospf6_if
->area
->ospf6
->router_id
)
886 ospf6_flood (from
, new);
888 /* (d), installing lsdb, which may cause routing
889 table calculation (replacing database copy) */
890 ospf6_install_lsa (new);
892 if (OSPF6_LSA_IS_MAXAGE (new))
893 ospf6_maxage_remove (from
->ospf6_if
->area
->ospf6
);
895 /* (e) possibly acknowledge */
896 ospf6_acknowledge_lsa (new, ismore_recent
, from
);
898 /* (f) Self Originated LSA, section 13.4 */
899 if (new->header
->adv_router
== from
->ospf6_if
->area
->ospf6
->router_id
)
901 /* Self-originated LSA (newer than ours) is received from
902 another router. We have to make a new instance of the LSA
903 or have to flush this LSA. */
906 zlog_debug ("Newer instance of the self-originated LSA");
907 zlog_debug ("Schedule reorigination");
910 thread_add_event(master
, ospf6_lsa_refresh
, new, 0, &new->refresh
);
916 /* (6) if there is instance on sending neighbor's request list */
917 if (ospf6_lsdb_lookup (new->header
->type
, new->header
->id
,
918 new->header
->adv_router
, from
->request_list
))
920 /* if no database copy, should go above state (5) */
925 zlog_debug ("Received is not newer, on the neighbor's request-list");
926 zlog_debug ("BadLSReq, discard the received LSA");
930 thread_add_event(master
, bad_lsreq
, from
, 0, NULL
);
932 ospf6_lsa_delete (new);
936 /* (7) if neither one is more recent */
937 if (ismore_recent
== 0)
940 zlog_debug ("The same instance as database copy (neither recent)");
942 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack */
943 rem
= ospf6_lsdb_lookup (new->header
->type
, new->header
->id
,
944 new->header
->adv_router
, from
->retrans_list
);
949 zlog_debug ("It is on the neighbor's retrans-list.");
950 zlog_debug ("Treat as an Implied acknowledgement");
952 SET_FLAG (new->flag
, OSPF6_LSA_IMPLIEDACK
);
953 ospf6_decrement_retrans_count (rem
);
954 ospf6_lsdb_remove (rem
, from
->retrans_list
);
958 zlog_debug ("Possibly acknowledge and then discard");
960 /* (b) possibly acknowledge */
961 ospf6_acknowledge_lsa (new, ismore_recent
, from
);
963 ospf6_lsa_delete (new);
967 /* (8) previous database copy is more recent */
971 /* If database copy is in 'Seqnumber Wrapping',
972 simply discard the received LSA */
973 if (OSPF6_LSA_IS_MAXAGE (old
) &&
974 old
->header
->seqnum
== htonl (OSPF_MAX_SEQUENCE_NUMBER
))
978 zlog_debug ("The LSA is in Seqnumber Wrapping");
979 zlog_debug ("MaxAge & MaxSeqNum, discard");
981 ospf6_lsa_delete (new);
985 /* Otherwise, Send database copy of this LSA to this neighbor */
989 zlog_debug ("Database copy is more recent.");
990 zlog_debug ("Send back directly and then discard");
993 /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
995 ospf6_lsdb_add (ospf6_lsa_copy (old
), from
->lsupdate_list
);
996 thread_add_event(master
, ospf6_lsupdate_send_neighbor
, from
, 0,
997 &from
->thread_send_lsupdate
);
998 ospf6_lsa_delete (new);
1006 DEFUN (debug_ospf6_flooding
,
1007 debug_ospf6_flooding_cmd
,
1008 "debug ospf6 flooding",
1011 "Debug OSPFv3 flooding function\n"
1014 OSPF6_DEBUG_FLOODING_ON ();
1018 DEFUN (no_debug_ospf6_flooding
,
1019 no_debug_ospf6_flooding_cmd
,
1020 "no debug ospf6 flooding",
1024 "Debug OSPFv3 flooding function\n"
1027 OSPF6_DEBUG_FLOODING_OFF ();
1032 config_write_ospf6_debug_flood (struct vty
*vty
)
1034 if (IS_OSPF6_DEBUG_FLOODING
)
1035 vty_out (vty
, "debug ospf6 flooding%s", VNL
);
1040 install_element_ospf6_debug_flood (void)
1042 install_element (ENABLE_NODE
, &debug_ospf6_flooding_cmd
);
1043 install_element (ENABLE_NODE
, &no_debug_ospf6_flooding_cmd
);
1044 install_element (CONFIG_NODE
, &debug_ospf6_flooding_cmd
);
1045 install_element (CONFIG_NODE
, &no_debug_ospf6_flooding_cmd
);