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
17 * along with GNU Zebra; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
31 #include "ospf6_proto.h"
32 #include "ospf6_lsa.h"
33 #include "ospf6_lsdb.h"
34 #include "ospf6_message.h"
35 #include "ospf6_route.h"
36 #include "ospf6_spf.h"
38 #include "ospf6_top.h"
39 #include "ospf6_area.h"
40 #include "ospf6_interface.h"
41 #include "ospf6_neighbor.h"
43 #include "ospf6_flood.h"
45 unsigned char conf_debug_ospf6_flooding
;
48 ospf6_get_scoped_lsdb (struct ospf6_lsa
*lsa
)
50 struct ospf6_lsdb
*lsdb
= NULL
;
51 switch (OSPF6_LSA_SCOPE (lsa
->header
->type
))
53 case OSPF6_SCOPE_LINKLOCAL
:
54 lsdb
= OSPF6_INTERFACE (lsa
->lsdb
->data
)->lsdb
;
56 case OSPF6_SCOPE_AREA
:
57 lsdb
= OSPF6_AREA (lsa
->lsdb
->data
)->lsdb
;
60 lsdb
= OSPF6_PROCESS (lsa
->lsdb
->data
)->lsdb
;
70 ospf6_get_scoped_lsdb_self (struct ospf6_lsa
*lsa
)
72 struct ospf6_lsdb
*lsdb_self
= NULL
;
73 switch (OSPF6_LSA_SCOPE (lsa
->header
->type
))
75 case OSPF6_SCOPE_LINKLOCAL
:
76 lsdb_self
= OSPF6_INTERFACE (lsa
->lsdb
->data
)->lsdb_self
;
78 case OSPF6_SCOPE_AREA
:
79 lsdb_self
= OSPF6_AREA (lsa
->lsdb
->data
)->lsdb_self
;
82 lsdb_self
= OSPF6_PROCESS (lsa
->lsdb
->data
)->lsdb_self
;
92 ospf6_lsa_originate (struct ospf6_lsa
*lsa
)
94 struct ospf6_lsa
*old
;
95 struct ospf6_lsdb
*lsdb_self
;
97 /* find previous LSA */
98 old
= ospf6_lsdb_lookup (lsa
->header
->type
, lsa
->header
->id
,
99 lsa
->header
->adv_router
, lsa
->lsdb
);
101 /* if the new LSA does not differ from previous,
102 suppress this update of the LSA */
103 if (old
&& ! OSPF6_LSA_IS_DIFFER (lsa
, old
))
105 if (IS_OSPF6_DEBUG_ORIGINATE_TYPE (lsa
->header
->type
))
106 zlog_debug ("Suppress updating LSA: %s", lsa
->name
);
107 ospf6_lsa_delete (lsa
);
111 /* store it in the LSDB for self-originated LSAs */
112 lsdb_self
= ospf6_get_scoped_lsdb_self (lsa
);
113 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), lsdb_self
);
115 lsa
->refresh
= thread_add_timer (master
, ospf6_lsa_refresh
, lsa
,
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
);
126 ospf6_flood_clear (old
);
127 ospf6_flood (NULL
, lsa
);
128 ospf6_install_lsa (lsa
);
132 ospf6_lsa_originate_process (struct ospf6_lsa
*lsa
,
133 struct ospf6
*process
)
135 lsa
->lsdb
= process
->lsdb
;
136 ospf6_lsa_originate (lsa
);
140 ospf6_lsa_originate_area (struct ospf6_lsa
*lsa
,
141 struct ospf6_area
*oa
)
143 lsa
->lsdb
= oa
->lsdb
;
144 ospf6_lsa_originate (lsa
);
148 ospf6_lsa_originate_interface (struct ospf6_lsa
*lsa
,
149 struct ospf6_interface
*oi
)
151 lsa
->lsdb
= oi
->lsdb
;
152 ospf6_lsa_originate (lsa
);
156 ospf6_lsa_purge (struct ospf6_lsa
*lsa
)
158 struct ospf6_lsa
*self
;
159 struct ospf6_lsdb
*lsdb_self
;
161 /* remove it from the LSDB for self-originated LSAs */
162 lsdb_self
= ospf6_get_scoped_lsdb_self (lsa
);
163 self
= ospf6_lsdb_lookup (lsa
->header
->type
, lsa
->header
->id
,
164 lsa
->header
->adv_router
, lsdb_self
);
167 THREAD_OFF (self
->expire
);
168 THREAD_OFF (self
->refresh
);
169 ospf6_lsdb_remove (self
, lsdb_self
);
172 ospf6_lsa_premature_aging (lsa
);
177 ospf6_increment_retrans_count (struct ospf6_lsa
*lsa
)
179 /* The LSA must be the original one (see the description
180 in ospf6_decrement_retrans_count () below) */
181 lsa
->retrans_count
++;
185 ospf6_decrement_retrans_count (struct ospf6_lsa
*lsa
)
187 struct ospf6_lsdb
*lsdb
;
188 struct ospf6_lsa
*orig
;
190 /* The LSA must be on the retrans-list of a neighbor. It means
191 the "lsa" is a copied one, and we have to decrement the
192 retransmission count of the original one (instead of this "lsa"'s).
193 In order to find the original LSA, first we have to find
194 appropriate LSDB that have the original LSA. */
195 lsdb
= ospf6_get_scoped_lsdb (lsa
);
197 /* Find the original LSA of which the retrans_count should be decremented */
198 orig
= ospf6_lsdb_lookup (lsa
->header
->type
, lsa
->header
->id
,
199 lsa
->header
->adv_router
, lsdb
);
202 orig
->retrans_count
--;
203 assert (orig
->retrans_count
>= 0);
207 /* RFC2328 section 13.2 Installing LSAs in the database */
209 ospf6_install_lsa (struct ospf6_lsa
*lsa
)
211 struct ospf6_lsa
*old
;
214 if (IS_OSPF6_DEBUG_LSA_TYPE (lsa
->header
->type
) ||
215 IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa
->header
->type
))
216 zlog_debug ("Install LSA: %s", lsa
->name
);
218 /* Remove the old instance from all neighbors' Link state
219 retransmission list (RFC2328 13.2 last paragraph) */
220 old
= ospf6_lsdb_lookup (lsa
->header
->type
, lsa
->header
->id
,
221 lsa
->header
->adv_router
, lsa
->lsdb
);
224 THREAD_OFF (old
->expire
);
225 ospf6_flood_clear (old
);
228 gettimeofday (&now
, (struct timezone
*) NULL
);
229 if (! OSPF6_LSA_IS_MAXAGE (lsa
))
230 lsa
->expire
= thread_add_timer (master
, ospf6_lsa_expire
, lsa
,
231 MAXAGE
+ lsa
->birth
.tv_sec
- now
.tv_sec
);
235 /* actually install */
236 lsa
->installed
= now
;
237 ospf6_lsdb_add (lsa
, lsa
->lsdb
);
242 /* RFC2740 section 3.5.2. Sending Link State Update packets */
243 /* RFC2328 section 13.3 Next step in the flooding procedure */
245 ospf6_flood_interface (struct ospf6_neighbor
*from
,
246 struct ospf6_lsa
*lsa
, struct ospf6_interface
*oi
)
248 struct listnode
*node
, *nnode
;
249 struct ospf6_neighbor
*on
;
250 struct ospf6_lsa
*req
;
251 int retrans_added
= 0;
254 if (IS_OSPF6_DEBUG_FLOODING
||
255 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa
->header
->type
))
258 zlog_debug ("Flooding on %s: %s", oi
->interface
->name
, lsa
->name
);
261 /* (1) For each neighbor */
262 for (ALL_LIST_ELEMENTS (oi
->neighbor_list
, node
, nnode
, on
))
265 zlog_debug ("To neighbor %s", on
->name
);
267 /* (a) if neighbor state < Exchange, examin next */
268 if (on
->state
< OSPF6_NEIGHBOR_EXCHANGE
)
271 zlog_debug ("Neighbor state less than ExChange, next neighbor");
275 /* (b) if neighbor not yet Full, check request-list */
276 if (on
->state
!= OSPF6_NEIGHBOR_FULL
)
279 zlog_debug ("Neighbor not yet Full");
281 req
= ospf6_lsdb_lookup (lsa
->header
->type
, lsa
->header
->id
,
282 lsa
->header
->adv_router
, on
->request_list
);
286 zlog_debug ("Not on request-list for this neighbor");
291 /* If new LSA less recent, examin next neighbor */
292 if (ospf6_lsa_compare (lsa
, req
) > 0)
295 zlog_debug ("Requesting is newer, next neighbor");
299 /* If the same instance, delete from request-list and
300 examin next neighbor */
301 if (ospf6_lsa_compare (lsa
, req
) == 0)
304 zlog_debug ("Requesting the same, remove it, next neighbor");
305 ospf6_lsdb_remove (req
, on
->request_list
);
309 /* If the new LSA is more recent, delete from request-list */
310 if (ospf6_lsa_compare (lsa
, req
) < 0)
313 zlog_debug ("Received is newer, remove requesting");
314 ospf6_lsdb_remove (req
, on
->request_list
);
320 /* (c) If the new LSA was received from this neighbor,
321 examin next neighbor */
325 zlog_debug ("Received is from the neighbor, next neighbor");
329 /* (d) add retrans-list, schedule retransmission */
331 zlog_debug ("Add retrans-list of this neighbor");
332 ospf6_increment_retrans_count (lsa
);
333 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), on
->retrans_list
);
334 if (on
->thread_send_lsupdate
== NULL
)
335 on
->thread_send_lsupdate
=
336 thread_add_timer (master
, ospf6_lsupdate_send_neighbor
,
337 on
, on
->ospf6_if
->rxmt_interval
);
341 /* (2) examin next interface if not added to retrans-list */
342 if (retrans_added
== 0)
345 zlog_debug ("No retransmission scheduled, next interface");
349 /* (3) If the new LSA was received on this interface,
350 and it was from DR or BDR, examin next interface */
351 if (from
&& from
->ospf6_if
== oi
&&
352 (from
->router_id
== oi
->drouter
|| from
->router_id
== oi
->bdrouter
))
355 zlog_debug ("Received is from the I/F's DR or BDR, next interface");
359 /* (4) If the new LSA was received on this interface,
360 and the interface state is BDR, examin next interface */
361 if (from
&& from
->ospf6_if
== oi
&& oi
->state
== OSPF6_INTERFACE_BDR
)
364 zlog_debug ("Received is from the I/F, itself BDR, next interface");
368 /* (5) flood the LSA out the interface. */
370 zlog_debug ("Schedule flooding for the interface");
371 if (if_is_broadcast (oi
->interface
))
373 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), oi
->lsupdate_list
);
374 if (oi
->thread_send_lsupdate
== NULL
)
375 oi
->thread_send_lsupdate
=
376 thread_add_event (master
, ospf6_lsupdate_send_interface
, oi
, 0);
380 /* reschedule retransmissions to all neighbors */
381 for (ALL_LIST_ELEMENTS (oi
->neighbor_list
, node
, nnode
, on
))
383 THREAD_OFF (on
->thread_send_lsupdate
);
384 on
->thread_send_lsupdate
=
385 thread_add_event (master
, ospf6_lsupdate_send_neighbor
, on
, 0);
391 ospf6_flood_area (struct ospf6_neighbor
*from
,
392 struct ospf6_lsa
*lsa
, struct ospf6_area
*oa
)
394 struct listnode
*node
, *nnode
;
395 struct ospf6_interface
*oi
;
397 for (ALL_LIST_ELEMENTS (oa
->if_list
, node
, nnode
, oi
))
399 if (OSPF6_LSA_SCOPE (lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
&&
400 oi
!= OSPF6_INTERFACE (lsa
->lsdb
->data
))
404 if (OSPF6_LSA_SCOPE (lsa
->header
->type
) == OSPF6_SCOPE_AS
&&
405 ospf6_is_interface_virtual_link (oi
))
409 ospf6_flood_interface (from
, lsa
, oi
);
414 ospf6_flood_process (struct ospf6_neighbor
*from
,
415 struct ospf6_lsa
*lsa
, struct ospf6
*process
)
417 struct listnode
*node
, *nnode
;
418 struct ospf6_area
*oa
;
420 for (ALL_LIST_ELEMENTS (process
->area_list
, node
, nnode
, oa
))
422 if (OSPF6_LSA_SCOPE (lsa
->header
->type
) == OSPF6_SCOPE_AREA
&&
423 oa
!= OSPF6_AREA (lsa
->lsdb
->data
))
425 if (OSPF6_LSA_SCOPE (lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
&&
426 oa
!= OSPF6_INTERFACE (lsa
->lsdb
->data
)->area
)
429 if (ntohs (lsa
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
&&
433 ospf6_flood_area (from
, lsa
, oa
);
438 ospf6_flood (struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
)
440 ospf6_flood_process (from
, lsa
, ospf6
);
444 ospf6_flood_clear_interface (struct ospf6_lsa
*lsa
, struct ospf6_interface
*oi
)
446 struct listnode
*node
, *nnode
;
447 struct ospf6_neighbor
*on
;
448 struct ospf6_lsa
*rem
;
450 for (ALL_LIST_ELEMENTS (oi
->neighbor_list
, node
, nnode
, on
))
452 rem
= ospf6_lsdb_lookup (lsa
->header
->type
, lsa
->header
->id
,
453 lsa
->header
->adv_router
, on
->retrans_list
);
454 if (rem
&& ! ospf6_lsa_compare (rem
, lsa
))
456 if (IS_OSPF6_DEBUG_FLOODING
||
457 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa
->header
->type
))
458 zlog_debug ("Remove %s from retrans_list of %s",
459 rem
->name
, on
->name
);
460 ospf6_decrement_retrans_count (rem
);
461 ospf6_lsdb_remove (rem
, on
->retrans_list
);
467 ospf6_flood_clear_area (struct ospf6_lsa
*lsa
, struct ospf6_area
*oa
)
469 struct listnode
*node
, *nnode
;
470 struct ospf6_interface
*oi
;
472 for (ALL_LIST_ELEMENTS (oa
->if_list
, node
, nnode
, oi
))
474 if (OSPF6_LSA_SCOPE (lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
&&
475 oi
!= OSPF6_INTERFACE (lsa
->lsdb
->data
))
479 if (OSPF6_LSA_SCOPE (lsa
->header
->type
) == OSPF6_SCOPE_AS
&&
480 ospf6_is_interface_virtual_link (oi
))
484 ospf6_flood_clear_interface (lsa
, oi
);
489 ospf6_flood_clear_process (struct ospf6_lsa
*lsa
, struct ospf6
*process
)
491 struct listnode
*node
, *nnode
;
492 struct ospf6_area
*oa
;
494 for (ALL_LIST_ELEMENTS (process
->area_list
, node
, nnode
, oa
))
496 if (OSPF6_LSA_SCOPE (lsa
->header
->type
) == OSPF6_SCOPE_AREA
&&
497 oa
!= OSPF6_AREA (lsa
->lsdb
->data
))
499 if (OSPF6_LSA_SCOPE (lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
&&
500 oa
!= OSPF6_INTERFACE (lsa
->lsdb
->data
)->area
)
503 if (ntohs (lsa
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
&&
507 ospf6_flood_clear_area (lsa
, oa
);
512 ospf6_flood_clear (struct ospf6_lsa
*lsa
)
514 ospf6_flood_clear_process (lsa
, ospf6
);
518 /* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
520 ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa
*lsa
, int ismore_recent
,
521 struct ospf6_neighbor
*from
)
523 struct ospf6_interface
*oi
;
526 if (IS_OSPF6_DEBUG_FLOODING
||
527 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa
->header
->type
))
530 assert (from
&& from
->ospf6_if
);
533 /* LSA has been flood back out receiving interface.
534 No acknowledgement sent. */
535 if (CHECK_FLAG (lsa
->flag
, OSPF6_LSA_FLOODBACK
))
538 zlog_debug ("No acknowledgement (BDR & FloodBack)");
542 /* LSA is more recent than database copy, but was not flooded
543 back out receiving interface. Delayed acknowledgement sent
544 if advertisement received from Designated Router,
545 otherwide do nothing. */
546 if (ismore_recent
< 0)
548 if (oi
->drouter
== from
->router_id
)
551 zlog_debug ("Delayed acknowledgement (BDR & MoreRecent & from DR)");
552 /* Delayed acknowledgement */
553 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), oi
->lsack_list
);
554 if (oi
->thread_send_lsack
== NULL
)
555 oi
->thread_send_lsack
=
556 thread_add_timer (master
, ospf6_lsack_send_interface
, oi
, 3);
561 zlog_debug ("No acknowledgement (BDR & MoreRecent & ! from DR)");
566 /* LSA is a duplicate, and was treated as an implied acknowledgement.
567 Delayed acknowledgement sent if advertisement received from
568 Designated Router, otherwise do nothing */
569 if (CHECK_FLAG (lsa
->flag
, OSPF6_LSA_DUPLICATE
) &&
570 CHECK_FLAG (lsa
->flag
, OSPF6_LSA_IMPLIEDACK
))
572 if (oi
->drouter
== from
->router_id
)
575 zlog_debug ("Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
576 /* Delayed acknowledgement */
577 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), oi
->lsack_list
);
578 if (oi
->thread_send_lsack
== NULL
)
579 oi
->thread_send_lsack
=
580 thread_add_timer (master
, ospf6_lsack_send_interface
, oi
, 3);
585 zlog_debug ("No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
590 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
591 Direct acknowledgement sent */
592 if (CHECK_FLAG (lsa
->flag
, OSPF6_LSA_DUPLICATE
) &&
593 ! CHECK_FLAG (lsa
->flag
, OSPF6_LSA_IMPLIEDACK
))
596 zlog_debug ("Direct acknowledgement (BDR & Duplicate)");
597 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), from
->lsack_list
);
598 if (from
->thread_send_lsack
== NULL
)
599 from
->thread_send_lsack
=
600 thread_add_event (master
, ospf6_lsack_send_neighbor
, from
, 0);
604 /* LSA's LS age is equal to Maxage, and there is no current instance
605 of the LSA in the link state database, and none of router's
606 neighbors are in states Exchange or Loading */
607 /* Direct acknowledgement sent, but this case is handled in
608 early of ospf6_receive_lsa () */
612 ospf6_acknowledge_lsa_allother (struct ospf6_lsa
*lsa
, int ismore_recent
,
613 struct ospf6_neighbor
*from
)
615 struct ospf6_interface
*oi
;
618 if (IS_OSPF6_DEBUG_FLOODING
||
619 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa
->header
->type
))
622 assert (from
&& from
->ospf6_if
);
625 /* LSA has been flood back out receiving interface.
626 No acknowledgement sent. */
627 if (CHECK_FLAG (lsa
->flag
, OSPF6_LSA_FLOODBACK
))
630 zlog_debug ("No acknowledgement (AllOther & FloodBack)");
634 /* LSA is more recent than database copy, but was not flooded
635 back out receiving interface. Delayed acknowledgement sent. */
636 if (ismore_recent
< 0)
639 zlog_debug ("Delayed acknowledgement (AllOther & MoreRecent)");
640 /* Delayed acknowledgement */
641 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), oi
->lsack_list
);
642 if (oi
->thread_send_lsack
== NULL
)
643 oi
->thread_send_lsack
=
644 thread_add_timer (master
, ospf6_lsack_send_interface
, oi
, 3);
648 /* LSA is a duplicate, and was treated as an implied acknowledgement.
649 No acknowledgement sent. */
650 if (CHECK_FLAG (lsa
->flag
, OSPF6_LSA_DUPLICATE
) &&
651 CHECK_FLAG (lsa
->flag
, OSPF6_LSA_IMPLIEDACK
))
654 zlog_debug ("No acknowledgement (AllOther & Duplicate & ImpliedAck)");
658 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
659 Direct acknowledgement sent */
660 if (CHECK_FLAG (lsa
->flag
, OSPF6_LSA_DUPLICATE
) &&
661 ! CHECK_FLAG (lsa
->flag
, OSPF6_LSA_IMPLIEDACK
))
664 zlog_debug ("Direct acknowledgement (AllOther & Duplicate)");
665 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), from
->lsack_list
);
666 if (from
->thread_send_lsack
== NULL
)
667 from
->thread_send_lsack
=
668 thread_add_event (master
, ospf6_lsack_send_neighbor
, from
, 0);
672 /* LSA's LS age is equal to Maxage, and there is no current instance
673 of the LSA in the link state database, and none of router's
674 neighbors are in states Exchange or Loading */
675 /* Direct acknowledgement sent, but this case is handled in
676 early of ospf6_receive_lsa () */
680 ospf6_acknowledge_lsa (struct ospf6_lsa
*lsa
, int ismore_recent
,
681 struct ospf6_neighbor
*from
)
683 struct ospf6_interface
*oi
;
685 assert (from
&& from
->ospf6_if
);
688 if (oi
->state
== OSPF6_INTERFACE_BDR
)
689 ospf6_acknowledge_lsa_bdrouter (lsa
, ismore_recent
, from
);
691 ospf6_acknowledge_lsa_allother (lsa
, ismore_recent
, from
);
694 /* RFC2328 section 13 (4):
695 if MaxAge LSA and if we have no instance, and no neighbor
696 is in states Exchange or Loading
697 returns 1 if match this case, else returns 0 */
699 ospf6_is_maxage_lsa_drop (struct ospf6_lsa
*lsa
, struct ospf6_neighbor
*from
)
701 struct ospf6_neighbor
*on
;
702 struct ospf6_interface
*oi
;
703 struct ospf6_area
*oa
;
704 struct ospf6
*process
= NULL
;
705 struct listnode
*i
, *j
, *k
;
708 if (! OSPF6_LSA_IS_MAXAGE (lsa
))
711 if (ospf6_lsdb_lookup (lsa
->header
->type
, lsa
->header
->id
,
712 lsa
->header
->adv_router
, lsa
->lsdb
))
715 process
= from
->ospf6_if
->area
->ospf6
;
717 for (ALL_LIST_ELEMENTS_RO (process
->area_list
, i
, oa
))
718 for (ALL_LIST_ELEMENTS_RO (oa
->if_list
, j
, oi
))
719 for (ALL_LIST_ELEMENTS_RO (oi
->neighbor_list
, k
, on
))
720 if (on
->state
== OSPF6_NEIGHBOR_EXCHANGE
||
721 on
->state
== OSPF6_NEIGHBOR_LOADING
)
729 /* RFC2328 section 13 The Flooding Procedure */
731 ospf6_receive_lsa (struct ospf6_neighbor
*from
,
732 struct ospf6_lsa_header
*lsa_header
)
734 struct ospf6_lsa
*new = NULL
, *old
= NULL
, *rem
= NULL
;
736 unsigned short cksum
;
742 /* make lsa structure for received lsa */
743 new = ospf6_lsa_create (lsa_header
);
745 if (IS_OSPF6_DEBUG_FLOODING
||
746 IS_OSPF6_DEBUG_FLOOD_TYPE (new->header
->type
))
749 zlog_debug ("LSA Receive from %s", from
->name
);
750 ospf6_lsa_header_print (new);
753 /* (1) LSA Checksum */
754 cksum
= ntohs (new->header
->checksum
);
755 if (ntohs (ospf6_lsa_checksum (new->header
)) != cksum
)
758 zlog_debug ("Wrong LSA Checksum, discard");
759 ospf6_lsa_delete (new);
763 /* (2) Examine the LSA's LS type.
764 RFC2470 3.5.1. Receiving Link State Update packets */
765 if (IS_AREA_STUB (from
->ospf6_if
->area
) &&
766 OSPF6_LSA_SCOPE (new->header
->type
) == OSPF6_SCOPE_AS
)
769 zlog_debug ("AS-External-LSA (or AS-scope LSA) in stub area, discard");
770 ospf6_lsa_delete (new);
774 /* (3) LSA which have reserved scope is discarded
775 RFC2470 3.5.1. Receiving Link State Update packets */
776 /* Flooding scope check. LSAs with unknown scope are discarded here.
777 Set appropriate LSDB for the LSA */
778 switch (OSPF6_LSA_SCOPE (new->header
->type
))
780 case OSPF6_SCOPE_LINKLOCAL
:
781 new->lsdb
= from
->ospf6_if
->lsdb
;
783 case OSPF6_SCOPE_AREA
:
784 new->lsdb
= from
->ospf6_if
->area
->lsdb
;
787 new->lsdb
= from
->ospf6_if
->area
->ospf6
->lsdb
;
791 zlog_debug ("LSA has reserved scope, discard");
792 ospf6_lsa_delete (new);
796 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
797 is in states Exchange or Loading */
798 if (ospf6_is_maxage_lsa_drop (new, from
))
802 zlog_debug ("Drop MaxAge LSA with direct acknowledgement.");
804 /* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */
805 ospf6_lsdb_add (ospf6_lsa_copy (new), from
->lsack_list
);
806 if (from
->thread_send_lsack
== NULL
)
807 from
->thread_send_lsack
=
808 thread_add_event (master
, ospf6_lsack_send_neighbor
, from
, 0);
811 ospf6_lsa_delete (new);
816 /* lookup the same database copy in lsdb */
817 old
= ospf6_lsdb_lookup (new->header
->type
, new->header
->id
,
818 new->header
->adv_router
, new->lsdb
);
821 ismore_recent
= ospf6_lsa_compare (new, old
);
822 if (ntohl (new->header
->seqnum
) == ntohl (old
->header
->seqnum
))
825 zlog_debug ("Received is duplicated LSA");
826 SET_FLAG (new->flag
, OSPF6_LSA_DUPLICATE
);
830 /* if no database copy or received is more recent */
831 if (old
== NULL
|| ismore_recent
< 0)
833 /* in case we have no database copy */
836 /* (a) MinLSArrival check */
839 struct timeval now
, res
;
840 gettimeofday (&now
, (struct timezone
*) NULL
);
841 timersub (&now
, &old
->installed
, &res
);
842 if (res
.tv_sec
< MIN_LS_ARRIVAL
)
845 zlog_debug ("LSA can't be updated within MinLSArrival, discard");
846 ospf6_lsa_delete (new);
847 return; /* examin next lsa */
851 gettimeofday (&new->received
, (struct timezone
*) NULL
);
854 zlog_debug ("Flood, Install, Possibly acknowledge the received LSA");
856 /* (b) immediately flood and (c) remove from all retrans-list */
857 /* Prevent self-originated LSA to be flooded. this is to make
858 reoriginated instance of the LSA not to be rejected by other routers
859 due to MinLSArrival. */
860 if (new->header
->adv_router
!= from
->ospf6_if
->area
->ospf6
->router_id
)
861 ospf6_flood (from
, new);
863 /* (c) Remove the current database copy from all neighbors' Link
864 state retransmission lists. */
865 /* XXX, flood_clear ? */
867 /* (d), installing lsdb, which may cause routing
868 table calculation (replacing database copy) */
869 ospf6_install_lsa (new);
871 /* (e) possibly acknowledge */
872 ospf6_acknowledge_lsa (new, ismore_recent
, from
);
874 /* (f) Self Originated LSA, section 13.4 */
875 if (new->header
->adv_router
== from
->ospf6_if
->area
->ospf6
->router_id
)
877 /* Self-originated LSA (newer than ours) is received from
878 another router. We have to make a new instance of the LSA
879 or have to flush this LSA. */
882 zlog_debug ("Newer instance of the self-originated LSA");
883 zlog_debug ("Schedule reorigination");
885 new->refresh
= thread_add_event (master
, ospf6_lsa_refresh
, new, 0);
891 /* (6) if there is instance on sending neighbor's request list */
892 if (ospf6_lsdb_lookup (new->header
->type
, new->header
->id
,
893 new->header
->adv_router
, from
->request_list
))
895 /* if no database copy, should go above state (5) */
900 zlog_debug ("Received is not newer, on the neighbor's request-list");
901 zlog_debug ("BadLSReq, discard the received LSA");
905 thread_add_event (master
, bad_lsreq
, from
, 0);
907 ospf6_lsa_delete (new);
911 /* (7) if neither one is more recent */
912 if (ismore_recent
== 0)
915 zlog_debug ("The same instance as database copy (neither recent)");
917 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack */
918 rem
= ospf6_lsdb_lookup (new->header
->type
, new->header
->id
,
919 new->header
->adv_router
, from
->retrans_list
);
924 zlog_debug ("It is on the neighbor's retrans-list.");
925 zlog_debug ("Treat as an Implied acknowledgement");
927 SET_FLAG (new->flag
, OSPF6_LSA_IMPLIEDACK
);
928 ospf6_decrement_retrans_count (rem
);
929 ospf6_lsdb_remove (rem
, from
->retrans_list
);
933 zlog_debug ("Possibly acknowledge and then discard");
935 /* (b) possibly acknowledge */
936 ospf6_acknowledge_lsa (new, ismore_recent
, from
);
938 ospf6_lsa_delete (new);
942 /* (8) previous database copy is more recent */
946 /* If database copy is in 'Seqnumber Wrapping',
947 simply discard the received LSA */
948 if (OSPF6_LSA_IS_MAXAGE (old
) &&
949 old
->header
->seqnum
== htonl (MAX_SEQUENCE_NUMBER
))
953 zlog_debug ("The LSA is in Seqnumber Wrapping");
954 zlog_debug ("MaxAge & MaxSeqNum, discard");
956 ospf6_lsa_delete (new);
960 /* Otherwise, Send database copy of this LSA to this neighbor */
964 zlog_debug ("Database copy is more recent.");
965 zlog_debug ("Send back directly and then discard");
968 /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
970 ospf6_lsdb_add (ospf6_lsa_copy (old
), from
->lsupdate_list
);
971 if (from
->thread_send_lsupdate
== NULL
)
972 from
->thread_send_lsupdate
=
973 thread_add_event (master
, ospf6_lsupdate_send_neighbor
, from
, 0);
974 ospf6_lsa_delete (new);
982 DEFUN (debug_ospf6_flooding
,
983 debug_ospf6_flooding_cmd
,
984 "debug ospf6 flooding",
987 "Debug OSPFv3 flooding function\n"
990 OSPF6_DEBUG_FLOODING_ON ();
994 DEFUN (no_debug_ospf6_flooding
,
995 no_debug_ospf6_flooding_cmd
,
996 "no debug ospf6 flooding",
1000 "Debug OSPFv3 flooding function\n"
1003 OSPF6_DEBUG_FLOODING_OFF ();
1008 config_write_ospf6_debug_flood (struct vty
*vty
)
1010 if (IS_OSPF6_DEBUG_FLOODING
)
1011 vty_out (vty
, "debug ospf6 flooding%s", VNL
);
1016 install_element_ospf6_debug_flood ()
1018 install_element (ENABLE_NODE
, &debug_ospf6_flooding_cmd
);
1019 install_element (ENABLE_NODE
, &no_debug_ospf6_flooding_cmd
);
1020 install_element (CONFIG_NODE
, &debug_ospf6_flooding_cmd
);
1021 install_element (CONFIG_NODE
, &no_debug_ospf6_flooding_cmd
);