]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_flood.c
Merge pull request #13649 from donaldsharp/unlock_the_node_or_else
[mirror_frr.git] / ospf6d / ospf6_flood.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
48454375 2/*
3 * Copyright (C) 2003 Yasuhiro Ohara
48454375 4 */
5
6#include <zebra.h>
7
8#include "log.h"
24a58196 9#include "frrevent.h"
48454375 10#include "linklist.h"
11#include "vty.h"
1e05838a 12#include "command.h"
48454375 13
14#include "ospf6d.h"
15#include "ospf6_proto.h"
16#include "ospf6_lsa.h"
17#include "ospf6_lsdb.h"
18#include "ospf6_message.h"
19#include "ospf6_route.h"
20#include "ospf6_spf.h"
21
22#include "ospf6_top.h"
23#include "ospf6_area.h"
24#include "ospf6_interface.h"
25#include "ospf6_neighbor.h"
26
6452df09 27#include "ospf6_flood.h"
ad500b22 28#include "ospf6_nssa.h"
0d1753a7 29#include "ospf6_gr.h"
48454375 30
1e05838a 31unsigned char conf_debug_ospf6_flooding;
32
d62a17ae 33struct ospf6_lsdb *ospf6_get_scoped_lsdb(struct ospf6_lsa *lsa)
48454375 34{
d62a17ae 35 struct ospf6_lsdb *lsdb = NULL;
36 switch (OSPF6_LSA_SCOPE(lsa->header->type)) {
37 case OSPF6_SCOPE_LINKLOCAL:
38 lsdb = OSPF6_INTERFACE(lsa->lsdb->data)->lsdb;
39 break;
40 case OSPF6_SCOPE_AREA:
41 lsdb = OSPF6_AREA(lsa->lsdb->data)->lsdb;
42 break;
43 case OSPF6_SCOPE_AS:
44 lsdb = OSPF6_PROCESS(lsa->lsdb->data)->lsdb;
45 break;
46 default:
47 assert(0);
48 break;
49 }
50 return lsdb;
48454375 51}
52
d62a17ae 53struct ospf6_lsdb *ospf6_get_scoped_lsdb_self(struct ospf6_lsa *lsa)
48454375 54{
d62a17ae 55 struct ospf6_lsdb *lsdb_self = NULL;
56 switch (OSPF6_LSA_SCOPE(lsa->header->type)) {
57 case OSPF6_SCOPE_LINKLOCAL:
58 lsdb_self = OSPF6_INTERFACE(lsa->lsdb->data)->lsdb_self;
59 break;
60 case OSPF6_SCOPE_AREA:
61 lsdb_self = OSPF6_AREA(lsa->lsdb->data)->lsdb_self;
62 break;
63 case OSPF6_SCOPE_AS:
64 lsdb_self = OSPF6_PROCESS(lsa->lsdb->data)->lsdb_self;
65 break;
66 default:
67 assert(0);
68 break;
69 }
70 return lsdb_self;
6452df09 71}
72
71165098 73void ospf6_lsa_originate(struct ospf6 *ospf6, struct ospf6_lsa *lsa)
6452df09 74{
d62a17ae 75 struct ospf6_lsa *old;
76 struct ospf6_lsdb *lsdb_self;
77
2e9db233
DL
78 if (lsa->header->adv_router == INADDR_ANY) {
79 if (IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa->header->type))
80 zlog_debug(
81 "Refusing to originate LSA (zero router ID): %s",
82 lsa->name);
83
84 ospf6_lsa_delete(lsa);
85 return;
86 }
87
d62a17ae 88 /* find previous LSA */
89 old = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
90 lsa->header->adv_router, lsa->lsdb);
91
92 /* if the new LSA does not differ from previous,
93 suppress this update of the LSA */
71165098
RW
94 if (old && !OSPF6_LSA_IS_DIFFER(lsa, old)
95 && !ospf6->gr_info.finishing_restart) {
d62a17ae 96 if (IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa->header->type))
97 zlog_debug("Suppress updating LSA: %s", lsa->name);
98 ospf6_lsa_delete(lsa);
99 return;
100 }
101
102 /* store it in the LSDB for self-originated LSAs */
103 lsdb_self = ospf6_get_scoped_lsdb_self(lsa);
104 ospf6_lsdb_add(ospf6_lsa_copy(lsa), lsdb_self);
105
e16d030c 106 EVENT_OFF(lsa->refresh);
907a2395
DS
107 event_add_timer(master, ospf6_lsa_refresh, lsa, OSPF_LS_REFRESH_TIME,
108 &lsa->refresh);
d62a17ae 109
110 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)
111 || IS_OSPF6_DEBUG_ORIGINATE_TYPE(lsa->header->type)) {
112 zlog_debug("LSA Originate:");
113 ospf6_lsa_header_print(lsa);
114 }
115
116 ospf6_install_lsa(lsa);
117 ospf6_flood(NULL, lsa);
6452df09 118}
3b4cd3a9 119
d62a17ae 120void ospf6_lsa_originate_process(struct ospf6_lsa *lsa, struct ospf6 *process)
6452df09 121{
d62a17ae 122 lsa->lsdb = process->lsdb;
71165098 123 ospf6_lsa_originate(process, lsa);
3b4cd3a9 124}
125
d62a17ae 126void ospf6_lsa_originate_area(struct ospf6_lsa *lsa, struct ospf6_area *oa)
48454375 127{
d62a17ae 128 lsa->lsdb = oa->lsdb;
71165098 129 ospf6_lsa_originate(oa->ospf6, lsa);
6452df09 130}
131
d62a17ae 132void ospf6_lsa_originate_interface(struct ospf6_lsa *lsa,
133 struct ospf6_interface *oi)
6452df09 134{
d62a17ae 135 lsa->lsdb = oi->lsdb;
71165098 136 ospf6_lsa_originate(oi->area->ospf6, lsa);
6452df09 137}
48454375 138
4dc43886
MR
139void ospf6_external_lsa_purge(struct ospf6 *ospf6, struct ospf6_lsa *lsa)
140{
523232c5
MR
141 uint32_t id = lsa->header->id;
142 struct ospf6_area *oa;
143 struct listnode *lnode;
144
4dc43886
MR
145 ospf6_lsa_purge(lsa);
146
523232c5
MR
147 /* Delete the corresponding NSSA LSA */
148 for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, lnode, oa)) {
149 lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_TYPE_7), id,
150 ospf6->router_id, oa->lsdb);
151 if (lsa) {
152 if (IS_OSPF6_DEBUG_NSSA)
153 zlog_debug("withdraw type 7 lsa, LS ID: %u",
154 htonl(id));
155
156 ospf6_lsa_purge(lsa);
157 }
158 }
4dc43886
MR
159}
160
d62a17ae 161void ospf6_lsa_purge(struct ospf6_lsa *lsa)
6452df09 162{
d62a17ae 163 struct ospf6_lsa *self;
164 struct ospf6_lsdb *lsdb_self;
165
166 /* remove it from the LSDB for self-originated LSAs */
167 lsdb_self = ospf6_get_scoped_lsdb_self(lsa);
168 self = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
169 lsa->header->adv_router, lsdb_self);
170 if (self) {
e16d030c
DS
171 EVENT_OFF(self->expire);
172 EVENT_OFF(self->refresh);
d62a17ae 173 ospf6_lsdb_remove(self, lsdb_self);
174 }
175
176 ospf6_lsa_premature_aging(lsa);
6452df09 177}
48454375 178
690df177
CS
179/* Puring Multi Link-State IDs LSAs:
180 * Same Advertising Router with Multiple Link-State IDs
181 * LSAs, purging require to traverse all Link-State IDs
182 */
183void ospf6_lsa_purge_multi_ls_id(struct ospf6_area *oa, struct ospf6_lsa *lsa)
184{
185 int ls_id = 0;
186 struct ospf6_lsa *lsa_next;
187 uint16_t type;
188
189 type = lsa->header->type;
190
191 ospf6_lsa_purge(lsa);
192
193 lsa_next = ospf6_lsdb_lookup(type, htonl(++ls_id),
194 oa->ospf6->router_id, oa->lsdb);
195 while (lsa_next) {
196 ospf6_lsa_purge(lsa_next);
197 lsa_next = ospf6_lsdb_lookup(type, htonl(++ls_id),
198 oa->ospf6->router_id, oa->lsdb);
199 }
200}
48454375 201
d62a17ae 202void ospf6_increment_retrans_count(struct ospf6_lsa *lsa)
6452df09 203{
d62a17ae 204 /* The LSA must be the original one (see the description
205 in ospf6_decrement_retrans_count () below) */
206 lsa->retrans_count++;
6452df09 207}
48454375 208
d62a17ae 209void ospf6_decrement_retrans_count(struct ospf6_lsa *lsa)
6452df09 210{
d62a17ae 211 struct ospf6_lsdb *lsdb;
212 struct ospf6_lsa *orig;
213
214 /* The LSA must be on the retrans-list of a neighbor. It means
215 the "lsa" is a copied one, and we have to decrement the
216 retransmission count of the original one (instead of this "lsa"'s).
217 In order to find the original LSA, first we have to find
218 appropriate LSDB that have the original LSA. */
219 lsdb = ospf6_get_scoped_lsdb(lsa);
220
221 /* Find the original LSA of which the retrans_count should be
222 * decremented */
223 orig = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
224 lsa->header->adv_router, lsdb);
225 if (orig) {
226 orig->retrans_count--;
227 assert(orig->retrans_count >= 0);
228 }
48454375 229}
230
231/* RFC2328 section 13.2 Installing LSAs in the database */
d62a17ae 232void ospf6_install_lsa(struct ospf6_lsa *lsa)
48454375 233{
9e49d1ac 234 struct ospf6 *ospf6;
d62a17ae 235 struct timeval now;
236 struct ospf6_lsa *old;
ad500b22 237 struct ospf6_area *area = NULL;
d62a17ae 238
9e49d1ac
RW
239 ospf6 = ospf6_get_by_lsdb(lsa);
240 assert(ospf6);
241
d62a17ae 242 /* Remove the old instance from all neighbors' Link state
243 retransmission list (RFC2328 13.2 last paragraph) */
244 old = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
245 lsa->header->adv_router, lsa->lsdb);
246 if (old) {
ad500b22
K
247 if (ntohs(lsa->header->type) == OSPF6_LSTYPE_TYPE_7) {
248 if (IS_OSPF6_DEBUG_NSSA)
249 zlog_debug("%s : old LSA %s", __func__,
250 lsa->name);
251 lsa->external_lsa_id = old->external_lsa_id;
252 }
e16d030c
DS
253 EVENT_OFF(old->expire);
254 EVENT_OFF(old->refresh);
d62a17ae 255 ospf6_flood_clear(old);
256 }
257
258 monotime(&now);
259 if (!OSPF6_LSA_IS_MAXAGE(lsa)) {
907a2395
DS
260 event_add_timer(master, ospf6_lsa_expire, lsa,
261 OSPF_LSA_MAXAGE + lsa->birth.tv_sec -
262 now.tv_sec,
263 &lsa->expire);
d62a17ae 264 } else
265 lsa->expire = NULL;
266
267 if (OSPF6_LSA_IS_SEQWRAP(lsa)
268 && !(CHECK_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED)
269 && lsa->header->seqnum == htonl(OSPF_MAX_SEQUENCE_NUMBER))) {
270 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa->header->type))
271 zlog_debug("lsa install wrapping: sequence 0x%x",
272 ntohl(lsa->header->seqnum));
273 SET_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED);
274 /* in lieu of premature_aging, since we do not want to recreate
275 * this lsa
276 * and/or mess with timers etc, we just want to wrap the
277 * sequence number
278 * and reflood the lsa before continuing.
279 * NOTE: Flood needs to be called right after this function
280 * call, by the
281 * caller
282 */
283 lsa->header->seqnum = htonl(OSPF_MAX_SEQUENCE_NUMBER);
284 lsa->header->age = htons(OSPF_LSA_MAXAGE);
285 ospf6_lsa_checksum(lsa->header);
286 }
287
76249532
CS
288 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)
289 || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa->header->type))
290 zlog_debug("%s Install LSA: %s age %d seqnum %x in LSDB.",
15569c58
DA
291 __func__, lsa->name, ntohs(lsa->header->age),
292 ntohl(lsa->header->seqnum));
76249532 293
d62a17ae 294 /* actually install */
295 lsa->installed = now;
9a06f23d 296
297 /* Topo change handling */
71165098
RW
298 if (CHECK_LSA_TOPO_CHG_ELIGIBLE(ntohs(lsa->header->type))
299 && !CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)) {
9a06f23d 300
301 /* check if it is new lsa ? or existing lsa got modified ?*/
9e49d1ac 302 if (!old || OSPF6_LSA_IS_CHANGED(old, lsa))
9a06f23d 303 ospf6_helper_handle_topo_chg(ospf6, lsa);
9a06f23d 304 }
305
d62a17ae 306 ospf6_lsdb_add(lsa, lsa->lsdb);
307
9e49d1ac
RW
308 if (ntohs(lsa->header->type) == OSPF6_LSTYPE_TYPE_7
309 && lsa->header->adv_router != ospf6->router_id) {
ad500b22
K
310 area = OSPF6_AREA(lsa->lsdb->data);
311 ospf6_translated_nssa_refresh(area, lsa, NULL);
312 ospf6_schedule_abr_task(area->ospf6);
313 }
314
315 if (ntohs(lsa->header->type) == OSPF6_LSTYPE_ROUTER) {
316 area = OSPF6_AREA(lsa->lsdb->data);
317 if (old == NULL) {
318 if (IS_OSPF6_DEBUG_LSA_TYPE(lsa->header->type)
319 || IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa->header->type))
320 zlog_debug("%s: New router LSA %s", __func__,
321 lsa->name);
322 ospf6_abr_nssa_check_status(area->ospf6);
323 }
324 }
d62a17ae 325 return;
48454375 326}
327
6452df09 328/* RFC2740 section 3.5.2. Sending Link State Update packets */
48454375 329/* RFC2328 section 13.3 Next step in the flooding procedure */
996c9314
LB
330void ospf6_flood_interface(struct ospf6_neighbor *from, struct ospf6_lsa *lsa,
331 struct ospf6_interface *oi)
48454375 332{
d62a17ae 333 struct listnode *node, *nnode;
334 struct ospf6_neighbor *on;
c1e4c0dc 335 struct ospf6_lsa *req, *old;
d62a17ae 336 int retrans_added = 0;
337 int is_debug = 0;
338
339 if (IS_OSPF6_DEBUG_FLOODING
340 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type)) {
341 is_debug++;
342 zlog_debug("Flooding on %s: %s", oi->interface->name,
343 lsa->name);
344 }
345
346 /* (1) For each neighbor */
347 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
348 if (is_debug)
349 zlog_debug("To neighbor %s", on->name);
350
351 /* (a) if neighbor state < Exchange, examin next */
352 if (on->state < OSPF6_NEIGHBOR_EXCHANGE) {
353 if (is_debug)
354 zlog_debug(
355 "Neighbor state less than ExChange, next neighbor");
356 continue;
357 }
358
359 /* (b) if neighbor not yet Full, check request-list */
360 if (on->state != OSPF6_NEIGHBOR_FULL) {
361 if (is_debug)
362 zlog_debug("Neighbor not yet Full");
363
364 req = ospf6_lsdb_lookup(
365 lsa->header->type, lsa->header->id,
366 lsa->header->adv_router, on->request_list);
367 if (req == NULL) {
368 if (is_debug)
369 zlog_debug(
370 "Not on request-list for this neighbor");
371 /* fall through */
372 } else {
373 /* If new LSA less recent, examin next neighbor
374 */
375 if (ospf6_lsa_compare(lsa, req) > 0) {
376 if (is_debug)
377 zlog_debug(
378 "Requesting is older, next neighbor");
379 continue;
380 }
381
382 /* If the same instance, delete from
383 request-list and
384 examin next neighbor */
385 if (ospf6_lsa_compare(lsa, req) == 0) {
386 if (is_debug)
387 zlog_debug(
388 "Requesting the same, remove it, next neighbor");
389 if (req == on->last_ls_req) {
c957f7d9
QY
390 /* sanity check refcount */
391 assert(req->lock >= 2);
744ba569 392 req = ospf6_lsa_unlock(req);
d62a17ae 393 on->last_ls_req = NULL;
394 }
744ba569
DS
395 if (req)
396 ospf6_lsdb_remove(
397 req, on->request_list);
d62a17ae 398 ospf6_check_nbr_loading(on);
399 continue;
400 }
401
402 /* If the new LSA is more recent, delete from
403 * request-list */
404 if (ospf6_lsa_compare(lsa, req) < 0) {
405 if (is_debug)
406 zlog_debug(
407 "Received is newer, remove requesting");
408 if (req == on->last_ls_req) {
744ba569 409 req = ospf6_lsa_unlock(req);
d62a17ae 410 on->last_ls_req = NULL;
411 }
ce872c6a 412 if (req)
413 ospf6_lsdb_remove(req,
414 on->request_list);
d62a17ae 415 ospf6_check_nbr_loading(on);
416 /* fall through */
417 }
418 }
419 }
420
421 /* (c) If the new LSA was received from this neighbor,
422 examin next neighbor */
423 if (from == on) {
424 if (is_debug)
425 zlog_debug(
426 "Received is from the neighbor, next neighbor");
427 continue;
428 }
429
ad500b22
K
430 if ((oi->area->ospf6->inst_shutdown)
431 || CHECK_FLAG(lsa->flag, OSPF6_LSA_FLUSH)) {
76249532 432 if (is_debug)
996c9314
LB
433 zlog_debug(
434 "%s: Send LSA %s (age %d) update now",
5e81f5dd 435 __func__, lsa->name,
996c9314 436 ntohs(lsa->header->age));
76249532
CS
437 ospf6_lsupdate_send_neighbor_now(on, lsa);
438 continue;
439 } else {
440 /* (d) add retrans-list, schedule retransmission */
441 if (is_debug)
f6c5f2e0 442 zlog_debug("Add retrans-list of neighbor %s ",
443 on->name);
c1e4c0dc
MR
444
445 /* Do not increment the retrans count if the lsa is
446 * already present in the retrans list.
447 */
448 old = ospf6_lsdb_lookup(
449 lsa->header->type, lsa->header->id,
450 lsa->header->adv_router, on->retrans_list);
451 if (!old) {
7c20ee06
MN
452 struct ospf6_lsa *orig;
453 struct ospf6_lsdb *lsdb;
454
c1e4c0dc
MR
455 if (is_debug)
456 zlog_debug(
457 "Increment %s from retrans_list of %s",
458 lsa->name, on->name);
7c20ee06
MN
459
460 /* Increment the retrans count on the original
461 * copy of LSA if present, to maintain the
462 * counter consistency.
463 */
464
465 lsdb = ospf6_get_scoped_lsdb(lsa);
466 orig = ospf6_lsdb_lookup(
467 lsa->header->type, lsa->header->id,
468 lsa->header->adv_router, lsdb);
469 if (orig)
470 ospf6_increment_retrans_count(orig);
471 else
472 ospf6_increment_retrans_count(lsa);
473
c1e4c0dc
MR
474 ospf6_lsdb_add(ospf6_lsa_copy(lsa),
475 on->retrans_list);
907a2395
DS
476 event_add_timer(master,
477 ospf6_lsupdate_send_neighbor,
478 on, on->ospf6_if->rxmt_interval,
479 &on->thread_send_lsupdate);
c1e4c0dc
MR
480 retrans_added++;
481 }
76249532 482 }
d62a17ae 483 }
484
485 /* (2) examin next interface if not added to retrans-list */
486 if (retrans_added == 0) {
487 if (is_debug)
488 zlog_debug(
f6c5f2e0 489 "No retransmission scheduled, next interface %s",
490 oi->interface->name);
d62a17ae 491 return;
492 }
493
494 /* (3) If the new LSA was received on this interface,
495 and it was from DR or BDR, examin next interface */
496 if (from && from->ospf6_if == oi
497 && (from->router_id == oi->drouter
498 || from->router_id == oi->bdrouter)) {
499 if (is_debug)
500 zlog_debug(
501 "Received is from the I/F's DR or BDR, next interface");
502 return;
503 }
504
505 /* (4) If the new LSA was received on this interface,
506 and the interface state is BDR, examin next interface */
507 if (from && from->ospf6_if == oi) {
508 if (oi->state == OSPF6_INTERFACE_BDR) {
509 if (is_debug)
510 zlog_debug(
511 "Received is from the I/F, itself BDR, next interface");
512 return;
513 }
514 SET_FLAG(lsa->flag, OSPF6_LSA_FLOODBACK);
515 }
516
517 /* (5) flood the LSA out the interface. */
518 if (is_debug)
519 zlog_debug("Schedule flooding for the interface");
520 if ((oi->type == OSPF_IFTYPE_BROADCAST)
521 || (oi->type == OSPF_IFTYPE_POINTOPOINT)) {
522 ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsupdate_list);
907a2395
DS
523 event_add_event(master, ospf6_lsupdate_send_interface, oi, 0,
524 &oi->thread_send_lsupdate);
d62a17ae 525 } else {
526 /* reschedule retransmissions to all neighbors */
527 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
e16d030c 528 EVENT_OFF(on->thread_send_lsupdate);
907a2395
DS
529 event_add_event(master, ospf6_lsupdate_send_neighbor,
530 on, 0, &on->thread_send_lsupdate);
d62a17ae 531 }
7cf99722 532 }
6452df09 533}
534
d62a17ae 535void ospf6_flood_area(struct ospf6_neighbor *from, struct ospf6_lsa *lsa,
536 struct ospf6_area *oa)
6452df09 537{
d62a17ae 538 struct listnode *node, *nnode;
539 struct ospf6_interface *oi;
6452df09 540
d62a17ae 541 for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) {
542 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL
543 && oi != OSPF6_INTERFACE(lsa->lsdb->data))
544 continue;
48454375 545
d62a17ae 546 ospf6_flood_interface(from, lsa, oi);
547 }
6452df09 548}
549
d62a17ae 550static void ospf6_flood_process(struct ospf6_neighbor *from,
551 struct ospf6_lsa *lsa, struct ospf6 *process)
6452df09 552{
d62a17ae 553 struct listnode *node, *nnode;
554 struct ospf6_area *oa;
555
556 for (ALL_LIST_ELEMENTS(process->area_list, node, nnode, oa)) {
0889da24
KS
557
558 /* If unknown LSA and U-bit clear, treat as link local
559 * flooding scope
560 */
561 if (!OSPF6_LSA_IS_KNOWN(lsa->header->type)
562 && !(ntohs(lsa->header->type) & OSPF6_LSTYPE_UBIT_MASK)
563 && (oa != OSPF6_INTERFACE(lsa->lsdb->data)->area)) {
564
565 if (IS_OSPF6_DEBUG_FLOODING)
566 zlog_debug("Unknown LSA, do not flood");
567 continue;
568 }
569
d62a17ae 570 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_AREA
571 && oa != OSPF6_AREA(lsa->lsdb->data))
572 continue;
573 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL
574 && oa != OSPF6_INTERFACE(lsa->lsdb->data)->area)
575 continue;
576
577 if (ntohs(lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL
ad500b22
K
578 && (IS_AREA_STUB(oa) || IS_AREA_NSSA(oa)))
579 continue;
580
581 /* Check for NSSA LSA */
582 if (ntohs(lsa->header->type) == OSPF6_LSTYPE_TYPE_7
583 && !IS_AREA_NSSA(oa) && !OSPF6_LSA_IS_MAXAGE(lsa))
d62a17ae 584 continue;
585
586 ospf6_flood_area(from, lsa, oa);
587 }
6452df09 588}
589
d62a17ae 590void ospf6_flood(struct ospf6_neighbor *from, struct ospf6_lsa *lsa)
6452df09 591{
beadc736 592 struct ospf6 *ospf6;
593
594 ospf6 = ospf6_get_by_lsdb(lsa);
595 if (ospf6 == NULL)
596 return;
597
d62a17ae 598 ospf6_flood_process(from, lsa, ospf6);
6452df09 599}
600
d62a17ae 601static void ospf6_flood_clear_interface(struct ospf6_lsa *lsa,
602 struct ospf6_interface *oi)
6452df09 603{
d62a17ae 604 struct listnode *node, *nnode;
605 struct ospf6_neighbor *on;
606 struct ospf6_lsa *rem;
607
608 for (ALL_LIST_ELEMENTS(oi->neighbor_list, node, nnode, on)) {
609 rem = ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
610 lsa->header->adv_router,
611 on->retrans_list);
612 if (rem && !ospf6_lsa_compare(rem, lsa)) {
613 if (IS_OSPF6_DEBUG_FLOODING
614 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type))
615 zlog_debug("Remove %s from retrans_list of %s",
616 rem->name, on->name);
617 ospf6_decrement_retrans_count(rem);
618 ospf6_lsdb_remove(rem, on->retrans_list);
619 }
620 }
6452df09 621}
622
ad500b22 623void ospf6_flood_clear_area(struct ospf6_lsa *lsa, struct ospf6_area *oa)
6452df09 624{
d62a17ae 625 struct listnode *node, *nnode;
626 struct ospf6_interface *oi;
6452df09 627
d62a17ae 628 for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi)) {
629 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL
630 && oi != OSPF6_INTERFACE(lsa->lsdb->data))
631 continue;
6452df09 632
d62a17ae 633 ospf6_flood_clear_interface(lsa, oi);
634 }
6452df09 635}
636
d62a17ae 637static void ospf6_flood_clear_process(struct ospf6_lsa *lsa,
638 struct ospf6 *process)
6452df09 639{
d62a17ae 640 struct listnode *node, *nnode;
641 struct ospf6_area *oa;
642
643 for (ALL_LIST_ELEMENTS(process->area_list, node, nnode, oa)) {
644 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_AREA
645 && oa != OSPF6_AREA(lsa->lsdb->data))
646 continue;
647 if (OSPF6_LSA_SCOPE(lsa->header->type) == OSPF6_SCOPE_LINKLOCAL
648 && oa != OSPF6_INTERFACE(lsa->lsdb->data)->area)
649 continue;
650
651 if (ntohs(lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL
ad500b22
K
652 && (IS_AREA_STUB(oa) || (IS_AREA_NSSA(oa))))
653 continue;
654 /* Check for NSSA LSA */
655 if (ntohs(lsa->header->type) == OSPF6_LSTYPE_TYPE_7
656 && !IS_AREA_NSSA(oa))
d62a17ae 657 continue;
658
659 ospf6_flood_clear_area(lsa, oa);
660 }
6452df09 661}
662
d62a17ae 663void ospf6_flood_clear(struct ospf6_lsa *lsa)
6452df09 664{
beadc736 665 struct ospf6 *ospf6;
666
667 ospf6 = ospf6_get_by_lsdb(lsa);
ad500b22
K
668 if (ospf6 == NULL)
669 return;
d62a17ae 670 ospf6_flood_clear_process(lsa, ospf6);
48454375 671}
672
6452df09 673
48454375 674/* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
d62a17ae 675static void ospf6_acknowledge_lsa_bdrouter(struct ospf6_lsa *lsa,
676 int ismore_recent,
677 struct ospf6_neighbor *from)
48454375 678{
d62a17ae 679 struct ospf6_interface *oi;
680 int is_debug = 0;
681
682 if (IS_OSPF6_DEBUG_FLOODING
683 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type))
684 is_debug++;
685
686 assert(from && from->ospf6_if);
687 oi = from->ospf6_if;
688
689 /* LSA is more recent than database copy, but was not flooded
690 back out receiving interface. Delayed acknowledgement sent
691 if advertisement received from Designated Router,
692 otherwide do nothing. */
693 if (ismore_recent < 0) {
694 if (oi->drouter == from->router_id) {
695 if (is_debug)
696 zlog_debug(
697 "Delayed acknowledgement (BDR & MoreRecent & from DR)");
698 /* Delayed acknowledgement */
699 ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list);
907a2395
DS
700 event_add_timer(master, ospf6_lsack_send_interface, oi,
701 3, &oi->thread_send_lsack);
d62a17ae 702 } else {
703 if (is_debug)
704 zlog_debug(
705 "No acknowledgement (BDR & MoreRecent & ! from DR)");
706 }
707 return;
708 }
709
710 /* LSA is a duplicate, and was treated as an implied acknowledgement.
711 Delayed acknowledgement sent if advertisement received from
712 Designated Router, otherwise do nothing */
713 if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)
714 && CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) {
715 if (oi->drouter == from->router_id) {
716 if (is_debug)
717 zlog_debug(
718 "Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
719 /* Delayed acknowledgement */
720 ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list);
907a2395
DS
721 event_add_timer(master, ospf6_lsack_send_interface, oi,
722 3, &oi->thread_send_lsack);
d62a17ae 723 } else {
724 if (is_debug)
725 zlog_debug(
726 "No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
727 }
728 return;
729 }
730
731 /* LSA is a duplicate, and was not treated as an implied
732 acknowledgement.
733 Direct acknowledgement sent */
734 if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)
735 && !CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) {
736 if (is_debug)
737 zlog_debug("Direct acknowledgement (BDR & Duplicate)");
738 ospf6_lsdb_add(ospf6_lsa_copy(lsa), from->lsack_list);
907a2395
DS
739 event_add_event(master, ospf6_lsack_send_neighbor, from, 0,
740 &from->thread_send_lsack);
d62a17ae 741 return;
742 }
743
744 /* LSA's LS age is equal to Maxage, and there is no current instance
745 of the LSA in the link state database, and none of router's
746 neighbors are in states Exchange or Loading */
747 /* Direct acknowledgement sent, but this case is handled in
748 early of ospf6_receive_lsa () */
48454375 749}
750
d62a17ae 751static void ospf6_acknowledge_lsa_allother(struct ospf6_lsa *lsa,
752 int ismore_recent,
753 struct ospf6_neighbor *from)
48454375 754{
d62a17ae 755 struct ospf6_interface *oi;
756 int is_debug = 0;
757
758 if (IS_OSPF6_DEBUG_FLOODING
759 || IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type))
760 is_debug++;
761
762 assert(from && from->ospf6_if);
763 oi = from->ospf6_if;
764
765 /* LSA has been flood back out receiving interface.
766 No acknowledgement sent. */
767 if (CHECK_FLAG(lsa->flag, OSPF6_LSA_FLOODBACK)) {
768 if (is_debug)
769 zlog_debug("No acknowledgement (AllOther & FloodBack)");
770 return;
771 }
772
773 /* LSA is more recent than database copy, but was not flooded
774 back out receiving interface. Delayed acknowledgement sent. */
775 if (ismore_recent < 0) {
776 if (is_debug)
777 zlog_debug(
778 "Delayed acknowledgement (AllOther & MoreRecent)");
779 /* Delayed acknowledgement */
780 ospf6_lsdb_add(ospf6_lsa_copy(lsa), oi->lsack_list);
907a2395
DS
781 event_add_timer(master, ospf6_lsack_send_interface, oi, 3,
782 &oi->thread_send_lsack);
d62a17ae 783 return;
784 }
785
786 /* LSA is a duplicate, and was treated as an implied acknowledgement.
787 No acknowledgement sent. */
788 if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)
789 && CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) {
790 if (is_debug)
791 zlog_debug(
792 "No acknowledgement (AllOther & Duplicate & ImpliedAck)");
793 return;
794 }
795
796 /* LSA is a duplicate, and was not treated as an implied
797 acknowledgement.
798 Direct acknowledgement sent */
799 if (CHECK_FLAG(lsa->flag, OSPF6_LSA_DUPLICATE)
800 && !CHECK_FLAG(lsa->flag, OSPF6_LSA_IMPLIEDACK)) {
801 if (is_debug)
802 zlog_debug(
803 "Direct acknowledgement (AllOther & Duplicate)");
804 ospf6_lsdb_add(ospf6_lsa_copy(lsa), from->lsack_list);
907a2395
DS
805 event_add_event(master, ospf6_lsack_send_neighbor, from, 0,
806 &from->thread_send_lsack);
d62a17ae 807 return;
808 }
809
810 /* LSA's LS age is equal to Maxage, and there is no current instance
811 of the LSA in the link state database, and none of router's
812 neighbors are in states Exchange or Loading */
813 /* Direct acknowledgement sent, but this case is handled in
814 early of ospf6_receive_lsa () */
48454375 815}
816
d62a17ae 817static void ospf6_acknowledge_lsa(struct ospf6_lsa *lsa, int ismore_recent,
818 struct ospf6_neighbor *from)
48454375 819{
d62a17ae 820 struct ospf6_interface *oi;
48454375 821
d62a17ae 822 assert(from && from->ospf6_if);
823 oi = from->ospf6_if;
48454375 824
d62a17ae 825 if (oi->state == OSPF6_INTERFACE_BDR)
826 ospf6_acknowledge_lsa_bdrouter(lsa, ismore_recent, from);
827 else
828 ospf6_acknowledge_lsa_allother(lsa, ismore_recent, from);
48454375 829}
830
831/* RFC2328 section 13 (4):
832 if MaxAge LSA and if we have no instance, and no neighbor
833 is in states Exchange or Loading
834 returns 1 if match this case, else returns 0 */
d62a17ae 835static int ospf6_is_maxage_lsa_drop(struct ospf6_lsa *lsa,
836 struct ospf6_neighbor *from)
48454375 837{
d62a17ae 838 struct ospf6_neighbor *on;
839 struct ospf6_interface *oi;
840 struct ospf6_area *oa;
841 struct ospf6 *process = NULL;
842 struct listnode *i, *j, *k;
843 int count = 0;
844
845 if (!OSPF6_LSA_IS_MAXAGE(lsa))
846 return 0;
847
848 if (ospf6_lsdb_lookup(lsa->header->type, lsa->header->id,
849 lsa->header->adv_router, lsa->lsdb))
850 return 0;
851
852 process = from->ospf6_if->area->ospf6;
853
854 for (ALL_LIST_ELEMENTS_RO(process->area_list, i, oa))
855 for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi))
856 for (ALL_LIST_ELEMENTS_RO(oi->neighbor_list, k, on))
857 if (on->state == OSPF6_NEIGHBOR_EXCHANGE
858 || on->state == OSPF6_NEIGHBOR_LOADING)
859 count++;
860
861 if (count == 0)
862 return 1;
863 return 0;
48454375 864}
865
ec58bf6f
YR
866static bool ospf6_lsa_check_min_arrival(struct ospf6_lsa *lsa,
867 struct ospf6_neighbor *from)
868{
869 struct timeval now, res;
870 unsigned int time_delta_ms;
871
872 monotime(&now);
873 timersub(&now, &lsa->installed, &res);
874 time_delta_ms = (res.tv_sec * 1000) + (int)(res.tv_usec / 1000);
875
876 if (time_delta_ms < from->ospf6_if->area->ospf6->lsa_minarrival) {
877 if (IS_OSPF6_DEBUG_FLOODING ||
878 IS_OSPF6_DEBUG_FLOOD_TYPE(lsa->header->type))
879 zlog_debug(
880 "LSA can't be updated within MinLSArrival, %dms < %dms, discard",
881 time_delta_ms,
882 from->ospf6_if->area->ospf6->lsa_minarrival);
883 return true;
884 }
885 return false;
886}
887
48454375 888/* RFC2328 section 13 The Flooding Procedure */
d62a17ae 889void ospf6_receive_lsa(struct ospf6_neighbor *from,
890 struct ospf6_lsa_header *lsa_header)
48454375 891{
d62a17ae 892 struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
893 int ismore_recent;
894 int is_debug = 0;
d62a17ae 895
896 ismore_recent = 1;
897 assert(from);
898
c5467a12 899 /* if we receive a LSA with invalid seqnum drop it */
900 if (ntohl(lsa_header->seqnum) - 1 == OSPF_MAX_SEQUENCE_NUMBER) {
901 if (IS_OSPF6_DEBUG_EXAMIN_TYPE(lsa_header->type)) {
902 zlog_debug(
903 "received lsa [%s Id:%pI4 Adv:%pI4] with invalid seqnum 0x%x, ignore",
904 ospf6_lstype_name(lsa_header->type),
905 &lsa_header->id, &lsa_header->adv_router,
906 ntohl(lsa_header->seqnum));
907 }
908 return;
909 }
910
d62a17ae 911 /* make lsa structure for received lsa */
912 new = ospf6_lsa_create(lsa_header);
913
914 if (IS_OSPF6_DEBUG_FLOODING
915 || IS_OSPF6_DEBUG_FLOOD_TYPE(new->header->type)) {
916 is_debug++;
917 zlog_debug("LSA Receive from %s", from->name);
918 ospf6_lsa_header_print(new);
919 }
920
921 /* (1) LSA Checksum */
922 if (!ospf6_lsa_checksum_valid(new->header)) {
923 if (is_debug)
ba427e63
DA
924 zlog_debug(
925 "Wrong LSA Checksum %s (Router-ID: %pI4) [Type:%s Checksum:%#06hx), discard",
926 from->name, &from->router_id,
927 ospf6_lstype_name(new->header->type),
928 ntohs(new->header->checksum));
d62a17ae 929 ospf6_lsa_delete(new);
930 return;
931 }
932
933 /* (2) Examine the LSA's LS type.
934 RFC2470 3.5.1. Receiving Link State Update packets */
935 if (IS_AREA_STUB(from->ospf6_if->area)
936 && OSPF6_LSA_SCOPE(new->header->type) == OSPF6_SCOPE_AS) {
937 if (is_debug)
938 zlog_debug(
939 "AS-External-LSA (or AS-scope LSA) in stub area, discard");
940 ospf6_lsa_delete(new);
941 return;
942 }
943
944 /* (3) LSA which have reserved scope is discarded
945 RFC2470 3.5.1. Receiving Link State Update packets */
946 /* Flooding scope check. LSAs with unknown scope are discarded here.
947 Set appropriate LSDB for the LSA */
948 switch (OSPF6_LSA_SCOPE(new->header->type)) {
949 case OSPF6_SCOPE_LINKLOCAL:
950 new->lsdb = from->ospf6_if->lsdb;
951 break;
952 case OSPF6_SCOPE_AREA:
953 new->lsdb = from->ospf6_if->area->lsdb;
954 break;
955 case OSPF6_SCOPE_AS:
956 new->lsdb = from->ospf6_if->area->ospf6->lsdb;
957 break;
958 default:
959 if (is_debug)
960 zlog_debug("LSA has reserved scope, discard");
961 ospf6_lsa_delete(new);
962 return;
963 }
964
965 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
966 is in states Exchange or Loading */
967 if (ospf6_is_maxage_lsa_drop(new, from)) {
968 /* log */
969 if (is_debug)
970 zlog_debug(
971 "Drop MaxAge LSA with direct acknowledgement.");
972
973 /* a) Acknowledge back to neighbor (Direct acknowledgement,
974 * 13.5) */
975 ospf6_lsdb_add(ospf6_lsa_copy(new), from->lsack_list);
907a2395
DS
976 event_add_event(master, ospf6_lsack_send_neighbor, from, 0,
977 &from->thread_send_lsack);
d62a17ae 978
979 /* b) Discard */
980 ospf6_lsa_delete(new);
981 return;
982 }
983
984 /* (5) */
985 /* lookup the same database copy in lsdb */
986 old = ospf6_lsdb_lookup(new->header->type, new->header->id,
987 new->header->adv_router, new->lsdb);
988 if (old) {
989 ismore_recent = ospf6_lsa_compare(new, old);
990 if (ntohl(new->header->seqnum) == ntohl(old->header->seqnum)) {
991 if (is_debug)
992 zlog_debug("Received is duplicated LSA");
993 SET_FLAG(new->flag, OSPF6_LSA_DUPLICATE);
994 }
995 }
996
997 /* if no database copy or received is more recent */
998 if (old == NULL || ismore_recent < 0) {
71165098
RW
999 bool self_originated;
1000
d62a17ae 1001 /* in case we have no database copy */
1002 ismore_recent = -1;
1003
1004 /* (a) MinLSArrival check */
1005 if (old) {
ec58bf6f 1006 if (ospf6_lsa_check_min_arrival(old, from)) {
d62a17ae 1007 ospf6_lsa_delete(new);
1008 return; /* examin next lsa */
1009 }
1010 }
1011
1012 monotime(&new->received);
1013
1014 if (is_debug)
1015 zlog_debug(
1016 "Install, Flood, Possibly acknowledge the received LSA");
1017
1018 /* Remove older copies of this LSA from retx lists */
1019 if (old)
1020 ospf6_flood_clear(old);
1021
71165098
RW
1022 self_originated = (new->header->adv_router
1023 == from->ospf6_if->area->ospf6->router_id);
d62a17ae 1024
71165098
RW
1025 /* Received non-self-originated Grace LSA. */
1026 if (IS_GRACE_LSA(new) && !self_originated) {
0d1753a7 1027 struct ospf6 *ospf6;
1028
1029 ospf6 = ospf6_get_by_lsdb(new);
1030
1031 assert(ospf6);
1032
9a06f23d 1033 if (OSPF6_LSA_IS_MAXAGE(new)) {
1034
0fc3e113 1035 if (IS_DEBUG_OSPF6_GR)
9a06f23d 1036 zlog_debug(
1037 "%s, Received a maxage GraceLSA from router %pI4",
1038 __func__,
1039 &new->header->adv_router);
1040 if (old) {
1041 ospf6_process_maxage_grace_lsa(
1042 ospf6, new, from);
1043 } else {
0fc3e113 1044 if (IS_DEBUG_OSPF6_GR)
9a06f23d 1045 zlog_debug(
1046 "%s, GraceLSA doesn't exist in lsdb, so discarding GraceLSA",
1047 __func__);
1048 return;
1049 }
1050 } else {
0d1753a7 1051
0fc3e113 1052 if (IS_DEBUG_OSPF6_GR)
0d1753a7 1053 zlog_debug(
9a06f23d 1054 "%s, Received a GraceLSA from router %pI4",
1055 __func__,
1056 &new->header->adv_router);
1057
1058 if (ospf6_process_grace_lsa(ospf6, new, from)
1059 == OSPF6_GR_NOT_HELPER) {
0fc3e113 1060 if (IS_DEBUG_OSPF6_GR)
9a06f23d 1061 zlog_debug(
1062 "%s, Not moving to HELPER role, So dicarding GraceLSA",
1063 __func__);
1064 return;
1065 }
0d1753a7 1066 }
1067 }
1068
a60eab9e 1069 /* (b) immediately flood and (c) remove from all retrans-list */
1070 /* Prevent self-originated LSA to be flooded. this is to make
1071 * reoriginated instance of the LSA not to be rejected by other
1072 * routers due to MinLSArrival.
1073 */
1074 if (!self_originated)
1075 ospf6_flood(from, new);
1076
d62a17ae 1077 /* (d), installing lsdb, which may cause routing
1078 table calculation (replacing database copy) */
1079 ospf6_install_lsa(new);
1080
1081 if (OSPF6_LSA_IS_MAXAGE(new))
1082 ospf6_maxage_remove(from->ospf6_if->area->ospf6);
1083
1084 /* (e) possibly acknowledge */
1085 ospf6_acknowledge_lsa(new, ismore_recent, from);
1086
1087 /* (f) Self Originated LSA, section 13.4 */
71165098
RW
1088 if (self_originated) {
1089 if (from->ospf6_if->area->ospf6->gr_info
1090 .restart_in_progress) {
1091 if (IS_DEBUG_OSPF6_GR)
1092 zlog_debug(
1093 "Graceful Restart in progress -- not flushing self-originated LSA: %s",
1094 new->name);
1095 return;
1096 }
1097
d62a17ae 1098 /* Self-originated LSA (newer than ours) is received
1099 from
1100 another router. We have to make a new instance of the
1101 LSA
1102 or have to flush this LSA. */
1103 if (is_debug) {
1104 zlog_debug(
1105 "Newer instance of the self-originated LSA");
1106 zlog_debug("Schedule reorigination");
1107 }
907a2395
DS
1108 event_add_event(master, ospf6_lsa_refresh, new, 0,
1109 &new->refresh);
d62a17ae 1110 }
1111
cb1f47c2 1112 /* GR: check for network topology change. */
71165098
RW
1113 struct ospf6 *ospf6 = from->ospf6_if->area->ospf6;
1114 struct ospf6_area *area = from->ospf6_if->area;
cb1f47c2
RW
1115 if (ospf6->gr_info.restart_in_progress &&
1116 (new->header->type == ntohs(OSPF6_LSTYPE_ROUTER) ||
1117 new->header->type == ntohs(OSPF6_LSTYPE_NETWORK)))
71165098
RW
1118 ospf6_gr_check_lsdb_consistency(ospf6, area);
1119
d62a17ae 1120 return;
1121 }
1122
1123 /* (6) if there is instance on sending neighbor's request list */
1124 if (ospf6_lsdb_lookup(new->header->type, new->header->id,
1125 new->header->adv_router, from->request_list)) {
1126 /* if no database copy, should go above state (5) */
1127 assert(old);
1128
1b1f7b4f 1129 zlog_warn(
1130 "Received is not newer, on the neighbor %s request-list",
1131 from->name);
1132 zlog_warn(
1133 "BadLSReq, discard the received LSA lsa %s send badLSReq",
1134 new->name);
d62a17ae 1135
1136 /* BadLSReq */
907a2395 1137 event_add_event(master, bad_lsreq, from, 0, NULL);
d62a17ae 1138
1139 ospf6_lsa_delete(new);
1140 return;
1141 }
1142
1143 /* (7) if neither one is more recent */
1144 if (ismore_recent == 0) {
1145 if (is_debug)
1146 zlog_debug(
1147 "The same instance as database copy (neither recent)");
1148
1149 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack
1150 */
1151 rem = ospf6_lsdb_lookup(new->header->type, new->header->id,
1152 new->header->adv_router,
1153 from->retrans_list);
1154 if (rem) {
1155 if (is_debug) {
1156 zlog_debug(
1157 "It is on the neighbor's retrans-list.");
1158 zlog_debug(
1159 "Treat as an Implied acknowledgement");
1160 }
1161 SET_FLAG(new->flag, OSPF6_LSA_IMPLIEDACK);
1162 ospf6_decrement_retrans_count(rem);
1163 ospf6_lsdb_remove(rem, from->retrans_list);
1164 }
1165
1166 if (is_debug)
1167 zlog_debug("Possibly acknowledge and then discard");
1168
1169 /* (b) possibly acknowledge */
1170 ospf6_acknowledge_lsa(new, ismore_recent, from);
1171
1172 ospf6_lsa_delete(new);
1173 return;
1174 }
1175
1176 /* (8) previous database copy is more recent */
1177 {
1178 assert(old);
1179
1180 /* If database copy is in 'Seqnumber Wrapping',
1181 simply discard the received LSA */
1182 if (OSPF6_LSA_IS_MAXAGE(old)
1183 && old->header->seqnum == htonl(OSPF_MAX_SEQUENCE_NUMBER)) {
1184 if (is_debug) {
1185 zlog_debug("The LSA is in Seqnumber Wrapping");
1186 zlog_debug("MaxAge & MaxSeqNum, discard");
1187 }
1188 ospf6_lsa_delete(new);
1189 return;
1190 }
1191
1192 /* Otherwise, Send database copy of this LSA to this neighbor */
1193 {
1194 if (is_debug) {
1195 zlog_debug("Database copy is more recent.");
1196 zlog_debug(
1197 "Send back directly and then discard");
1198 }
1199
76249532
CS
1200 /* Neighbor router sent recent age for LSA,
1201 * Router could be restarted while current copy is
1202 * MAXAGEd and not removed.*/
996c9314
LB
1203 if (OSPF6_LSA_IS_MAXAGE(old)
1204 && !OSPF6_LSA_IS_MAXAGE(new)) {
76249532 1205 if (new->header->adv_router
4c63a76a
MB
1206 != from->ospf6_if->area->ospf6->router_id) {
1207 if (is_debug)
1208 zlog_debug(
1209 "%s: Current copy of LSA %s is MAXAGE, but new has recent age, flooding/installing.",
2d84ae9c 1210 __PRETTY_FUNCTION__, old->name);
4c63a76a 1211 ospf6_lsa_purge(old);
76249532 1212 ospf6_flood(from, new);
4c63a76a 1213 ospf6_install_lsa(new);
2d84ae9c 1214 return;
4c63a76a 1215 }
2d84ae9c
MB
1216 /* For self-originated LSA, only trust
1217 * ourselves. Fall through and send
1218 * LS Update with our current copy.
1219 */
1220 if (is_debug)
1221 zlog_debug(
1222 "%s: Current copy of self-originated LSA %s is MAXAGE, but new has recent age, re-sending current one.",
1223 __PRETTY_FUNCTION__, old->name);
76249532
CS
1224 }
1225
ec58bf6f
YR
1226 /* MinLSArrival check as per RFC 2328 13 (8) */
1227 if (ospf6_lsa_check_min_arrival(old, from)) {
1228 ospf6_lsa_delete(new);
1229 return; /* examin next lsa */
1230 }
d62a17ae 1231
1232 ospf6_lsdb_add(ospf6_lsa_copy(old),
1233 from->lsupdate_list);
907a2395
DS
1234 event_add_event(master, ospf6_lsupdate_send_neighbor,
1235 from, 0, &from->thread_send_lsupdate);
76249532 1236
d62a17ae 1237 ospf6_lsa_delete(new);
1238 return;
1239 }
d62a17ae 1240 }
48454375 1241}
1242
1e05838a 1243DEFUN (debug_ospf6_flooding,
1244 debug_ospf6_flooding_cmd,
1245 "debug ospf6 flooding",
1246 DEBUG_STR
1247 OSPF6_STR
1248 "Debug OSPFv3 flooding function\n"
1249 )
1250{
d62a17ae 1251 OSPF6_DEBUG_FLOODING_ON();
1252 return CMD_SUCCESS;
1e05838a 1253}
1254
1255DEFUN (no_debug_ospf6_flooding,
1256 no_debug_ospf6_flooding_cmd,
1257 "no debug ospf6 flooding",
1258 NO_STR
1259 DEBUG_STR
1260 OSPF6_STR
1261 "Debug OSPFv3 flooding function\n"
1262 )
1263{
d62a17ae 1264 OSPF6_DEBUG_FLOODING_OFF();
1265 return CMD_SUCCESS;
1e05838a 1266}
1267
d62a17ae 1268int config_write_ospf6_debug_flood(struct vty *vty)
1e05838a 1269{
d62a17ae 1270 if (IS_OSPF6_DEBUG_FLOODING)
1271 vty_out(vty, "debug ospf6 flooding\n");
1272 return 0;
1e05838a 1273}
1274
d62a17ae 1275void install_element_ospf6_debug_flood(void)
1e05838a 1276{
d62a17ae 1277 install_element(ENABLE_NODE, &debug_ospf6_flooding_cmd);
1278 install_element(ENABLE_NODE, &no_debug_ospf6_flooding_cmd);
1279 install_element(CONFIG_NODE, &debug_ospf6_flooding_cmd);
1280 install_element(CONFIG_NODE, &no_debug_ospf6_flooding_cmd);
1e05838a 1281}