1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2003 Yasuhiro Ohara
15 #include "ospf6_proto.h"
16 #include "ospf6_lsa.h"
17 #include "ospf6_lsdb.h"
18 #include "ospf6_message.h"
19 #include "ospf6_route.h"
20 #include "ospf6_spf.h"
22 #include "ospf6_top.h"
23 #include "ospf6_area.h"
24 #include "ospf6_interface.h"
25 #include "ospf6_neighbor.h"
27 #include "ospf6_flood.h"
28 #include "ospf6_nssa.h"
31 unsigned char conf_debug_ospf6_flooding
;
33 struct ospf6_lsdb
*ospf6_get_scoped_lsdb(struct ospf6_lsa
*lsa
)
35 struct ospf6_lsdb
*lsdb
= NULL
;
36 switch (OSPF6_LSA_SCOPE(lsa
->header
->type
)) {
37 case OSPF6_SCOPE_LINKLOCAL
:
38 lsdb
= OSPF6_INTERFACE(lsa
->lsdb
->data
)->lsdb
;
40 case OSPF6_SCOPE_AREA
:
41 lsdb
= OSPF6_AREA(lsa
->lsdb
->data
)->lsdb
;
44 lsdb
= OSPF6_PROCESS(lsa
->lsdb
->data
)->lsdb
;
53 struct ospf6_lsdb
*ospf6_get_scoped_lsdb_self(struct ospf6_lsa
*lsa
)
55 struct ospf6_lsdb
*lsdb_self
= NULL
;
56 switch (OSPF6_LSA_SCOPE(lsa
->header
->type
)) {
57 case OSPF6_SCOPE_LINKLOCAL
:
58 lsdb_self
= OSPF6_INTERFACE(lsa
->lsdb
->data
)->lsdb_self
;
60 case OSPF6_SCOPE_AREA
:
61 lsdb_self
= OSPF6_AREA(lsa
->lsdb
->data
)->lsdb_self
;
64 lsdb_self
= OSPF6_PROCESS(lsa
->lsdb
->data
)->lsdb_self
;
73 void ospf6_lsa_originate(struct ospf6
*ospf6
, struct ospf6_lsa
*lsa
)
75 struct ospf6_lsa
*old
;
76 struct ospf6_lsdb
*lsdb_self
;
78 if (lsa
->header
->adv_router
== INADDR_ANY
) {
79 if (IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa
->header
->type
))
81 "Refusing to originate LSA (zero router ID): %s",
84 ospf6_lsa_delete(lsa
);
88 /* find previous LSA */
89 old
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
90 lsa
->header
->adv_router
, lsa
->lsdb
);
92 /* if the new LSA does not differ from previous,
93 suppress this update of the LSA */
94 if (old
&& !OSPF6_LSA_IS_DIFFER(lsa
, old
)
95 && !ospf6
->gr_info
.finishing_restart
) {
96 if (IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa
->header
->type
))
97 zlog_debug("Suppress updating LSA: %s", lsa
->name
);
98 ospf6_lsa_delete(lsa
);
102 /* store it in the LSDB for self-originated LSAs */
103 lsdb_self
= ospf6_get_scoped_lsdb_self(lsa
);
104 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), lsdb_self
);
106 EVENT_OFF(lsa
->refresh
);
107 event_add_timer(master
, ospf6_lsa_refresh
, lsa
, OSPF_LS_REFRESH_TIME
,
110 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
)
111 || IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa
->header
->type
)) {
112 zlog_debug("LSA Originate:");
113 ospf6_lsa_header_print(lsa
);
116 ospf6_install_lsa(lsa
);
117 ospf6_flood(NULL
, lsa
);
120 void ospf6_lsa_originate_process(struct ospf6_lsa
*lsa
, struct ospf6
*process
)
122 lsa
->lsdb
= process
->lsdb
;
123 ospf6_lsa_originate(process
, lsa
);
126 void ospf6_lsa_originate_area(struct ospf6_lsa
*lsa
, struct ospf6_area
*oa
)
128 lsa
->lsdb
= oa
->lsdb
;
129 ospf6_lsa_originate(oa
->ospf6
, lsa
);
132 void ospf6_lsa_originate_interface(struct ospf6_lsa
*lsa
,
133 struct ospf6_interface
*oi
)
135 lsa
->lsdb
= oi
->lsdb
;
136 ospf6_lsa_originate(oi
->area
->ospf6
, lsa
);
139 void ospf6_external_lsa_purge(struct ospf6
*ospf6
, struct ospf6_lsa
*lsa
)
141 uint32_t id
= lsa
->header
->id
;
142 struct ospf6_area
*oa
;
143 struct listnode
*lnode
;
145 ospf6_lsa_purge(lsa
);
147 /* Delete the corresponding NSSA LSA */
148 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, lnode
, oa
)) {
149 lsa
= ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_TYPE_7
), id
,
150 ospf6
->router_id
, oa
->lsdb
);
152 if (IS_OSPF6_DEBUG_NSSA
)
153 zlog_debug("withdraw type 7 lsa, LS ID: %u",
156 ospf6_lsa_purge(lsa
);
161 void ospf6_lsa_purge(struct ospf6_lsa
*lsa
)
163 struct ospf6_lsa
*self
;
164 struct ospf6_lsdb
*lsdb_self
;
166 /* remove it from the LSDB for self-originated LSAs */
167 lsdb_self
= ospf6_get_scoped_lsdb_self(lsa
);
168 self
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
169 lsa
->header
->adv_router
, lsdb_self
);
171 EVENT_OFF(self
->expire
);
172 EVENT_OFF(self
->refresh
);
173 ospf6_lsdb_remove(self
, lsdb_self
);
176 ospf6_lsa_premature_aging(lsa
);
179 /* Puring Multi Link-State IDs LSAs:
180 * Same Advertising Router with Multiple Link-State IDs
181 * LSAs, purging require to traverse all Link-State IDs
183 void ospf6_lsa_purge_multi_ls_id(struct ospf6_area
*oa
, struct ospf6_lsa
*lsa
)
186 struct ospf6_lsa
*lsa_next
;
189 type
= lsa
->header
->type
;
191 ospf6_lsa_purge(lsa
);
193 lsa_next
= ospf6_lsdb_lookup(type
, htonl(++ls_id
),
194 oa
->ospf6
->router_id
, oa
->lsdb
);
196 ospf6_lsa_purge(lsa_next
);
197 lsa_next
= ospf6_lsdb_lookup(type
, htonl(++ls_id
),
198 oa
->ospf6
->router_id
, oa
->lsdb
);
202 void ospf6_increment_retrans_count(struct ospf6_lsa
*lsa
)
204 /* The LSA must be the original one (see the description
205 in ospf6_decrement_retrans_count () below) */
206 lsa
->retrans_count
++;
209 void ospf6_decrement_retrans_count(struct ospf6_lsa
*lsa
)
211 struct ospf6_lsdb
*lsdb
;
212 struct ospf6_lsa
*orig
;
214 /* The LSA must be on the retrans-list of a neighbor. It means
215 the "lsa" is a copied one, and we have to decrement the
216 retransmission count of the original one (instead of this "lsa"'s).
217 In order to find the original LSA, first we have to find
218 appropriate LSDB that have the original LSA. */
219 lsdb
= ospf6_get_scoped_lsdb(lsa
);
221 /* Find the original LSA of which the retrans_count should be
223 orig
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
224 lsa
->header
->adv_router
, lsdb
);
226 orig
->retrans_count
--;
227 assert(orig
->retrans_count
>= 0);
231 /* RFC2328 section 13.2 Installing LSAs in the database */
232 void ospf6_install_lsa(struct ospf6_lsa
*lsa
)
236 struct ospf6_lsa
*old
;
237 struct ospf6_area
*area
= NULL
;
239 ospf6
= ospf6_get_by_lsdb(lsa
);
242 /* Remove the old instance from all neighbors' Link state
243 retransmission list (RFC2328 13.2 last paragraph) */
244 old
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
245 lsa
->header
->adv_router
, lsa
->lsdb
);
247 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_TYPE_7
) {
248 if (IS_OSPF6_DEBUG_NSSA
)
249 zlog_debug("%s : old LSA %s", __func__
,
251 lsa
->external_lsa_id
= old
->external_lsa_id
;
253 EVENT_OFF(old
->expire
);
254 EVENT_OFF(old
->refresh
);
255 ospf6_flood_clear(old
);
259 if (!OSPF6_LSA_IS_MAXAGE(lsa
)) {
260 event_add_timer(master
, ospf6_lsa_expire
, lsa
,
261 OSPF_LSA_MAXAGE
+ lsa
->birth
.tv_sec
-
267 if (OSPF6_LSA_IS_SEQWRAP(lsa
)
268 && !(CHECK_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
)
269 && lsa
->header
->seqnum
== htonl(OSPF_MAX_SEQUENCE_NUMBER
))) {
270 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
))
271 zlog_debug("lsa install wrapping: sequence 0x%x",
272 ntohl(lsa
->header
->seqnum
));
273 SET_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
);
274 /* in lieu of premature_aging, since we do not want to recreate
276 * and/or mess with timers etc, we just want to wrap the
278 * and reflood the lsa before continuing.
279 * NOTE: Flood needs to be called right after this function
283 lsa
->header
->seqnum
= htonl(OSPF_MAX_SEQUENCE_NUMBER
);
284 lsa
->header
->age
= htons(OSPF_LSA_MAXAGE
);
285 ospf6_lsa_checksum(lsa
->header
);
288 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
)
289 || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
))
290 zlog_debug("%s Install LSA: %s age %d seqnum %x in LSDB.",
291 __func__
, lsa
->name
, ntohs(lsa
->header
->age
),
292 ntohl(lsa
->header
->seqnum
));
294 /* actually install */
295 lsa
->installed
= now
;
297 /* Topo change handling */
298 if (CHECK_LSA_TOPO_CHG_ELIGIBLE(ntohs(lsa
->header
->type
))
299 && !CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)) {
301 /* check if it is new lsa ? or existing lsa got modified ?*/
302 if (!old
|| OSPF6_LSA_IS_CHANGED(old
, lsa
))
303 ospf6_helper_handle_topo_chg(ospf6
, lsa
);
306 ospf6_lsdb_add(lsa
, lsa
->lsdb
);
308 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_TYPE_7
309 && lsa
->header
->adv_router
!= ospf6
->router_id
) {
310 area
= OSPF6_AREA(lsa
->lsdb
->data
);
311 ospf6_translated_nssa_refresh(area
, lsa
, NULL
);
312 ospf6_schedule_abr_task(area
->ospf6
);
315 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_ROUTER
) {
316 area
= OSPF6_AREA(lsa
->lsdb
->data
);
318 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
)
319 || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
))
320 zlog_debug("%s: New router LSA %s", __func__
,
322 ospf6_abr_nssa_check_status(area
->ospf6
);
328 /* RFC2740 section 3.5.2. Sending Link State Update packets */
329 /* RFC2328 section 13.3 Next step in the flooding procedure */
330 void ospf6_flood_interface(struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
,
331 struct ospf6_interface
*oi
)
333 struct listnode
*node
, *nnode
;
334 struct ospf6_neighbor
*on
;
335 struct ospf6_lsa
*req
, *old
;
336 int retrans_added
= 0;
339 if (IS_OSPF6_DEBUG_FLOODING
340 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
)) {
342 zlog_debug("Flooding on %s: %s", oi
->interface
->name
,
346 /* (1) For each neighbor */
347 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
349 zlog_debug("To neighbor %s", on
->name
);
351 /* (a) if neighbor state < Exchange, examin next */
352 if (on
->state
< OSPF6_NEIGHBOR_EXCHANGE
) {
355 "Neighbor state less than ExChange, next neighbor");
359 /* (b) if neighbor not yet Full, check request-list */
360 if (on
->state
!= OSPF6_NEIGHBOR_FULL
) {
362 zlog_debug("Neighbor not yet Full");
364 req
= ospf6_lsdb_lookup(
365 lsa
->header
->type
, lsa
->header
->id
,
366 lsa
->header
->adv_router
, on
->request_list
);
370 "Not on request-list for this neighbor");
373 /* If new LSA less recent, examin next neighbor
375 if (ospf6_lsa_compare(lsa
, req
) > 0) {
378 "Requesting is older, next neighbor");
382 /* If the same instance, delete from
384 examin next neighbor */
385 if (ospf6_lsa_compare(lsa
, req
) == 0) {
388 "Requesting the same, remove it, next neighbor");
389 if (req
== on
->last_ls_req
) {
390 /* sanity check refcount */
391 assert(req
->lock
>= 2);
392 req
= ospf6_lsa_unlock(req
);
393 on
->last_ls_req
= NULL
;
397 req
, on
->request_list
);
398 ospf6_check_nbr_loading(on
);
402 /* If the new LSA is more recent, delete from
404 if (ospf6_lsa_compare(lsa
, req
) < 0) {
407 "Received is newer, remove requesting");
408 if (req
== on
->last_ls_req
) {
409 req
= ospf6_lsa_unlock(req
);
410 on
->last_ls_req
= NULL
;
413 ospf6_lsdb_remove(req
,
415 ospf6_check_nbr_loading(on
);
421 /* (c) If the new LSA was received from this neighbor,
422 examin next neighbor */
426 "Received is from the neighbor, next neighbor");
430 if ((oi
->area
->ospf6
->inst_shutdown
)
431 || CHECK_FLAG(lsa
->flag
, OSPF6_LSA_FLUSH
)) {
434 "%s: Send LSA %s (age %d) update now",
436 ntohs(lsa
->header
->age
));
437 ospf6_lsupdate_send_neighbor_now(on
, lsa
);
440 /* (d) add retrans-list, schedule retransmission */
442 zlog_debug("Add retrans-list of neighbor %s ",
445 /* Do not increment the retrans count if the lsa is
446 * already present in the retrans list.
448 old
= ospf6_lsdb_lookup(
449 lsa
->header
->type
, lsa
->header
->id
,
450 lsa
->header
->adv_router
, on
->retrans_list
);
452 struct ospf6_lsa
*orig
;
453 struct ospf6_lsdb
*lsdb
;
457 "Increment %s from retrans_list of %s",
458 lsa
->name
, on
->name
);
460 /* Increment the retrans count on the original
461 * copy of LSA if present, to maintain the
462 * counter consistency.
465 lsdb
= ospf6_get_scoped_lsdb(lsa
);
466 orig
= ospf6_lsdb_lookup(
467 lsa
->header
->type
, lsa
->header
->id
,
468 lsa
->header
->adv_router
, lsdb
);
470 ospf6_increment_retrans_count(orig
);
472 ospf6_increment_retrans_count(lsa
);
474 ospf6_lsdb_add(ospf6_lsa_copy(lsa
),
476 event_add_timer(master
,
477 ospf6_lsupdate_send_neighbor
,
478 on
, on
->ospf6_if
->rxmt_interval
,
479 &on
->thread_send_lsupdate
);
485 /* (2) examin next interface if not added to retrans-list */
486 if (retrans_added
== 0) {
489 "No retransmission scheduled, next interface %s",
490 oi
->interface
->name
);
494 /* (3) If the new LSA was received on this interface,
495 and it was from DR or BDR, examin next interface */
496 if (from
&& from
->ospf6_if
== oi
497 && (from
->router_id
== oi
->drouter
498 || from
->router_id
== oi
->bdrouter
)) {
501 "Received is from the I/F's DR or BDR, next interface");
505 /* (4) If the new LSA was received on this interface,
506 and the interface state is BDR, examin next interface */
507 if (from
&& from
->ospf6_if
== oi
) {
508 if (oi
->state
== OSPF6_INTERFACE_BDR
) {
511 "Received is from the I/F, itself BDR, next interface");
514 SET_FLAG(lsa
->flag
, OSPF6_LSA_FLOODBACK
);
517 /* (5) flood the LSA out the interface. */
519 zlog_debug("Schedule flooding for the interface");
520 if ((oi
->type
== OSPF_IFTYPE_BROADCAST
)
521 || (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)) {
522 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsupdate_list
);
523 event_add_event(master
, ospf6_lsupdate_send_interface
, oi
, 0,
524 &oi
->thread_send_lsupdate
);
526 /* reschedule retransmissions to all neighbors */
527 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
528 EVENT_OFF(on
->thread_send_lsupdate
);
529 event_add_event(master
, ospf6_lsupdate_send_neighbor
,
530 on
, 0, &on
->thread_send_lsupdate
);
535 void ospf6_flood_area(struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
,
536 struct ospf6_area
*oa
)
538 struct listnode
*node
, *nnode
;
539 struct ospf6_interface
*oi
;
541 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
)) {
542 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
543 && oi
!= OSPF6_INTERFACE(lsa
->lsdb
->data
))
546 ospf6_flood_interface(from
, lsa
, oi
);
550 static void ospf6_flood_process(struct ospf6_neighbor
*from
,
551 struct ospf6_lsa
*lsa
, struct ospf6
*process
)
553 struct listnode
*node
, *nnode
;
554 struct ospf6_area
*oa
;
556 for (ALL_LIST_ELEMENTS(process
->area_list
, node
, nnode
, oa
)) {
558 /* If unknown LSA and U-bit clear, treat as link local
561 if (!OSPF6_LSA_IS_KNOWN(lsa
->header
->type
)
562 && !(ntohs(lsa
->header
->type
) & OSPF6_LSTYPE_UBIT_MASK
)
563 && (oa
!= OSPF6_INTERFACE(lsa
->lsdb
->data
)->area
)) {
565 if (IS_OSPF6_DEBUG_FLOODING
)
566 zlog_debug("Unknown LSA, do not flood");
570 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_AREA
571 && oa
!= OSPF6_AREA(lsa
->lsdb
->data
))
573 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
574 && oa
!= OSPF6_INTERFACE(lsa
->lsdb
->data
)->area
)
577 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
578 && (IS_AREA_STUB(oa
) || IS_AREA_NSSA(oa
)))
581 /* Check for NSSA LSA */
582 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_TYPE_7
583 && !IS_AREA_NSSA(oa
) && !OSPF6_LSA_IS_MAXAGE(lsa
))
586 ospf6_flood_area(from
, lsa
, oa
);
590 void ospf6_flood(struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
)
594 ospf6
= ospf6_get_by_lsdb(lsa
);
598 ospf6_flood_process(from
, lsa
, ospf6
);
601 static void ospf6_flood_clear_interface(struct ospf6_lsa
*lsa
,
602 struct ospf6_interface
*oi
)
604 struct listnode
*node
, *nnode
;
605 struct ospf6_neighbor
*on
;
606 struct ospf6_lsa
*rem
;
608 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
609 rem
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
610 lsa
->header
->adv_router
,
612 if (rem
&& !ospf6_lsa_compare(rem
, lsa
)) {
613 if (IS_OSPF6_DEBUG_FLOODING
614 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
615 zlog_debug("Remove %s from retrans_list of %s",
616 rem
->name
, on
->name
);
617 ospf6_decrement_retrans_count(rem
);
618 ospf6_lsdb_remove(rem
, on
->retrans_list
);
623 void ospf6_flood_clear_area(struct ospf6_lsa
*lsa
, struct ospf6_area
*oa
)
625 struct listnode
*node
, *nnode
;
626 struct ospf6_interface
*oi
;
628 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
)) {
629 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
630 && oi
!= OSPF6_INTERFACE(lsa
->lsdb
->data
))
633 ospf6_flood_clear_interface(lsa
, oi
);
637 static void ospf6_flood_clear_process(struct ospf6_lsa
*lsa
,
638 struct ospf6
*process
)
640 struct listnode
*node
, *nnode
;
641 struct ospf6_area
*oa
;
643 for (ALL_LIST_ELEMENTS(process
->area_list
, node
, nnode
, oa
)) {
644 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_AREA
645 && oa
!= OSPF6_AREA(lsa
->lsdb
->data
))
647 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
648 && oa
!= OSPF6_INTERFACE(lsa
->lsdb
->data
)->area
)
651 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
652 && (IS_AREA_STUB(oa
) || (IS_AREA_NSSA(oa
))))
654 /* Check for NSSA LSA */
655 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_TYPE_7
656 && !IS_AREA_NSSA(oa
))
659 ospf6_flood_clear_area(lsa
, oa
);
663 void ospf6_flood_clear(struct ospf6_lsa
*lsa
)
667 ospf6
= ospf6_get_by_lsdb(lsa
);
670 ospf6_flood_clear_process(lsa
, ospf6
);
674 /* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
675 static void ospf6_acknowledge_lsa_bdrouter(struct ospf6_lsa
*lsa
,
677 struct ospf6_neighbor
*from
)
679 struct ospf6_interface
*oi
;
682 if (IS_OSPF6_DEBUG_FLOODING
683 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
686 assert(from
&& from
->ospf6_if
);
689 /* LSA is more recent than database copy, but was not flooded
690 back out receiving interface. Delayed acknowledgement sent
691 if advertisement received from Designated Router,
692 otherwide do nothing. */
693 if (ismore_recent
< 0) {
694 if (oi
->drouter
== from
->router_id
) {
697 "Delayed acknowledgement (BDR & MoreRecent & from DR)");
698 /* Delayed acknowledgement */
699 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsack_list
);
700 event_add_timer(master
, ospf6_lsack_send_interface
, oi
,
701 3, &oi
->thread_send_lsack
);
705 "No acknowledgement (BDR & MoreRecent & ! from DR)");
710 /* LSA is a duplicate, and was treated as an implied acknowledgement.
711 Delayed acknowledgement sent if advertisement received from
712 Designated Router, otherwise do nothing */
713 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
714 && CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
715 if (oi
->drouter
== from
->router_id
) {
718 "Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
719 /* Delayed acknowledgement */
720 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsack_list
);
721 event_add_timer(master
, ospf6_lsack_send_interface
, oi
,
722 3, &oi
->thread_send_lsack
);
726 "No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
731 /* LSA is a duplicate, and was not treated as an implied
733 Direct acknowledgement sent */
734 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
735 && !CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
737 zlog_debug("Direct acknowledgement (BDR & Duplicate)");
738 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), from
->lsack_list
);
739 event_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
740 &from
->thread_send_lsack
);
744 /* LSA's LS age is equal to Maxage, and there is no current instance
745 of the LSA in the link state database, and none of router's
746 neighbors are in states Exchange or Loading */
747 /* Direct acknowledgement sent, but this case is handled in
748 early of ospf6_receive_lsa () */
751 static void ospf6_acknowledge_lsa_allother(struct ospf6_lsa
*lsa
,
753 struct ospf6_neighbor
*from
)
755 struct ospf6_interface
*oi
;
758 if (IS_OSPF6_DEBUG_FLOODING
759 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
762 assert(from
&& from
->ospf6_if
);
765 /* LSA has been flood back out receiving interface.
766 No acknowledgement sent. */
767 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_FLOODBACK
)) {
769 zlog_debug("No acknowledgement (AllOther & FloodBack)");
773 /* LSA is more recent than database copy, but was not flooded
774 back out receiving interface. Delayed acknowledgement sent. */
775 if (ismore_recent
< 0) {
778 "Delayed acknowledgement (AllOther & MoreRecent)");
779 /* Delayed acknowledgement */
780 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsack_list
);
781 event_add_timer(master
, ospf6_lsack_send_interface
, oi
, 3,
782 &oi
->thread_send_lsack
);
786 /* LSA is a duplicate, and was treated as an implied acknowledgement.
787 No acknowledgement sent. */
788 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
789 && CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
792 "No acknowledgement (AllOther & Duplicate & ImpliedAck)");
796 /* LSA is a duplicate, and was not treated as an implied
798 Direct acknowledgement sent */
799 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
800 && !CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
803 "Direct acknowledgement (AllOther & Duplicate)");
804 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), from
->lsack_list
);
805 event_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
806 &from
->thread_send_lsack
);
810 /* LSA's LS age is equal to Maxage, and there is no current instance
811 of the LSA in the link state database, and none of router's
812 neighbors are in states Exchange or Loading */
813 /* Direct acknowledgement sent, but this case is handled in
814 early of ospf6_receive_lsa () */
817 static void ospf6_acknowledge_lsa(struct ospf6_lsa
*lsa
, int ismore_recent
,
818 struct ospf6_neighbor
*from
)
820 struct ospf6_interface
*oi
;
822 assert(from
&& from
->ospf6_if
);
825 if (oi
->state
== OSPF6_INTERFACE_BDR
)
826 ospf6_acknowledge_lsa_bdrouter(lsa
, ismore_recent
, from
);
828 ospf6_acknowledge_lsa_allother(lsa
, ismore_recent
, from
);
831 /* RFC2328 section 13 (4):
832 if MaxAge LSA and if we have no instance, and no neighbor
833 is in states Exchange or Loading
834 returns 1 if match this case, else returns 0 */
835 static int ospf6_is_maxage_lsa_drop(struct ospf6_lsa
*lsa
,
836 struct ospf6_neighbor
*from
)
838 struct ospf6_neighbor
*on
;
839 struct ospf6_interface
*oi
;
840 struct ospf6_area
*oa
;
841 struct ospf6
*process
= NULL
;
842 struct listnode
*i
, *j
, *k
;
845 if (!OSPF6_LSA_IS_MAXAGE(lsa
))
848 if (ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
849 lsa
->header
->adv_router
, lsa
->lsdb
))
852 process
= from
->ospf6_if
->area
->ospf6
;
854 for (ALL_LIST_ELEMENTS_RO(process
->area_list
, i
, oa
))
855 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
856 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, k
, on
))
857 if (on
->state
== OSPF6_NEIGHBOR_EXCHANGE
858 || on
->state
== OSPF6_NEIGHBOR_LOADING
)
866 static bool ospf6_lsa_check_min_arrival(struct ospf6_lsa
*lsa
,
867 struct ospf6_neighbor
*from
)
869 struct timeval now
, res
;
870 unsigned int time_delta_ms
;
873 timersub(&now
, &lsa
->installed
, &res
);
874 time_delta_ms
= (res
.tv_sec
* 1000) + (int)(res
.tv_usec
/ 1000);
876 if (time_delta_ms
< from
->ospf6_if
->area
->ospf6
->lsa_minarrival
) {
877 if (IS_OSPF6_DEBUG_FLOODING
||
878 IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
880 "LSA can't be updated within MinLSArrival, %dms < %dms, discard",
882 from
->ospf6_if
->area
->ospf6
->lsa_minarrival
);
888 /* RFC2328 section 13 The Flooding Procedure */
889 void ospf6_receive_lsa(struct ospf6_neighbor
*from
,
890 struct ospf6_lsa_header
*lsa_header
)
892 struct ospf6_lsa
*new = NULL
, *old
= NULL
, *rem
= NULL
;
899 /* if we receive a LSA with invalid seqnum drop it */
900 if (ntohl(lsa_header
->seqnum
) - 1 == OSPF_MAX_SEQUENCE_NUMBER
) {
901 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa_header
->type
)) {
903 "received lsa [%s Id:%pI4 Adv:%pI4] with invalid seqnum 0x%x, ignore",
904 ospf6_lstype_name(lsa_header
->type
),
905 &lsa_header
->id
, &lsa_header
->adv_router
,
906 ntohl(lsa_header
->seqnum
));
911 /* make lsa structure for received lsa */
912 new = ospf6_lsa_create(lsa_header
);
914 if (IS_OSPF6_DEBUG_FLOODING
915 || IS_OSPF6_DEBUG_FLOOD_TYPE(new->header
->type
)) {
917 zlog_debug("LSA Receive from %s", from
->name
);
918 ospf6_lsa_header_print(new);
921 /* (1) LSA Checksum */
922 if (!ospf6_lsa_checksum_valid(new->header
)) {
925 "Wrong LSA Checksum %s (Router-ID: %pI4) [Type:%s Checksum:%#06hx), discard",
926 from
->name
, &from
->router_id
,
927 ospf6_lstype_name(new->header
->type
),
928 ntohs(new->header
->checksum
));
929 ospf6_lsa_delete(new);
933 /* (2) Examine the LSA's LS type.
934 RFC2470 3.5.1. Receiving Link State Update packets */
935 if (IS_AREA_STUB(from
->ospf6_if
->area
)
936 && OSPF6_LSA_SCOPE(new->header
->type
) == OSPF6_SCOPE_AS
) {
939 "AS-External-LSA (or AS-scope LSA) in stub area, discard");
940 ospf6_lsa_delete(new);
944 /* (3) LSA which have reserved scope is discarded
945 RFC2470 3.5.1. Receiving Link State Update packets */
946 /* Flooding scope check. LSAs with unknown scope are discarded here.
947 Set appropriate LSDB for the LSA */
948 switch (OSPF6_LSA_SCOPE(new->header
->type
)) {
949 case OSPF6_SCOPE_LINKLOCAL
:
950 new->lsdb
= from
->ospf6_if
->lsdb
;
952 case OSPF6_SCOPE_AREA
:
953 new->lsdb
= from
->ospf6_if
->area
->lsdb
;
956 new->lsdb
= from
->ospf6_if
->area
->ospf6
->lsdb
;
960 zlog_debug("LSA has reserved scope, discard");
961 ospf6_lsa_delete(new);
965 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
966 is in states Exchange or Loading */
967 if (ospf6_is_maxage_lsa_drop(new, from
)) {
971 "Drop MaxAge LSA with direct acknowledgement.");
973 /* a) Acknowledge back to neighbor (Direct acknowledgement,
975 ospf6_lsdb_add(ospf6_lsa_copy(new), from
->lsack_list
);
976 event_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
977 &from
->thread_send_lsack
);
980 ospf6_lsa_delete(new);
985 /* lookup the same database copy in lsdb */
986 old
= ospf6_lsdb_lookup(new->header
->type
, new->header
->id
,
987 new->header
->adv_router
, new->lsdb
);
989 ismore_recent
= ospf6_lsa_compare(new, old
);
990 if (ntohl(new->header
->seqnum
) == ntohl(old
->header
->seqnum
)) {
992 zlog_debug("Received is duplicated LSA");
993 SET_FLAG(new->flag
, OSPF6_LSA_DUPLICATE
);
997 /* if no database copy or received is more recent */
998 if (old
== NULL
|| ismore_recent
< 0) {
999 bool self_originated
;
1001 /* in case we have no database copy */
1004 /* (a) MinLSArrival check */
1006 if (ospf6_lsa_check_min_arrival(old
, from
)) {
1007 ospf6_lsa_delete(new);
1008 return; /* examin next lsa */
1012 monotime(&new->received
);
1016 "Install, Flood, Possibly acknowledge the received LSA");
1018 /* Remove older copies of this LSA from retx lists */
1020 ospf6_flood_clear(old
);
1022 self_originated
= (new->header
->adv_router
1023 == from
->ospf6_if
->area
->ospf6
->router_id
);
1025 /* Received non-self-originated Grace LSA. */
1026 if (IS_GRACE_LSA(new) && !self_originated
) {
1027 struct ospf6
*ospf6
;
1029 ospf6
= ospf6_get_by_lsdb(new);
1033 if (OSPF6_LSA_IS_MAXAGE(new)) {
1035 if (IS_DEBUG_OSPF6_GR
)
1037 "%s, Received a maxage GraceLSA from router %pI4",
1039 &new->header
->adv_router
);
1041 ospf6_process_maxage_grace_lsa(
1044 if (IS_DEBUG_OSPF6_GR
)
1046 "%s, GraceLSA doesn't exist in lsdb, so discarding GraceLSA",
1052 if (IS_DEBUG_OSPF6_GR
)
1054 "%s, Received a GraceLSA from router %pI4",
1056 &new->header
->adv_router
);
1058 if (ospf6_process_grace_lsa(ospf6
, new, from
)
1059 == OSPF6_GR_NOT_HELPER
) {
1060 if (IS_DEBUG_OSPF6_GR
)
1062 "%s, Not moving to HELPER role, So dicarding GraceLSA",
1069 /* (b) immediately flood and (c) remove from all retrans-list */
1070 /* Prevent self-originated LSA to be flooded. this is to make
1071 * reoriginated instance of the LSA not to be rejected by other
1072 * routers due to MinLSArrival.
1074 if (!self_originated
)
1075 ospf6_flood(from
, new);
1077 /* (d), installing lsdb, which may cause routing
1078 table calculation (replacing database copy) */
1079 ospf6_install_lsa(new);
1081 if (OSPF6_LSA_IS_MAXAGE(new))
1082 ospf6_maxage_remove(from
->ospf6_if
->area
->ospf6
);
1084 /* (e) possibly acknowledge */
1085 ospf6_acknowledge_lsa(new, ismore_recent
, from
);
1087 /* (f) Self Originated LSA, section 13.4 */
1088 if (self_originated
) {
1089 if (from
->ospf6_if
->area
->ospf6
->gr_info
1090 .restart_in_progress
) {
1091 if (IS_DEBUG_OSPF6_GR
)
1093 "Graceful Restart in progress -- not flushing self-originated LSA: %s",
1098 /* Self-originated LSA (newer than ours) is received
1100 another router. We have to make a new instance of the
1102 or have to flush this LSA. */
1105 "Newer instance of the self-originated LSA");
1106 zlog_debug("Schedule reorigination");
1108 event_add_event(master
, ospf6_lsa_refresh
, new, 0,
1112 /* GR: check for network topology change. */
1113 struct ospf6
*ospf6
= from
->ospf6_if
->area
->ospf6
;
1114 struct ospf6_area
*area
= from
->ospf6_if
->area
;
1115 if (ospf6
->gr_info
.restart_in_progress
&&
1116 (new->header
->type
== ntohs(OSPF6_LSTYPE_ROUTER
) ||
1117 new->header
->type
== ntohs(OSPF6_LSTYPE_NETWORK
)))
1118 ospf6_gr_check_lsdb_consistency(ospf6
, area
);
1123 /* (6) if there is instance on sending neighbor's request list */
1124 if (ospf6_lsdb_lookup(new->header
->type
, new->header
->id
,
1125 new->header
->adv_router
, from
->request_list
)) {
1126 /* if no database copy, should go above state (5) */
1130 "Received is not newer, on the neighbor %s request-list",
1133 "BadLSReq, discard the received LSA lsa %s send badLSReq",
1137 event_add_event(master
, bad_lsreq
, from
, 0, NULL
);
1139 ospf6_lsa_delete(new);
1143 /* (7) if neither one is more recent */
1144 if (ismore_recent
== 0) {
1147 "The same instance as database copy (neither recent)");
1149 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack
1151 rem
= ospf6_lsdb_lookup(new->header
->type
, new->header
->id
,
1152 new->header
->adv_router
,
1153 from
->retrans_list
);
1157 "It is on the neighbor's retrans-list.");
1159 "Treat as an Implied acknowledgement");
1161 SET_FLAG(new->flag
, OSPF6_LSA_IMPLIEDACK
);
1162 ospf6_decrement_retrans_count(rem
);
1163 ospf6_lsdb_remove(rem
, from
->retrans_list
);
1167 zlog_debug("Possibly acknowledge and then discard");
1169 /* (b) possibly acknowledge */
1170 ospf6_acknowledge_lsa(new, ismore_recent
, from
);
1172 ospf6_lsa_delete(new);
1176 /* (8) previous database copy is more recent */
1180 /* If database copy is in 'Seqnumber Wrapping',
1181 simply discard the received LSA */
1182 if (OSPF6_LSA_IS_MAXAGE(old
)
1183 && old
->header
->seqnum
== htonl(OSPF_MAX_SEQUENCE_NUMBER
)) {
1185 zlog_debug("The LSA is in Seqnumber Wrapping");
1186 zlog_debug("MaxAge & MaxSeqNum, discard");
1188 ospf6_lsa_delete(new);
1192 /* Otherwise, Send database copy of this LSA to this neighbor */
1195 zlog_debug("Database copy is more recent.");
1197 "Send back directly and then discard");
1200 /* Neighbor router sent recent age for LSA,
1201 * Router could be restarted while current copy is
1202 * MAXAGEd and not removed.*/
1203 if (OSPF6_LSA_IS_MAXAGE(old
)
1204 && !OSPF6_LSA_IS_MAXAGE(new)) {
1205 if (new->header
->adv_router
1206 != from
->ospf6_if
->area
->ospf6
->router_id
) {
1209 "%s: Current copy of LSA %s is MAXAGE, but new has recent age, flooding/installing.",
1210 __PRETTY_FUNCTION__
, old
->name
);
1211 ospf6_lsa_purge(old
);
1212 ospf6_flood(from
, new);
1213 ospf6_install_lsa(new);
1216 /* For self-originated LSA, only trust
1217 * ourselves. Fall through and send
1218 * LS Update with our current copy.
1222 "%s: Current copy of self-originated LSA %s is MAXAGE, but new has recent age, re-sending current one.",
1223 __PRETTY_FUNCTION__
, old
->name
);
1226 /* MinLSArrival check as per RFC 2328 13 (8) */
1227 if (ospf6_lsa_check_min_arrival(old
, from
)) {
1228 ospf6_lsa_delete(new);
1229 return; /* examin next lsa */
1232 ospf6_lsdb_add(ospf6_lsa_copy(old
),
1233 from
->lsupdate_list
);
1234 event_add_event(master
, ospf6_lsupdate_send_neighbor
,
1235 from
, 0, &from
->thread_send_lsupdate
);
1237 ospf6_lsa_delete(new);
1243 DEFUN (debug_ospf6_flooding
,
1244 debug_ospf6_flooding_cmd
,
1245 "debug ospf6 flooding",
1248 "Debug OSPFv3 flooding function\n"
1251 OSPF6_DEBUG_FLOODING_ON();
1255 DEFUN (no_debug_ospf6_flooding
,
1256 no_debug_ospf6_flooding_cmd
,
1257 "no debug ospf6 flooding",
1261 "Debug OSPFv3 flooding function\n"
1264 OSPF6_DEBUG_FLOODING_OFF();
1268 int config_write_ospf6_debug_flood(struct vty
*vty
)
1270 if (IS_OSPF6_DEBUG_FLOODING
)
1271 vty_out(vty
, "debug ospf6 flooding\n");
1275 void install_element_ospf6_debug_flood(void)
1277 install_element(ENABLE_NODE
, &debug_ospf6_flooding_cmd
);
1278 install_element(ENABLE_NODE
, &no_debug_ospf6_flooding_cmd
);
1279 install_element(CONFIG_NODE
, &debug_ospf6_flooding_cmd
);
1280 install_element(CONFIG_NODE
, &no_debug_ospf6_flooding_cmd
);