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