]> git.proxmox.com Git - mirror_frr.git/blame - ospf6d/ospf6_flood.c
Merge remote-tracking branch 'origin/stable/3.0'
[mirror_frr.git] / ospf6d / ospf6_flood.c
CommitLineData
48454375 1/*
2 * Copyright (C) 2003 Yasuhiro Ohara
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
896014f4
DL
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
48454375 19 */
20
21#include <zebra.h>
22
23#include "log.h"
24#include "thread.h"
25#include "linklist.h"
26#include "vty.h"
1e05838a 27#include "command.h"
48454375 28
29#include "ospf6d.h"
30#include "ospf6_proto.h"
31#include "ospf6_lsa.h"
32#include "ospf6_lsdb.h"
33#include "ospf6_message.h"
34#include "ospf6_route.h"
35#include "ospf6_spf.h"
36
37#include "ospf6_top.h"
38#include "ospf6_area.h"
39#include "ospf6_interface.h"
40#include "ospf6_neighbor.h"
41
6452df09 42#include "ospf6_flood.h"
48454375 43
1e05838a 44unsigned char conf_debug_ospf6_flooding;
45
6452df09 46struct ospf6_lsdb *
47ospf6_get_scoped_lsdb (struct ospf6_lsa *lsa)
48454375 48{
6452df09 49 struct ospf6_lsdb *lsdb = NULL;
50 switch (OSPF6_LSA_SCOPE (lsa->header->type))
51 {
52 case OSPF6_SCOPE_LINKLOCAL:
53 lsdb = OSPF6_INTERFACE (lsa->lsdb->data)->lsdb;
54 break;
55 case OSPF6_SCOPE_AREA:
56 lsdb = OSPF6_AREA (lsa->lsdb->data)->lsdb;
57 break;
58 case OSPF6_SCOPE_AS:
59 lsdb = OSPF6_PROCESS (lsa->lsdb->data)->lsdb;
60 break;
61 default:
62 assert (0);
63 break;
48454375 64 }
6452df09 65 return lsdb;
48454375 66}
67
68struct ospf6_lsdb *
6452df09 69ospf6_get_scoped_lsdb_self (struct ospf6_lsa *lsa)
48454375 70{
6452df09 71 struct ospf6_lsdb *lsdb_self = NULL;
72 switch (OSPF6_LSA_SCOPE (lsa->header->type))
73 {
74 case OSPF6_SCOPE_LINKLOCAL:
75 lsdb_self = OSPF6_INTERFACE (lsa->lsdb->data)->lsdb_self;
76 break;
77 case OSPF6_SCOPE_AREA:
78 lsdb_self = OSPF6_AREA (lsa->lsdb->data)->lsdb_self;
79 break;
80 case OSPF6_SCOPE_AS:
81 lsdb_self = OSPF6_PROCESS (lsa->lsdb->data)->lsdb_self;
82 break;
83 default:
84 assert (0);
85 break;
86 }
87 return lsdb_self;
88}
89
90void
91ospf6_lsa_originate (struct ospf6_lsa *lsa)
92{
93 struct ospf6_lsa *old;
94 struct ospf6_lsdb *lsdb_self;
48454375 95
6452df09 96 /* find previous LSA */
97 old = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
98 lsa->header->adv_router, lsa->lsdb);
48454375 99
6452df09 100 /* if the new LSA does not differ from previous,
101 suppress this update of the LSA */
102 if (old && ! OSPF6_LSA_IS_DIFFER (lsa, old))
48454375 103 {
1e05838a 104 if (IS_OSPF6_DEBUG_ORIGINATE_TYPE (lsa->header->type))
c6487d61 105 zlog_debug ("Suppress updating LSA: %s", lsa->name);
6452df09 106 ospf6_lsa_delete (lsa);
107 return;
48454375 108 }
109
6452df09 110 /* store it in the LSDB for self-originated LSAs */
111 lsdb_self = ospf6_get_scoped_lsdb_self (lsa);
112 ospf6_lsdb_add (ospf6_lsa_copy (lsa), lsdb_self);
48454375 113
66e78ae6
QY
114 lsa->refresh = NULL;
115 thread_add_timer(master, ospf6_lsa_refresh, lsa, OSPF_LS_REFRESH_TIME,
116 &lsa->refresh);
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);
66e78ae6
QY
228 if (! OSPF6_LSA_IS_MAXAGE (lsa)) {
229 lsa->expire = NULL;
230 thread_add_timer(master, ospf6_lsa_expire, lsa, OSPF_LSA_MAXAGE + lsa->birth.tv_sec - now.tv_sec,
231 &lsa->expire);
232 }
3b68735f 233 else
234 lsa->expire = NULL;
48454375 235
3b220289
DD
236 if (OSPF6_LSA_IS_SEQWRAP(lsa) &&
237 ! (CHECK_FLAG(lsa->flag,OSPF6_LSA_SEQWRAPPED) &&
238 lsa->header->seqnum == htonl(OSPF_MAX_SEQUENCE_NUMBER)))
239 {
240 if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
241 zlog_debug("lsa install wrapping: sequence 0x%x",
242 ntohl(lsa->header->seqnum));
243 SET_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED);
244 /* in lieu of premature_aging, since we do not want to recreate this lsa
245 * and/or mess with timers etc, we just want to wrap the sequence number
246 * and reflood the lsa before continuing.
247 * NOTE: Flood needs to be called right after this function call, by the
248 * caller
249 */
250 lsa->header->seqnum = htonl (OSPF_MAX_SEQUENCE_NUMBER);
251 lsa->header->age = htons (OSPF_LSA_MAXAGE);
252 ospf6_lsa_checksum (lsa->header);
253 }
254
48454375 255 /* actually install */
3b68735f 256 lsa->installed = now;
6452df09 257 ospf6_lsdb_add (lsa, lsa->lsdb);
48454375 258
259 return;
260}
261
6452df09 262/* RFC2740 section 3.5.2. Sending Link State Update packets */
48454375 263/* RFC2328 section 13.3 Next step in the flooding procedure */
6ac29a51 264static void
6452df09 265ospf6_flood_interface (struct ospf6_neighbor *from,
266 struct ospf6_lsa *lsa, struct ospf6_interface *oi)
48454375 267{
1eb8ef25 268 struct listnode *node, *nnode;
48454375 269 struct ospf6_neighbor *on;
48454375 270 struct ospf6_lsa *req;
271 int retrans_added = 0;
1e05838a 272 int is_debug = 0;
48454375 273
1e05838a 274 if (IS_OSPF6_DEBUG_FLOODING ||
275 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
276 {
277 is_debug++;
c6487d61 278 zlog_debug ("Flooding on %s: %s", oi->interface->name, lsa->name);
1e05838a 279 }
48454375 280
6452df09 281 /* (1) For each neighbor */
1eb8ef25 282 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
48454375 283 {
1e05838a 284 if (is_debug)
c6487d61 285 zlog_debug ("To neighbor %s", on->name);
48454375 286
6452df09 287 /* (a) if neighbor state < Exchange, examin next */
288 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
289 {
1e05838a 290 if (is_debug)
c6487d61 291 zlog_debug ("Neighbor state less than ExChange, next neighbor");
6452df09 292 continue;
48454375 293 }
48454375 294
6452df09 295 /* (b) if neighbor not yet Full, check request-list */
296 if (on->state != OSPF6_NEIGHBOR_FULL)
48454375 297 {
1e05838a 298 if (is_debug)
c6487d61 299 zlog_debug ("Neighbor not yet Full");
48454375 300
6452df09 301 req = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
302 lsa->header->adv_router, on->request_list);
303 if (req == NULL)
48454375 304 {
1e05838a 305 if (is_debug)
c6487d61 306 zlog_debug ("Not on request-list for this neighbor");
6452df09 307 /* fall through */
308 }
309 else
310 {
311 /* If new LSA less recent, examin next neighbor */
312 if (ospf6_lsa_compare (lsa, req) > 0)
313 {
1e05838a 314 if (is_debug)
eb82e9ee 315 zlog_debug ("Requesting is older, next neighbor");
6452df09 316 continue;
317 }
318
319 /* If the same instance, delete from request-list and
320 examin next neighbor */
321 if (ospf6_lsa_compare (lsa, req) == 0)
48454375 322 {
eb82e9ee
DD
323 if (is_debug)
324 zlog_debug ("Requesting the same, remove it, next neighbor");
325 if (req == on->last_ls_req)
326 {
327 ospf6_lsa_unlock (req);
328 on->last_ls_req = NULL;
329 }
6452df09 330 ospf6_lsdb_remove (req, on->request_list);
eb82e9ee 331 ospf6_check_nbr_loading (on);
6452df09 332 continue;
333 }
334
335 /* If the new LSA is more recent, delete from request-list */
336 if (ospf6_lsa_compare (lsa, req) < 0)
337 {
eb82e9ee
DD
338 if (is_debug)
339 zlog_debug ("Received is newer, remove requesting");
340 if (req == on->last_ls_req)
341 {
342 ospf6_lsa_unlock (req);
343 on->last_ls_req = NULL;
344 }
6452df09 345 ospf6_lsdb_remove (req, on->request_list);
eb82e9ee 346 ospf6_check_nbr_loading (on);
6452df09 347 /* fall through */
48454375 348 }
349 }
6452df09 350 }
48454375 351
6452df09 352 /* (c) If the new LSA was received from this neighbor,
353 examin next neighbor */
354 if (from == on)
355 {
1e05838a 356 if (is_debug)
c6487d61 357 zlog_debug ("Received is from the neighbor, next neighbor");
6452df09 358 continue;
48454375 359 }
360
6452df09 361 /* (d) add retrans-list, schedule retransmission */
1e05838a 362 if (is_debug)
c6487d61 363 zlog_debug ("Add retrans-list of this neighbor");
6452df09 364 ospf6_increment_retrans_count (lsa);
365 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
66e78ae6
QY
366 thread_add_timer(master, ospf6_lsupdate_send_neighbor, on, on->ospf6_if->rxmt_interval,
367 &on->thread_send_lsupdate);
6452df09 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);
66e78ae6
QY
409 thread_add_event(master, ospf6_lsupdate_send_interface, oi, 0,
410 &oi->thread_send_lsupdate);
6452df09 411 }
412 else
413 {
414 /* reschedule retransmissions to all neighbors */
1eb8ef25 415 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
6452df09 416 {
6452df09 417 THREAD_OFF (on->thread_send_lsupdate);
66e78ae6
QY
418 on->thread_send_lsupdate = NULL;
419 thread_add_event(master, ospf6_lsupdate_send_neighbor, on, 0,
420 &on->thread_send_lsupdate);
6452df09 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);
66e78ae6
QY
580 thread_add_timer(master, ospf6_lsack_send_interface, oi, 3,
581 &oi->thread_send_lsack);
48454375 582 }
583 else
584 {
1e05838a 585 if (is_debug)
c6487d61 586 zlog_debug ("No acknowledgement (BDR & MoreRecent & ! from DR)");
48454375 587 }
588 return;
589 }
590
591 /* LSA is a duplicate, and was treated as an implied acknowledgement.
592 Delayed acknowledgement sent if advertisement received from
593 Designated Router, otherwise do nothing */
594 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
595 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
596 {
48454375 597 if (oi->drouter == from->router_id)
598 {
1e05838a 599 if (is_debug)
c6487d61 600 zlog_debug ("Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
48454375 601 /* Delayed acknowledgement */
48454375 602 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
66e78ae6
QY
603 thread_add_timer(master, ospf6_lsack_send_interface, oi, 3,
604 &oi->thread_send_lsack);
48454375 605 }
606 else
607 {
1e05838a 608 if (is_debug)
c6487d61 609 zlog_debug ("No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
48454375 610 }
611 return;
612 }
613
614 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
615 Direct acknowledgement sent */
616 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
617 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
618 {
1e05838a 619 if (is_debug)
c6487d61 620 zlog_debug ("Direct acknowledgement (BDR & Duplicate)");
48454375 621 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
66e78ae6
QY
622 thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
623 &from->thread_send_lsack);
48454375 624 return;
625 }
626
627 /* LSA's LS age is equal to Maxage, and there is no current instance
628 of the LSA in the link state database, and none of router's
629 neighbors are in states Exchange or Loading */
630 /* Direct acknowledgement sent, but this case is handled in
631 early of ospf6_receive_lsa () */
632}
633
634static void
635ospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent,
636 struct ospf6_neighbor *from)
637{
638 struct ospf6_interface *oi;
1e05838a 639 int is_debug = 0;
640
641 if (IS_OSPF6_DEBUG_FLOODING ||
642 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
643 is_debug++;
48454375 644
645 assert (from && from->ospf6_if);
646 oi = from->ospf6_if;
647
648 /* LSA has been flood back out receiving interface.
649 No acknowledgement sent. */
650 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
651 {
1e05838a 652 if (is_debug)
c6487d61 653 zlog_debug ("No acknowledgement (AllOther & FloodBack)");
48454375 654 return;
655 }
656
657 /* LSA is more recent than database copy, but was not flooded
658 back out receiving interface. Delayed acknowledgement sent. */
659 if (ismore_recent < 0)
660 {
1e05838a 661 if (is_debug)
c6487d61 662 zlog_debug ("Delayed acknowledgement (AllOther & MoreRecent)");
48454375 663 /* Delayed acknowledgement */
48454375 664 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
66e78ae6
QY
665 thread_add_timer(master, ospf6_lsack_send_interface, oi, 3,
666 &oi->thread_send_lsack);
48454375 667 return;
668 }
669
670 /* LSA is a duplicate, and was treated as an implied acknowledgement.
671 No acknowledgement sent. */
672 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
673 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
674 {
1e05838a 675 if (is_debug)
c6487d61 676 zlog_debug ("No acknowledgement (AllOther & Duplicate & ImpliedAck)");
48454375 677 return;
678 }
679
680 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
681 Direct acknowledgement sent */
682 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
683 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
684 {
1e05838a 685 if (is_debug)
c6487d61 686 zlog_debug ("Direct acknowledgement (AllOther & Duplicate)");
48454375 687 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
66e78ae6
QY
688 thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
689 &from->thread_send_lsack);
48454375 690 return;
691 }
692
693 /* LSA's LS age is equal to Maxage, and there is no current instance
694 of the LSA in the link state database, and none of router's
695 neighbors are in states Exchange or Loading */
696 /* Direct acknowledgement sent, but this case is handled in
697 early of ospf6_receive_lsa () */
698}
699
6ac29a51 700static void
48454375 701ospf6_acknowledge_lsa (struct ospf6_lsa *lsa, int ismore_recent,
702 struct ospf6_neighbor *from)
703{
704 struct ospf6_interface *oi;
705
706 assert (from && from->ospf6_if);
707 oi = from->ospf6_if;
708
709 if (oi->state == OSPF6_INTERFACE_BDR)
710 ospf6_acknowledge_lsa_bdrouter (lsa, ismore_recent, from);
711 else
712 ospf6_acknowledge_lsa_allother (lsa, ismore_recent, from);
713}
714
715/* RFC2328 section 13 (4):
716 if MaxAge LSA and if we have no instance, and no neighbor
717 is in states Exchange or Loading
718 returns 1 if match this case, else returns 0 */
719static int
6452df09 720ospf6_is_maxage_lsa_drop (struct ospf6_lsa *lsa, struct ospf6_neighbor *from)
48454375 721{
48454375 722 struct ospf6_neighbor *on;
6452df09 723 struct ospf6_interface *oi;
724 struct ospf6_area *oa;
725 struct ospf6 *process = NULL;
52dc7ee6 726 struct listnode *i, *j, *k;
48454375 727 int count = 0;
728
729 if (! OSPF6_LSA_IS_MAXAGE (lsa))
730 return 0;
731
48454375 732 if (ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
6452df09 733 lsa->header->adv_router, lsa->lsdb))
48454375 734 return 0;
735
6452df09 736 process = from->ospf6_if->area->ospf6;
1eb8ef25 737
738 for (ALL_LIST_ELEMENTS_RO (process->area_list, i, oa))
739 for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
740 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on))
741 if (on->state == OSPF6_NEIGHBOR_EXCHANGE ||
742 on->state == OSPF6_NEIGHBOR_LOADING)
743 count++;
48454375 744
48454375 745 if (count == 0)
746 return 1;
48454375 747 return 0;
748}
749
750/* RFC2328 section 13 The Flooding Procedure */
751void
6452df09 752ospf6_receive_lsa (struct ospf6_neighbor *from,
753 struct ospf6_lsa_header *lsa_header)
48454375 754{
755 struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
756 int ismore_recent;
1e05838a 757 int is_debug = 0;
ed2eb093 758 unsigned int time_delta_ms;
48454375 759
760 ismore_recent = 1;
6452df09 761 assert (from);
48454375 762
763 /* make lsa structure for received lsa */
764 new = ospf6_lsa_create (lsa_header);
765
1e05838a 766 if (IS_OSPF6_DEBUG_FLOODING ||
767 IS_OSPF6_DEBUG_FLOOD_TYPE (new->header->type))
48454375 768 {
1e05838a 769 is_debug++;
c6487d61 770 zlog_debug ("LSA Receive from %s", from->name);
48454375 771 ospf6_lsa_header_print (new);
772 }
773
6452df09 774 /* (1) LSA Checksum */
d8a4e42b 775 if (! ospf6_lsa_checksum_valid (new->header))
48454375 776 {
1e05838a 777 if (is_debug)
c6487d61 778 zlog_debug ("Wrong LSA Checksum, discard");
48454375 779 ospf6_lsa_delete (new);
780 return;
781 }
782
6452df09 783 /* (2) Examine the LSA's LS type.
784 RFC2470 3.5.1. Receiving Link State Update packets */
785 if (IS_AREA_STUB (from->ospf6_if->area) &&
786 OSPF6_LSA_SCOPE (new->header->type) == OSPF6_SCOPE_AS)
48454375 787 {
1e05838a 788 if (is_debug)
c6487d61 789 zlog_debug ("AS-External-LSA (or AS-scope LSA) in stub area, discard");
48454375 790 ospf6_lsa_delete (new);
791 return;
792 }
793
6452df09 794 /* (3) LSA which have reserved scope is discarded
795 RFC2470 3.5.1. Receiving Link State Update packets */
796 /* Flooding scope check. LSAs with unknown scope are discarded here.
797 Set appropriate LSDB for the LSA */
798 switch (OSPF6_LSA_SCOPE (new->header->type))
799 {
800 case OSPF6_SCOPE_LINKLOCAL:
801 new->lsdb = from->ospf6_if->lsdb;
802 break;
803 case OSPF6_SCOPE_AREA:
804 new->lsdb = from->ospf6_if->area->lsdb;
805 break;
806 case OSPF6_SCOPE_AS:
807 new->lsdb = from->ospf6_if->area->ospf6->lsdb;
808 break;
809 default:
1e05838a 810 if (is_debug)
c6487d61 811 zlog_debug ("LSA has reserved scope, discard");
48454375 812 ospf6_lsa_delete (new);
813 return;
814 }
815
816 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
817 is in states Exchange or Loading */
818 if (ospf6_is_maxage_lsa_drop (new, from))
819 {
820 /* log */
1e05838a 821 if (is_debug)
eb82e9ee 822 zlog_debug ("Drop MaxAge LSA with direct acknowledgement.");
48454375 823
824 /* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */
6452df09 825 ospf6_lsdb_add (ospf6_lsa_copy (new), from->lsack_list);
66e78ae6
QY
826 thread_add_event(master, ospf6_lsack_send_neighbor, from, 0,
827 &from->thread_send_lsack);
48454375 828
829 /* b) Discard */
6452df09 830 ospf6_lsa_delete (new);
48454375 831 return;
832 }
833
834 /* (5) */
835 /* lookup the same database copy in lsdb */
48454375 836 old = ospf6_lsdb_lookup (new->header->type, new->header->id,
6452df09 837 new->header->adv_router, new->lsdb);
48454375 838 if (old)
839 {
840 ismore_recent = ospf6_lsa_compare (new, old);
841 if (ntohl (new->header->seqnum) == ntohl (old->header->seqnum))
842 {
1e05838a 843 if (is_debug)
c6487d61 844 zlog_debug ("Received is duplicated LSA");
48454375 845 SET_FLAG (new->flag, OSPF6_LSA_DUPLICATE);
846 }
847 }
848
849 /* if no database copy or received is more recent */
850 if (old == NULL || ismore_recent < 0)
851 {
852 /* in case we have no database copy */
853 ismore_recent = -1;
854
855 /* (a) MinLSArrival check */
856 if (old)
857 {
858 struct timeval now, res;
cf672a86 859 monotime(&now);
48454375 860 timersub (&now, &old->installed, &res);
b6927875
DS
861 time_delta_ms = (res.tv_sec * 1000) + (int)(res.tv_usec/1000);
862 if (time_delta_ms < from->ospf6_if->area->ospf6->lsa_minarrival)
48454375 863 {
1e05838a 864 if (is_debug)
b6927875
DS
865 zlog_debug ("LSA can't be updated within MinLSArrival, %dms < %dms, discard",
866 time_delta_ms, from->ospf6_if->area->ospf6->lsa_minarrival);
48454375 867 ospf6_lsa_delete (new);
868 return; /* examin next lsa */
869 }
870 }
871
cf672a86 872 monotime(&new->received);
ccb59b11 873
1e05838a 874 if (is_debug)
bf986da7
DD
875 zlog_debug ("Install, Flood, Possibly acknowledge the received LSA");
876
877 /* Remove older copies of this LSA from retx lists */
878 if (old)
879 ospf6_flood_clear (old);
6452df09 880
48454375 881 /* (b) immediately flood and (c) remove from all retrans-list */
ccb59b11 882 /* Prevent self-originated LSA to be flooded. this is to make
883 reoriginated instance of the LSA not to be rejected by other routers
884 due to MinLSArrival. */
885 if (new->header->adv_router != from->ospf6_if->area->ospf6->router_id)
886 ospf6_flood (from, new);
6452df09 887
48454375 888 /* (d), installing lsdb, which may cause routing
889 table calculation (replacing database copy) */
6452df09 890 ospf6_install_lsa (new);
48454375 891
c3c0ac83
DS
892 if (OSPF6_LSA_IS_MAXAGE (new))
893 ospf6_maxage_remove (from->ospf6_if->area->ospf6);
894
48454375 895 /* (e) possibly acknowledge */
896 ospf6_acknowledge_lsa (new, ismore_recent, from);
897
6452df09 898 /* (f) Self Originated LSA, section 13.4 */
899 if (new->header->adv_router == from->ospf6_if->area->ospf6->router_id)
48454375 900 {
6452df09 901 /* Self-originated LSA (newer than ours) is received from
902 another router. We have to make a new instance of the LSA
48454375 903 or have to flush this LSA. */
1e05838a 904 if (is_debug)
6452df09 905 {
c6487d61 906 zlog_debug ("Newer instance of the self-originated LSA");
907 zlog_debug ("Schedule reorigination");
6452df09 908 }
66e78ae6
QY
909 new->refresh = NULL;
910 thread_add_event(master, ospf6_lsa_refresh, new, 0, &new->refresh);
48454375 911 }
6452df09 912
48454375 913 return;
914 }
915
916 /* (6) if there is instance on sending neighbor's request list */
917 if (ospf6_lsdb_lookup (new->header->type, new->header->id,
918 new->header->adv_router, from->request_list))
919 {
920 /* if no database copy, should go above state (5) */
921 assert (old);
922
1e05838a 923 if (is_debug)
6452df09 924 {
c6487d61 925 zlog_debug ("Received is not newer, on the neighbor's request-list");
926 zlog_debug ("BadLSReq, discard the received LSA");
6452df09 927 }
48454375 928
929 /* BadLSReq */
ffa2c898 930 thread_add_event(master, bad_lsreq, from, 0, NULL);
48454375 931
932 ospf6_lsa_delete (new);
933 return;
934 }
935
936 /* (7) if neither one is more recent */
937 if (ismore_recent == 0)
938 {
1e05838a 939 if (is_debug)
c6487d61 940 zlog_debug ("The same instance as database copy (neither recent)");
48454375 941
942 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack */
943 rem = ospf6_lsdb_lookup (new->header->type, new->header->id,
944 new->header->adv_router, from->retrans_list);
945 if (rem)
946 {
1e05838a 947 if (is_debug)
6452df09 948 {
c6487d61 949 zlog_debug ("It is on the neighbor's retrans-list.");
950 zlog_debug ("Treat as an Implied acknowledgement");
6452df09 951 }
48454375 952 SET_FLAG (new->flag, OSPF6_LSA_IMPLIEDACK);
6452df09 953 ospf6_decrement_retrans_count (rem);
48454375 954 ospf6_lsdb_remove (rem, from->retrans_list);
955 }
956
1e05838a 957 if (is_debug)
c6487d61 958 zlog_debug ("Possibly acknowledge and then discard");
6452df09 959
48454375 960 /* (b) possibly acknowledge */
961 ospf6_acknowledge_lsa (new, ismore_recent, from);
962
963 ospf6_lsa_delete (new);
964 return;
965 }
966
967 /* (8) previous database copy is more recent */
968 {
969 assert (old);
970
971 /* If database copy is in 'Seqnumber Wrapping',
972 simply discard the received LSA */
973 if (OSPF6_LSA_IS_MAXAGE (old) &&
8551e6da 974 old->header->seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
48454375 975 {
1e05838a 976 if (is_debug)
6452df09 977 {
c6487d61 978 zlog_debug ("The LSA is in Seqnumber Wrapping");
979 zlog_debug ("MaxAge & MaxSeqNum, discard");
6452df09 980 }
eb82e9ee
DD
981 ospf6_lsa_delete (new);
982 return;
48454375 983 }
984
985 /* Otherwise, Send database copy of this LSA to this neighbor */
986 {
1e05838a 987 if (is_debug)
6452df09 988 {
c6487d61 989 zlog_debug ("Database copy is more recent.");
990 zlog_debug ("Send back directly and then discard");
6452df09 991 }
48454375 992
993 /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
994
48454375 995 ospf6_lsdb_add (ospf6_lsa_copy (old), from->lsupdate_list);
66e78ae6
QY
996 thread_add_event(master, ospf6_lsupdate_send_neighbor, from, 0,
997 &from->thread_send_lsupdate);
eb82e9ee
DD
998 ospf6_lsa_delete (new);
999 return;
48454375 1000 }
1001 return;
1002 }
1003}
1004
1005
1e05838a 1006DEFUN (debug_ospf6_flooding,
1007 debug_ospf6_flooding_cmd,
1008 "debug ospf6 flooding",
1009 DEBUG_STR
1010 OSPF6_STR
1011 "Debug OSPFv3 flooding function\n"
1012 )
1013{
1014 OSPF6_DEBUG_FLOODING_ON ();
1015 return CMD_SUCCESS;
1016}
1017
1018DEFUN (no_debug_ospf6_flooding,
1019 no_debug_ospf6_flooding_cmd,
1020 "no debug ospf6 flooding",
1021 NO_STR
1022 DEBUG_STR
1023 OSPF6_STR
1024 "Debug OSPFv3 flooding function\n"
1025 )
1026{
1027 OSPF6_DEBUG_FLOODING_OFF ();
1028 return CMD_SUCCESS;
1029}
1030
1031int
1032config_write_ospf6_debug_flood (struct vty *vty)
1033{
1034 if (IS_OSPF6_DEBUG_FLOODING)
1035 vty_out (vty, "debug ospf6 flooding%s", VNL);
1036 return 0;
1037}
1038
1039void
6ac29a51 1040install_element_ospf6_debug_flood (void)
1e05838a 1041{
1042 install_element (ENABLE_NODE, &debug_ospf6_flooding_cmd);
1043 install_element (ENABLE_NODE, &no_debug_ospf6_flooding_cmd);
1044 install_element (CONFIG_NODE, &debug_ospf6_flooding_cmd);
1045 install_element (CONFIG_NODE, &no_debug_ospf6_flooding_cmd);
1046}
1047
1048
1049
1050
48454375 1051