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
;
46 struct ospf6_lsdb
*ospf6_get_scoped_lsdb(struct ospf6_lsa
*lsa
)
48 struct ospf6_lsdb
*lsdb
= NULL
;
49 switch (OSPF6_LSA_SCOPE(lsa
->header
->type
)) {
50 case OSPF6_SCOPE_LINKLOCAL
:
51 lsdb
= OSPF6_INTERFACE(lsa
->lsdb
->data
)->lsdb
;
53 case OSPF6_SCOPE_AREA
:
54 lsdb
= OSPF6_AREA(lsa
->lsdb
->data
)->lsdb
;
57 lsdb
= OSPF6_PROCESS(lsa
->lsdb
->data
)->lsdb
;
66 struct ospf6_lsdb
*ospf6_get_scoped_lsdb_self(struct ospf6_lsa
*lsa
)
68 struct ospf6_lsdb
*lsdb_self
= NULL
;
69 switch (OSPF6_LSA_SCOPE(lsa
->header
->type
)) {
70 case OSPF6_SCOPE_LINKLOCAL
:
71 lsdb_self
= OSPF6_INTERFACE(lsa
->lsdb
->data
)->lsdb_self
;
73 case OSPF6_SCOPE_AREA
:
74 lsdb_self
= OSPF6_AREA(lsa
->lsdb
->data
)->lsdb_self
;
77 lsdb_self
= OSPF6_PROCESS(lsa
->lsdb
->data
)->lsdb_self
;
86 void ospf6_lsa_originate(struct ospf6_lsa
*lsa
)
88 struct ospf6_lsa
*old
;
89 struct ospf6_lsdb
*lsdb_self
;
91 /* find previous LSA */
92 old
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
93 lsa
->header
->adv_router
, lsa
->lsdb
);
95 /* if the new LSA does not differ from previous,
96 suppress this update of the LSA */
97 if (old
&& !OSPF6_LSA_IS_DIFFER(lsa
, old
)) {
98 if (IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa
->header
->type
))
99 zlog_debug("Suppress updating LSA: %s", lsa
->name
);
100 ospf6_lsa_delete(lsa
);
104 /* store it in the LSDB for self-originated LSAs */
105 lsdb_self
= ospf6_get_scoped_lsdb_self(lsa
);
106 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), lsdb_self
);
109 thread_add_timer(master
, ospf6_lsa_refresh
, lsa
, OSPF_LS_REFRESH_TIME
,
112 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
)
113 || IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa
->header
->type
)) {
114 zlog_debug("LSA Originate:");
115 ospf6_lsa_header_print(lsa
);
118 ospf6_install_lsa(lsa
);
119 ospf6_flood(NULL
, lsa
);
122 void ospf6_lsa_originate_process(struct ospf6_lsa
*lsa
, struct ospf6
*process
)
124 lsa
->lsdb
= process
->lsdb
;
125 ospf6_lsa_originate(lsa
);
128 void ospf6_lsa_originate_area(struct ospf6_lsa
*lsa
, struct ospf6_area
*oa
)
130 lsa
->lsdb
= oa
->lsdb
;
131 ospf6_lsa_originate(lsa
);
134 void ospf6_lsa_originate_interface(struct ospf6_lsa
*lsa
,
135 struct ospf6_interface
*oi
)
137 lsa
->lsdb
= oi
->lsdb
;
138 ospf6_lsa_originate(lsa
);
141 void ospf6_lsa_purge(struct ospf6_lsa
*lsa
)
143 struct ospf6_lsa
*self
;
144 struct ospf6_lsdb
*lsdb_self
;
146 /* remove it from the LSDB for self-originated LSAs */
147 lsdb_self
= ospf6_get_scoped_lsdb_self(lsa
);
148 self
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
149 lsa
->header
->adv_router
, lsdb_self
);
151 THREAD_OFF(self
->expire
);
152 THREAD_OFF(self
->refresh
);
153 ospf6_lsdb_remove(self
, lsdb_self
);
156 ospf6_lsa_premature_aging(lsa
);
160 void ospf6_increment_retrans_count(struct ospf6_lsa
*lsa
)
162 /* The LSA must be the original one (see the description
163 in ospf6_decrement_retrans_count () below) */
164 lsa
->retrans_count
++;
167 void ospf6_decrement_retrans_count(struct ospf6_lsa
*lsa
)
169 struct ospf6_lsdb
*lsdb
;
170 struct ospf6_lsa
*orig
;
172 /* The LSA must be on the retrans-list of a neighbor. It means
173 the "lsa" is a copied one, and we have to decrement the
174 retransmission count of the original one (instead of this "lsa"'s).
175 In order to find the original LSA, first we have to find
176 appropriate LSDB that have the original LSA. */
177 lsdb
= ospf6_get_scoped_lsdb(lsa
);
179 /* Find the original LSA of which the retrans_count should be
181 orig
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
182 lsa
->header
->adv_router
, lsdb
);
184 orig
->retrans_count
--;
185 assert(orig
->retrans_count
>= 0);
189 /* RFC2328 section 13.2 Installing LSAs in the database */
190 void ospf6_install_lsa(struct ospf6_lsa
*lsa
)
193 struct ospf6_lsa
*old
;
195 /* Remove the old instance from all neighbors' Link state
196 retransmission list (RFC2328 13.2 last paragraph) */
197 old
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
198 lsa
->header
->adv_router
, lsa
->lsdb
);
200 THREAD_OFF(old
->expire
);
201 THREAD_OFF(old
->refresh
);
202 ospf6_flood_clear(old
);
206 if (!OSPF6_LSA_IS_MAXAGE(lsa
)) {
208 thread_add_timer(master
, ospf6_lsa_expire
, lsa
,
209 OSPF_LSA_MAXAGE
+ lsa
->birth
.tv_sec
215 if (OSPF6_LSA_IS_SEQWRAP(lsa
)
216 && !(CHECK_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
)
217 && lsa
->header
->seqnum
== htonl(OSPF_MAX_SEQUENCE_NUMBER
))) {
218 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
))
219 zlog_debug("lsa install wrapping: sequence 0x%x",
220 ntohl(lsa
->header
->seqnum
));
221 SET_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
);
222 /* in lieu of premature_aging, since we do not want to recreate
224 * and/or mess with timers etc, we just want to wrap the
226 * and reflood the lsa before continuing.
227 * NOTE: Flood needs to be called right after this function
231 lsa
->header
->seqnum
= htonl(OSPF_MAX_SEQUENCE_NUMBER
);
232 lsa
->header
->age
= htons(OSPF_LSA_MAXAGE
);
233 ospf6_lsa_checksum(lsa
->header
);
236 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
)
237 || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
))
238 zlog_debug("%s Install LSA: %s age %d seqnum %x in LSDB.",
239 __PRETTY_FUNCTION__
, lsa
->name
,
240 ntohs(lsa
->header
->age
), ntohl(lsa
->header
->seqnum
));
242 /* actually install */
243 lsa
->installed
= now
;
244 ospf6_lsdb_add(lsa
, lsa
->lsdb
);
249 /* RFC2740 section 3.5.2. Sending Link State Update packets */
250 /* RFC2328 section 13.3 Next step in the flooding procedure */
251 void ospf6_flood_interface(struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
,
252 struct ospf6_interface
*oi
)
254 struct listnode
*node
, *nnode
;
255 struct ospf6_neighbor
*on
;
256 struct ospf6_lsa
*req
;
257 int retrans_added
= 0;
260 if (IS_OSPF6_DEBUG_FLOODING
261 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
)) {
263 zlog_debug("Flooding on %s: %s", oi
->interface
->name
,
267 /* (1) For each neighbor */
268 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
270 zlog_debug("To neighbor %s", on
->name
);
272 /* (a) if neighbor state < Exchange, examin next */
273 if (on
->state
< OSPF6_NEIGHBOR_EXCHANGE
) {
276 "Neighbor state less than ExChange, next neighbor");
280 /* (b) if neighbor not yet Full, check request-list */
281 if (on
->state
!= OSPF6_NEIGHBOR_FULL
) {
283 zlog_debug("Neighbor not yet Full");
285 req
= ospf6_lsdb_lookup(
286 lsa
->header
->type
, lsa
->header
->id
,
287 lsa
->header
->adv_router
, on
->request_list
);
291 "Not on request-list for this neighbor");
294 /* If new LSA less recent, examin next neighbor
296 if (ospf6_lsa_compare(lsa
, req
) > 0) {
299 "Requesting is older, next neighbor");
303 /* If the same instance, delete from
305 examin next neighbor */
306 if (ospf6_lsa_compare(lsa
, req
) == 0) {
309 "Requesting the same, remove it, next neighbor");
310 if (req
== on
->last_ls_req
) {
311 ospf6_lsa_unlock(req
);
312 on
->last_ls_req
= NULL
;
314 ospf6_lsdb_remove(req
,
316 ospf6_check_nbr_loading(on
);
320 /* If the new LSA is more recent, delete from
322 if (ospf6_lsa_compare(lsa
, req
) < 0) {
325 "Received is newer, remove requesting");
326 if (req
== on
->last_ls_req
) {
327 ospf6_lsa_unlock(req
);
328 on
->last_ls_req
= NULL
;
330 ospf6_lsdb_remove(req
,
332 ospf6_check_nbr_loading(on
);
338 /* (c) If the new LSA was received from this neighbor,
339 examin next neighbor */
343 "Received is from the neighbor, next neighbor");
347 if (ospf6
->inst_shutdown
) {
350 "%s: Send LSA %s (age %d) update now",
351 __PRETTY_FUNCTION__
, lsa
->name
,
352 ntohs(lsa
->header
->age
));
353 ospf6_lsupdate_send_neighbor_now(on
, lsa
);
356 /* (d) add retrans-list, schedule retransmission */
358 zlog_debug("Add retrans-list of this neighbor");
359 ospf6_increment_retrans_count(lsa
);
360 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), on
->retrans_list
);
361 thread_add_timer(master
, ospf6_lsupdate_send_neighbor
,
362 on
, on
->ospf6_if
->rxmt_interval
,
363 &on
->thread_send_lsupdate
);
368 /* (2) examin next interface if not added to retrans-list */
369 if (retrans_added
== 0) {
372 "No retransmission scheduled, next interface");
376 /* (3) If the new LSA was received on this interface,
377 and it was from DR or BDR, examin next interface */
378 if (from
&& from
->ospf6_if
== oi
379 && (from
->router_id
== oi
->drouter
380 || from
->router_id
== oi
->bdrouter
)) {
383 "Received is from the I/F's DR or BDR, next interface");
387 /* (4) If the new LSA was received on this interface,
388 and the interface state is BDR, examin next interface */
389 if (from
&& from
->ospf6_if
== oi
) {
390 if (oi
->state
== OSPF6_INTERFACE_BDR
) {
393 "Received is from the I/F, itself BDR, next interface");
396 SET_FLAG(lsa
->flag
, OSPF6_LSA_FLOODBACK
);
399 /* (5) flood the LSA out the interface. */
401 zlog_debug("Schedule flooding for the interface");
402 if ((oi
->type
== OSPF_IFTYPE_BROADCAST
)
403 || (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)) {
404 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsupdate_list
);
405 thread_add_event(master
, ospf6_lsupdate_send_interface
, oi
, 0,
406 &oi
->thread_send_lsupdate
);
408 /* reschedule retransmissions to all neighbors */
409 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
410 THREAD_OFF(on
->thread_send_lsupdate
);
411 on
->thread_send_lsupdate
= NULL
;
412 thread_add_event(master
, ospf6_lsupdate_send_neighbor
,
413 on
, 0, &on
->thread_send_lsupdate
);
418 void ospf6_flood_area(struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
,
419 struct ospf6_area
*oa
)
421 struct listnode
*node
, *nnode
;
422 struct ospf6_interface
*oi
;
424 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
)) {
425 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
426 && oi
!= OSPF6_INTERFACE(lsa
->lsdb
->data
))
430 if (OSPF6_LSA_SCOPE (lsa
->header
->type
) == OSPF6_SCOPE_AS
&&
431 ospf6_is_interface_virtual_link (oi
))
435 ospf6_flood_interface(from
, lsa
, oi
);
439 static void ospf6_flood_process(struct ospf6_neighbor
*from
,
440 struct ospf6_lsa
*lsa
, struct ospf6
*process
)
442 struct listnode
*node
, *nnode
;
443 struct ospf6_area
*oa
;
445 for (ALL_LIST_ELEMENTS(process
->area_list
, node
, nnode
, oa
)) {
446 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_AREA
447 && oa
!= OSPF6_AREA(lsa
->lsdb
->data
))
449 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
450 && oa
!= OSPF6_INTERFACE(lsa
->lsdb
->data
)->area
)
453 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
457 ospf6_flood_area(from
, lsa
, oa
);
461 void ospf6_flood(struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
)
463 ospf6_flood_process(from
, lsa
, ospf6
);
466 static void ospf6_flood_clear_interface(struct ospf6_lsa
*lsa
,
467 struct ospf6_interface
*oi
)
469 struct listnode
*node
, *nnode
;
470 struct ospf6_neighbor
*on
;
471 struct ospf6_lsa
*rem
;
473 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
474 rem
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
475 lsa
->header
->adv_router
,
477 if (rem
&& !ospf6_lsa_compare(rem
, lsa
)) {
478 if (IS_OSPF6_DEBUG_FLOODING
479 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
480 zlog_debug("Remove %s from retrans_list of %s",
481 rem
->name
, on
->name
);
482 ospf6_decrement_retrans_count(rem
);
483 ospf6_lsdb_remove(rem
, on
->retrans_list
);
488 static void ospf6_flood_clear_area(struct ospf6_lsa
*lsa
, struct ospf6_area
*oa
)
490 struct listnode
*node
, *nnode
;
491 struct ospf6_interface
*oi
;
493 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
)) {
494 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
495 && oi
!= OSPF6_INTERFACE(lsa
->lsdb
->data
))
499 if (OSPF6_LSA_SCOPE (lsa
->header
->type
) == OSPF6_SCOPE_AS
&&
500 ospf6_is_interface_virtual_link (oi
))
504 ospf6_flood_clear_interface(lsa
, oi
);
508 static void ospf6_flood_clear_process(struct ospf6_lsa
*lsa
,
509 struct ospf6
*process
)
511 struct listnode
*node
, *nnode
;
512 struct ospf6_area
*oa
;
514 for (ALL_LIST_ELEMENTS(process
->area_list
, node
, nnode
, oa
)) {
515 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_AREA
516 && oa
!= OSPF6_AREA(lsa
->lsdb
->data
))
518 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
519 && oa
!= OSPF6_INTERFACE(lsa
->lsdb
->data
)->area
)
522 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
526 ospf6_flood_clear_area(lsa
, oa
);
530 void ospf6_flood_clear(struct ospf6_lsa
*lsa
)
532 ospf6_flood_clear_process(lsa
, ospf6
);
536 /* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
537 static void ospf6_acknowledge_lsa_bdrouter(struct ospf6_lsa
*lsa
,
539 struct ospf6_neighbor
*from
)
541 struct ospf6_interface
*oi
;
544 if (IS_OSPF6_DEBUG_FLOODING
545 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
548 assert(from
&& from
->ospf6_if
);
551 /* LSA is more recent than database copy, but was not flooded
552 back out receiving interface. Delayed acknowledgement sent
553 if advertisement received from Designated Router,
554 otherwide do nothing. */
555 if (ismore_recent
< 0) {
556 if (oi
->drouter
== from
->router_id
) {
559 "Delayed acknowledgement (BDR & MoreRecent & from DR)");
560 /* Delayed acknowledgement */
561 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsack_list
);
562 thread_add_timer(master
, ospf6_lsack_send_interface
, oi
,
563 3, &oi
->thread_send_lsack
);
567 "No acknowledgement (BDR & MoreRecent & ! from DR)");
572 /* LSA is a duplicate, and was treated as an implied acknowledgement.
573 Delayed acknowledgement sent if advertisement received from
574 Designated Router, otherwise do nothing */
575 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
576 && CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
577 if (oi
->drouter
== from
->router_id
) {
580 "Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
581 /* Delayed acknowledgement */
582 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsack_list
);
583 thread_add_timer(master
, ospf6_lsack_send_interface
, oi
,
584 3, &oi
->thread_send_lsack
);
588 "No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
593 /* LSA is a duplicate, and was not treated as an implied
595 Direct acknowledgement sent */
596 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
597 && !CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
599 zlog_debug("Direct acknowledgement (BDR & Duplicate)");
600 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), from
->lsack_list
);
601 thread_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
602 &from
->thread_send_lsack
);
606 /* LSA's LS age is equal to Maxage, and there is no current instance
607 of the LSA in the link state database, and none of router's
608 neighbors are in states Exchange or Loading */
609 /* Direct acknowledgement sent, but this case is handled in
610 early of ospf6_receive_lsa () */
613 static void ospf6_acknowledge_lsa_allother(struct ospf6_lsa
*lsa
,
615 struct ospf6_neighbor
*from
)
617 struct ospf6_interface
*oi
;
620 if (IS_OSPF6_DEBUG_FLOODING
621 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
624 assert(from
&& from
->ospf6_if
);
627 /* LSA has been flood back out receiving interface.
628 No acknowledgement sent. */
629 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_FLOODBACK
)) {
631 zlog_debug("No acknowledgement (AllOther & FloodBack)");
635 /* LSA is more recent than database copy, but was not flooded
636 back out receiving interface. Delayed acknowledgement sent. */
637 if (ismore_recent
< 0) {
640 "Delayed acknowledgement (AllOther & MoreRecent)");
641 /* Delayed acknowledgement */
642 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsack_list
);
643 thread_add_timer(master
, ospf6_lsack_send_interface
, oi
, 3,
644 &oi
->thread_send_lsack
);
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 "No acknowledgement (AllOther & Duplicate & ImpliedAck)");
658 /* LSA is a duplicate, and was not treated as an implied
660 Direct acknowledgement sent */
661 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
662 && !CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
665 "Direct acknowledgement (AllOther & Duplicate)");
666 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), from
->lsack_list
);
667 thread_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
668 &from
->thread_send_lsack
);
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 () */
679 static void ospf6_acknowledge_lsa(struct ospf6_lsa
*lsa
, int ismore_recent
,
680 struct ospf6_neighbor
*from
)
682 struct ospf6_interface
*oi
;
684 assert(from
&& from
->ospf6_if
);
687 if (oi
->state
== OSPF6_INTERFACE_BDR
)
688 ospf6_acknowledge_lsa_bdrouter(lsa
, ismore_recent
, from
);
690 ospf6_acknowledge_lsa_allother(lsa
, ismore_recent
, from
);
693 /* RFC2328 section 13 (4):
694 if MaxAge LSA and if we have no instance, and no neighbor
695 is in states Exchange or Loading
696 returns 1 if match this case, else returns 0 */
697 static int ospf6_is_maxage_lsa_drop(struct ospf6_lsa
*lsa
,
698 struct ospf6_neighbor
*from
)
700 struct ospf6_neighbor
*on
;
701 struct ospf6_interface
*oi
;
702 struct ospf6_area
*oa
;
703 struct ospf6
*process
= NULL
;
704 struct listnode
*i
, *j
, *k
;
707 if (!OSPF6_LSA_IS_MAXAGE(lsa
))
710 if (ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
711 lsa
->header
->adv_router
, lsa
->lsdb
))
714 process
= from
->ospf6_if
->area
->ospf6
;
716 for (ALL_LIST_ELEMENTS_RO(process
->area_list
, i
, oa
))
717 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
718 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, k
, on
))
719 if (on
->state
== OSPF6_NEIGHBOR_EXCHANGE
720 || on
->state
== OSPF6_NEIGHBOR_LOADING
)
728 /* RFC2328 section 13 The Flooding Procedure */
729 void ospf6_receive_lsa(struct ospf6_neighbor
*from
,
730 struct ospf6_lsa_header
*lsa_header
)
732 struct ospf6_lsa
*new = NULL
, *old
= NULL
, *rem
= NULL
;
735 unsigned int time_delta_ms
;
740 /* make lsa structure for received lsa */
741 new = ospf6_lsa_create(lsa_header
);
743 if (IS_OSPF6_DEBUG_FLOODING
744 || IS_OSPF6_DEBUG_FLOOD_TYPE(new->header
->type
)) {
746 zlog_debug("LSA Receive from %s", from
->name
);
747 ospf6_lsa_header_print(new);
750 /* (1) LSA Checksum */
751 if (!ospf6_lsa_checksum_valid(new->header
)) {
753 zlog_debug("Wrong LSA Checksum, discard");
754 ospf6_lsa_delete(new);
758 /* (2) Examine the LSA's LS type.
759 RFC2470 3.5.1. Receiving Link State Update packets */
760 if (IS_AREA_STUB(from
->ospf6_if
->area
)
761 && OSPF6_LSA_SCOPE(new->header
->type
) == OSPF6_SCOPE_AS
) {
764 "AS-External-LSA (or AS-scope LSA) in stub area, discard");
765 ospf6_lsa_delete(new);
769 /* (3) LSA which have reserved scope is discarded
770 RFC2470 3.5.1. Receiving Link State Update packets */
771 /* Flooding scope check. LSAs with unknown scope are discarded here.
772 Set appropriate LSDB for the LSA */
773 switch (OSPF6_LSA_SCOPE(new->header
->type
)) {
774 case OSPF6_SCOPE_LINKLOCAL
:
775 new->lsdb
= from
->ospf6_if
->lsdb
;
777 case OSPF6_SCOPE_AREA
:
778 new->lsdb
= from
->ospf6_if
->area
->lsdb
;
781 new->lsdb
= from
->ospf6_if
->area
->ospf6
->lsdb
;
785 zlog_debug("LSA has reserved scope, discard");
786 ospf6_lsa_delete(new);
790 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
791 is in states Exchange or Loading */
792 if (ospf6_is_maxage_lsa_drop(new, from
)) {
796 "Drop MaxAge LSA with direct acknowledgement.");
798 /* a) Acknowledge back to neighbor (Direct acknowledgement,
800 ospf6_lsdb_add(ospf6_lsa_copy(new), from
->lsack_list
);
801 thread_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
802 &from
->thread_send_lsack
);
805 ospf6_lsa_delete(new);
810 /* lookup the same database copy in lsdb */
811 old
= ospf6_lsdb_lookup(new->header
->type
, new->header
->id
,
812 new->header
->adv_router
, new->lsdb
);
814 ismore_recent
= ospf6_lsa_compare(new, old
);
815 if (ntohl(new->header
->seqnum
) == ntohl(old
->header
->seqnum
)) {
817 zlog_debug("Received is duplicated LSA");
818 SET_FLAG(new->flag
, OSPF6_LSA_DUPLICATE
);
820 if (old
->header
->adv_router
821 == from
->ospf6_if
->area
->ospf6
->router_id
822 && OSPF6_LSA_IS_MAXAGE(new)) {
823 ospf6_acknowledge_lsa(new, ismore_recent
, from
);
824 ospf6_lsa_delete(new);
827 "%s: Received is self orig MAXAGE LSA %s, discard (ismore_recent %d)",
828 __PRETTY_FUNCTION__
, old
->name
,
834 /* if no database copy or received is more recent */
835 if (old
== NULL
|| ismore_recent
< 0) {
836 /* in case we have no database copy */
839 /* (a) MinLSArrival check */
841 struct timeval now
, res
;
843 timersub(&now
, &old
->installed
, &res
);
845 (res
.tv_sec
* 1000) + (int)(res
.tv_usec
/ 1000);
847 < from
->ospf6_if
->area
->ospf6
->lsa_minarrival
) {
850 "LSA can't be updated within MinLSArrival, %dms < %dms, discard",
852 from
->ospf6_if
->area
->ospf6
854 ospf6_lsa_delete(new);
855 return; /* examin next lsa */
859 monotime(&new->received
);
863 "Install, Flood, Possibly acknowledge the received LSA");
865 /* Remove older copies of this LSA from retx lists */
867 ospf6_flood_clear(old
);
869 /* (b) immediately flood and (c) remove from all retrans-list */
870 /* Prevent self-originated LSA to be flooded. this is to make
871 reoriginated instance of the LSA not to be rejected by other
873 due to MinLSArrival. */
874 if (new->header
->adv_router
875 != from
->ospf6_if
->area
->ospf6
->router_id
)
876 ospf6_flood(from
, new);
878 /* (d), installing lsdb, which may cause routing
879 table calculation (replacing database copy) */
880 ospf6_install_lsa(new);
882 if (OSPF6_LSA_IS_MAXAGE(new))
883 ospf6_maxage_remove(from
->ospf6_if
->area
->ospf6
);
885 /* (e) possibly acknowledge */
886 ospf6_acknowledge_lsa(new, ismore_recent
, from
);
888 /* (f) Self Originated LSA, section 13.4 */
889 if (new->header
->adv_router
890 == from
->ospf6_if
->area
->ospf6
->router_id
) {
891 /* Self-originated LSA (newer than ours) is received
893 another router. We have to make a new instance of the
895 or have to flush this LSA. */
898 "Newer instance of the self-originated LSA");
899 zlog_debug("Schedule reorigination");
902 thread_add_event(master
, ospf6_lsa_refresh
, new, 0,
909 /* (6) if there is instance on sending neighbor's request list */
910 if (ospf6_lsdb_lookup(new->header
->type
, new->header
->id
,
911 new->header
->adv_router
, from
->request_list
)) {
912 /* if no database copy, should go above state (5) */
917 "Received is not newer, on the neighbor's request-list");
918 zlog_debug("BadLSReq, discard the received LSA");
922 thread_add_event(master
, bad_lsreq
, from
, 0, NULL
);
924 ospf6_lsa_delete(new);
928 /* (7) if neither one is more recent */
929 if (ismore_recent
== 0) {
932 "The same instance as database copy (neither recent)");
934 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack
936 rem
= ospf6_lsdb_lookup(new->header
->type
, new->header
->id
,
937 new->header
->adv_router
,
942 "It is on the neighbor's retrans-list.");
944 "Treat as an Implied acknowledgement");
946 SET_FLAG(new->flag
, OSPF6_LSA_IMPLIEDACK
);
947 ospf6_decrement_retrans_count(rem
);
948 ospf6_lsdb_remove(rem
, from
->retrans_list
);
952 zlog_debug("Possibly acknowledge and then discard");
954 /* (b) possibly acknowledge */
955 ospf6_acknowledge_lsa(new, ismore_recent
, from
);
957 ospf6_lsa_delete(new);
961 /* (8) previous database copy is more recent */
965 /* If database copy is in 'Seqnumber Wrapping',
966 simply discard the received LSA */
967 if (OSPF6_LSA_IS_MAXAGE(old
)
968 && old
->header
->seqnum
== htonl(OSPF_MAX_SEQUENCE_NUMBER
)) {
970 zlog_debug("The LSA is in Seqnumber Wrapping");
971 zlog_debug("MaxAge & MaxSeqNum, discard");
973 ospf6_lsa_delete(new);
977 /* Otherwise, Send database copy of this LSA to this neighbor */
980 zlog_debug("Database copy is more recent.");
982 "Send back directly and then discard");
985 /* Neighbor router sent recent age for LSA,
986 * Router could be restarted while current copy is
987 * MAXAGEd and not removed.*/
988 if (OSPF6_LSA_IS_MAXAGE(old
)
989 && !OSPF6_LSA_IS_MAXAGE(new)) {
993 "%s: Current copy of LSA %s is MAXAGE, but new has recent Age.",
994 old
->name
, __PRETTY_FUNCTION__
);
996 ospf6_lsa_purge(old
);
997 if (new->header
->adv_router
998 != from
->ospf6_if
->area
->ospf6
->router_id
)
999 ospf6_flood(from
, new);
1001 ospf6_install_lsa(new);
1005 /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
1007 ospf6_lsdb_add(ospf6_lsa_copy(old
),
1008 from
->lsupdate_list
);
1009 thread_add_event(master
, ospf6_lsupdate_send_neighbor
,
1010 from
, 0, &from
->thread_send_lsupdate
);
1012 ospf6_lsa_delete(new);
1019 DEFUN (debug_ospf6_flooding
,
1020 debug_ospf6_flooding_cmd
,
1021 "debug ospf6 flooding",
1024 "Debug OSPFv3 flooding function\n"
1027 OSPF6_DEBUG_FLOODING_ON();
1031 DEFUN (no_debug_ospf6_flooding
,
1032 no_debug_ospf6_flooding_cmd
,
1033 "no debug ospf6 flooding",
1037 "Debug OSPFv3 flooding function\n"
1040 OSPF6_DEBUG_FLOODING_OFF();
1044 int config_write_ospf6_debug_flood(struct vty
*vty
)
1046 if (IS_OSPF6_DEBUG_FLOODING
)
1047 vty_out(vty
, "debug ospf6 flooding\n");
1051 void install_element_ospf6_debug_flood(void)
1053 install_element(ENABLE_NODE
, &debug_ospf6_flooding_cmd
);
1054 install_element(ENABLE_NODE
, &no_debug_ospf6_flooding_cmd
);
1055 install_element(CONFIG_NODE
, &debug_ospf6_flooding_cmd
);
1056 install_element(CONFIG_NODE
, &no_debug_ospf6_flooding_cmd
);