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