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