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