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