blob: 9971ef1c9e610ebf0db6970e13acb1614b9c2d0d [file] [log] [blame]
hasso48454372004-05-18 19:14:52 +00001/*
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"
hasso1e058382004-09-01 21:36:14 +000028#include "command.h"
hasso48454372004-05-18 19:14:52 +000029
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
hasso6452df02004-08-15 05:52:07 +000043#include "ospf6_flood.h"
hasso48454372004-05-18 19:14:52 +000044
hasso1e058382004-09-01 21:36:14 +000045unsigned char conf_debug_ospf6_flooding;
46
hasso48454372004-05-18 19:14:52 +000047struct ospf6_lsdb *
hasso6452df02004-08-15 05:52:07 +000048ospf6_get_scoped_lsdb (struct ospf6_lsa *lsa)
hasso48454372004-05-18 19:14:52 +000049{
50 struct ospf6_lsdb *lsdb = NULL;
hasso6452df02004-08-15 05:52:07 +000051 switch (OSPF6_LSA_SCOPE (lsa->header->type))
hasso48454372004-05-18 19:14:52 +000052 {
hasso6452df02004-08-15 05:52:07 +000053 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;
hasso48454372004-05-18 19:14:52 +000065 }
hasso48454372004-05-18 19:14:52 +000066 return lsdb;
67}
68
hasso6452df02004-08-15 05:52:07 +000069struct ospf6_lsdb *
70ospf6_get_scoped_lsdb_self (struct ospf6_lsa *lsa)
hasso3b4cd3a2004-05-18 19:28:32 +000071{
hasso6452df02004-08-15 05:52:07 +000072 struct ospf6_lsdb *lsdb_self = NULL;
73 switch (OSPF6_LSA_SCOPE (lsa->header->type))
hasso3b4cd3a2004-05-18 19:28:32 +000074 {
hasso6452df02004-08-15 05:52:07 +000075 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;
hasso3b4cd3a2004-05-18 19:28:32 +000087 }
hasso6452df02004-08-15 05:52:07 +000088 return lsdb_self;
hasso3b4cd3a2004-05-18 19:28:32 +000089}
90
91void
hasso6452df02004-08-15 05:52:07 +000092ospf6_lsa_originate (struct ospf6_lsa *lsa)
hasso48454372004-05-18 19:14:52 +000093{
hasso6452df02004-08-15 05:52:07 +000094 struct ospf6_lsa *old;
95 struct ospf6_lsdb *lsdb_self;
hasso48454372004-05-18 19:14:52 +000096
hasso6452df02004-08-15 05:52:07 +000097 /* find previous LSA */
98 old = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
99 lsa->header->adv_router, lsa->lsdb);
hasso48454372004-05-18 19:14:52 +0000100
hasso6452df02004-08-15 05:52:07 +0000101 /* 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))
hasso48454372004-05-18 19:14:52 +0000104 {
hasso1e058382004-09-01 21:36:14 +0000105 if (IS_OSPF6_DEBUG_ORIGINATE_TYPE (lsa->header->type))
hassoc6487d62004-12-24 06:00:11 +0000106 zlog_debug ("Suppress updating LSA: %s", lsa->name);
hasso6452df02004-08-15 05:52:07 +0000107 ospf6_lsa_delete (lsa);
hasso48454372004-05-18 19:14:52 +0000108 return;
109 }
110
hasso6452df02004-08-15 05:52:07 +0000111 /* 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 LS_REFRESH_TIME);
117
hasso1e058382004-09-01 21:36:14 +0000118 if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type) ||
119 IS_OSPF6_DEBUG_ORIGINATE_TYPE (lsa->header->type))
hasso48454372004-05-18 19:14:52 +0000120 {
hassoc6487d62004-12-24 06:00:11 +0000121 zlog_debug ("LSA Originate:");
hasso6452df02004-08-15 05:52:07 +0000122 ospf6_lsa_header_print (lsa);
hasso48454372004-05-18 19:14:52 +0000123 }
124
hasso6452df02004-08-15 05:52:07 +0000125 if (old)
126 ospf6_flood_clear (old);
127 ospf6_flood (NULL, lsa);
128 ospf6_install_lsa (lsa);
129}
130
131void
132ospf6_lsa_originate_process (struct ospf6_lsa *lsa,
133 struct ospf6 *process)
134{
135 lsa->lsdb = process->lsdb;
136 ospf6_lsa_originate (lsa);
137}
138
139void
140ospf6_lsa_originate_area (struct ospf6_lsa *lsa,
141 struct ospf6_area *oa)
142{
143 lsa->lsdb = oa->lsdb;
144 ospf6_lsa_originate (lsa);
145}
146
147void
148ospf6_lsa_originate_interface (struct ospf6_lsa *lsa,
149 struct ospf6_interface *oi)
150{
151 lsa->lsdb = oi->lsdb;
152 ospf6_lsa_originate (lsa);
153}
154
155void
156ospf6_lsa_purge (struct ospf6_lsa *lsa)
157{
158 struct ospf6_lsa *self;
159 struct ospf6_lsdb *lsdb_self;
160
161 /* remove it from the LSDB for self-originated LSAs */
162 lsdb_self = ospf6_get_scoped_lsdb_self (lsa);
163 self = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
164 lsa->header->adv_router, lsdb_self);
165 if (self)
hasso48454372004-05-18 19:14:52 +0000166 {
hasso6452df02004-08-15 05:52:07 +0000167 THREAD_OFF (self->expire);
168 THREAD_OFF (self->refresh);
169 ospf6_lsdb_remove (self, lsdb_self);
hasso48454372004-05-18 19:14:52 +0000170 }
171
hasso6452df02004-08-15 05:52:07 +0000172 ospf6_lsa_premature_aging (lsa);
173}
174
175
176void
177ospf6_increment_retrans_count (struct ospf6_lsa *lsa)
178{
179 /* The LSA must be the original one (see the description
180 in ospf6_decrement_retrans_count () below) */
181 lsa->retrans_count++;
182}
183
184void
185ospf6_decrement_retrans_count (struct ospf6_lsa *lsa)
186{
187 struct ospf6_lsdb *lsdb;
188 struct ospf6_lsa *orig;
189
190 /* The LSA must be on the retrans-list of a neighbor. It means
191 the "lsa" is a copied one, and we have to decrement the
hasso1e058382004-09-01 21:36:14 +0000192 retransmission count of the original one (instead of this "lsa"'s).
hasso6452df02004-08-15 05:52:07 +0000193 In order to find the original LSA, first we have to find
194 appropriate LSDB that have the original LSA. */
195 lsdb = ospf6_get_scoped_lsdb (lsa);
196
197 /* Find the original LSA of which the retrans_count should be decremented */
198 orig = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
hasso1e058382004-09-01 21:36:14 +0000199 lsa->header->adv_router, lsdb);
hasso6452df02004-08-15 05:52:07 +0000200 if (orig)
hasso6861b302004-08-26 18:19:59 +0000201 {
202 orig->retrans_count--;
203 assert (orig->retrans_count >= 0);
204 }
hasso48454372004-05-18 19:14:52 +0000205}
206
207/* RFC2328 section 13.2 Installing LSAs in the database */
208void
hasso6452df02004-08-15 05:52:07 +0000209ospf6_install_lsa (struct ospf6_lsa *lsa)
hasso48454372004-05-18 19:14:52 +0000210{
211 struct ospf6_lsa *old;
hasso3b687352004-08-19 06:56:53 +0000212 struct timeval now;
hasso48454372004-05-18 19:14:52 +0000213
hasso1e058382004-09-01 21:36:14 +0000214 if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type) ||
215 IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
hassoc6487d62004-12-24 06:00:11 +0000216 zlog_debug ("Install LSA: %s", lsa->name);
hasso48454372004-05-18 19:14:52 +0000217
218 /* Remove the old instance from all neighbors' Link state
219 retransmission list (RFC2328 13.2 last paragraph) */
220 old = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
hasso6452df02004-08-15 05:52:07 +0000221 lsa->header->adv_router, lsa->lsdb);
hasso48454372004-05-18 19:14:52 +0000222 if (old)
hasso3b687352004-08-19 06:56:53 +0000223 {
224 THREAD_OFF (old->expire);
225 ospf6_flood_clear (old);
226 }
227
228 gettimeofday (&now, (struct timezone *) NULL);
hassoccb59b12004-08-25 09:10:37 +0000229 if (! OSPF6_LSA_IS_MAXAGE (lsa))
hasso3b687352004-08-19 06:56:53 +0000230 lsa->expire = thread_add_timer (master, ospf6_lsa_expire, lsa,
231 MAXAGE + lsa->birth.tv_sec - now.tv_sec);
232 else
233 lsa->expire = NULL;
hasso48454372004-05-18 19:14:52 +0000234
235 /* actually install */
hasso3b687352004-08-19 06:56:53 +0000236 lsa->installed = now;
hasso6452df02004-08-15 05:52:07 +0000237 ospf6_lsdb_add (lsa, lsa->lsdb);
hasso48454372004-05-18 19:14:52 +0000238
239 return;
240}
241
hasso6452df02004-08-15 05:52:07 +0000242/* RFC2740 section 3.5.2. Sending Link State Update packets */
hasso48454372004-05-18 19:14:52 +0000243/* RFC2328 section 13.3 Next step in the flooding procedure */
244void
hasso6452df02004-08-15 05:52:07 +0000245ospf6_flood_interface (struct ospf6_neighbor *from,
246 struct ospf6_lsa *lsa, struct ospf6_interface *oi)
hasso48454372004-05-18 19:14:52 +0000247{
hasso52dc7ee2004-09-23 19:18:23 +0000248 struct listnode *node;
hasso48454372004-05-18 19:14:52 +0000249 struct ospf6_neighbor *on;
hasso48454372004-05-18 19:14:52 +0000250 struct ospf6_lsa *req;
251 int retrans_added = 0;
hasso1e058382004-09-01 21:36:14 +0000252 int is_debug = 0;
hasso48454372004-05-18 19:14:52 +0000253
hasso1e058382004-09-01 21:36:14 +0000254 if (IS_OSPF6_DEBUG_FLOODING ||
255 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
256 {
257 is_debug++;
hassoc6487d62004-12-24 06:00:11 +0000258 zlog_debug ("Flooding on %s: %s", oi->interface->name, lsa->name);
hasso1e058382004-09-01 21:36:14 +0000259 }
hasso48454372004-05-18 19:14:52 +0000260
hasso6452df02004-08-15 05:52:07 +0000261 /* (1) For each neighbor */
262 for (node = listhead (oi->neighbor_list); node; nextnode (node))
hasso48454372004-05-18 19:14:52 +0000263 {
hasso6452df02004-08-15 05:52:07 +0000264 on = (struct ospf6_neighbor *) getdata (node);
hasso48454372004-05-18 19:14:52 +0000265
hasso1e058382004-09-01 21:36:14 +0000266 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000267 zlog_debug ("To neighbor %s", on->name);
hasso6452df02004-08-15 05:52:07 +0000268
269 /* (a) if neighbor state < Exchange, examin next */
270 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
hasso48454372004-05-18 19:14:52 +0000271 {
hasso1e058382004-09-01 21:36:14 +0000272 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000273 zlog_debug ("Neighbor state less than ExChange, next neighbor");
hasso6452df02004-08-15 05:52:07 +0000274 continue;
hasso48454372004-05-18 19:14:52 +0000275 }
hasso48454372004-05-18 19:14:52 +0000276
hasso6452df02004-08-15 05:52:07 +0000277 /* (b) if neighbor not yet Full, check request-list */
278 if (on->state != OSPF6_NEIGHBOR_FULL)
hasso48454372004-05-18 19:14:52 +0000279 {
hasso1e058382004-09-01 21:36:14 +0000280 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000281 zlog_debug ("Neighbor not yet Full");
hasso48454372004-05-18 19:14:52 +0000282
hasso6452df02004-08-15 05:52:07 +0000283 req = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
284 lsa->header->adv_router, on->request_list);
285 if (req == NULL)
hasso48454372004-05-18 19:14:52 +0000286 {
hasso1e058382004-09-01 21:36:14 +0000287 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000288 zlog_debug ("Not on request-list for this neighbor");
hasso6452df02004-08-15 05:52:07 +0000289 /* fall through */
290 }
291 else
292 {
293 /* If new LSA less recent, examin next neighbor */
294 if (ospf6_lsa_compare (lsa, req) > 0)
hasso48454372004-05-18 19:14:52 +0000295 {
hasso1e058382004-09-01 21:36:14 +0000296 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000297 zlog_debug ("Requesting is newer, next neighbor");
hasso6452df02004-08-15 05:52:07 +0000298 continue;
299 }
hasso48454372004-05-18 19:14:52 +0000300
hasso6452df02004-08-15 05:52:07 +0000301 /* If the same instance, delete from request-list and
302 examin next neighbor */
303 if (ospf6_lsa_compare (lsa, req) == 0)
304 {
hasso1e058382004-09-01 21:36:14 +0000305 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000306 zlog_debug ("Requesting the same, remove it, next neighbor");
hasso6452df02004-08-15 05:52:07 +0000307 ospf6_lsdb_remove (req, on->request_list);
308 continue;
309 }
hasso48454372004-05-18 19:14:52 +0000310
hasso6452df02004-08-15 05:52:07 +0000311 /* If the new LSA is more recent, delete from request-list */
312 if (ospf6_lsa_compare (lsa, req) < 0)
313 {
hasso1e058382004-09-01 21:36:14 +0000314 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000315 zlog_debug ("Received is newer, remove requesting");
hasso6452df02004-08-15 05:52:07 +0000316 ospf6_lsdb_remove (req, on->request_list);
317 /* fall through */
hasso48454372004-05-18 19:14:52 +0000318 }
319 }
hasso48454372004-05-18 19:14:52 +0000320 }
321
hasso6452df02004-08-15 05:52:07 +0000322 /* (c) If the new LSA was received from this neighbor,
323 examin next neighbor */
324 if (from == on)
hasso48454372004-05-18 19:14:52 +0000325 {
hasso1e058382004-09-01 21:36:14 +0000326 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000327 zlog_debug ("Received is from the neighbor, next neighbor");
hasso6452df02004-08-15 05:52:07 +0000328 continue;
hasso48454372004-05-18 19:14:52 +0000329 }
hasso6452df02004-08-15 05:52:07 +0000330
331 /* (d) add retrans-list, schedule retransmission */
hasso1e058382004-09-01 21:36:14 +0000332 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000333 zlog_debug ("Add retrans-list of this neighbor");
hasso6452df02004-08-15 05:52:07 +0000334 ospf6_increment_retrans_count (lsa);
335 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
336 if (on->thread_send_lsupdate == NULL)
337 on->thread_send_lsupdate =
gdt6639a042004-11-05 18:42:27 +0000338 thread_add_timer (master, ospf6_lsupdate_send_neighbor,
hasso6452df02004-08-15 05:52:07 +0000339 on, on->ospf6_if->rxmt_interval);
340 retrans_added++;
hasso48454372004-05-18 19:14:52 +0000341 }
342
hasso6452df02004-08-15 05:52:07 +0000343 /* (2) examin next interface if not added to retrans-list */
344 if (retrans_added == 0)
345 {
hasso1e058382004-09-01 21:36:14 +0000346 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000347 zlog_debug ("No retransmission scheduled, next interface");
hasso6452df02004-08-15 05:52:07 +0000348 return;
349 }
350
351 /* (3) If the new LSA was received on this interface,
352 and it was from DR or BDR, examin next interface */
353 if (from && from->ospf6_if == oi &&
354 (from->router_id == oi->drouter || from->router_id == oi->bdrouter))
355 {
hasso1e058382004-09-01 21:36:14 +0000356 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000357 zlog_debug ("Received is from the I/F's DR or BDR, next interface");
hasso6452df02004-08-15 05:52:07 +0000358 return;
359 }
360
361 /* (4) If the new LSA was received on this interface,
362 and the interface state is BDR, examin next interface */
363 if (from && from->ospf6_if == oi && oi->state == OSPF6_INTERFACE_BDR)
364 {
hasso1e058382004-09-01 21:36:14 +0000365 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000366 zlog_debug ("Received is from the I/F, itself BDR, next interface");
hasso6452df02004-08-15 05:52:07 +0000367 return;
368 }
369
370 /* (5) flood the LSA out the interface. */
hasso1e058382004-09-01 21:36:14 +0000371 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000372 zlog_debug ("Schedule flooding for the interface");
hasso6452df02004-08-15 05:52:07 +0000373 if (if_is_broadcast (oi->interface))
374 {
375 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list);
376 if (oi->thread_send_lsupdate == NULL)
377 oi->thread_send_lsupdate =
378 thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
379 }
380 else
381 {
382 /* reschedule retransmissions to all neighbors */
383 for (node = listhead (oi->neighbor_list); node; nextnode (node))
384 {
385 on = (struct ospf6_neighbor *) getdata (node);
386 THREAD_OFF (on->thread_send_lsupdate);
387 on->thread_send_lsupdate =
388 thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
389 }
390 }
hasso48454372004-05-18 19:14:52 +0000391}
392
hasso6452df02004-08-15 05:52:07 +0000393void
394ospf6_flood_area (struct ospf6_neighbor *from,
395 struct ospf6_lsa *lsa, struct ospf6_area *oa)
396{
hasso52dc7ee2004-09-23 19:18:23 +0000397 struct listnode *node;
hasso6452df02004-08-15 05:52:07 +0000398 struct ospf6_interface *oi;
399
400 for (node = listhead (oa->if_list); node; nextnode (node))
401 {
402 oi = OSPF6_INTERFACE (getdata (node));
403
404 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
405 oi != OSPF6_INTERFACE (lsa->lsdb->data))
406 continue;
407
408#if 0
409 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
410 ospf6_is_interface_virtual_link (oi))
411 continue;
412#endif/*0*/
413
414 ospf6_flood_interface (from, lsa, oi);
415 }
416}
417
418void
419ospf6_flood_process (struct ospf6_neighbor *from,
420 struct ospf6_lsa *lsa, struct ospf6 *process)
421{
hasso52dc7ee2004-09-23 19:18:23 +0000422 struct listnode *node;
hasso6452df02004-08-15 05:52:07 +0000423 struct ospf6_area *oa;
424
425 for (node = listhead (process->area_list); node; nextnode (node))
426 {
427 oa = OSPF6_AREA (getdata (node));
428
429 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
430 oa != OSPF6_AREA (lsa->lsdb->data))
431 continue;
432 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
433 oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
434 continue;
435
436 if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
437 IS_AREA_STUB (oa))
438 continue;
439
440 ospf6_flood_area (from, lsa, oa);
441 }
442}
443
444void
445ospf6_flood (struct ospf6_neighbor *from, struct ospf6_lsa *lsa)
446{
447 ospf6_flood_process (from, lsa, ospf6);
448}
449
450void
451ospf6_flood_clear_interface (struct ospf6_lsa *lsa, struct ospf6_interface *oi)
452{
hasso52dc7ee2004-09-23 19:18:23 +0000453 struct listnode *node;
hasso6452df02004-08-15 05:52:07 +0000454 struct ospf6_neighbor *on;
455 struct ospf6_lsa *rem;
456
457 for (node = listhead (oi->neighbor_list); node; nextnode (node))
458 {
459 on = OSPF6_NEIGHBOR (getdata (node));
460 rem = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
461 lsa->header->adv_router, on->retrans_list);
462 if (rem && ! ospf6_lsa_compare (rem, lsa))
463 {
hasso1e058382004-09-01 21:36:14 +0000464 if (IS_OSPF6_DEBUG_FLOODING ||
465 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
hassoc6487d62004-12-24 06:00:11 +0000466 zlog_debug ("Remove %s from retrans_list of %s",
hasso6452df02004-08-15 05:52:07 +0000467 rem->name, on->name);
468 ospf6_decrement_retrans_count (rem);
469 ospf6_lsdb_remove (rem, on->retrans_list);
470 }
471 }
472}
473
474void
475ospf6_flood_clear_area (struct ospf6_lsa *lsa, struct ospf6_area *oa)
476{
hasso52dc7ee2004-09-23 19:18:23 +0000477 struct listnode *node;
hasso6452df02004-08-15 05:52:07 +0000478 struct ospf6_interface *oi;
479
480 for (node = listhead (oa->if_list); node; nextnode (node))
481 {
482 oi = OSPF6_INTERFACE (getdata (node));
483
484 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
485 oi != OSPF6_INTERFACE (lsa->lsdb->data))
486 continue;
487
488#if 0
489 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
490 ospf6_is_interface_virtual_link (oi))
491 continue;
492#endif/*0*/
493
494 ospf6_flood_clear_interface (lsa, oi);
495 }
496}
497
498void
499ospf6_flood_clear_process (struct ospf6_lsa *lsa, struct ospf6 *process)
500{
hasso52dc7ee2004-09-23 19:18:23 +0000501 struct listnode *node;
hasso6452df02004-08-15 05:52:07 +0000502 struct ospf6_area *oa;
503
504 for (node = listhead (process->area_list); node; nextnode (node))
505 {
506 oa = OSPF6_AREA (getdata (node));
507
508 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
509 oa != OSPF6_AREA (lsa->lsdb->data))
510 continue;
511 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
512 oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
513 continue;
514
515 if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
516 IS_AREA_STUB (oa))
517 continue;
518
519 ospf6_flood_clear_area (lsa, oa);
520 }
521}
522
523void
524ospf6_flood_clear (struct ospf6_lsa *lsa)
525{
526 ospf6_flood_clear_process (lsa, ospf6);
527}
528
529
hasso48454372004-05-18 19:14:52 +0000530/* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
531static void
532ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
533 struct ospf6_neighbor *from)
534{
535 struct ospf6_interface *oi;
hasso1e058382004-09-01 21:36:14 +0000536 int is_debug = 0;
537
538 if (IS_OSPF6_DEBUG_FLOODING ||
539 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
540 is_debug++;
hasso48454372004-05-18 19:14:52 +0000541
542 assert (from && from->ospf6_if);
543 oi = from->ospf6_if;
544
545 /* LSA has been flood back out receiving interface.
546 No acknowledgement sent. */
547 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
548 {
hasso1e058382004-09-01 21:36:14 +0000549 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000550 zlog_debug ("No acknowledgement (BDR & FloodBack)");
hasso48454372004-05-18 19:14:52 +0000551 return;
552 }
553
554 /* LSA is more recent than database copy, but was not flooded
555 back out receiving interface. Delayed acknowledgement sent
556 if advertisement received from Designated Router,
557 otherwide do nothing. */
558 if (ismore_recent < 0)
559 {
hasso48454372004-05-18 19:14:52 +0000560 if (oi->drouter == from->router_id)
561 {
hasso1e058382004-09-01 21:36:14 +0000562 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000563 zlog_debug ("Delayed acknowledgement (BDR & MoreRecent & from DR)");
hasso48454372004-05-18 19:14:52 +0000564 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000565 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
566 if (oi->thread_send_lsack == NULL)
567 oi->thread_send_lsack =
568 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
569 }
570 else
571 {
hasso1e058382004-09-01 21:36:14 +0000572 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000573 zlog_debug ("No acknowledgement (BDR & MoreRecent & ! from DR)");
hasso48454372004-05-18 19:14:52 +0000574 }
575 return;
576 }
577
578 /* LSA is a duplicate, and was treated as an implied acknowledgement.
579 Delayed acknowledgement sent if advertisement received from
580 Designated Router, otherwise do nothing */
581 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
582 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
583 {
hasso48454372004-05-18 19:14:52 +0000584 if (oi->drouter == from->router_id)
585 {
hasso1e058382004-09-01 21:36:14 +0000586 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000587 zlog_debug ("Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
hasso48454372004-05-18 19:14:52 +0000588 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000589 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
590 if (oi->thread_send_lsack == NULL)
591 oi->thread_send_lsack =
592 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
593 }
594 else
595 {
hasso1e058382004-09-01 21:36:14 +0000596 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000597 zlog_debug ("No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
hasso48454372004-05-18 19:14:52 +0000598 }
599 return;
600 }
601
602 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
603 Direct acknowledgement sent */
604 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
605 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
606 {
hasso1e058382004-09-01 21:36:14 +0000607 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000608 zlog_debug ("Direct acknowledgement (BDR & Duplicate)");
hasso48454372004-05-18 19:14:52 +0000609 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
610 if (from->thread_send_lsack == NULL)
611 from->thread_send_lsack =
612 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
613 return;
614 }
615
616 /* LSA's LS age is equal to Maxage, and there is no current instance
617 of the LSA in the link state database, and none of router's
618 neighbors are in states Exchange or Loading */
619 /* Direct acknowledgement sent, but this case is handled in
620 early of ospf6_receive_lsa () */
621}
622
623static void
624ospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent,
625 struct ospf6_neighbor *from)
626{
627 struct ospf6_interface *oi;
hasso1e058382004-09-01 21:36:14 +0000628 int is_debug = 0;
629
630 if (IS_OSPF6_DEBUG_FLOODING ||
631 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
632 is_debug++;
hasso48454372004-05-18 19:14:52 +0000633
634 assert (from && from->ospf6_if);
635 oi = from->ospf6_if;
636
637 /* LSA has been flood back out receiving interface.
638 No acknowledgement sent. */
639 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
640 {
hasso1e058382004-09-01 21:36:14 +0000641 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000642 zlog_debug ("No acknowledgement (AllOther & FloodBack)");
hasso48454372004-05-18 19:14:52 +0000643 return;
644 }
645
646 /* LSA is more recent than database copy, but was not flooded
647 back out receiving interface. Delayed acknowledgement sent. */
648 if (ismore_recent < 0)
649 {
hasso1e058382004-09-01 21:36:14 +0000650 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000651 zlog_debug ("Delayed acknowledgement (AllOther & MoreRecent)");
hasso48454372004-05-18 19:14:52 +0000652 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000653 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
654 if (oi->thread_send_lsack == NULL)
655 oi->thread_send_lsack =
656 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
657 return;
658 }
659
660 /* LSA is a duplicate, and was treated as an implied acknowledgement.
661 No acknowledgement sent. */
662 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
663 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
664 {
hasso1e058382004-09-01 21:36:14 +0000665 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000666 zlog_debug ("No acknowledgement (AllOther & Duplicate & ImpliedAck)");
hasso48454372004-05-18 19:14:52 +0000667 return;
668 }
669
670 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
671 Direct acknowledgement sent */
672 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
673 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
674 {
hasso1e058382004-09-01 21:36:14 +0000675 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000676 zlog_debug ("Direct acknowledgement (AllOther & Duplicate)");
hasso48454372004-05-18 19:14:52 +0000677 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
678 if (from->thread_send_lsack == NULL)
679 from->thread_send_lsack =
680 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
681 return;
682 }
683
684 /* LSA's LS age is equal to Maxage, and there is no current instance
685 of the LSA in the link state database, and none of router's
686 neighbors are in states Exchange or Loading */
687 /* Direct acknowledgement sent, but this case is handled in
688 early of ospf6_receive_lsa () */
689}
690
691void
692ospf6_acknowledge_lsa (struct ospf6_lsa *lsa, int ismore_recent,
693 struct ospf6_neighbor *from)
694{
695 struct ospf6_interface *oi;
696
697 assert (from && from->ospf6_if);
698 oi = from->ospf6_if;
699
700 if (oi->state == OSPF6_INTERFACE_BDR)
701 ospf6_acknowledge_lsa_bdrouter (lsa, ismore_recent, from);
702 else
703 ospf6_acknowledge_lsa_allother (lsa, ismore_recent, from);
704}
705
706/* RFC2328 section 13 (4):
707 if MaxAge LSA and if we have no instance, and no neighbor
708 is in states Exchange or Loading
709 returns 1 if match this case, else returns 0 */
710static int
hasso6452df02004-08-15 05:52:07 +0000711ospf6_is_maxage_lsa_drop (struct ospf6_lsa *lsa, struct ospf6_neighbor *from)
hasso48454372004-05-18 19:14:52 +0000712{
hasso48454372004-05-18 19:14:52 +0000713 struct ospf6_neighbor *on;
hasso6452df02004-08-15 05:52:07 +0000714 struct ospf6_interface *oi;
715 struct ospf6_area *oa;
716 struct ospf6 *process = NULL;
hasso52dc7ee2004-09-23 19:18:23 +0000717 struct listnode *i, *j, *k;
hasso48454372004-05-18 19:14:52 +0000718 int count = 0;
719
720 if (! OSPF6_LSA_IS_MAXAGE (lsa))
721 return 0;
722
hasso48454372004-05-18 19:14:52 +0000723 if (ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
hasso6452df02004-08-15 05:52:07 +0000724 lsa->header->adv_router, lsa->lsdb))
hasso48454372004-05-18 19:14:52 +0000725 return 0;
726
hasso6452df02004-08-15 05:52:07 +0000727 process = from->ospf6_if->area->ospf6;
728 for (i = listhead (process->area_list); i; nextnode (i))
hasso48454372004-05-18 19:14:52 +0000729 {
hasso6452df02004-08-15 05:52:07 +0000730 oa = OSPF6_AREA (getdata (i));
hasso48454372004-05-18 19:14:52 +0000731 for (j = listhead (oa->if_list); j; nextnode (j))
732 {
hasso6452df02004-08-15 05:52:07 +0000733 oi = OSPF6_INTERFACE (getdata (j));
734 for (k = listhead (oi->neighbor_list); k; nextnode (k))
735 {
736 on = OSPF6_NEIGHBOR (getdata (k));
737 if (on->state == OSPF6_NEIGHBOR_EXCHANGE ||
738 on->state == OSPF6_NEIGHBOR_LOADING)
739 count++;
740 }
hasso48454372004-05-18 19:14:52 +0000741 }
742 }
743
hasso48454372004-05-18 19:14:52 +0000744 if (count == 0)
745 return 1;
hasso48454372004-05-18 19:14:52 +0000746 return 0;
747}
748
749/* RFC2328 section 13 The Flooding Procedure */
750void
hasso6452df02004-08-15 05:52:07 +0000751ospf6_receive_lsa (struct ospf6_neighbor *from,
752 struct ospf6_lsa_header *lsa_header)
hasso48454372004-05-18 19:14:52 +0000753{
754 struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
755 int ismore_recent;
756 unsigned short cksum;
hasso1e058382004-09-01 21:36:14 +0000757 int is_debug = 0;
hasso48454372004-05-18 19:14:52 +0000758
759 ismore_recent = 1;
hasso6452df02004-08-15 05:52:07 +0000760 assert (from);
hasso48454372004-05-18 19:14:52 +0000761
762 /* make lsa structure for received lsa */
763 new = ospf6_lsa_create (lsa_header);
764
hasso1e058382004-09-01 21:36:14 +0000765 if (IS_OSPF6_DEBUG_FLOODING ||
766 IS_OSPF6_DEBUG_FLOOD_TYPE (new->header->type))
hasso48454372004-05-18 19:14:52 +0000767 {
hasso1e058382004-09-01 21:36:14 +0000768 is_debug++;
hassoc6487d62004-12-24 06:00:11 +0000769 zlog_debug ("LSA Receive from %s", from->name);
hasso48454372004-05-18 19:14:52 +0000770 ospf6_lsa_header_print (new);
771 }
772
hasso48454372004-05-18 19:14:52 +0000773 /* (1) LSA Checksum */
774 cksum = ntohs (new->header->checksum);
775 if (ntohs (ospf6_lsa_checksum (new->header)) != cksum)
776 {
hasso1e058382004-09-01 21:36:14 +0000777 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000778 zlog_debug ("Wrong LSA Checksum, discard");
hasso48454372004-05-18 19:14:52 +0000779 ospf6_lsa_delete (new);
780 return;
781 }
782
hasso6452df02004-08-15 05:52:07 +0000783 /* (2) Examine the LSA's LS type.
784 RFC2470 3.5.1. Receiving Link State Update packets */
785 if (IS_AREA_STUB (from->ospf6_if->area) &&
786 OSPF6_LSA_SCOPE (new->header->type) == OSPF6_SCOPE_AS)
hasso48454372004-05-18 19:14:52 +0000787 {
hasso1e058382004-09-01 21:36:14 +0000788 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000789 zlog_debug ("AS-External-LSA (or AS-scope LSA) in stub area, discard");
hasso6452df02004-08-15 05:52:07 +0000790 ospf6_lsa_delete (new);
791 return;
792 }
793
794 /* (3) LSA which have reserved scope is discarded
795 RFC2470 3.5.1. Receiving Link State Update packets */
796 /* Flooding scope check. LSAs with unknown scope are discarded here.
797 Set appropriate LSDB for the LSA */
798 switch (OSPF6_LSA_SCOPE (new->header->type))
799 {
800 case OSPF6_SCOPE_LINKLOCAL:
801 new->lsdb = from->ospf6_if->lsdb;
802 break;
803 case OSPF6_SCOPE_AREA:
804 new->lsdb = from->ospf6_if->area->lsdb;
805 break;
806 case OSPF6_SCOPE_AS:
807 new->lsdb = from->ospf6_if->area->ospf6->lsdb;
808 break;
809 default:
hasso1e058382004-09-01 21:36:14 +0000810 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000811 zlog_debug ("LSA has reserved scope, discard");
hasso48454372004-05-18 19:14:52 +0000812 ospf6_lsa_delete (new);
813 return;
814 }
815
816 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
817 is in states Exchange or Loading */
818 if (ospf6_is_maxage_lsa_drop (new, from))
819 {
820 /* log */
hasso1e058382004-09-01 21:36:14 +0000821 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000822 zlog_debug ("Drop MaxAge LSA with direct acknowledgement.");
hasso48454372004-05-18 19:14:52 +0000823
824 /* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */
hasso6452df02004-08-15 05:52:07 +0000825 ospf6_lsdb_add (ospf6_lsa_copy (new), from->lsack_list);
hasso48454372004-05-18 19:14:52 +0000826 if (from->thread_send_lsack == NULL)
827 from->thread_send_lsack =
828 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
829
830 /* b) Discard */
hasso6452df02004-08-15 05:52:07 +0000831 ospf6_lsa_delete (new);
hasso48454372004-05-18 19:14:52 +0000832 return;
833 }
834
835 /* (5) */
836 /* lookup the same database copy in lsdb */
hasso48454372004-05-18 19:14:52 +0000837 old = ospf6_lsdb_lookup (new->header->type, new->header->id,
hasso6452df02004-08-15 05:52:07 +0000838 new->header->adv_router, new->lsdb);
hasso48454372004-05-18 19:14:52 +0000839 if (old)
840 {
841 ismore_recent = ospf6_lsa_compare (new, old);
842 if (ntohl (new->header->seqnum) == ntohl (old->header->seqnum))
843 {
hasso1e058382004-09-01 21:36:14 +0000844 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000845 zlog_debug ("Received is duplicated LSA");
hasso48454372004-05-18 19:14:52 +0000846 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 gettimeofday (&now, (struct timezone *) NULL);
861 timersub (&now, &old->installed, &res);
862 if (res.tv_sec < MIN_LS_ARRIVAL)
863 {
hasso1e058382004-09-01 21:36:14 +0000864 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000865 zlog_debug ("LSA can't be updated within MinLSArrival, discard");
hasso48454372004-05-18 19:14:52 +0000866 ospf6_lsa_delete (new);
867 return; /* examin next lsa */
868 }
869 }
870
hassoccb59b12004-08-25 09:10:37 +0000871 gettimeofday (&new->received, (struct timezone *) NULL);
872
hasso1e058382004-09-01 21:36:14 +0000873 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000874 zlog_debug ("Flood, Install, Possibly acknowledge the received LSA");
hasso6452df02004-08-15 05:52:07 +0000875
hasso48454372004-05-18 19:14:52 +0000876 /* (b) immediately flood and (c) remove from all retrans-list */
hassoccb59b12004-08-25 09:10:37 +0000877 /* Prevent self-originated LSA to be flooded. this is to make
878 reoriginated instance of the LSA not to be rejected by other routers
879 due to MinLSArrival. */
880 if (new->header->adv_router != from->ospf6_if->area->ospf6->router_id)
881 ospf6_flood (from, new);
hasso6452df02004-08-15 05:52:07 +0000882
883 /* (c) Remove the current database copy from all neighbors' Link
884 state retransmission lists. */
885 /* XXX, flood_clear ? */
hasso48454372004-05-18 19:14:52 +0000886
887 /* (d), installing lsdb, which may cause routing
888 table calculation (replacing database copy) */
hasso6452df02004-08-15 05:52:07 +0000889 ospf6_install_lsa (new);
hasso48454372004-05-18 19:14:52 +0000890
891 /* (e) possibly acknowledge */
892 ospf6_acknowledge_lsa (new, ismore_recent, from);
893
hasso6452df02004-08-15 05:52:07 +0000894 /* (f) Self Originated LSA, section 13.4 */
895 if (new->header->adv_router == from->ospf6_if->area->ospf6->router_id)
hasso48454372004-05-18 19:14:52 +0000896 {
hasso6452df02004-08-15 05:52:07 +0000897 /* Self-originated LSA (newer than ours) is received from
898 another router. We have to make a new instance of the LSA
hasso48454372004-05-18 19:14:52 +0000899 or have to flush this LSA. */
hasso1e058382004-09-01 21:36:14 +0000900 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000901 {
hassoc6487d62004-12-24 06:00:11 +0000902 zlog_debug ("Newer instance of the self-originated LSA");
903 zlog_debug ("Schedule reorigination");
hasso6452df02004-08-15 05:52:07 +0000904 }
905 new->refresh = thread_add_event (master, ospf6_lsa_refresh, new, 0);
hasso48454372004-05-18 19:14:52 +0000906 }
hasso6452df02004-08-15 05:52:07 +0000907
hasso48454372004-05-18 19:14:52 +0000908 return;
909 }
910
911 /* (6) if there is instance on sending neighbor's request list */
912 if (ospf6_lsdb_lookup (new->header->type, new->header->id,
913 new->header->adv_router, from->request_list))
914 {
915 /* if no database copy, should go above state (5) */
916 assert (old);
917
hasso1e058382004-09-01 21:36:14 +0000918 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000919 {
hassoc6487d62004-12-24 06:00:11 +0000920 zlog_debug ("Received is not newer, on the neighbor's request-list");
921 zlog_debug ("BadLSReq, discard the received LSA");
hasso6452df02004-08-15 05:52:07 +0000922 }
hasso48454372004-05-18 19:14:52 +0000923
924 /* BadLSReq */
925 thread_add_event (master, bad_lsreq, from, 0);
926
927 ospf6_lsa_delete (new);
928 return;
929 }
930
931 /* (7) if neither one is more recent */
932 if (ismore_recent == 0)
933 {
hasso1e058382004-09-01 21:36:14 +0000934 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000935 zlog_debug ("The same instance as database copy (neither recent)");
hasso48454372004-05-18 19:14:52 +0000936
937 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack */
938 rem = ospf6_lsdb_lookup (new->header->type, new->header->id,
939 new->header->adv_router, from->retrans_list);
940 if (rem)
941 {
hasso1e058382004-09-01 21:36:14 +0000942 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000943 {
hassoc6487d62004-12-24 06:00:11 +0000944 zlog_debug ("It is on the neighbor's retrans-list.");
945 zlog_debug ("Treat as an Implied acknowledgement");
hasso6452df02004-08-15 05:52:07 +0000946 }
hasso48454372004-05-18 19:14:52 +0000947 SET_FLAG (new->flag, OSPF6_LSA_IMPLIEDACK);
hasso6452df02004-08-15 05:52:07 +0000948 ospf6_decrement_retrans_count (rem);
hasso48454372004-05-18 19:14:52 +0000949 ospf6_lsdb_remove (rem, from->retrans_list);
950 }
951
hasso1e058382004-09-01 21:36:14 +0000952 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000953 zlog_debug ("Possibly acknowledge and then discard");
hasso6452df02004-08-15 05:52:07 +0000954
hasso48454372004-05-18 19:14:52 +0000955 /* (b) possibly acknowledge */
956 ospf6_acknowledge_lsa (new, ismore_recent, from);
957
958 ospf6_lsa_delete (new);
959 return;
960 }
961
962 /* (8) previous database copy is more recent */
963 {
964 assert (old);
965
966 /* If database copy is in 'Seqnumber Wrapping',
967 simply discard the received LSA */
968 if (OSPF6_LSA_IS_MAXAGE (old) &&
969 old->header->seqnum == htonl (MAX_SEQUENCE_NUMBER))
970 {
hasso1e058382004-09-01 21:36:14 +0000971 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000972 {
hassoc6487d62004-12-24 06:00:11 +0000973 zlog_debug ("The LSA is in Seqnumber Wrapping");
974 zlog_debug ("MaxAge & MaxSeqNum, discard");
hasso6452df02004-08-15 05:52:07 +0000975 }
hasso48454372004-05-18 19:14:52 +0000976 ospf6_lsa_delete (new);
977 return;
978 }
979
980 /* Otherwise, Send database copy of this LSA to this neighbor */
981 {
hasso1e058382004-09-01 21:36:14 +0000982 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000983 {
hassoc6487d62004-12-24 06:00:11 +0000984 zlog_debug ("Database copy is more recent.");
985 zlog_debug ("Send back directly and then discard");
hasso6452df02004-08-15 05:52:07 +0000986 }
hasso48454372004-05-18 19:14:52 +0000987
988 /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
989
hasso48454372004-05-18 19:14:52 +0000990 ospf6_lsdb_add (ospf6_lsa_copy (old), from->lsupdate_list);
991 if (from->thread_send_lsupdate == NULL)
992 from->thread_send_lsupdate =
993 thread_add_event (master, ospf6_lsupdate_send_neighbor, from, 0);
994 ospf6_lsa_delete (new);
995 return;
996 }
997 return;
998 }
999}
1000
1001
hasso1e058382004-09-01 21:36:14 +00001002DEFUN (debug_ospf6_flooding,
1003 debug_ospf6_flooding_cmd,
1004 "debug ospf6 flooding",
1005 DEBUG_STR
1006 OSPF6_STR
1007 "Debug OSPFv3 flooding function\n"
1008 )
1009{
1010 OSPF6_DEBUG_FLOODING_ON ();
1011 return CMD_SUCCESS;
1012}
1013
1014DEFUN (no_debug_ospf6_flooding,
1015 no_debug_ospf6_flooding_cmd,
1016 "no debug ospf6 flooding",
1017 NO_STR
1018 DEBUG_STR
1019 OSPF6_STR
1020 "Debug OSPFv3 flooding function\n"
1021 )
1022{
1023 OSPF6_DEBUG_FLOODING_OFF ();
1024 return CMD_SUCCESS;
1025}
1026
1027int
1028config_write_ospf6_debug_flood (struct vty *vty)
1029{
1030 if (IS_OSPF6_DEBUG_FLOODING)
1031 vty_out (vty, "debug ospf6 flooding%s", VNL);
1032 return 0;
1033}
1034
1035void
1036install_element_ospf6_debug_flood ()
1037{
1038 install_element (ENABLE_NODE, &debug_ospf6_flooding_cmd);
1039 install_element (ENABLE_NODE, &no_debug_ospf6_flooding_cmd);
1040 install_element (CONFIG_NODE, &debug_ospf6_flooding_cmd);
1041 install_element (CONFIG_NODE, &no_debug_ospf6_flooding_cmd);
1042}
1043
1044
1045
1046
hasso48454372004-05-18 19:14:52 +00001047