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
);
159 /* Puring Multi Link-State IDs LSAs:
160 * Same Advertising Router with Multiple Link-State IDs
161 * LSAs, purging require to traverse all Link-State IDs
163 void ospf6_lsa_purge_multi_ls_id(struct ospf6_area
*oa
, struct ospf6_lsa
*lsa
)
166 struct ospf6_lsa
*lsa_next
;
169 type
= lsa
->header
->type
;
171 ospf6_lsa_purge(lsa
);
173 lsa_next
= ospf6_lsdb_lookup(type
, htonl(++ls_id
),
174 oa
->ospf6
->router_id
, oa
->lsdb
);
176 ospf6_lsa_purge(lsa_next
);
177 lsa_next
= ospf6_lsdb_lookup(type
, htonl(++ls_id
),
178 oa
->ospf6
->router_id
, oa
->lsdb
);
182 void ospf6_increment_retrans_count(struct ospf6_lsa
*lsa
)
184 /* The LSA must be the original one (see the description
185 in ospf6_decrement_retrans_count () below) */
186 lsa
->retrans_count
++;
189 void ospf6_decrement_retrans_count(struct ospf6_lsa
*lsa
)
191 struct ospf6_lsdb
*lsdb
;
192 struct ospf6_lsa
*orig
;
194 /* The LSA must be on the retrans-list of a neighbor. It means
195 the "lsa" is a copied one, and we have to decrement the
196 retransmission count of the original one (instead of this "lsa"'s).
197 In order to find the original LSA, first we have to find
198 appropriate LSDB that have the original LSA. */
199 lsdb
= ospf6_get_scoped_lsdb(lsa
);
201 /* Find the original LSA of which the retrans_count should be
203 orig
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
204 lsa
->header
->adv_router
, lsdb
);
206 orig
->retrans_count
--;
207 assert(orig
->retrans_count
>= 0);
211 /* RFC2328 section 13.2 Installing LSAs in the database */
212 void ospf6_install_lsa(struct ospf6_lsa
*lsa
)
215 struct ospf6_lsa
*old
;
217 /* Remove the old instance from all neighbors' Link state
218 retransmission list (RFC2328 13.2 last paragraph) */
219 old
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
220 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
,
231 OSPF_LSA_MAXAGE
+ lsa
->birth
.tv_sec
237 if (OSPF6_LSA_IS_SEQWRAP(lsa
)
238 && !(CHECK_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
)
239 && 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
246 * and/or mess with timers etc, we just want to wrap the
248 * and reflood the lsa before continuing.
249 * NOTE: Flood needs to be called right after this function
253 lsa
->header
->seqnum
= htonl(OSPF_MAX_SEQUENCE_NUMBER
);
254 lsa
->header
->age
= htons(OSPF_LSA_MAXAGE
);
255 ospf6_lsa_checksum(lsa
->header
);
258 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
)
259 || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
))
260 zlog_debug("%s Install LSA: %s age %d seqnum %x in LSDB.",
261 __func__
, lsa
->name
, ntohs(lsa
->header
->age
),
262 ntohl(lsa
->header
->seqnum
));
264 /* actually install */
265 lsa
->installed
= now
;
266 ospf6_lsdb_add(lsa
, lsa
->lsdb
);
271 /* RFC2740 section 3.5.2. Sending Link State Update packets */
272 /* RFC2328 section 13.3 Next step in the flooding procedure */
273 void ospf6_flood_interface(struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
,
274 struct ospf6_interface
*oi
)
276 struct listnode
*node
, *nnode
;
277 struct ospf6_neighbor
*on
;
278 struct ospf6_lsa
*req
;
279 int retrans_added
= 0;
282 if (IS_OSPF6_DEBUG_FLOODING
283 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
)) {
285 zlog_debug("Flooding on %s: %s", oi
->interface
->name
,
289 /* (1) For each neighbor */
290 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
292 zlog_debug("To neighbor %s", on
->name
);
294 /* (a) if neighbor state < Exchange, examin next */
295 if (on
->state
< OSPF6_NEIGHBOR_EXCHANGE
) {
298 "Neighbor state less than ExChange, next neighbor");
302 /* (b) if neighbor not yet Full, check request-list */
303 if (on
->state
!= OSPF6_NEIGHBOR_FULL
) {
305 zlog_debug("Neighbor not yet Full");
307 req
= ospf6_lsdb_lookup(
308 lsa
->header
->type
, lsa
->header
->id
,
309 lsa
->header
->adv_router
, on
->request_list
);
313 "Not on request-list for this neighbor");
316 /* If new LSA less recent, examin next neighbor
318 if (ospf6_lsa_compare(lsa
, req
) > 0) {
321 "Requesting is older, next neighbor");
325 /* If the same instance, delete from
327 examin next neighbor */
328 if (ospf6_lsa_compare(lsa
, req
) == 0) {
331 "Requesting the same, remove it, next neighbor");
332 if (req
== on
->last_ls_req
) {
333 /* sanity check refcount */
334 assert(req
->lock
>= 2);
335 req
= ospf6_lsa_unlock(req
);
336 on
->last_ls_req
= NULL
;
340 req
, on
->request_list
);
341 ospf6_check_nbr_loading(on
);
345 /* If the new LSA is more recent, delete from
347 if (ospf6_lsa_compare(lsa
, req
) < 0) {
350 "Received is newer, remove requesting");
351 if (req
== on
->last_ls_req
) {
352 req
= ospf6_lsa_unlock(req
);
353 on
->last_ls_req
= NULL
;
356 ospf6_lsdb_remove(req
,
358 ospf6_check_nbr_loading(on
);
364 /* (c) If the new LSA was received from this neighbor,
365 examin next neighbor */
369 "Received is from the neighbor, next neighbor");
373 if (oi
->area
->ospf6
->inst_shutdown
) {
376 "%s: Send LSA %s (age %d) update now",
378 ntohs(lsa
->header
->age
));
379 ospf6_lsupdate_send_neighbor_now(on
, lsa
);
382 /* (d) add retrans-list, schedule retransmission */
384 zlog_debug("Add retrans-list of this neighbor");
385 ospf6_increment_retrans_count(lsa
);
386 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), on
->retrans_list
);
387 thread_add_timer(master
, ospf6_lsupdate_send_neighbor
,
388 on
, on
->ospf6_if
->rxmt_interval
,
389 &on
->thread_send_lsupdate
);
394 /* (2) examin next interface if not added to retrans-list */
395 if (retrans_added
== 0) {
398 "No retransmission scheduled, next interface");
402 /* (3) If the new LSA was received on this interface,
403 and it was from DR or BDR, examin next interface */
404 if (from
&& from
->ospf6_if
== oi
405 && (from
->router_id
== oi
->drouter
406 || from
->router_id
== oi
->bdrouter
)) {
409 "Received is from the I/F's DR or BDR, next interface");
413 /* (4) If the new LSA was received on this interface,
414 and the interface state is BDR, examin next interface */
415 if (from
&& from
->ospf6_if
== oi
) {
416 if (oi
->state
== OSPF6_INTERFACE_BDR
) {
419 "Received is from the I/F, itself BDR, next interface");
422 SET_FLAG(lsa
->flag
, OSPF6_LSA_FLOODBACK
);
425 /* (5) flood the LSA out the interface. */
427 zlog_debug("Schedule flooding for the interface");
428 if ((oi
->type
== OSPF_IFTYPE_BROADCAST
)
429 || (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)) {
430 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsupdate_list
);
431 thread_add_event(master
, ospf6_lsupdate_send_interface
, oi
, 0,
432 &oi
->thread_send_lsupdate
);
434 /* reschedule retransmissions to all neighbors */
435 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
436 THREAD_OFF(on
->thread_send_lsupdate
);
437 on
->thread_send_lsupdate
= NULL
;
438 thread_add_event(master
, ospf6_lsupdate_send_neighbor
,
439 on
, 0, &on
->thread_send_lsupdate
);
444 void ospf6_flood_area(struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
,
445 struct ospf6_area
*oa
)
447 struct listnode
*node
, *nnode
;
448 struct ospf6_interface
*oi
;
450 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
)) {
451 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
452 && oi
!= OSPF6_INTERFACE(lsa
->lsdb
->data
))
455 ospf6_flood_interface(from
, lsa
, oi
);
459 static void ospf6_flood_process(struct ospf6_neighbor
*from
,
460 struct ospf6_lsa
*lsa
, struct ospf6
*process
)
462 struct listnode
*node
, *nnode
;
463 struct ospf6_area
*oa
;
465 for (ALL_LIST_ELEMENTS(process
->area_list
, node
, nnode
, oa
)) {
466 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_AREA
467 && oa
!= OSPF6_AREA(lsa
->lsdb
->data
))
469 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
470 && oa
!= OSPF6_INTERFACE(lsa
->lsdb
->data
)->area
)
473 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
477 ospf6_flood_area(from
, lsa
, oa
);
481 void ospf6_flood(struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
)
485 ospf6
= ospf6_get_by_lsdb(lsa
);
489 ospf6_flood_process(from
, lsa
, ospf6
);
492 static void ospf6_flood_clear_interface(struct ospf6_lsa
*lsa
,
493 struct ospf6_interface
*oi
)
495 struct listnode
*node
, *nnode
;
496 struct ospf6_neighbor
*on
;
497 struct ospf6_lsa
*rem
;
499 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
500 rem
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
501 lsa
->header
->adv_router
,
503 if (rem
&& !ospf6_lsa_compare(rem
, lsa
)) {
504 if (IS_OSPF6_DEBUG_FLOODING
505 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
506 zlog_debug("Remove %s from retrans_list of %s",
507 rem
->name
, on
->name
);
508 ospf6_decrement_retrans_count(rem
);
509 ospf6_lsdb_remove(rem
, on
->retrans_list
);
514 static void ospf6_flood_clear_area(struct ospf6_lsa
*lsa
, struct ospf6_area
*oa
)
516 struct listnode
*node
, *nnode
;
517 struct ospf6_interface
*oi
;
519 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
)) {
520 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
521 && oi
!= OSPF6_INTERFACE(lsa
->lsdb
->data
))
524 ospf6_flood_clear_interface(lsa
, oi
);
528 static void ospf6_flood_clear_process(struct ospf6_lsa
*lsa
,
529 struct ospf6
*process
)
531 struct listnode
*node
, *nnode
;
532 struct ospf6_area
*oa
;
534 for (ALL_LIST_ELEMENTS(process
->area_list
, node
, nnode
, oa
)) {
535 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_AREA
536 && oa
!= OSPF6_AREA(lsa
->lsdb
->data
))
538 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
539 && oa
!= OSPF6_INTERFACE(lsa
->lsdb
->data
)->area
)
542 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
546 ospf6_flood_clear_area(lsa
, oa
);
550 void ospf6_flood_clear(struct ospf6_lsa
*lsa
)
554 ospf6
= ospf6_get_by_lsdb(lsa
);
555 ospf6_flood_clear_process(lsa
, ospf6
);
559 /* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
560 static void ospf6_acknowledge_lsa_bdrouter(struct ospf6_lsa
*lsa
,
562 struct ospf6_neighbor
*from
)
564 struct ospf6_interface
*oi
;
567 if (IS_OSPF6_DEBUG_FLOODING
568 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
571 assert(from
&& from
->ospf6_if
);
574 /* LSA is more recent than database copy, but was not flooded
575 back out receiving interface. Delayed acknowledgement sent
576 if advertisement received from Designated Router,
577 otherwide do nothing. */
578 if (ismore_recent
< 0) {
579 if (oi
->drouter
== from
->router_id
) {
582 "Delayed acknowledgement (BDR & MoreRecent & from DR)");
583 /* Delayed acknowledgement */
584 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsack_list
);
585 thread_add_timer(master
, ospf6_lsack_send_interface
, oi
,
586 3, &oi
->thread_send_lsack
);
590 "No acknowledgement (BDR & MoreRecent & ! from DR)");
595 /* LSA is a duplicate, and was treated as an implied acknowledgement.
596 Delayed acknowledgement sent if advertisement received from
597 Designated Router, otherwise do nothing */
598 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
599 && CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
600 if (oi
->drouter
== from
->router_id
) {
603 "Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
604 /* Delayed acknowledgement */
605 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsack_list
);
606 thread_add_timer(master
, ospf6_lsack_send_interface
, oi
,
607 3, &oi
->thread_send_lsack
);
611 "No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
616 /* LSA is a duplicate, and was not treated as an implied
618 Direct acknowledgement sent */
619 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
620 && !CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
622 zlog_debug("Direct acknowledgement (BDR & Duplicate)");
623 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), from
->lsack_list
);
624 thread_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
625 &from
->thread_send_lsack
);
629 /* LSA's LS age is equal to Maxage, and there is no current instance
630 of the LSA in the link state database, and none of router's
631 neighbors are in states Exchange or Loading */
632 /* Direct acknowledgement sent, but this case is handled in
633 early of ospf6_receive_lsa () */
636 static void ospf6_acknowledge_lsa_allother(struct ospf6_lsa
*lsa
,
638 struct ospf6_neighbor
*from
)
640 struct ospf6_interface
*oi
;
643 if (IS_OSPF6_DEBUG_FLOODING
644 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
647 assert(from
&& from
->ospf6_if
);
650 /* LSA has been flood back out receiving interface.
651 No acknowledgement sent. */
652 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_FLOODBACK
)) {
654 zlog_debug("No acknowledgement (AllOther & FloodBack)");
658 /* LSA is more recent than database copy, but was not flooded
659 back out receiving interface. Delayed acknowledgement sent. */
660 if (ismore_recent
< 0) {
663 "Delayed acknowledgement (AllOther & MoreRecent)");
664 /* Delayed acknowledgement */
665 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsack_list
);
666 thread_add_timer(master
, ospf6_lsack_send_interface
, oi
, 3,
667 &oi
->thread_send_lsack
);
671 /* LSA is a duplicate, and was treated as an implied acknowledgement.
672 No acknowledgement sent. */
673 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
674 && CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
677 "No acknowledgement (AllOther & Duplicate & ImpliedAck)");
681 /* LSA is a duplicate, and was not treated as an implied
683 Direct acknowledgement sent */
684 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
685 && !CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
688 "Direct acknowledgement (AllOther & Duplicate)");
689 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), from
->lsack_list
);
690 thread_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
691 &from
->thread_send_lsack
);
695 /* LSA's LS age is equal to Maxage, and there is no current instance
696 of the LSA in the link state database, and none of router's
697 neighbors are in states Exchange or Loading */
698 /* Direct acknowledgement sent, but this case is handled in
699 early of ospf6_receive_lsa () */
702 static void ospf6_acknowledge_lsa(struct ospf6_lsa
*lsa
, int ismore_recent
,
703 struct ospf6_neighbor
*from
)
705 struct ospf6_interface
*oi
;
707 assert(from
&& from
->ospf6_if
);
710 if (oi
->state
== OSPF6_INTERFACE_BDR
)
711 ospf6_acknowledge_lsa_bdrouter(lsa
, ismore_recent
, from
);
713 ospf6_acknowledge_lsa_allother(lsa
, ismore_recent
, from
);
716 /* RFC2328 section 13 (4):
717 if MaxAge LSA and if we have no instance, and no neighbor
718 is in states Exchange or Loading
719 returns 1 if match this case, else returns 0 */
720 static int ospf6_is_maxage_lsa_drop(struct ospf6_lsa
*lsa
,
721 struct ospf6_neighbor
*from
)
723 struct ospf6_neighbor
*on
;
724 struct ospf6_interface
*oi
;
725 struct ospf6_area
*oa
;
726 struct ospf6
*process
= NULL
;
727 struct listnode
*i
, *j
, *k
;
730 if (!OSPF6_LSA_IS_MAXAGE(lsa
))
733 if (ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
734 lsa
->header
->adv_router
, lsa
->lsdb
))
737 process
= from
->ospf6_if
->area
->ospf6
;
739 for (ALL_LIST_ELEMENTS_RO(process
->area_list
, i
, oa
))
740 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
741 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, k
, on
))
742 if (on
->state
== OSPF6_NEIGHBOR_EXCHANGE
743 || on
->state
== OSPF6_NEIGHBOR_LOADING
)
751 /* RFC2328 section 13 The Flooding Procedure */
752 void 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
)) {
769 zlog_debug("LSA Receive from %s", from
->name
);
770 ospf6_lsa_header_print(new);
773 /* (1) LSA Checksum */
774 if (!ospf6_lsa_checksum_valid(new->header
)) {
776 zlog_debug("Wrong LSA Checksum, discard");
777 ospf6_lsa_delete(new);
781 /* (2) Examine the LSA's LS type.
782 RFC2470 3.5.1. Receiving Link State Update packets */
783 if (IS_AREA_STUB(from
->ospf6_if
->area
)
784 && OSPF6_LSA_SCOPE(new->header
->type
) == OSPF6_SCOPE_AS
) {
787 "AS-External-LSA (or AS-scope LSA) in stub area, discard");
788 ospf6_lsa_delete(new);
792 /* (3) LSA which have reserved scope is discarded
793 RFC2470 3.5.1. Receiving Link State Update packets */
794 /* Flooding scope check. LSAs with unknown scope are discarded here.
795 Set appropriate LSDB for the LSA */
796 switch (OSPF6_LSA_SCOPE(new->header
->type
)) {
797 case OSPF6_SCOPE_LINKLOCAL
:
798 new->lsdb
= from
->ospf6_if
->lsdb
;
800 case OSPF6_SCOPE_AREA
:
801 new->lsdb
= from
->ospf6_if
->area
->lsdb
;
804 new->lsdb
= from
->ospf6_if
->area
->ospf6
->lsdb
;
808 zlog_debug("LSA has reserved scope, discard");
809 ospf6_lsa_delete(new);
813 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
814 is in states Exchange or Loading */
815 if (ospf6_is_maxage_lsa_drop(new, from
)) {
819 "Drop MaxAge LSA with direct acknowledgement.");
821 /* a) Acknowledge back to neighbor (Direct acknowledgement,
823 ospf6_lsdb_add(ospf6_lsa_copy(new), from
->lsack_list
);
824 thread_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
825 &from
->thread_send_lsack
);
828 ospf6_lsa_delete(new);
833 /* lookup the same database copy in lsdb */
834 old
= ospf6_lsdb_lookup(new->header
->type
, new->header
->id
,
835 new->header
->adv_router
, new->lsdb
);
837 ismore_recent
= ospf6_lsa_compare(new, old
);
838 if (ntohl(new->header
->seqnum
) == ntohl(old
->header
->seqnum
)) {
840 zlog_debug("Received is duplicated LSA");
841 SET_FLAG(new->flag
, OSPF6_LSA_DUPLICATE
);
845 /* if no database copy or received is more recent */
846 if (old
== NULL
|| ismore_recent
< 0) {
847 /* in case we have no database copy */
850 /* (a) MinLSArrival check */
852 struct timeval now
, res
;
854 timersub(&now
, &old
->installed
, &res
);
856 (res
.tv_sec
* 1000) + (int)(res
.tv_usec
/ 1000);
858 < from
->ospf6_if
->area
->ospf6
->lsa_minarrival
) {
861 "LSA can't be updated within MinLSArrival, %dms < %dms, discard",
863 from
->ospf6_if
->area
->ospf6
865 ospf6_lsa_delete(new);
866 return; /* examin next lsa */
870 monotime(&new->received
);
874 "Install, Flood, Possibly acknowledge the received LSA");
876 /* Remove older copies of this LSA from retx lists */
878 ospf6_flood_clear(old
);
880 /* (b) immediately flood and (c) remove from all retrans-list */
881 /* Prevent self-originated LSA to be flooded. this is to make
882 reoriginated instance of the LSA not to be rejected by other
884 due to MinLSArrival. */
885 if (new->header
->adv_router
886 != from
->ospf6_if
->area
->ospf6
->router_id
)
887 ospf6_flood(from
, new);
889 /* (d), installing lsdb, which may cause routing
890 table calculation (replacing database copy) */
891 ospf6_install_lsa(new);
893 if (OSPF6_LSA_IS_MAXAGE(new))
894 ospf6_maxage_remove(from
->ospf6_if
->area
->ospf6
);
896 /* (e) possibly acknowledge */
897 ospf6_acknowledge_lsa(new, ismore_recent
, from
);
899 /* (f) Self Originated LSA, section 13.4 */
900 if (new->header
->adv_router
901 == from
->ospf6_if
->area
->ospf6
->router_id
) {
902 /* Self-originated LSA (newer than ours) is received
904 another router. We have to make a new instance of the
906 or have to flush this LSA. */
909 "Newer instance of the self-originated LSA");
910 zlog_debug("Schedule reorigination");
913 thread_add_event(master
, ospf6_lsa_refresh
, new, 0,
920 /* (6) if there is instance on sending neighbor's request list */
921 if (ospf6_lsdb_lookup(new->header
->type
, new->header
->id
,
922 new->header
->adv_router
, from
->request_list
)) {
923 /* if no database copy, should go above state (5) */
928 "Received is not newer, on the neighbor's request-list");
929 zlog_debug("BadLSReq, discard the received LSA");
933 thread_add_event(master
, bad_lsreq
, from
, 0, NULL
);
935 ospf6_lsa_delete(new);
939 /* (7) if neither one is more recent */
940 if (ismore_recent
== 0) {
943 "The same instance as database copy (neither recent)");
945 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack
947 rem
= ospf6_lsdb_lookup(new->header
->type
, new->header
->id
,
948 new->header
->adv_router
,
953 "It is on the neighbor's retrans-list.");
955 "Treat as an Implied acknowledgement");
957 SET_FLAG(new->flag
, OSPF6_LSA_IMPLIEDACK
);
958 ospf6_decrement_retrans_count(rem
);
959 ospf6_lsdb_remove(rem
, from
->retrans_list
);
963 zlog_debug("Possibly acknowledge and then discard");
965 /* (b) possibly acknowledge */
966 ospf6_acknowledge_lsa(new, ismore_recent
, from
);
968 ospf6_lsa_delete(new);
972 /* (8) previous database copy is more recent */
976 /* If database copy is in 'Seqnumber Wrapping',
977 simply discard the received LSA */
978 if (OSPF6_LSA_IS_MAXAGE(old
)
979 && old
->header
->seqnum
== htonl(OSPF_MAX_SEQUENCE_NUMBER
)) {
981 zlog_debug("The LSA is in Seqnumber Wrapping");
982 zlog_debug("MaxAge & MaxSeqNum, discard");
984 ospf6_lsa_delete(new);
988 /* Otherwise, Send database copy of this LSA to this neighbor */
991 zlog_debug("Database copy is more recent.");
993 "Send back directly and then discard");
996 /* Neighbor router sent recent age for LSA,
997 * Router could be restarted while current copy is
998 * MAXAGEd and not removed.*/
999 if (OSPF6_LSA_IS_MAXAGE(old
)
1000 && !OSPF6_LSA_IS_MAXAGE(new)) {
1001 if (new->header
->adv_router
1002 != from
->ospf6_if
->area
->ospf6
->router_id
) {
1005 "%s: Current copy of LSA %s is MAXAGE, but new has recent age, flooding/installing.",
1006 old
->name
, __PRETTY_FUNCTION__
);
1007 ospf6_lsa_purge(old
);
1008 ospf6_flood(from
, new);
1009 ospf6_install_lsa(new);
1013 "%s: Current copy of self-originated LSA %s is MAXAGE, but new has recent age, ignoring new.",
1014 old
->name
, __PRETTY_FUNCTION__
);
1015 ospf6_lsa_delete(new);
1020 /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
1022 ospf6_lsdb_add(ospf6_lsa_copy(old
),
1023 from
->lsupdate_list
);
1024 thread_add_event(master
, ospf6_lsupdate_send_neighbor
,
1025 from
, 0, &from
->thread_send_lsupdate
);
1027 ospf6_lsa_delete(new);
1034 DEFUN (debug_ospf6_flooding
,
1035 debug_ospf6_flooding_cmd
,
1036 "debug ospf6 flooding",
1039 "Debug OSPFv3 flooding function\n"
1042 OSPF6_DEBUG_FLOODING_ON();
1046 DEFUN (no_debug_ospf6_flooding
,
1047 no_debug_ospf6_flooding_cmd
,
1048 "no debug ospf6 flooding",
1052 "Debug OSPFv3 flooding function\n"
1055 OSPF6_DEBUG_FLOODING_OFF();
1059 int config_write_ospf6_debug_flood(struct vty
*vty
)
1061 if (IS_OSPF6_DEBUG_FLOODING
)
1062 vty_out(vty
, "debug ospf6 flooding\n");
1066 void install_element_ospf6_debug_flood(void)
1068 install_element(ENABLE_NODE
, &debug_ospf6_flooding_cmd
);
1069 install_element(ENABLE_NODE
, &no_debug_ospf6_flooding_cmd
);
1070 install_element(CONFIG_NODE
, &debug_ospf6_flooding_cmd
);
1071 install_element(CONFIG_NODE
, &no_debug_ospf6_flooding_cmd
);