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"
45 unsigned char conf_debug_ospf6_flooding
;
47 struct ospf6_lsdb
*ospf6_get_scoped_lsdb(struct ospf6_lsa
*lsa
)
49 struct ospf6_lsdb
*lsdb
= NULL
;
50 switch (OSPF6_LSA_SCOPE(lsa
->header
->type
)) {
51 case OSPF6_SCOPE_LINKLOCAL
:
52 lsdb
= OSPF6_INTERFACE(lsa
->lsdb
->data
)->lsdb
;
54 case OSPF6_SCOPE_AREA
:
55 lsdb
= OSPF6_AREA(lsa
->lsdb
->data
)->lsdb
;
58 lsdb
= OSPF6_PROCESS(lsa
->lsdb
->data
)->lsdb
;
67 struct ospf6_lsdb
*ospf6_get_scoped_lsdb_self(struct ospf6_lsa
*lsa
)
69 struct ospf6_lsdb
*lsdb_self
= NULL
;
70 switch (OSPF6_LSA_SCOPE(lsa
->header
->type
)) {
71 case OSPF6_SCOPE_LINKLOCAL
:
72 lsdb_self
= OSPF6_INTERFACE(lsa
->lsdb
->data
)->lsdb_self
;
74 case OSPF6_SCOPE_AREA
:
75 lsdb_self
= OSPF6_AREA(lsa
->lsdb
->data
)->lsdb_self
;
78 lsdb_self
= OSPF6_PROCESS(lsa
->lsdb
->data
)->lsdb_self
;
87 void ospf6_lsa_originate(struct ospf6_lsa
*lsa
)
89 struct ospf6_lsa
*old
;
90 struct ospf6_lsdb
*lsdb_self
;
92 if (lsa
->header
->adv_router
== INADDR_ANY
) {
93 if (IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa
->header
->type
))
95 "Refusing to originate LSA (zero router ID): %s",
98 ospf6_lsa_delete(lsa
);
102 /* find previous LSA */
103 old
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
104 lsa
->header
->adv_router
, lsa
->lsdb
);
106 /* if the new LSA does not differ from previous,
107 suppress this update of the LSA */
108 if (old
&& !OSPF6_LSA_IS_DIFFER(lsa
, old
)) {
109 if (IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa
->header
->type
))
110 zlog_debug("Suppress updating LSA: %s", lsa
->name
);
111 ospf6_lsa_delete(lsa
);
115 /* store it in the LSDB for self-originated LSAs */
116 lsdb_self
= ospf6_get_scoped_lsdb_self(lsa
);
117 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), lsdb_self
);
119 THREAD_OFF(lsa
->refresh
);
120 thread_add_timer(master
, ospf6_lsa_refresh
, lsa
, OSPF_LS_REFRESH_TIME
,
123 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
)
124 || IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa
->header
->type
)) {
125 zlog_debug("LSA Originate:");
126 ospf6_lsa_header_print(lsa
);
129 ospf6_install_lsa(lsa
);
130 ospf6_flood(NULL
, lsa
);
133 void ospf6_lsa_originate_process(struct ospf6_lsa
*lsa
, struct ospf6
*process
)
135 lsa
->lsdb
= process
->lsdb
;
136 ospf6_lsa_originate(lsa
);
139 void ospf6_lsa_originate_area(struct ospf6_lsa
*lsa
, struct ospf6_area
*oa
)
141 lsa
->lsdb
= oa
->lsdb
;
142 ospf6_lsa_originate(lsa
);
145 void ospf6_lsa_originate_interface(struct ospf6_lsa
*lsa
,
146 struct ospf6_interface
*oi
)
148 lsa
->lsdb
= oi
->lsdb
;
149 ospf6_lsa_originate(lsa
);
152 void ospf6_remove_id_from_external_id_table(struct ospf6
*ospf6
,
155 struct prefix prefix_id
;
156 struct route_node
*node
;
158 /* remove binding in external_id_table */
159 prefix_id
.family
= AF_INET
;
160 prefix_id
.prefixlen
= 32;
161 prefix_id
.u
.prefix4
.s_addr
= id
;
162 node
= route_node_lookup(ospf6
->external_id_table
, &prefix_id
);
165 route_unlock_node(node
); /* to free the lookup lock */
166 route_unlock_node(node
); /* to free the original lock */
170 void ospf6_external_lsa_purge(struct ospf6
*ospf6
, struct ospf6_lsa
*lsa
)
172 ospf6_lsa_purge(lsa
);
174 ospf6_remove_id_from_external_id_table(ospf6
, lsa
->header
->id
);
177 void ospf6_lsa_purge(struct ospf6_lsa
*lsa
)
179 struct ospf6_lsa
*self
;
180 struct ospf6_lsdb
*lsdb_self
;
182 /* remove it from the LSDB for self-originated LSAs */
183 lsdb_self
= ospf6_get_scoped_lsdb_self(lsa
);
184 self
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
185 lsa
->header
->adv_router
, lsdb_self
);
187 THREAD_OFF(self
->expire
);
188 THREAD_OFF(self
->refresh
);
189 ospf6_lsdb_remove(self
, lsdb_self
);
192 ospf6_lsa_premature_aging(lsa
);
195 /* Puring Multi Link-State IDs LSAs:
196 * Same Advertising Router with Multiple Link-State IDs
197 * LSAs, purging require to traverse all Link-State IDs
199 void ospf6_lsa_purge_multi_ls_id(struct ospf6_area
*oa
, struct ospf6_lsa
*lsa
)
202 struct ospf6_lsa
*lsa_next
;
205 type
= lsa
->header
->type
;
207 ospf6_lsa_purge(lsa
);
209 lsa_next
= ospf6_lsdb_lookup(type
, htonl(++ls_id
),
210 oa
->ospf6
->router_id
, oa
->lsdb
);
212 ospf6_lsa_purge(lsa_next
);
213 lsa_next
= ospf6_lsdb_lookup(type
, htonl(++ls_id
),
214 oa
->ospf6
->router_id
, oa
->lsdb
);
218 void ospf6_increment_retrans_count(struct ospf6_lsa
*lsa
)
220 /* The LSA must be the original one (see the description
221 in ospf6_decrement_retrans_count () below) */
222 lsa
->retrans_count
++;
225 void ospf6_decrement_retrans_count(struct ospf6_lsa
*lsa
)
227 struct ospf6_lsdb
*lsdb
;
228 struct ospf6_lsa
*orig
;
230 /* The LSA must be on the retrans-list of a neighbor. It means
231 the "lsa" is a copied one, and we have to decrement the
232 retransmission count of the original one (instead of this "lsa"'s).
233 In order to find the original LSA, first we have to find
234 appropriate LSDB that have the original LSA. */
235 lsdb
= ospf6_get_scoped_lsdb(lsa
);
237 /* Find the original LSA of which the retrans_count should be
239 orig
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
240 lsa
->header
->adv_router
, lsdb
);
242 orig
->retrans_count
--;
243 assert(orig
->retrans_count
>= 0);
247 /* RFC2328 section 13.2 Installing LSAs in the database */
248 void ospf6_install_lsa(struct ospf6_lsa
*lsa
)
251 struct ospf6_lsa
*old
;
252 struct ospf6_area
*area
= NULL
;
254 /* Remove the old instance from all neighbors' Link state
255 retransmission list (RFC2328 13.2 last paragraph) */
256 old
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
257 lsa
->header
->adv_router
, lsa
->lsdb
);
259 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_TYPE_7
) {
260 if (IS_OSPF6_DEBUG_NSSA
)
261 zlog_debug("%s : old LSA %s", __func__
,
263 lsa
->external_lsa_id
= old
->external_lsa_id
;
265 THREAD_OFF(old
->expire
);
266 THREAD_OFF(old
->refresh
);
267 ospf6_flood_clear(old
);
271 if (!OSPF6_LSA_IS_MAXAGE(lsa
)) {
273 thread_add_timer(master
, ospf6_lsa_expire
, lsa
,
274 OSPF_LSA_MAXAGE
+ lsa
->birth
.tv_sec
280 if (OSPF6_LSA_IS_SEQWRAP(lsa
)
281 && !(CHECK_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
)
282 && lsa
->header
->seqnum
== htonl(OSPF_MAX_SEQUENCE_NUMBER
))) {
283 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
))
284 zlog_debug("lsa install wrapping: sequence 0x%x",
285 ntohl(lsa
->header
->seqnum
));
286 SET_FLAG(lsa
->flag
, OSPF6_LSA_SEQWRAPPED
);
287 /* in lieu of premature_aging, since we do not want to recreate
289 * and/or mess with timers etc, we just want to wrap the
291 * and reflood the lsa before continuing.
292 * NOTE: Flood needs to be called right after this function
296 lsa
->header
->seqnum
= htonl(OSPF_MAX_SEQUENCE_NUMBER
);
297 lsa
->header
->age
= htons(OSPF_LSA_MAXAGE
);
298 ospf6_lsa_checksum(lsa
->header
);
301 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
)
302 || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
))
303 zlog_debug("%s Install LSA: %s age %d seqnum %x in LSDB.",
304 __func__
, lsa
->name
, ntohs(lsa
->header
->age
),
305 ntohl(lsa
->header
->seqnum
));
307 /* actually install */
308 lsa
->installed
= now
;
309 ospf6_lsdb_add(lsa
, lsa
->lsdb
);
311 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_TYPE_7
) {
312 area
= OSPF6_AREA(lsa
->lsdb
->data
);
313 ospf6_translated_nssa_refresh(area
, lsa
, NULL
);
314 ospf6_schedule_abr_task(area
->ospf6
);
317 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_ROUTER
) {
318 area
= OSPF6_AREA(lsa
->lsdb
->data
);
320 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa
->header
->type
)
321 || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa
->header
->type
))
322 zlog_debug("%s: New router LSA %s", __func__
,
324 ospf6_abr_nssa_check_status(area
->ospf6
);
330 /* RFC2740 section 3.5.2. Sending Link State Update packets */
331 /* RFC2328 section 13.3 Next step in the flooding procedure */
332 void ospf6_flood_interface(struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
,
333 struct ospf6_interface
*oi
)
335 struct listnode
*node
, *nnode
;
336 struct ospf6_neighbor
*on
;
337 struct ospf6_lsa
*req
, *old
;
338 int retrans_added
= 0;
341 if (IS_OSPF6_DEBUG_FLOODING
342 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
)) {
344 zlog_debug("Flooding on %s: %s", oi
->interface
->name
,
348 /* (1) For each neighbor */
349 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
351 zlog_debug("To neighbor %s", on
->name
);
353 /* (a) if neighbor state < Exchange, examin next */
354 if (on
->state
< OSPF6_NEIGHBOR_EXCHANGE
) {
357 "Neighbor state less than ExChange, next neighbor");
361 /* (b) if neighbor not yet Full, check request-list */
362 if (on
->state
!= OSPF6_NEIGHBOR_FULL
) {
364 zlog_debug("Neighbor not yet Full");
366 req
= ospf6_lsdb_lookup(
367 lsa
->header
->type
, lsa
->header
->id
,
368 lsa
->header
->adv_router
, on
->request_list
);
372 "Not on request-list for this neighbor");
375 /* If new LSA less recent, examin next neighbor
377 if (ospf6_lsa_compare(lsa
, req
) > 0) {
380 "Requesting is older, next neighbor");
384 /* If the same instance, delete from
386 examin next neighbor */
387 if (ospf6_lsa_compare(lsa
, req
) == 0) {
390 "Requesting the same, remove it, next neighbor");
391 if (req
== on
->last_ls_req
) {
392 /* sanity check refcount */
393 assert(req
->lock
>= 2);
394 req
= ospf6_lsa_unlock(req
);
395 on
->last_ls_req
= NULL
;
399 req
, on
->request_list
);
400 ospf6_check_nbr_loading(on
);
404 /* If the new LSA is more recent, delete from
406 if (ospf6_lsa_compare(lsa
, req
) < 0) {
409 "Received is newer, remove requesting");
410 if (req
== on
->last_ls_req
) {
411 req
= ospf6_lsa_unlock(req
);
412 on
->last_ls_req
= NULL
;
415 ospf6_lsdb_remove(req
,
417 ospf6_check_nbr_loading(on
);
423 /* (c) If the new LSA was received from this neighbor,
424 examin next neighbor */
428 "Received is from the neighbor, next neighbor");
432 if ((oi
->area
->ospf6
->inst_shutdown
)
433 || CHECK_FLAG(lsa
->flag
, OSPF6_LSA_FLUSH
)) {
436 "%s: Send LSA %s (age %d) update now",
438 ntohs(lsa
->header
->age
));
439 ospf6_lsupdate_send_neighbor_now(on
, lsa
);
442 /* (d) add retrans-list, schedule retransmission */
444 zlog_debug("Add retrans-list of neighbor %s ",
447 /* Do not increment the retrans count if the lsa is
448 * already present in the retrans list.
450 old
= ospf6_lsdb_lookup(
451 lsa
->header
->type
, lsa
->header
->id
,
452 lsa
->header
->adv_router
, on
->retrans_list
);
456 "Increment %s from retrans_list of %s",
457 lsa
->name
, on
->name
);
458 ospf6_increment_retrans_count(lsa
);
459 ospf6_lsdb_add(ospf6_lsa_copy(lsa
),
462 master
, ospf6_lsupdate_send_neighbor
,
463 on
, on
->ospf6_if
->rxmt_interval
,
464 &on
->thread_send_lsupdate
);
470 /* (2) examin next interface if not added to retrans-list */
471 if (retrans_added
== 0) {
474 "No retransmission scheduled, next interface %s",
475 oi
->interface
->name
);
479 /* (3) If the new LSA was received on this interface,
480 and it was from DR or BDR, examin next interface */
481 if (from
&& from
->ospf6_if
== oi
482 && (from
->router_id
== oi
->drouter
483 || from
->router_id
== oi
->bdrouter
)) {
486 "Received is from the I/F's DR or BDR, next interface");
490 /* (4) If the new LSA was received on this interface,
491 and the interface state is BDR, examin next interface */
492 if (from
&& from
->ospf6_if
== oi
) {
493 if (oi
->state
== OSPF6_INTERFACE_BDR
) {
496 "Received is from the I/F, itself BDR, next interface");
499 SET_FLAG(lsa
->flag
, OSPF6_LSA_FLOODBACK
);
502 /* (5) flood the LSA out the interface. */
504 zlog_debug("Schedule flooding for the interface");
505 if ((oi
->type
== OSPF_IFTYPE_BROADCAST
)
506 || (oi
->type
== OSPF_IFTYPE_POINTOPOINT
)) {
507 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsupdate_list
);
508 thread_add_event(master
, ospf6_lsupdate_send_interface
, oi
, 0,
509 &oi
->thread_send_lsupdate
);
511 /* reschedule retransmissions to all neighbors */
512 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
513 THREAD_OFF(on
->thread_send_lsupdate
);
514 on
->thread_send_lsupdate
= NULL
;
515 thread_add_event(master
, ospf6_lsupdate_send_neighbor
,
516 on
, 0, &on
->thread_send_lsupdate
);
521 void ospf6_flood_area(struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
,
522 struct ospf6_area
*oa
)
524 struct listnode
*node
, *nnode
;
525 struct ospf6_interface
*oi
;
527 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
)) {
528 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
529 && oi
!= OSPF6_INTERFACE(lsa
->lsdb
->data
))
532 ospf6_flood_interface(from
, lsa
, oi
);
536 static void ospf6_flood_process(struct ospf6_neighbor
*from
,
537 struct ospf6_lsa
*lsa
, struct ospf6
*process
)
539 struct listnode
*node
, *nnode
;
540 struct ospf6_area
*oa
;
542 for (ALL_LIST_ELEMENTS(process
->area_list
, node
, nnode
, oa
)) {
544 /* If unknown LSA and U-bit clear, treat as link local
547 if (!OSPF6_LSA_IS_KNOWN(lsa
->header
->type
)
548 && !(ntohs(lsa
->header
->type
) & OSPF6_LSTYPE_UBIT_MASK
)
549 && (oa
!= OSPF6_INTERFACE(lsa
->lsdb
->data
)->area
)) {
551 if (IS_OSPF6_DEBUG_FLOODING
)
552 zlog_debug("Unknown LSA, do not flood");
556 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_AREA
557 && oa
!= OSPF6_AREA(lsa
->lsdb
->data
))
559 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
560 && oa
!= OSPF6_INTERFACE(lsa
->lsdb
->data
)->area
)
563 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
564 && (IS_AREA_STUB(oa
) || IS_AREA_NSSA(oa
)))
567 /* Check for NSSA LSA */
568 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_TYPE_7
569 && !IS_AREA_NSSA(oa
) && !OSPF6_LSA_IS_MAXAGE(lsa
))
572 ospf6_flood_area(from
, lsa
, oa
);
576 void ospf6_flood(struct ospf6_neighbor
*from
, struct ospf6_lsa
*lsa
)
580 ospf6
= ospf6_get_by_lsdb(lsa
);
584 ospf6_flood_process(from
, lsa
, ospf6
);
587 static void ospf6_flood_clear_interface(struct ospf6_lsa
*lsa
,
588 struct ospf6_interface
*oi
)
590 struct listnode
*node
, *nnode
;
591 struct ospf6_neighbor
*on
;
592 struct ospf6_lsa
*rem
;
594 for (ALL_LIST_ELEMENTS(oi
->neighbor_list
, node
, nnode
, on
)) {
595 rem
= ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
596 lsa
->header
->adv_router
,
598 if (rem
&& !ospf6_lsa_compare(rem
, lsa
)) {
599 if (IS_OSPF6_DEBUG_FLOODING
600 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
601 zlog_debug("Remove %s from retrans_list of %s",
602 rem
->name
, on
->name
);
603 ospf6_decrement_retrans_count(rem
);
604 ospf6_lsdb_remove(rem
, on
->retrans_list
);
609 void ospf6_flood_clear_area(struct ospf6_lsa
*lsa
, struct ospf6_area
*oa
)
611 struct listnode
*node
, *nnode
;
612 struct ospf6_interface
*oi
;
614 for (ALL_LIST_ELEMENTS(oa
->if_list
, node
, nnode
, oi
)) {
615 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
616 && oi
!= OSPF6_INTERFACE(lsa
->lsdb
->data
))
619 ospf6_flood_clear_interface(lsa
, oi
);
623 static void ospf6_flood_clear_process(struct ospf6_lsa
*lsa
,
624 struct ospf6
*process
)
626 struct listnode
*node
, *nnode
;
627 struct ospf6_area
*oa
;
629 for (ALL_LIST_ELEMENTS(process
->area_list
, node
, nnode
, oa
)) {
630 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_AREA
631 && oa
!= OSPF6_AREA(lsa
->lsdb
->data
))
633 if (OSPF6_LSA_SCOPE(lsa
->header
->type
) == OSPF6_SCOPE_LINKLOCAL
634 && oa
!= OSPF6_INTERFACE(lsa
->lsdb
->data
)->area
)
637 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
638 && (IS_AREA_STUB(oa
) || (IS_AREA_NSSA(oa
))))
640 /* Check for NSSA LSA */
641 if (ntohs(lsa
->header
->type
) == OSPF6_LSTYPE_TYPE_7
642 && !IS_AREA_NSSA(oa
))
645 ospf6_flood_clear_area(lsa
, oa
);
649 void ospf6_flood_clear(struct ospf6_lsa
*lsa
)
653 ospf6
= ospf6_get_by_lsdb(lsa
);
656 ospf6_flood_clear_process(lsa
, ospf6
);
660 /* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
661 static void ospf6_acknowledge_lsa_bdrouter(struct ospf6_lsa
*lsa
,
663 struct ospf6_neighbor
*from
)
665 struct ospf6_interface
*oi
;
668 if (IS_OSPF6_DEBUG_FLOODING
669 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
672 assert(from
&& from
->ospf6_if
);
675 /* LSA is more recent than database copy, but was not flooded
676 back out receiving interface. Delayed acknowledgement sent
677 if advertisement received from Designated Router,
678 otherwide do nothing. */
679 if (ismore_recent
< 0) {
680 if (oi
->drouter
== from
->router_id
) {
683 "Delayed acknowledgement (BDR & MoreRecent & from DR)");
684 /* Delayed acknowledgement */
685 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsack_list
);
686 thread_add_timer(master
, ospf6_lsack_send_interface
, oi
,
687 3, &oi
->thread_send_lsack
);
691 "No acknowledgement (BDR & MoreRecent & ! from DR)");
696 /* LSA is a duplicate, and was treated as an implied acknowledgement.
697 Delayed acknowledgement sent if advertisement received from
698 Designated Router, otherwise do nothing */
699 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
700 && CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
701 if (oi
->drouter
== from
->router_id
) {
704 "Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
705 /* Delayed acknowledgement */
706 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsack_list
);
707 thread_add_timer(master
, ospf6_lsack_send_interface
, oi
,
708 3, &oi
->thread_send_lsack
);
712 "No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
717 /* LSA is a duplicate, and was not treated as an implied
719 Direct acknowledgement sent */
720 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
721 && !CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
723 zlog_debug("Direct acknowledgement (BDR & Duplicate)");
724 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), from
->lsack_list
);
725 thread_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
726 &from
->thread_send_lsack
);
730 /* LSA's LS age is equal to Maxage, and there is no current instance
731 of the LSA in the link state database, and none of router's
732 neighbors are in states Exchange or Loading */
733 /* Direct acknowledgement sent, but this case is handled in
734 early of ospf6_receive_lsa () */
737 static void ospf6_acknowledge_lsa_allother(struct ospf6_lsa
*lsa
,
739 struct ospf6_neighbor
*from
)
741 struct ospf6_interface
*oi
;
744 if (IS_OSPF6_DEBUG_FLOODING
745 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa
->header
->type
))
748 assert(from
&& from
->ospf6_if
);
751 /* LSA has been flood back out receiving interface.
752 No acknowledgement sent. */
753 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_FLOODBACK
)) {
755 zlog_debug("No acknowledgement (AllOther & FloodBack)");
759 /* LSA is more recent than database copy, but was not flooded
760 back out receiving interface. Delayed acknowledgement sent. */
761 if (ismore_recent
< 0) {
764 "Delayed acknowledgement (AllOther & MoreRecent)");
765 /* Delayed acknowledgement */
766 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), oi
->lsack_list
);
767 thread_add_timer(master
, ospf6_lsack_send_interface
, oi
, 3,
768 &oi
->thread_send_lsack
);
772 /* LSA is a duplicate, and was treated as an implied acknowledgement.
773 No acknowledgement sent. */
774 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
775 && CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
778 "No acknowledgement (AllOther & Duplicate & ImpliedAck)");
782 /* LSA is a duplicate, and was not treated as an implied
784 Direct acknowledgement sent */
785 if (CHECK_FLAG(lsa
->flag
, OSPF6_LSA_DUPLICATE
)
786 && !CHECK_FLAG(lsa
->flag
, OSPF6_LSA_IMPLIEDACK
)) {
789 "Direct acknowledgement (AllOther & Duplicate)");
790 ospf6_lsdb_add(ospf6_lsa_copy(lsa
), from
->lsack_list
);
791 thread_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
792 &from
->thread_send_lsack
);
796 /* LSA's LS age is equal to Maxage, and there is no current instance
797 of the LSA in the link state database, and none of router's
798 neighbors are in states Exchange or Loading */
799 /* Direct acknowledgement sent, but this case is handled in
800 early of ospf6_receive_lsa () */
803 static void ospf6_acknowledge_lsa(struct ospf6_lsa
*lsa
, int ismore_recent
,
804 struct ospf6_neighbor
*from
)
806 struct ospf6_interface
*oi
;
808 assert(from
&& from
->ospf6_if
);
811 if (oi
->state
== OSPF6_INTERFACE_BDR
)
812 ospf6_acknowledge_lsa_bdrouter(lsa
, ismore_recent
, from
);
814 ospf6_acknowledge_lsa_allother(lsa
, ismore_recent
, from
);
817 /* RFC2328 section 13 (4):
818 if MaxAge LSA and if we have no instance, and no neighbor
819 is in states Exchange or Loading
820 returns 1 if match this case, else returns 0 */
821 static int ospf6_is_maxage_lsa_drop(struct ospf6_lsa
*lsa
,
822 struct ospf6_neighbor
*from
)
824 struct ospf6_neighbor
*on
;
825 struct ospf6_interface
*oi
;
826 struct ospf6_area
*oa
;
827 struct ospf6
*process
= NULL
;
828 struct listnode
*i
, *j
, *k
;
831 if (!OSPF6_LSA_IS_MAXAGE(lsa
))
834 if (ospf6_lsdb_lookup(lsa
->header
->type
, lsa
->header
->id
,
835 lsa
->header
->adv_router
, lsa
->lsdb
))
838 process
= from
->ospf6_if
->area
->ospf6
;
840 for (ALL_LIST_ELEMENTS_RO(process
->area_list
, i
, oa
))
841 for (ALL_LIST_ELEMENTS_RO(oa
->if_list
, j
, oi
))
842 for (ALL_LIST_ELEMENTS_RO(oi
->neighbor_list
, k
, on
))
843 if (on
->state
== OSPF6_NEIGHBOR_EXCHANGE
844 || on
->state
== OSPF6_NEIGHBOR_LOADING
)
852 /* RFC2328 section 13 The Flooding Procedure */
853 void ospf6_receive_lsa(struct ospf6_neighbor
*from
,
854 struct ospf6_lsa_header
*lsa_header
)
856 struct ospf6_lsa
*new = NULL
, *old
= NULL
, *rem
= NULL
;
859 unsigned int time_delta_ms
;
864 /* if we receive a LSA with invalid seqnum drop it */
865 if (ntohl(lsa_header
->seqnum
) - 1 == OSPF_MAX_SEQUENCE_NUMBER
) {
866 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa_header
->type
)) {
868 "received lsa [%s Id:%pI4 Adv:%pI4] with invalid seqnum 0x%x, ignore",
869 ospf6_lstype_name(lsa_header
->type
),
870 &lsa_header
->id
, &lsa_header
->adv_router
,
871 ntohl(lsa_header
->seqnum
));
876 /* make lsa structure for received lsa */
877 new = ospf6_lsa_create(lsa_header
);
879 if (IS_OSPF6_DEBUG_FLOODING
880 || IS_OSPF6_DEBUG_FLOOD_TYPE(new->header
->type
)) {
882 zlog_debug("LSA Receive from %s", from
->name
);
883 ospf6_lsa_header_print(new);
886 /* (1) LSA Checksum */
887 if (!ospf6_lsa_checksum_valid(new->header
)) {
889 zlog_debug("Wrong LSA Checksum, discard");
890 ospf6_lsa_delete(new);
894 /* (2) Examine the LSA's LS type.
895 RFC2470 3.5.1. Receiving Link State Update packets */
896 if (IS_AREA_STUB(from
->ospf6_if
->area
)
897 && OSPF6_LSA_SCOPE(new->header
->type
) == OSPF6_SCOPE_AS
) {
900 "AS-External-LSA (or AS-scope LSA) in stub area, discard");
901 ospf6_lsa_delete(new);
905 /* (3) LSA which have reserved scope is discarded
906 RFC2470 3.5.1. Receiving Link State Update packets */
907 /* Flooding scope check. LSAs with unknown scope are discarded here.
908 Set appropriate LSDB for the LSA */
909 switch (OSPF6_LSA_SCOPE(new->header
->type
)) {
910 case OSPF6_SCOPE_LINKLOCAL
:
911 new->lsdb
= from
->ospf6_if
->lsdb
;
913 case OSPF6_SCOPE_AREA
:
914 new->lsdb
= from
->ospf6_if
->area
->lsdb
;
917 new->lsdb
= from
->ospf6_if
->area
->ospf6
->lsdb
;
921 zlog_debug("LSA has reserved scope, discard");
922 ospf6_lsa_delete(new);
926 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
927 is in states Exchange or Loading */
928 if (ospf6_is_maxage_lsa_drop(new, from
)) {
932 "Drop MaxAge LSA with direct acknowledgement.");
934 /* a) Acknowledge back to neighbor (Direct acknowledgement,
936 ospf6_lsdb_add(ospf6_lsa_copy(new), from
->lsack_list
);
937 thread_add_event(master
, ospf6_lsack_send_neighbor
, from
, 0,
938 &from
->thread_send_lsack
);
941 ospf6_lsa_delete(new);
946 /* lookup the same database copy in lsdb */
947 old
= ospf6_lsdb_lookup(new->header
->type
, new->header
->id
,
948 new->header
->adv_router
, new->lsdb
);
950 ismore_recent
= ospf6_lsa_compare(new, old
);
951 if (ntohl(new->header
->seqnum
) == ntohl(old
->header
->seqnum
)) {
953 zlog_debug("Received is duplicated LSA");
954 SET_FLAG(new->flag
, OSPF6_LSA_DUPLICATE
);
958 /* if no database copy or received is more recent */
959 if (old
== NULL
|| ismore_recent
< 0) {
960 /* in case we have no database copy */
963 /* (a) MinLSArrival check */
965 struct timeval now
, res
;
967 timersub(&now
, &old
->installed
, &res
);
969 (res
.tv_sec
* 1000) + (int)(res
.tv_usec
/ 1000);
971 < from
->ospf6_if
->area
->ospf6
->lsa_minarrival
) {
974 "LSA can't be updated within MinLSArrival, %dms < %dms, discard",
976 from
->ospf6_if
->area
->ospf6
978 ospf6_lsa_delete(new);
979 return; /* examin next lsa */
983 monotime(&new->received
);
987 "Install, Flood, Possibly acknowledge the received LSA");
989 /* Remove older copies of this LSA from retx lists */
991 ospf6_flood_clear(old
);
993 /* (b) immediately flood and (c) remove from all retrans-list */
994 /* Prevent self-originated LSA to be flooded. this is to make
995 reoriginated instance of the LSA not to be rejected by other
997 due to MinLSArrival. */
998 if (new->header
->adv_router
999 != from
->ospf6_if
->area
->ospf6
->router_id
)
1000 ospf6_flood(from
, new);
1002 /* (d), installing lsdb, which may cause routing
1003 table calculation (replacing database copy) */
1004 ospf6_install_lsa(new);
1006 if (OSPF6_LSA_IS_MAXAGE(new))
1007 ospf6_maxage_remove(from
->ospf6_if
->area
->ospf6
);
1009 /* (e) possibly acknowledge */
1010 ospf6_acknowledge_lsa(new, ismore_recent
, from
);
1012 /* (f) Self Originated LSA, section 13.4 */
1013 if (new->header
->adv_router
1014 == from
->ospf6_if
->area
->ospf6
->router_id
) {
1015 /* Self-originated LSA (newer than ours) is received
1017 another router. We have to make a new instance of the
1019 or have to flush this LSA. */
1022 "Newer instance of the self-originated LSA");
1023 zlog_debug("Schedule reorigination");
1025 new->refresh
= NULL
;
1026 thread_add_event(master
, ospf6_lsa_refresh
, new, 0,
1033 /* (6) if there is instance on sending neighbor's request list */
1034 if (ospf6_lsdb_lookup(new->header
->type
, new->header
->id
,
1035 new->header
->adv_router
, from
->request_list
)) {
1036 /* if no database copy, should go above state (5) */
1040 "Received is not newer, on the neighbor %s request-list",
1043 "BadLSReq, discard the received LSA lsa %s send badLSReq",
1047 thread_add_event(master
, bad_lsreq
, from
, 0, NULL
);
1049 ospf6_lsa_delete(new);
1053 /* (7) if neither one is more recent */
1054 if (ismore_recent
== 0) {
1057 "The same instance as database copy (neither recent)");
1059 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack
1061 rem
= ospf6_lsdb_lookup(new->header
->type
, new->header
->id
,
1062 new->header
->adv_router
,
1063 from
->retrans_list
);
1067 "It is on the neighbor's retrans-list.");
1069 "Treat as an Implied acknowledgement");
1071 SET_FLAG(new->flag
, OSPF6_LSA_IMPLIEDACK
);
1072 ospf6_decrement_retrans_count(rem
);
1073 ospf6_lsdb_remove(rem
, from
->retrans_list
);
1077 zlog_debug("Possibly acknowledge and then discard");
1079 /* (b) possibly acknowledge */
1080 ospf6_acknowledge_lsa(new, ismore_recent
, from
);
1082 ospf6_lsa_delete(new);
1086 /* (8) previous database copy is more recent */
1090 /* If database copy is in 'Seqnumber Wrapping',
1091 simply discard the received LSA */
1092 if (OSPF6_LSA_IS_MAXAGE(old
)
1093 && old
->header
->seqnum
== htonl(OSPF_MAX_SEQUENCE_NUMBER
)) {
1095 zlog_debug("The LSA is in Seqnumber Wrapping");
1096 zlog_debug("MaxAge & MaxSeqNum, discard");
1098 ospf6_lsa_delete(new);
1102 /* Otherwise, Send database copy of this LSA to this neighbor */
1105 zlog_debug("Database copy is more recent.");
1107 "Send back directly and then discard");
1110 /* Neighbor router sent recent age for LSA,
1111 * Router could be restarted while current copy is
1112 * MAXAGEd and not removed.*/
1113 if (OSPF6_LSA_IS_MAXAGE(old
)
1114 && !OSPF6_LSA_IS_MAXAGE(new)) {
1115 if (new->header
->adv_router
1116 != from
->ospf6_if
->area
->ospf6
->router_id
) {
1119 "%s: Current copy of LSA %s is MAXAGE, but new has recent age, flooding/installing.",
1120 __PRETTY_FUNCTION__
, old
->name
);
1121 ospf6_lsa_purge(old
);
1122 ospf6_flood(from
, new);
1123 ospf6_install_lsa(new);
1126 /* For self-originated LSA, only trust
1127 * ourselves. Fall through and send
1128 * LS Update with our current copy.
1132 "%s: Current copy of self-originated LSA %s is MAXAGE, but new has recent age, re-sending current one.",
1133 __PRETTY_FUNCTION__
, old
->name
);
1136 /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
1138 ospf6_lsdb_add(ospf6_lsa_copy(old
),
1139 from
->lsupdate_list
);
1140 thread_add_event(master
, ospf6_lsupdate_send_neighbor
,
1141 from
, 0, &from
->thread_send_lsupdate
);
1143 ospf6_lsa_delete(new);
1150 DEFUN (debug_ospf6_flooding
,
1151 debug_ospf6_flooding_cmd
,
1152 "debug ospf6 flooding",
1155 "Debug OSPFv3 flooding function\n"
1158 OSPF6_DEBUG_FLOODING_ON();
1162 DEFUN (no_debug_ospf6_flooding
,
1163 no_debug_ospf6_flooding_cmd
,
1164 "no debug ospf6 flooding",
1168 "Debug OSPFv3 flooding function\n"
1171 OSPF6_DEBUG_FLOODING_OFF();
1175 int config_write_ospf6_debug_flood(struct vty
*vty
)
1177 if (IS_OSPF6_DEBUG_FLOODING
)
1178 vty_out(vty
, "debug ospf6 flooding\n");
1182 void install_element_ospf6_debug_flood(void)
1184 install_element(ENABLE_NODE
, &debug_ospf6_flooding_cmd
);
1185 install_element(ENABLE_NODE
, &no_debug_ospf6_flooding_cmd
);
1186 install_element(CONFIG_NODE
, &debug_ospf6_flooding_cmd
);
1187 install_element(CONFIG_NODE
, &no_debug_ospf6_flooding_cmd
);