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_remove_id_from_external_id_table(struct ospf6
*ospf6
,
157 struct prefix prefix_id
;
158 struct route_node
*node
;
160 /* remove binding in external_id_table */
161 prefix_id
.family
= AF_INET
;
162 prefix_id
.prefixlen
= 32;
163 prefix_id
.u
.prefix4
.s_addr
= id
;
164 node
= route_node_lookup(ospf6
->external_id_table
, &prefix_id
);
167 route_unlock_node(node
); /* to free the lookup lock */
168 route_unlock_node(node
); /* to free the original lock */
172 void ospf6_external_lsa_purge(struct ospf6
*ospf6
, struct ospf6_lsa
*lsa
)
174 uint32_t id
= lsa
->header
->id
;
175 struct ospf6_area
*oa
;
176 struct listnode
*lnode
;
178 ospf6_lsa_purge(lsa
);
180 ospf6_remove_id_from_external_id_table(ospf6
, id
);
182 /* Delete the corresponding NSSA LSA */
183 for (ALL_LIST_ELEMENTS_RO(ospf6
->area_list
, lnode
, oa
)) {
184 lsa
= ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_TYPE_7
), id
,
185 ospf6
->router_id
, oa
->lsdb
);
187 if (IS_OSPF6_DEBUG_NSSA
)
188 zlog_debug("withdraw type 7 lsa, LS ID: %u",
191 ospf6_lsa_purge(lsa
);
196 void ospf6_lsa_purge(struct ospf6_lsa
*lsa
)
198 struct ospf6_lsa
*self
;
199 struct ospf6_lsdb
*lsdb_self
;
201 /* remove it from the LSDB for self-originated LSAs */
202 lsdb_self
= ospf6_get_scoped_lsdb_self(lsa
);
203 self
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
204 lsa
->header
->adv_router
, lsdb_self
);
206 THREAD_OFF(self
->expire
);
207 THREAD_OFF(self
->refresh
);
208 ospf6_lsdb_remove(self
, lsdb_self
);
211 ospf6_lsa_premature_aging(lsa
);
214 /* Puring Multi Link-State IDs LSAs:
215 * Same Advertising Router with Multiple Link-State IDs
216 * LSAs, purging require to traverse all Link-State IDs
218 void ospf6_lsa_purge_multi_ls_id(struct ospf6_area
*oa
, struct ospf6_lsa
*lsa
)
221 struct ospf6_lsa
*lsa_next
;
224 type
= lsa
->header
->type
;
226 ospf6_lsa_purge(lsa
);
228 lsa_next
= ospf6_lsdb_lookup(type
, htonl(++ls_id
),
229 oa
->ospf6
->router_id
, oa
->lsdb
);
231 ospf6_lsa_purge(lsa_next
);
232 lsa_next
= ospf6_lsdb_lookup(type
, htonl(++ls_id
),
233 oa
->ospf6
->router_id
, oa
->lsdb
);
237 void ospf6_increment_retrans_count(struct ospf6_lsa
*lsa
)
239 /* The LSA must be the original one (see the description
240 in ospf6_decrement_retrans_count () below) */
241 lsa
->retrans_count
++;
244 void ospf6_decrement_retrans_count(struct ospf6_lsa
*lsa
)
246 struct ospf6_lsdb
*lsdb
;
247 struct ospf6_lsa
*orig
;
249 /* The LSA must be on the retrans-list of a neighbor. It means
250 the "lsa" is a copied one, and we have to decrement the
251 retransmission count of the original one (instead of this "lsa"'s).
252 In order to find the original LSA, first we have to find
253 appropriate LSDB that have the original LSA. */
254 lsdb
= ospf6_get_scoped_lsdb(lsa
);
256 /* Find the original LSA of which the retrans_count should be
258 orig
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
259 lsa
->header
->adv_router
, lsdb
);
261 orig
->retrans_count
--;
262 assert(orig
->retrans_count
>= 0);
266 /* RFC2328 section 13.2 Installing LSAs in the database */
267 void ospf6_install_lsa(struct ospf6_lsa
*lsa
)
271 struct ospf6_lsa
*old
;
272 struct ospf6_area
*area
= NULL
;
274 ospf6
= ospf6_get_by_lsdb(lsa
);
277 /* Remove the old instance from all neighbors' Link state
278 retransmission list (RFC2328 13.2 last paragraph) */
279 old
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
280 lsa
->header
->adv_router
, lsa
->lsdb
);
282 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_TYPE_7
) {
283 if (IS_OSPF6_DEBUG_NSSA
)
284 zlog_debug("%s : old LSA %s", __func__
,
286 lsa
->external_lsa_id
= old
->external_lsa_id
;
288 THREAD_OFF(old
->expire
);
289 THREAD_OFF(old
->refresh
);
290 ospf6_flood_clear(old
);
294 if (!OSPF6_LSA_IS_MAXAGE(lsa
)) {
295 thread_add_timer(master
, ospf6_lsa_expire
, lsa
,
296 OSPF_LSA_MAXAGE
+ lsa
->birth
.tv_sec
302 if (OSPF6_LSA_IS_SEQWRAP(lsa
)
303 && !(CHECK_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
)
304 && lsa
->header
->seqnum
== htonl(OSPF_MAX_SEQUENCE_NUMBER
))) {
305 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
))
306 zlog_debug("lsa install wrapping: sequence 0x%x",
307 ntohl(lsa
->header
->seqnum
));
308 SET_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
);
309 /* in lieu of premature_aging, since we do not want to recreate
311 * and/or mess with timers etc, we just want to wrap the
313 * and reflood the lsa before continuing.
314 * NOTE: Flood needs to be called right after this function
318 lsa
->header
->seqnum
= htonl(OSPF_MAX_SEQUENCE_NUMBER
);
319 lsa
->header
->age
= htons(OSPF_LSA_MAXAGE
);
320 ospf6_lsa_checksum(lsa
->header
);
323 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
)
324 || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
))
325 zlog_debug("%s Install LSA: %s age %d seqnum %x in LSDB.",
326 __func__
, lsa
->name
, ntohs(lsa
->header
->age
),
327 ntohl(lsa
->header
->seqnum
));
329 /* actually install */
330 lsa
->installed
= now
;
332 /* Topo change handling */
333 if (CHECK_LSA_TOPO_CHG_ELIGIBLE(ntohs(lsa
->header
->type
))
334 && !CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)) {
336 /* check if it is new lsa ? or existing lsa got modified ?*/
337 if (!old
|| OSPF6_LSA_IS_CHANGED(old
, lsa
))
338 ospf6_helper_handle_topo_chg(ospf6
, lsa
);
341 ospf6_lsdb_add(lsa
, lsa
->lsdb
);
343 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_TYPE_7
344 && lsa
->header
->adv_router
!= ospf6
->router_id
) {
345 area
= OSPF6_AREA(lsa
->lsdb
->data
);
346 ospf6_translated_nssa_refresh(area
, lsa
, NULL
);
347 ospf6_schedule_abr_task(area
->ospf6
);
350 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_ROUTER
) {
351 area
= OSPF6_AREA(lsa
->lsdb
->data
);
353 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
)
354 || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
))
355 zlog_debug("%s: New router LSA %s", __func__
,
357 ospf6_abr_nssa_check_status(area
->ospf6
);
363 /* RFC2740 section 3.5.2. Sending Link State Update packets */
364 /* RFC2328 section 13.3 Next step in the flooding procedure */
365 void ospf6_flood_interface(struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
,
366 struct ospf6_interface
*oi
)
368 struct listnode
*node
, *nnode
;
369 struct ospf6_neighbor
*on
;
370 struct ospf6_lsa
*req
, *old
;
371 int retrans_added
= 0;
374 if (IS_OSPF6_DEBUG_FLOODING
375 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
)) {
377 zlog_debug("Flooding on %s: %s", oi
->interface
->name
,
381 /* (1) For each neighbor */
382 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
384 zlog_debug("To neighbor %s", on
->name
);
386 /* (a) if neighbor state < Exchange, examin next */
387 if (on
->state
< OSPF6_NEIGHBOR_EXCHANGE
) {
390 "Neighbor state less than ExChange, next neighbor");
394 /* (b) if neighbor not yet Full, check request-list */
395 if (on
->state
!= OSPF6_NEIGHBOR_FULL
) {
397 zlog_debug("Neighbor not yet Full");
399 req
= ospf6_lsdb_lookup(
400 lsa
->header
->type
, lsa
->header
->id
,
401 lsa
->header
->adv_router
, on
->request_list
);
405 "Not on request-list for this neighbor");
408 /* If new LSA less recent, examin next neighbor
410 if (ospf6_lsa_compare(lsa
, req
) > 0) {
413 "Requesting is older, next neighbor");
417 /* If the same instance, delete from
419 examin next neighbor */
420 if (ospf6_lsa_compare(lsa
, req
) == 0) {
423 "Requesting the same, remove it, next neighbor");
424 if (req
== on
->last_ls_req
) {
425 /* sanity check refcount */
426 assert(req
->lock
>= 2);
427 req
= ospf6_lsa_unlock(req
);
428 on
->last_ls_req
= NULL
;
432 req
, on
->request_list
);
433 ospf6_check_nbr_loading(on
);
437 /* If the new LSA is more recent, delete from
439 if (ospf6_lsa_compare(lsa
, req
) < 0) {
442 "Received is newer, remove requesting");
443 if (req
== on
->last_ls_req
) {
444 req
= ospf6_lsa_unlock(req
);
445 on
->last_ls_req
= NULL
;
448 ospf6_lsdb_remove(req
,
450 ospf6_check_nbr_loading(on
);
456 /* (c) If the new LSA was received from this neighbor,
457 examin next neighbor */
461 "Received is from the neighbor, next neighbor");
465 if ((oi
->area
->ospf6
->inst_shutdown
)
466 || CHECK_FLAG(lsa
->flag
, OSPF6_LSA_FLUSH
)) {
469 "%s: Send LSA %s (age %d) update now",
471 ntohs(lsa
->header
->age
));
472 ospf6_lsupdate_send_neighbor_now(on
, lsa
);
475 /* (d) add retrans-list, schedule retransmission */
477 zlog_debug("Add retrans-list of neighbor %s ",
480 /* Do not increment the retrans count if the lsa is
481 * already present in the retrans list.
483 old
= ospf6_lsdb_lookup(
484 lsa
->header
->type
, lsa
->header
->id
,
485 lsa
->header
->adv_router
, on
->retrans_list
);
489 "Increment %s from retrans_list of %s",
490 lsa
->name
, on
->name
);
491 ospf6_increment_retrans_count(lsa
);
492 ospf6_lsdb_add(ospf6_lsa_copy(lsa
),
495 master
, ospf6_lsupdate_send_neighbor
,
496 on
, on
->ospf6_if
->rxmt_interval
,
497 &on
->thread_send_lsupdate
);
503 /* (2) examin next interface if not added to retrans-list */
504 if (retrans_added
== 0) {
507 "No retransmission scheduled, next interface %s",
508 oi
->interface
->name
);
512 /* (3) If the new LSA was received on this interface,
513 and it was from DR or BDR, examin next interface */
514 if (from
&& from
->ospf6_if
== oi
515 && (from
->router_id
== oi
->drouter
516 || from
->router_id
== oi
->bdrouter
)) {
519 "Received is from the I/F's DR or BDR, next interface");
523 /* (4) If the new LSA was received on this interface,
524 and the interface state is BDR, examin next interface */
525 if (from
&& from
->ospf6_if
== oi
) {
526 if (oi
->state
== OSPF6_INTERFACE_BDR
) {
529 "Received is from the I/F, itself BDR, next interface");
532 SET_FLAG(lsa
->flag
, OSPF6_LSA_FLOODBACK
);
535 /* (5) flood the LSA out the interface. */
537 zlog_debug("Schedule flooding for the interface");
538 if ((oi
->type
== OSPF_IFTYPE_BROADCAST
)
539 || (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)) {
540 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsupdate_list
);
541 thread_add_event(master
, ospf6_lsupdate_send_interface
, oi
, 0,
542 &oi
->thread_send_lsupdate
);
544 /* reschedule retransmissions to all neighbors */
545 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
546 THREAD_OFF(on
->thread_send_lsupdate
);
547 thread_add_event(master
, ospf6_lsupdate_send_neighbor
,
548 on
, 0, &on
->thread_send_lsupdate
);
553 void ospf6_flood_area(struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
,
554 struct ospf6_area
*oa
)
556 struct listnode
*node
, *nnode
;
557 struct ospf6_interface
*oi
;
559 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
)) {
560 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
561 && oi
!= OSPF6_INTERFACE(lsa
->lsdb
->data
))
564 ospf6_flood_interface(from
, lsa
, oi
);
568 static void ospf6_flood_process(struct ospf6_neighbor
*from
,
569 struct ospf6_lsa
*lsa
, struct ospf6
*process
)
571 struct listnode
*node
, *nnode
;
572 struct ospf6_area
*oa
;
574 for (ALL_LIST_ELEMENTS(process
->area_list
, node
, nnode
, oa
)) {
576 /* If unknown LSA and U-bit clear, treat as link local
579 if (!OSPF6_LSA_IS_KNOWN(lsa
->header
->type
)
580 && !(ntohs(lsa
->header
->type
) & OSPF6_LSTYPE_UBIT_MASK
)
581 && (oa
!= OSPF6_INTERFACE(lsa
->lsdb
->data
)->area
)) {
583 if (IS_OSPF6_DEBUG_FLOODING
)
584 zlog_debug("Unknown LSA, do not flood");
588 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_AREA
589 && oa
!= OSPF6_AREA(lsa
->lsdb
->data
))
591 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
592 && oa
!= OSPF6_INTERFACE(lsa
->lsdb
->data
)->area
)
595 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
596 && (IS_AREA_STUB(oa
) || IS_AREA_NSSA(oa
)))
599 /* Check for NSSA LSA */
600 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_TYPE_7
601 && !IS_AREA_NSSA(oa
) && !OSPF6_LSA_IS_MAXAGE(lsa
))
604 ospf6_flood_area(from
, lsa
, oa
);
608 void ospf6_flood(struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
)
612 ospf6
= ospf6_get_by_lsdb(lsa
);
616 ospf6_flood_process(from
, lsa
, ospf6
);
619 static void ospf6_flood_clear_interface(struct ospf6_lsa
*lsa
,
620 struct ospf6_interface
*oi
)
622 struct listnode
*node
, *nnode
;
623 struct ospf6_neighbor
*on
;
624 struct ospf6_lsa
*rem
;
626 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
627 rem
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
628 lsa
->header
->adv_router
,
630 if (rem
&& !ospf6_lsa_compare(rem
, lsa
)) {
631 if (IS_OSPF6_DEBUG_FLOODING
632 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
633 zlog_debug("Remove %s from retrans_list of %s",
634 rem
->name
, on
->name
);
635 ospf6_decrement_retrans_count(rem
);
636 ospf6_lsdb_remove(rem
, on
->retrans_list
);
641 void ospf6_flood_clear_area(struct ospf6_lsa
*lsa
, struct ospf6_area
*oa
)
643 struct listnode
*node
, *nnode
;
644 struct ospf6_interface
*oi
;
646 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
)) {
647 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
648 && oi
!= OSPF6_INTERFACE(lsa
->lsdb
->data
))
651 ospf6_flood_clear_interface(lsa
, oi
);
655 static void ospf6_flood_clear_process(struct ospf6_lsa
*lsa
,
656 struct ospf6
*process
)
658 struct listnode
*node
, *nnode
;
659 struct ospf6_area
*oa
;
661 for (ALL_LIST_ELEMENTS(process
->area_list
, node
, nnode
, oa
)) {
662 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_AREA
663 && oa
!= OSPF6_AREA(lsa
->lsdb
->data
))
665 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
666 && oa
!= OSPF6_INTERFACE(lsa
->lsdb
->data
)->area
)
669 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
670 && (IS_AREA_STUB(oa
) || (IS_AREA_NSSA(oa
))))
672 /* Check for NSSA LSA */
673 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_TYPE_7
674 && !IS_AREA_NSSA(oa
))
677 ospf6_flood_clear_area(lsa
, oa
);
681 void ospf6_flood_clear(struct ospf6_lsa
*lsa
)
685 ospf6
= ospf6_get_by_lsdb(lsa
);
688 ospf6_flood_clear_process(lsa
, ospf6
);
692 /* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
693 static void ospf6_acknowledge_lsa_bdrouter(struct ospf6_lsa
*lsa
,
695 struct ospf6_neighbor
*from
)
697 struct ospf6_interface
*oi
;
700 if (IS_OSPF6_DEBUG_FLOODING
701 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
704 assert(from
&& from
->ospf6_if
);
707 /* LSA is more recent than database copy, but was not flooded
708 back out receiving interface. Delayed acknowledgement sent
709 if advertisement received from Designated Router,
710 otherwide do nothing. */
711 if (ismore_recent
< 0) {
712 if (oi
->drouter
== from
->router_id
) {
715 "Delayed acknowledgement (BDR & MoreRecent & from DR)");
716 /* Delayed acknowledgement */
717 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsack_list
);
718 thread_add_timer(master
, ospf6_lsack_send_interface
, oi
,
719 3, &oi
->thread_send_lsack
);
723 "No acknowledgement (BDR & MoreRecent & ! from DR)");
728 /* LSA is a duplicate, and was treated as an implied acknowledgement.
729 Delayed acknowledgement sent if advertisement received from
730 Designated Router, otherwise do nothing */
731 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
732 && CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
733 if (oi
->drouter
== from
->router_id
) {
736 "Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
737 /* Delayed acknowledgement */
738 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsack_list
);
739 thread_add_timer(master
, ospf6_lsack_send_interface
, oi
,
740 3, &oi
->thread_send_lsack
);
744 "No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
749 /* LSA is a duplicate, and was not treated as an implied
751 Direct acknowledgement sent */
752 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
753 && !CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
755 zlog_debug("Direct acknowledgement (BDR & Duplicate)");
756 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), from
->lsack_list
);
757 thread_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
758 &from
->thread_send_lsack
);
762 /* LSA's LS age is equal to Maxage, and there is no current instance
763 of the LSA in the link state database, and none of router's
764 neighbors are in states Exchange or Loading */
765 /* Direct acknowledgement sent, but this case is handled in
766 early of ospf6_receive_lsa () */
769 static void ospf6_acknowledge_lsa_allother(struct ospf6_lsa
*lsa
,
771 struct ospf6_neighbor
*from
)
773 struct ospf6_interface
*oi
;
776 if (IS_OSPF6_DEBUG_FLOODING
777 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
780 assert(from
&& from
->ospf6_if
);
783 /* LSA has been flood back out receiving interface.
784 No acknowledgement sent. */
785 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_FLOODBACK
)) {
787 zlog_debug("No acknowledgement (AllOther & FloodBack)");
791 /* LSA is more recent than database copy, but was not flooded
792 back out receiving interface. Delayed acknowledgement sent. */
793 if (ismore_recent
< 0) {
796 "Delayed acknowledgement (AllOther & MoreRecent)");
797 /* Delayed acknowledgement */
798 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsack_list
);
799 thread_add_timer(master
, ospf6_lsack_send_interface
, oi
, 3,
800 &oi
->thread_send_lsack
);
804 /* LSA is a duplicate, and was treated as an implied acknowledgement.
805 No acknowledgement sent. */
806 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
807 && CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
810 "No acknowledgement (AllOther & Duplicate & ImpliedAck)");
814 /* LSA is a duplicate, and was not treated as an implied
816 Direct acknowledgement sent */
817 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
818 && !CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
821 "Direct acknowledgement (AllOther & Duplicate)");
822 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), from
->lsack_list
);
823 thread_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
824 &from
->thread_send_lsack
);
828 /* LSA's LS age is equal to Maxage, and there is no current instance
829 of the LSA in the link state database, and none of router's
830 neighbors are in states Exchange or Loading */
831 /* Direct acknowledgement sent, but this case is handled in
832 early of ospf6_receive_lsa () */
835 static void ospf6_acknowledge_lsa(struct ospf6_lsa
*lsa
, int ismore_recent
,
836 struct ospf6_neighbor
*from
)
838 struct ospf6_interface
*oi
;
840 assert(from
&& from
->ospf6_if
);
843 if (oi
->state
== OSPF6_INTERFACE_BDR
)
844 ospf6_acknowledge_lsa_bdrouter(lsa
, ismore_recent
, from
);
846 ospf6_acknowledge_lsa_allother(lsa
, ismore_recent
, from
);
849 /* RFC2328 section 13 (4):
850 if MaxAge LSA and if we have no instance, and no neighbor
851 is in states Exchange or Loading
852 returns 1 if match this case, else returns 0 */
853 static int ospf6_is_maxage_lsa_drop(struct ospf6_lsa
*lsa
,
854 struct ospf6_neighbor
*from
)
856 struct ospf6_neighbor
*on
;
857 struct ospf6_interface
*oi
;
858 struct ospf6_area
*oa
;
859 struct ospf6
*process
= NULL
;
860 struct listnode
*i
, *j
, *k
;
863 if (!OSPF6_LSA_IS_MAXAGE(lsa
))
866 if (ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
867 lsa
->header
->adv_router
, lsa
->lsdb
))
870 process
= from
->ospf6_if
->area
->ospf6
;
872 for (ALL_LIST_ELEMENTS_RO(process
->area_list
, i
, oa
))
873 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
874 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, k
, on
))
875 if (on
->state
== OSPF6_NEIGHBOR_EXCHANGE
876 || on
->state
== OSPF6_NEIGHBOR_LOADING
)
884 /* RFC2328 section 13 The Flooding Procedure */
885 void ospf6_receive_lsa(struct ospf6_neighbor
*from
,
886 struct ospf6_lsa_header
*lsa_header
)
888 struct ospf6_lsa
*new = NULL
, *old
= NULL
, *rem
= NULL
;
891 unsigned int time_delta_ms
;
896 /* if we receive a LSA with invalid seqnum drop it */
897 if (ntohl(lsa_header
->seqnum
) - 1 == OSPF_MAX_SEQUENCE_NUMBER
) {
898 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa_header
->type
)) {
900 "received lsa [%s Id:%pI4 Adv:%pI4] with invalid seqnum 0x%x, ignore",
901 ospf6_lstype_name(lsa_header
->type
),
902 &lsa_header
->id
, &lsa_header
->adv_router
,
903 ntohl(lsa_header
->seqnum
));
908 /* make lsa structure for received lsa */
909 new = ospf6_lsa_create(lsa_header
);
911 if (IS_OSPF6_DEBUG_FLOODING
912 || IS_OSPF6_DEBUG_FLOOD_TYPE(new->header
->type
)) {
914 zlog_debug("LSA Receive from %s", from
->name
);
915 ospf6_lsa_header_print(new);
918 /* (1) LSA Checksum */
919 if (!ospf6_lsa_checksum_valid(new->header
)) {
921 zlog_debug("Wrong LSA Checksum, discard");
922 ospf6_lsa_delete(new);
926 /* (2) Examine the LSA's LS type.
927 RFC2470 3.5.1. Receiving Link State Update packets */
928 if (IS_AREA_STUB(from
->ospf6_if
->area
)
929 && OSPF6_LSA_SCOPE(new->header
->type
) == OSPF6_SCOPE_AS
) {
932 "AS-External-LSA (or AS-scope LSA) in stub area, discard");
933 ospf6_lsa_delete(new);
937 /* (3) LSA which have reserved scope is discarded
938 RFC2470 3.5.1. Receiving Link State Update packets */
939 /* Flooding scope check. LSAs with unknown scope are discarded here.
940 Set appropriate LSDB for the LSA */
941 switch (OSPF6_LSA_SCOPE(new->header
->type
)) {
942 case OSPF6_SCOPE_LINKLOCAL
:
943 new->lsdb
= from
->ospf6_if
->lsdb
;
945 case OSPF6_SCOPE_AREA
:
946 new->lsdb
= from
->ospf6_if
->area
->lsdb
;
949 new->lsdb
= from
->ospf6_if
->area
->ospf6
->lsdb
;
953 zlog_debug("LSA has reserved scope, discard");
954 ospf6_lsa_delete(new);
958 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
959 is in states Exchange or Loading */
960 if (ospf6_is_maxage_lsa_drop(new, from
)) {
964 "Drop MaxAge LSA with direct acknowledgement.");
966 /* a) Acknowledge back to neighbor (Direct acknowledgement,
968 ospf6_lsdb_add(ospf6_lsa_copy(new), from
->lsack_list
);
969 thread_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
970 &from
->thread_send_lsack
);
973 ospf6_lsa_delete(new);
978 /* lookup the same database copy in lsdb */
979 old
= ospf6_lsdb_lookup(new->header
->type
, new->header
->id
,
980 new->header
->adv_router
, new->lsdb
);
982 ismore_recent
= ospf6_lsa_compare(new, old
);
983 if (ntohl(new->header
->seqnum
) == ntohl(old
->header
->seqnum
)) {
985 zlog_debug("Received is duplicated LSA");
986 SET_FLAG(new->flag
, OSPF6_LSA_DUPLICATE
);
990 /* if no database copy or received is more recent */
991 if (old
== NULL
|| ismore_recent
< 0) {
992 bool self_originated
;
994 /* in case we have no database copy */
997 /* (a) MinLSArrival check */
999 struct timeval now
, res
;
1001 timersub(&now
, &old
->installed
, &res
);
1003 (res
.tv_sec
* 1000) + (int)(res
.tv_usec
/ 1000);
1005 < from
->ospf6_if
->area
->ospf6
->lsa_minarrival
) {
1008 "LSA can't be updated within MinLSArrival, %dms < %dms, discard",
1010 from
->ospf6_if
->area
->ospf6
1012 ospf6_lsa_delete(new);
1013 return; /* examin next lsa */
1017 monotime(&new->received
);
1021 "Install, Flood, Possibly acknowledge the received LSA");
1023 /* Remove older copies of this LSA from retx lists */
1025 ospf6_flood_clear(old
);
1027 self_originated
= (new->header
->adv_router
1028 == from
->ospf6_if
->area
->ospf6
->router_id
);
1030 /* Received non-self-originated Grace LSA. */
1031 if (IS_GRACE_LSA(new) && !self_originated
) {
1032 struct ospf6
*ospf6
;
1034 ospf6
= ospf6_get_by_lsdb(new);
1038 if (OSPF6_LSA_IS_MAXAGE(new)) {
1040 if (IS_DEBUG_OSPF6_GR
)
1042 "%s, Received a maxage GraceLSA from router %pI4",
1044 &new->header
->adv_router
);
1046 ospf6_process_maxage_grace_lsa(
1049 if (IS_DEBUG_OSPF6_GR
)
1051 "%s, GraceLSA doesn't exist in lsdb, so discarding GraceLSA",
1057 if (IS_DEBUG_OSPF6_GR
)
1059 "%s, Received a GraceLSA from router %pI4",
1061 &new->header
->adv_router
);
1063 if (ospf6_process_grace_lsa(ospf6
, new, from
)
1064 == OSPF6_GR_NOT_HELPER
) {
1065 if (IS_DEBUG_OSPF6_GR
)
1067 "%s, Not moving to HELPER role, So dicarding GraceLSA",
1074 /* (b) immediately flood and (c) remove from all retrans-list */
1075 /* Prevent self-originated LSA to be flooded. this is to make
1076 * reoriginated instance of the LSA not to be rejected by other
1077 * routers due to MinLSArrival.
1079 if (!self_originated
)
1080 ospf6_flood(from
, new);
1082 /* (d), installing lsdb, which may cause routing
1083 table calculation (replacing database copy) */
1084 ospf6_install_lsa(new);
1086 if (OSPF6_LSA_IS_MAXAGE(new))
1087 ospf6_maxage_remove(from
->ospf6_if
->area
->ospf6
);
1089 /* (e) possibly acknowledge */
1090 ospf6_acknowledge_lsa(new, ismore_recent
, from
);
1092 /* (f) Self Originated LSA, section 13.4 */
1093 if (self_originated
) {
1094 if (from
->ospf6_if
->area
->ospf6
->gr_info
1095 .restart_in_progress
) {
1096 if (IS_DEBUG_OSPF6_GR
)
1098 "Graceful Restart in progress -- not flushing self-originated LSA: %s",
1103 /* Self-originated LSA (newer than ours) is received
1105 another router. We have to make a new instance of the
1107 or have to flush this LSA. */
1110 "Newer instance of the self-originated LSA");
1111 zlog_debug("Schedule reorigination");
1113 thread_add_event(master
, ospf6_lsa_refresh
, new, 0,
1117 struct ospf6
*ospf6
= from
->ospf6_if
->area
->ospf6
;
1118 struct ospf6_area
*area
= from
->ospf6_if
->area
;
1119 if (ospf6
->gr_info
.restart_in_progress
)
1120 ospf6_gr_check_lsdb_consistency(ospf6
, area
);
1125 /* (6) if there is instance on sending neighbor's request list */
1126 if (ospf6_lsdb_lookup(new->header
->type
, new->header
->id
,
1127 new->header
->adv_router
, from
->request_list
)) {
1128 /* if no database copy, should go above state (5) */
1132 "Received is not newer, on the neighbor %s request-list",
1135 "BadLSReq, discard the received LSA lsa %s send badLSReq",
1139 thread_add_event(master
, bad_lsreq
, from
, 0, NULL
);
1141 ospf6_lsa_delete(new);
1145 /* (7) if neither one is more recent */
1146 if (ismore_recent
== 0) {
1149 "The same instance as database copy (neither recent)");
1151 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack
1153 rem
= ospf6_lsdb_lookup(new->header
->type
, new->header
->id
,
1154 new->header
->adv_router
,
1155 from
->retrans_list
);
1159 "It is on the neighbor's retrans-list.");
1161 "Treat as an Implied acknowledgement");
1163 SET_FLAG(new->flag
, OSPF6_LSA_IMPLIEDACK
);
1164 ospf6_decrement_retrans_count(rem
);
1165 ospf6_lsdb_remove(rem
, from
->retrans_list
);
1169 zlog_debug("Possibly acknowledge and then discard");
1171 /* (b) possibly acknowledge */
1172 ospf6_acknowledge_lsa(new, ismore_recent
, from
);
1174 ospf6_lsa_delete(new);
1178 /* (8) previous database copy is more recent */
1182 /* If database copy is in 'Seqnumber Wrapping',
1183 simply discard the received LSA */
1184 if (OSPF6_LSA_IS_MAXAGE(old
)
1185 && old
->header
->seqnum
== htonl(OSPF_MAX_SEQUENCE_NUMBER
)) {
1187 zlog_debug("The LSA is in Seqnumber Wrapping");
1188 zlog_debug("MaxAge & MaxSeqNum, discard");
1190 ospf6_lsa_delete(new);
1194 /* Otherwise, Send database copy of this LSA to this neighbor */
1197 zlog_debug("Database copy is more recent.");
1199 "Send back directly and then discard");
1202 /* Neighbor router sent recent age for LSA,
1203 * Router could be restarted while current copy is
1204 * MAXAGEd and not removed.*/
1205 if (OSPF6_LSA_IS_MAXAGE(old
)
1206 && !OSPF6_LSA_IS_MAXAGE(new)) {
1207 if (new->header
->adv_router
1208 != from
->ospf6_if
->area
->ospf6
->router_id
) {
1211 "%s: Current copy of LSA %s is MAXAGE, but new has recent age, flooding/installing.",
1212 __PRETTY_FUNCTION__
, old
->name
);
1213 ospf6_lsa_purge(old
);
1214 ospf6_flood(from
, new);
1215 ospf6_install_lsa(new);
1218 /* For self-originated LSA, only trust
1219 * ourselves. Fall through and send
1220 * LS Update with our current copy.
1224 "%s: Current copy of self-originated LSA %s is MAXAGE, but new has recent age, re-sending current one.",
1225 __PRETTY_FUNCTION__
, old
->name
);
1228 /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
1230 ospf6_lsdb_add(ospf6_lsa_copy(old
),
1231 from
->lsupdate_list
);
1232 thread_add_event(master
, ospf6_lsupdate_send_neighbor
,
1233 from
, 0, &from
->thread_send_lsupdate
);
1235 ospf6_lsa_delete(new);
1241 DEFUN (debug_ospf6_flooding
,
1242 debug_ospf6_flooding_cmd
,
1243 "debug ospf6 flooding",
1246 "Debug OSPFv3 flooding function\n"
1249 OSPF6_DEBUG_FLOODING_ON();
1253 DEFUN (no_debug_ospf6_flooding
,
1254 no_debug_ospf6_flooding_cmd
,
1255 "no debug ospf6 flooding",
1259 "Debug OSPFv3 flooding function\n"
1262 OSPF6_DEBUG_FLOODING_OFF();
1266 int config_write_ospf6_debug_flood(struct vty
*vty
)
1268 if (IS_OSPF6_DEBUG_FLOODING
)
1269 vty_out(vty
, "debug ospf6 flooding\n");
1273 void install_element_ospf6_debug_flood(void)
1275 install_element(ENABLE_NODE
, &debug_ospf6_flooding_cmd
);
1276 install_element(ENABLE_NODE
, &no_debug_ospf6_flooding_cmd
);
1277 install_element(CONFIG_NODE
, &debug_ospf6_flooding_cmd
);
1278 install_element(CONFIG_NODE
, &no_debug_ospf6_flooding_cmd
);