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