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