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"
43 #include "ospf6_nssa.h"
46 unsigned char conf_debug_ospf6_flooding
;
48 struct ospf6_lsdb
*ospf6_get_scoped_lsdb(struct ospf6_lsa
*lsa
)
50 struct ospf6_lsdb
*lsdb
= NULL
;
51 switch (OSPF6_LSA_SCOPE(lsa
->header
->type
)) {
52 case OSPF6_SCOPE_LINKLOCAL
:
53 lsdb
= OSPF6_INTERFACE(lsa
->lsdb
->data
)->lsdb
;
55 case OSPF6_SCOPE_AREA
:
56 lsdb
= OSPF6_AREA(lsa
->lsdb
->data
)->lsdb
;
59 lsdb
= OSPF6_PROCESS(lsa
->lsdb
->data
)->lsdb
;
68 struct ospf6_lsdb
*ospf6_get_scoped_lsdb_self(struct ospf6_lsa
*lsa
)
70 struct ospf6_lsdb
*lsdb_self
= NULL
;
71 switch (OSPF6_LSA_SCOPE(lsa
->header
->type
)) {
72 case OSPF6_SCOPE_LINKLOCAL
:
73 lsdb_self
= OSPF6_INTERFACE(lsa
->lsdb
->data
)->lsdb_self
;
75 case OSPF6_SCOPE_AREA
:
76 lsdb_self
= OSPF6_AREA(lsa
->lsdb
->data
)->lsdb_self
;
79 lsdb_self
= OSPF6_PROCESS(lsa
->lsdb
->data
)->lsdb_self
;
88 void ospf6_lsa_originate(struct ospf6
*ospf6
, struct ospf6_lsa
*lsa
)
90 struct ospf6_lsa
*old
;
91 struct ospf6_lsdb
*lsdb_self
;
93 if (lsa
->header
->adv_router
== INADDR_ANY
) {
94 if (IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa
->header
->type
))
96 "Refusing to originate LSA (zero router ID): %s",
99 ospf6_lsa_delete(lsa
);
103 /* find previous LSA */
104 old
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
105 lsa
->header
->adv_router
, lsa
->lsdb
);
107 /* if the new LSA does not differ from previous,
108 suppress this update of the LSA */
109 if (old
&& !OSPF6_LSA_IS_DIFFER(lsa
, old
)
110 && !ospf6
->gr_info
.finishing_restart
) {
111 if (IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa
->header
->type
))
112 zlog_debug("Suppress updating LSA: %s", lsa
->name
);
113 ospf6_lsa_delete(lsa
);
117 /* store it in the LSDB for self-originated LSAs */
118 lsdb_self
= ospf6_get_scoped_lsdb_self(lsa
);
119 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), lsdb_self
);
121 THREAD_OFF(lsa
->refresh
);
122 thread_add_timer(master
, ospf6_lsa_refresh
, lsa
, OSPF_LS_REFRESH_TIME
,
125 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
)
126 || IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa
->header
->type
)) {
127 zlog_debug("LSA Originate:");
128 ospf6_lsa_header_print(lsa
);
131 ospf6_install_lsa(lsa
);
132 ospf6_flood(NULL
, lsa
);
135 void ospf6_lsa_originate_process(struct ospf6_lsa
*lsa
, struct ospf6
*process
)
137 lsa
->lsdb
= process
->lsdb
;
138 ospf6_lsa_originate(process
, lsa
);
141 void ospf6_lsa_originate_area(struct ospf6_lsa
*lsa
, struct ospf6_area
*oa
)
143 lsa
->lsdb
= oa
->lsdb
;
144 ospf6_lsa_originate(oa
->ospf6
, lsa
);
147 void ospf6_lsa_originate_interface(struct ospf6_lsa
*lsa
,
148 struct ospf6_interface
*oi
)
150 lsa
->lsdb
= oi
->lsdb
;
151 ospf6_lsa_originate(oi
->area
->ospf6
, lsa
);
154 void ospf6_external_lsa_purge(struct ospf6
*ospf6
, struct ospf6_lsa
*lsa
)
156 uint32_t id
= lsa
->header
->id
;
157 struct ospf6_area
*oa
;
158 struct listnode
*lnode
;
160 ospf6_lsa_purge(lsa
);
162 /* Delete the corresponding NSSA LSA */
163 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, lnode
, oa
)) {
164 lsa
= ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_TYPE_7
), id
,
165 ospf6
->router_id
, oa
->lsdb
);
167 if (IS_OSPF6_DEBUG_NSSA
)
168 zlog_debug("withdraw type 7 lsa, LS ID: %u",
171 ospf6_lsa_purge(lsa
);
176 void ospf6_lsa_purge(struct ospf6_lsa
*lsa
)
178 struct ospf6_lsa
*self
;
179 struct ospf6_lsdb
*lsdb_self
;
181 /* remove it from the LSDB for self-originated LSAs */
182 lsdb_self
= ospf6_get_scoped_lsdb_self(lsa
);
183 self
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
184 lsa
->header
->adv_router
, lsdb_self
);
186 THREAD_OFF(self
->expire
);
187 THREAD_OFF(self
->refresh
);
188 ospf6_lsdb_remove(self
, lsdb_self
);
191 ospf6_lsa_premature_aging(lsa
);
194 /* Puring Multi Link-State IDs LSAs:
195 * Same Advertising Router with Multiple Link-State IDs
196 * LSAs, purging require to traverse all Link-State IDs
198 void ospf6_lsa_purge_multi_ls_id(struct ospf6_area
*oa
, struct ospf6_lsa
*lsa
)
201 struct ospf6_lsa
*lsa_next
;
204 type
= lsa
->header
->type
;
206 ospf6_lsa_purge(lsa
);
208 lsa_next
= ospf6_lsdb_lookup(type
, htonl(++ls_id
),
209 oa
->ospf6
->router_id
, oa
->lsdb
);
211 ospf6_lsa_purge(lsa_next
);
212 lsa_next
= ospf6_lsdb_lookup(type
, htonl(++ls_id
),
213 oa
->ospf6
->router_id
, oa
->lsdb
);
217 void ospf6_increment_retrans_count(struct ospf6_lsa
*lsa
)
219 /* The LSA must be the original one (see the description
220 in ospf6_decrement_retrans_count () below) */
221 lsa
->retrans_count
++;
224 void ospf6_decrement_retrans_count(struct ospf6_lsa
*lsa
)
226 struct ospf6_lsdb
*lsdb
;
227 struct ospf6_lsa
*orig
;
229 /* The LSA must be on the retrans-list of a neighbor. It means
230 the "lsa" is a copied one, and we have to decrement the
231 retransmission count of the original one (instead of this "lsa"'s).
232 In order to find the original LSA, first we have to find
233 appropriate LSDB that have the original LSA. */
234 lsdb
= ospf6_get_scoped_lsdb(lsa
);
236 /* Find the original LSA of which the retrans_count should be
238 orig
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
239 lsa
->header
->adv_router
, lsdb
);
241 orig
->retrans_count
--;
242 assert(orig
->retrans_count
>= 0);
246 /* RFC2328 section 13.2 Installing LSAs in the database */
247 void ospf6_install_lsa(struct ospf6_lsa
*lsa
)
251 struct ospf6_lsa
*old
;
252 struct ospf6_area
*area
= NULL
;
254 ospf6
= ospf6_get_by_lsdb(lsa
);
257 /* Remove the old instance from all neighbors' Link state
258 retransmission list (RFC2328 13.2 last paragraph) */
259 old
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
260 lsa
->header
->adv_router
, lsa
->lsdb
);
262 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_TYPE_7
) {
263 if (IS_OSPF6_DEBUG_NSSA
)
264 zlog_debug("%s : old LSA %s", __func__
,
266 lsa
->external_lsa_id
= old
->external_lsa_id
;
268 THREAD_OFF(old
->expire
);
269 THREAD_OFF(old
->refresh
);
270 ospf6_flood_clear(old
);
274 if (!OSPF6_LSA_IS_MAXAGE(lsa
)) {
275 thread_add_timer(master
, ospf6_lsa_expire
, lsa
,
276 OSPF_LSA_MAXAGE
+ lsa
->birth
.tv_sec
282 if (OSPF6_LSA_IS_SEQWRAP(lsa
)
283 && !(CHECK_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
)
284 && lsa
->header
->seqnum
== htonl(OSPF_MAX_SEQUENCE_NUMBER
))) {
285 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
))
286 zlog_debug("lsa install wrapping: sequence 0x%x",
287 ntohl(lsa
->header
->seqnum
));
288 SET_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
);
289 /* in lieu of premature_aging, since we do not want to recreate
291 * and/or mess with timers etc, we just want to wrap the
293 * and reflood the lsa before continuing.
294 * NOTE: Flood needs to be called right after this function
298 lsa
->header
->seqnum
= htonl(OSPF_MAX_SEQUENCE_NUMBER
);
299 lsa
->header
->age
= htons(OSPF_LSA_MAXAGE
);
300 ospf6_lsa_checksum(lsa
->header
);
303 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
)
304 || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
))
305 zlog_debug("%s Install LSA: %s age %d seqnum %x in LSDB.",
306 __func__
, lsa
->name
, ntohs(lsa
->header
->age
),
307 ntohl(lsa
->header
->seqnum
));
309 /* actually install */
310 lsa
->installed
= now
;
312 /* Topo change handling */
313 if (CHECK_LSA_TOPO_CHG_ELIGIBLE(ntohs(lsa
->header
->type
))
314 && !CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)) {
316 /* check if it is new lsa ? or existing lsa got modified ?*/
317 if (!old
|| OSPF6_LSA_IS_CHANGED(old
, lsa
))
318 ospf6_helper_handle_topo_chg(ospf6
, lsa
);
321 ospf6_lsdb_add(lsa
, lsa
->lsdb
);
323 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_TYPE_7
324 && lsa
->header
->adv_router
!= ospf6
->router_id
) {
325 area
= OSPF6_AREA(lsa
->lsdb
->data
);
326 ospf6_translated_nssa_refresh(area
, lsa
, NULL
);
327 ospf6_schedule_abr_task(area
->ospf6
);
330 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_ROUTER
) {
331 area
= OSPF6_AREA(lsa
->lsdb
->data
);
333 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
)
334 || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
))
335 zlog_debug("%s: New router LSA %s", __func__
,
337 ospf6_abr_nssa_check_status(area
->ospf6
);
343 /* RFC2740 section 3.5.2. Sending Link State Update packets */
344 /* RFC2328 section 13.3 Next step in the flooding procedure */
345 void ospf6_flood_interface(struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
,
346 struct ospf6_interface
*oi
)
348 struct listnode
*node
, *nnode
;
349 struct ospf6_neighbor
*on
;
350 struct ospf6_lsa
*req
, *old
;
351 int retrans_added
= 0;
354 if (IS_OSPF6_DEBUG_FLOODING
355 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
)) {
357 zlog_debug("Flooding on %s: %s", oi
->interface
->name
,
361 /* (1) For each neighbor */
362 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
364 zlog_debug("To neighbor %s", on
->name
);
366 /* (a) if neighbor state < Exchange, examin next */
367 if (on
->state
< OSPF6_NEIGHBOR_EXCHANGE
) {
370 "Neighbor state less than ExChange, next neighbor");
374 /* (b) if neighbor not yet Full, check request-list */
375 if (on
->state
!= OSPF6_NEIGHBOR_FULL
) {
377 zlog_debug("Neighbor not yet Full");
379 req
= ospf6_lsdb_lookup(
380 lsa
->header
->type
, lsa
->header
->id
,
381 lsa
->header
->adv_router
, on
->request_list
);
385 "Not on request-list for this neighbor");
388 /* If new LSA less recent, examin next neighbor
390 if (ospf6_lsa_compare(lsa
, req
) > 0) {
393 "Requesting is older, next neighbor");
397 /* If the same instance, delete from
399 examin next neighbor */
400 if (ospf6_lsa_compare(lsa
, req
) == 0) {
403 "Requesting the same, remove it, next neighbor");
404 if (req
== on
->last_ls_req
) {
405 /* sanity check refcount */
406 assert(req
->lock
>= 2);
407 req
= ospf6_lsa_unlock(req
);
408 on
->last_ls_req
= NULL
;
412 req
, on
->request_list
);
413 ospf6_check_nbr_loading(on
);
417 /* If the new LSA is more recent, delete from
419 if (ospf6_lsa_compare(lsa
, req
) < 0) {
422 "Received is newer, remove requesting");
423 if (req
== on
->last_ls_req
) {
424 req
= ospf6_lsa_unlock(req
);
425 on
->last_ls_req
= NULL
;
428 ospf6_lsdb_remove(req
,
430 ospf6_check_nbr_loading(on
);
436 /* (c) If the new LSA was received from this neighbor,
437 examin next neighbor */
441 "Received is from the neighbor, next neighbor");
445 if ((oi
->area
->ospf6
->inst_shutdown
)
446 || CHECK_FLAG(lsa
->flag
, OSPF6_LSA_FLUSH
)) {
449 "%s: Send LSA %s (age %d) update now",
451 ntohs(lsa
->header
->age
));
452 ospf6_lsupdate_send_neighbor_now(on
, lsa
);
455 /* (d) add retrans-list, schedule retransmission */
457 zlog_debug("Add retrans-list of neighbor %s ",
460 /* Do not increment the retrans count if the lsa is
461 * already present in the retrans list.
463 old
= ospf6_lsdb_lookup(
464 lsa
->header
->type
, lsa
->header
->id
,
465 lsa
->header
->adv_router
, on
->retrans_list
);
467 struct ospf6_lsa
*orig
;
468 struct ospf6_lsdb
*lsdb
;
472 "Increment %s from retrans_list of %s",
473 lsa
->name
, on
->name
);
475 /* Increment the retrans count on the original
476 * copy of LSA if present, to maintain the
477 * counter consistency.
480 lsdb
= ospf6_get_scoped_lsdb(lsa
);
481 orig
= ospf6_lsdb_lookup(
482 lsa
->header
->type
, lsa
->header
->id
,
483 lsa
->header
->adv_router
, lsdb
);
485 ospf6_increment_retrans_count(orig
);
487 ospf6_increment_retrans_count(lsa
);
489 ospf6_lsdb_add(ospf6_lsa_copy(lsa
),
492 master
, ospf6_lsupdate_send_neighbor
,
493 on
, on
->ospf6_if
->rxmt_interval
,
494 &on
->thread_send_lsupdate
);
500 /* (2) examin next interface if not added to retrans-list */
501 if (retrans_added
== 0) {
504 "No retransmission scheduled, next interface %s",
505 oi
->interface
->name
);
509 /* (3) If the new LSA was received on this interface,
510 and it was from DR or BDR, examin next interface */
511 if (from
&& from
->ospf6_if
== oi
512 && (from
->router_id
== oi
->drouter
513 || from
->router_id
== oi
->bdrouter
)) {
516 "Received is from the I/F's DR or BDR, next interface");
520 /* (4) If the new LSA was received on this interface,
521 and the interface state is BDR, examin next interface */
522 if (from
&& from
->ospf6_if
== oi
) {
523 if (oi
->state
== OSPF6_INTERFACE_BDR
) {
526 "Received is from the I/F, itself BDR, next interface");
529 SET_FLAG(lsa
->flag
, OSPF6_LSA_FLOODBACK
);
532 /* (5) flood the LSA out the interface. */
534 zlog_debug("Schedule flooding for the interface");
535 if ((oi
->type
== OSPF_IFTYPE_BROADCAST
)
536 || (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)) {
537 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsupdate_list
);
538 thread_add_event(master
, ospf6_lsupdate_send_interface
, oi
, 0,
539 &oi
->thread_send_lsupdate
);
541 /* reschedule retransmissions to all neighbors */
542 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
543 THREAD_OFF(on
->thread_send_lsupdate
);
544 thread_add_event(master
, ospf6_lsupdate_send_neighbor
,
545 on
, 0, &on
->thread_send_lsupdate
);
550 void ospf6_flood_area(struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
,
551 struct ospf6_area
*oa
)
553 struct listnode
*node
, *nnode
;
554 struct ospf6_interface
*oi
;
556 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
)) {
557 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
558 && oi
!= OSPF6_INTERFACE(lsa
->lsdb
->data
))
561 ospf6_flood_interface(from
, lsa
, oi
);
565 static void ospf6_flood_process(struct ospf6_neighbor
*from
,
566 struct ospf6_lsa
*lsa
, struct ospf6
*process
)
568 struct listnode
*node
, *nnode
;
569 struct ospf6_area
*oa
;
571 for (ALL_LIST_ELEMENTS(process
->area_list
, node
, nnode
, oa
)) {
573 /* If unknown LSA and U-bit clear, treat as link local
576 if (!OSPF6_LSA_IS_KNOWN(lsa
->header
->type
)
577 && !(ntohs(lsa
->header
->type
) & OSPF6_LSTYPE_UBIT_MASK
)
578 && (oa
!= OSPF6_INTERFACE(lsa
->lsdb
->data
)->area
)) {
580 if (IS_OSPF6_DEBUG_FLOODING
)
581 zlog_debug("Unknown LSA, do not flood");
585 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_AREA
586 && oa
!= OSPF6_AREA(lsa
->lsdb
->data
))
588 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
589 && oa
!= OSPF6_INTERFACE(lsa
->lsdb
->data
)->area
)
592 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
593 && (IS_AREA_STUB(oa
) || IS_AREA_NSSA(oa
)))
596 /* Check for NSSA LSA */
597 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_TYPE_7
598 && !IS_AREA_NSSA(oa
) && !OSPF6_LSA_IS_MAXAGE(lsa
))
601 ospf6_flood_area(from
, lsa
, oa
);
605 void ospf6_flood(struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
)
609 ospf6
= ospf6_get_by_lsdb(lsa
);
613 ospf6_flood_process(from
, lsa
, ospf6
);
616 static void ospf6_flood_clear_interface(struct ospf6_lsa
*lsa
,
617 struct ospf6_interface
*oi
)
619 struct listnode
*node
, *nnode
;
620 struct ospf6_neighbor
*on
;
621 struct ospf6_lsa
*rem
;
623 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
624 rem
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
625 lsa
->header
->adv_router
,
627 if (rem
&& !ospf6_lsa_compare(rem
, lsa
)) {
628 if (IS_OSPF6_DEBUG_FLOODING
629 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
630 zlog_debug("Remove %s from retrans_list of %s",
631 rem
->name
, on
->name
);
632 ospf6_decrement_retrans_count(rem
);
633 ospf6_lsdb_remove(rem
, on
->retrans_list
);
638 void ospf6_flood_clear_area(struct ospf6_lsa
*lsa
, struct ospf6_area
*oa
)
640 struct listnode
*node
, *nnode
;
641 struct ospf6_interface
*oi
;
643 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
)) {
644 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
645 && oi
!= OSPF6_INTERFACE(lsa
->lsdb
->data
))
648 ospf6_flood_clear_interface(lsa
, oi
);
652 static void ospf6_flood_clear_process(struct ospf6_lsa
*lsa
,
653 struct ospf6
*process
)
655 struct listnode
*node
, *nnode
;
656 struct ospf6_area
*oa
;
658 for (ALL_LIST_ELEMENTS(process
->area_list
, node
, nnode
, oa
)) {
659 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_AREA
660 && oa
!= OSPF6_AREA(lsa
->lsdb
->data
))
662 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
663 && oa
!= OSPF6_INTERFACE(lsa
->lsdb
->data
)->area
)
666 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
667 && (IS_AREA_STUB(oa
) || (IS_AREA_NSSA(oa
))))
669 /* Check for NSSA LSA */
670 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_TYPE_7
671 && !IS_AREA_NSSA(oa
))
674 ospf6_flood_clear_area(lsa
, oa
);
678 void ospf6_flood_clear(struct ospf6_lsa
*lsa
)
682 ospf6
= ospf6_get_by_lsdb(lsa
);
685 ospf6_flood_clear_process(lsa
, ospf6
);
689 /* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
690 static void ospf6_acknowledge_lsa_bdrouter(struct ospf6_lsa
*lsa
,
692 struct ospf6_neighbor
*from
)
694 struct ospf6_interface
*oi
;
697 if (IS_OSPF6_DEBUG_FLOODING
698 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
701 assert(from
&& from
->ospf6_if
);
704 /* LSA is more recent than database copy, but was not flooded
705 back out receiving interface. Delayed acknowledgement sent
706 if advertisement received from Designated Router,
707 otherwide do nothing. */
708 if (ismore_recent
< 0) {
709 if (oi
->drouter
== from
->router_id
) {
712 "Delayed acknowledgement (BDR & MoreRecent & from DR)");
713 /* Delayed acknowledgement */
714 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsack_list
);
715 thread_add_timer(master
, ospf6_lsack_send_interface
, oi
,
716 3, &oi
->thread_send_lsack
);
720 "No acknowledgement (BDR & MoreRecent & ! from DR)");
725 /* LSA is a duplicate, and was treated as an implied acknowledgement.
726 Delayed acknowledgement sent if advertisement received from
727 Designated Router, otherwise do nothing */
728 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
729 && CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
730 if (oi
->drouter
== from
->router_id
) {
733 "Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
734 /* Delayed acknowledgement */
735 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsack_list
);
736 thread_add_timer(master
, ospf6_lsack_send_interface
, oi
,
737 3, &oi
->thread_send_lsack
);
741 "No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
746 /* LSA is a duplicate, and was not treated as an implied
748 Direct acknowledgement sent */
749 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
750 && !CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
752 zlog_debug("Direct acknowledgement (BDR & Duplicate)");
753 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), from
->lsack_list
);
754 thread_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
755 &from
->thread_send_lsack
);
759 /* LSA's LS age is equal to Maxage, and there is no current instance
760 of the LSA in the link state database, and none of router's
761 neighbors are in states Exchange or Loading */
762 /* Direct acknowledgement sent, but this case is handled in
763 early of ospf6_receive_lsa () */
766 static void ospf6_acknowledge_lsa_allother(struct ospf6_lsa
*lsa
,
768 struct ospf6_neighbor
*from
)
770 struct ospf6_interface
*oi
;
773 if (IS_OSPF6_DEBUG_FLOODING
774 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
777 assert(from
&& from
->ospf6_if
);
780 /* LSA has been flood back out receiving interface.
781 No acknowledgement sent. */
782 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_FLOODBACK
)) {
784 zlog_debug("No acknowledgement (AllOther & FloodBack)");
788 /* LSA is more recent than database copy, but was not flooded
789 back out receiving interface. Delayed acknowledgement sent. */
790 if (ismore_recent
< 0) {
793 "Delayed acknowledgement (AllOther & MoreRecent)");
794 /* Delayed acknowledgement */
795 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsack_list
);
796 thread_add_timer(master
, ospf6_lsack_send_interface
, oi
, 3,
797 &oi
->thread_send_lsack
);
801 /* LSA is a duplicate, and was treated as an implied acknowledgement.
802 No acknowledgement sent. */
803 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
804 && CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
807 "No acknowledgement (AllOther & Duplicate & ImpliedAck)");
811 /* LSA is a duplicate, and was not treated as an implied
813 Direct acknowledgement sent */
814 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
815 && !CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
818 "Direct acknowledgement (AllOther & Duplicate)");
819 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), from
->lsack_list
);
820 thread_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
821 &from
->thread_send_lsack
);
825 /* LSA's LS age is equal to Maxage, and there is no current instance
826 of the LSA in the link state database, and none of router's
827 neighbors are in states Exchange or Loading */
828 /* Direct acknowledgement sent, but this case is handled in
829 early of ospf6_receive_lsa () */
832 static void ospf6_acknowledge_lsa(struct ospf6_lsa
*lsa
, int ismore_recent
,
833 struct ospf6_neighbor
*from
)
835 struct ospf6_interface
*oi
;
837 assert(from
&& from
->ospf6_if
);
840 if (oi
->state
== OSPF6_INTERFACE_BDR
)
841 ospf6_acknowledge_lsa_bdrouter(lsa
, ismore_recent
, from
);
843 ospf6_acknowledge_lsa_allother(lsa
, ismore_recent
, from
);
846 /* RFC2328 section 13 (4):
847 if MaxAge LSA and if we have no instance, and no neighbor
848 is in states Exchange or Loading
849 returns 1 if match this case, else returns 0 */
850 static int ospf6_is_maxage_lsa_drop(struct ospf6_lsa
*lsa
,
851 struct ospf6_neighbor
*from
)
853 struct ospf6_neighbor
*on
;
854 struct ospf6_interface
*oi
;
855 struct ospf6_area
*oa
;
856 struct ospf6
*process
= NULL
;
857 struct listnode
*i
, *j
, *k
;
860 if (!OSPF6_LSA_IS_MAXAGE(lsa
))
863 if (ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
864 lsa
->header
->adv_router
, lsa
->lsdb
))
867 process
= from
->ospf6_if
->area
->ospf6
;
869 for (ALL_LIST_ELEMENTS_RO(process
->area_list
, i
, oa
))
870 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
871 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, k
, on
))
872 if (on
->state
== OSPF6_NEIGHBOR_EXCHANGE
873 || on
->state
== OSPF6_NEIGHBOR_LOADING
)
881 static bool ospf6_lsa_check_min_arrival(struct ospf6_lsa
*lsa
,
882 struct ospf6_neighbor
*from
)
884 struct timeval now
, res
;
885 unsigned int time_delta_ms
;
888 timersub(&now
, &lsa
->installed
, &res
);
889 time_delta_ms
= (res
.tv_sec
* 1000) + (int)(res
.tv_usec
/ 1000);
891 if (time_delta_ms
< from
->ospf6_if
->area
->ospf6
->lsa_minarrival
) {
892 if (IS_OSPF6_DEBUG_FLOODING
||
893 IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
895 "LSA can't be updated within MinLSArrival, %dms < %dms, discard",
897 from
->ospf6_if
->area
->ospf6
->lsa_minarrival
);
903 /* RFC2328 section 13 The Flooding Procedure */
904 void ospf6_receive_lsa(struct ospf6_neighbor
*from
,
905 struct ospf6_lsa_header
*lsa_header
)
907 struct ospf6_lsa
*new = NULL
, *old
= NULL
, *rem
= NULL
;
914 /* if we receive a LSA with invalid seqnum drop it */
915 if (ntohl(lsa_header
->seqnum
) - 1 == OSPF_MAX_SEQUENCE_NUMBER
) {
916 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa_header
->type
)) {
918 "received lsa [%s Id:%pI4 Adv:%pI4] with invalid seqnum 0x%x, ignore",
919 ospf6_lstype_name(lsa_header
->type
),
920 &lsa_header
->id
, &lsa_header
->adv_router
,
921 ntohl(lsa_header
->seqnum
));
926 /* make lsa structure for received lsa */
927 new = ospf6_lsa_create(lsa_header
);
929 if (IS_OSPF6_DEBUG_FLOODING
930 || IS_OSPF6_DEBUG_FLOOD_TYPE(new->header
->type
)) {
932 zlog_debug("LSA Receive from %s", from
->name
);
933 ospf6_lsa_header_print(new);
936 /* (1) LSA Checksum */
937 if (!ospf6_lsa_checksum_valid(new->header
)) {
939 zlog_debug("Wrong LSA Checksum, discard");
940 ospf6_lsa_delete(new);
944 /* (2) Examine the LSA's LS type.
945 RFC2470 3.5.1. Receiving Link State Update packets */
946 if (IS_AREA_STUB(from
->ospf6_if
->area
)
947 && OSPF6_LSA_SCOPE(new->header
->type
) == OSPF6_SCOPE_AS
) {
950 "AS-External-LSA (or AS-scope LSA) in stub area, discard");
951 ospf6_lsa_delete(new);
955 /* (3) LSA which have reserved scope is discarded
956 RFC2470 3.5.1. Receiving Link State Update packets */
957 /* Flooding scope check. LSAs with unknown scope are discarded here.
958 Set appropriate LSDB for the LSA */
959 switch (OSPF6_LSA_SCOPE(new->header
->type
)) {
960 case OSPF6_SCOPE_LINKLOCAL
:
961 new->lsdb
= from
->ospf6_if
->lsdb
;
963 case OSPF6_SCOPE_AREA
:
964 new->lsdb
= from
->ospf6_if
->area
->lsdb
;
967 new->lsdb
= from
->ospf6_if
->area
->ospf6
->lsdb
;
971 zlog_debug("LSA has reserved scope, discard");
972 ospf6_lsa_delete(new);
976 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
977 is in states Exchange or Loading */
978 if (ospf6_is_maxage_lsa_drop(new, from
)) {
982 "Drop MaxAge LSA with direct acknowledgement.");
984 /* a) Acknowledge back to neighbor (Direct acknowledgement,
986 ospf6_lsdb_add(ospf6_lsa_copy(new), from
->lsack_list
);
987 thread_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
988 &from
->thread_send_lsack
);
991 ospf6_lsa_delete(new);
996 /* lookup the same database copy in lsdb */
997 old
= ospf6_lsdb_lookup(new->header
->type
, new->header
->id
,
998 new->header
->adv_router
, new->lsdb
);
1000 ismore_recent
= ospf6_lsa_compare(new, old
);
1001 if (ntohl(new->header
->seqnum
) == ntohl(old
->header
->seqnum
)) {
1003 zlog_debug("Received is duplicated LSA");
1004 SET_FLAG(new->flag
, OSPF6_LSA_DUPLICATE
);
1008 /* if no database copy or received is more recent */
1009 if (old
== NULL
|| ismore_recent
< 0) {
1010 bool self_originated
;
1012 /* in case we have no database copy */
1015 /* (a) MinLSArrival check */
1017 if (ospf6_lsa_check_min_arrival(old
, from
)) {
1018 ospf6_lsa_delete(new);
1019 return; /* examin next lsa */
1023 monotime(&new->received
);
1027 "Install, Flood, Possibly acknowledge the received LSA");
1029 /* Remove older copies of this LSA from retx lists */
1031 ospf6_flood_clear(old
);
1033 self_originated
= (new->header
->adv_router
1034 == from
->ospf6_if
->area
->ospf6
->router_id
);
1036 /* Received non-self-originated Grace LSA. */
1037 if (IS_GRACE_LSA(new) && !self_originated
) {
1038 struct ospf6
*ospf6
;
1040 ospf6
= ospf6_get_by_lsdb(new);
1044 if (OSPF6_LSA_IS_MAXAGE(new)) {
1046 if (IS_DEBUG_OSPF6_GR
)
1048 "%s, Received a maxage GraceLSA from router %pI4",
1050 &new->header
->adv_router
);
1052 ospf6_process_maxage_grace_lsa(
1055 if (IS_DEBUG_OSPF6_GR
)
1057 "%s, GraceLSA doesn't exist in lsdb, so discarding GraceLSA",
1063 if (IS_DEBUG_OSPF6_GR
)
1065 "%s, Received a GraceLSA from router %pI4",
1067 &new->header
->adv_router
);
1069 if (ospf6_process_grace_lsa(ospf6
, new, from
)
1070 == OSPF6_GR_NOT_HELPER
) {
1071 if (IS_DEBUG_OSPF6_GR
)
1073 "%s, Not moving to HELPER role, So dicarding GraceLSA",
1080 /* (b) immediately flood and (c) remove from all retrans-list */
1081 /* Prevent self-originated LSA to be flooded. this is to make
1082 * reoriginated instance of the LSA not to be rejected by other
1083 * routers due to MinLSArrival.
1085 if (!self_originated
)
1086 ospf6_flood(from
, new);
1088 /* (d), installing lsdb, which may cause routing
1089 table calculation (replacing database copy) */
1090 ospf6_install_lsa(new);
1092 if (OSPF6_LSA_IS_MAXAGE(new))
1093 ospf6_maxage_remove(from
->ospf6_if
->area
->ospf6
);
1095 /* (e) possibly acknowledge */
1096 ospf6_acknowledge_lsa(new, ismore_recent
, from
);
1098 /* (f) Self Originated LSA, section 13.4 */
1099 if (self_originated
) {
1100 if (from
->ospf6_if
->area
->ospf6
->gr_info
1101 .restart_in_progress
) {
1102 if (IS_DEBUG_OSPF6_GR
)
1104 "Graceful Restart in progress -- not flushing self-originated LSA: %s",
1109 /* Self-originated LSA (newer than ours) is received
1111 another router. We have to make a new instance of the
1113 or have to flush this LSA. */
1116 "Newer instance of the self-originated LSA");
1117 zlog_debug("Schedule reorigination");
1119 thread_add_event(master
, ospf6_lsa_refresh
, new, 0,
1123 struct ospf6
*ospf6
= from
->ospf6_if
->area
->ospf6
;
1124 struct ospf6_area
*area
= from
->ospf6_if
->area
;
1125 if (ospf6
->gr_info
.restart_in_progress
)
1126 ospf6_gr_check_lsdb_consistency(ospf6
, area
);
1131 /* (6) if there is instance on sending neighbor's request list */
1132 if (ospf6_lsdb_lookup(new->header
->type
, new->header
->id
,
1133 new->header
->adv_router
, from
->request_list
)) {
1134 /* if no database copy, should go above state (5) */
1138 "Received is not newer, on the neighbor %s request-list",
1141 "BadLSReq, discard the received LSA lsa %s send badLSReq",
1145 thread_add_event(master
, bad_lsreq
, from
, 0, NULL
);
1147 ospf6_lsa_delete(new);
1151 /* (7) if neither one is more recent */
1152 if (ismore_recent
== 0) {
1155 "The same instance as database copy (neither recent)");
1157 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack
1159 rem
= ospf6_lsdb_lookup(new->header
->type
, new->header
->id
,
1160 new->header
->adv_router
,
1161 from
->retrans_list
);
1165 "It is on the neighbor's retrans-list.");
1167 "Treat as an Implied acknowledgement");
1169 SET_FLAG(new->flag
, OSPF6_LSA_IMPLIEDACK
);
1170 ospf6_decrement_retrans_count(rem
);
1171 ospf6_lsdb_remove(rem
, from
->retrans_list
);
1175 zlog_debug("Possibly acknowledge and then discard");
1177 /* (b) possibly acknowledge */
1178 ospf6_acknowledge_lsa(new, ismore_recent
, from
);
1180 ospf6_lsa_delete(new);
1184 /* (8) previous database copy is more recent */
1188 /* If database copy is in 'Seqnumber Wrapping',
1189 simply discard the received LSA */
1190 if (OSPF6_LSA_IS_MAXAGE(old
)
1191 && old
->header
->seqnum
== htonl(OSPF_MAX_SEQUENCE_NUMBER
)) {
1193 zlog_debug("The LSA is in Seqnumber Wrapping");
1194 zlog_debug("MaxAge & MaxSeqNum, discard");
1196 ospf6_lsa_delete(new);
1200 /* Otherwise, Send database copy of this LSA to this neighbor */
1203 zlog_debug("Database copy is more recent.");
1205 "Send back directly and then discard");
1208 /* Neighbor router sent recent age for LSA,
1209 * Router could be restarted while current copy is
1210 * MAXAGEd and not removed.*/
1211 if (OSPF6_LSA_IS_MAXAGE(old
)
1212 && !OSPF6_LSA_IS_MAXAGE(new)) {
1213 if (new->header
->adv_router
1214 != from
->ospf6_if
->area
->ospf6
->router_id
) {
1217 "%s: Current copy of LSA %s is MAXAGE, but new has recent age, flooding/installing.",
1218 __PRETTY_FUNCTION__
, old
->name
);
1219 ospf6_lsa_purge(old
);
1220 ospf6_flood(from
, new);
1221 ospf6_install_lsa(new);
1224 /* For self-originated LSA, only trust
1225 * ourselves. Fall through and send
1226 * LS Update with our current copy.
1230 "%s: Current copy of self-originated LSA %s is MAXAGE, but new has recent age, re-sending current one.",
1231 __PRETTY_FUNCTION__
, old
->name
);
1234 /* MinLSArrival check as per RFC 2328 13 (8) */
1235 if (ospf6_lsa_check_min_arrival(old
, from
)) {
1236 ospf6_lsa_delete(new);
1237 return; /* examin next lsa */
1240 ospf6_lsdb_add(ospf6_lsa_copy(old
),
1241 from
->lsupdate_list
);
1242 thread_add_event(master
, ospf6_lsupdate_send_neighbor
,
1243 from
, 0, &from
->thread_send_lsupdate
);
1245 ospf6_lsa_delete(new);
1251 DEFUN (debug_ospf6_flooding
,
1252 debug_ospf6_flooding_cmd
,
1253 "debug ospf6 flooding",
1256 "Debug OSPFv3 flooding function\n"
1259 OSPF6_DEBUG_FLOODING_ON();
1263 DEFUN (no_debug_ospf6_flooding
,
1264 no_debug_ospf6_flooding_cmd
,
1265 "no debug ospf6 flooding",
1269 "Debug OSPFv3 flooding function\n"
1272 OSPF6_DEBUG_FLOODING_OFF();
1276 int config_write_ospf6_debug_flood(struct vty
*vty
)
1278 if (IS_OSPF6_DEBUG_FLOODING
)
1279 vty_out(vty
, "debug ospf6 flooding\n");
1283 void install_element_ospf6_debug_flood(void)
1285 install_element(ENABLE_NODE
, &debug_ospf6_flooding_cmd
);
1286 install_element(ENABLE_NODE
, &no_debug_ospf6_flooding_cmd
);
1287 install_element(CONFIG_NODE
, &debug_ospf6_flooding_cmd
);
1288 install_element(CONFIG_NODE
, &no_debug_ospf6_flooding_cmd
);