blob: 3a9af01d9cf6dd94653508fa2e019200f7d45522 [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,
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700116 OSPF_LS_REFRESH_TIME);
hasso6452df02004-08-15 05:52:07 +0000117
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
Takashi Sogabe86f72dc2009-06-22 13:07:02 +0900228 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
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,
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700231 OSPF_LSA_MAXAGE + lsa->birth.tv_sec - now.tv_sec);
hasso3b687352004-08-19 06:56:53 +0000232 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 */
Paul Jakma6ac29a52008-08-15 13:45:30 +0100244static void
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{
paul1eb8ef22005-04-07 07:30:20 +0000248 struct listnode *node, *nnode;
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 */
paul1eb8ef22005-04-07 07:30:20 +0000262 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
hasso48454372004-05-18 19:14:52 +0000263 {
hasso1e058382004-09-01 21:36:14 +0000264 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000265 zlog_debug ("To neighbor %s", on->name);
hasso6452df02004-08-15 05:52:07 +0000266
267 /* (a) if neighbor state < Exchange, examin next */
268 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
hasso48454372004-05-18 19:14:52 +0000269 {
hasso1e058382004-09-01 21:36:14 +0000270 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000271 zlog_debug ("Neighbor state less than ExChange, next neighbor");
hasso6452df02004-08-15 05:52:07 +0000272 continue;
hasso48454372004-05-18 19:14:52 +0000273 }
hasso48454372004-05-18 19:14:52 +0000274
hasso6452df02004-08-15 05:52:07 +0000275 /* (b) if neighbor not yet Full, check request-list */
276 if (on->state != OSPF6_NEIGHBOR_FULL)
hasso48454372004-05-18 19:14:52 +0000277 {
hasso1e058382004-09-01 21:36:14 +0000278 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000279 zlog_debug ("Neighbor not yet Full");
hasso48454372004-05-18 19:14:52 +0000280
hasso6452df02004-08-15 05:52:07 +0000281 req = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
282 lsa->header->adv_router, on->request_list);
283 if (req == NULL)
hasso48454372004-05-18 19:14:52 +0000284 {
hasso1e058382004-09-01 21:36:14 +0000285 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000286 zlog_debug ("Not on request-list for this neighbor");
hasso6452df02004-08-15 05:52:07 +0000287 /* fall through */
288 }
289 else
290 {
291 /* If new LSA less recent, examin next neighbor */
292 if (ospf6_lsa_compare (lsa, req) > 0)
hasso48454372004-05-18 19:14:52 +0000293 {
hasso1e058382004-09-01 21:36:14 +0000294 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000295 zlog_debug ("Requesting is newer, next neighbor");
hasso6452df02004-08-15 05:52:07 +0000296 continue;
297 }
hasso48454372004-05-18 19:14:52 +0000298
hasso6452df02004-08-15 05:52:07 +0000299 /* If the same instance, delete from request-list and
300 examin next neighbor */
301 if (ospf6_lsa_compare (lsa, req) == 0)
302 {
hasso1e058382004-09-01 21:36:14 +0000303 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000304 zlog_debug ("Requesting the same, remove it, next neighbor");
hasso6452df02004-08-15 05:52:07 +0000305 ospf6_lsdb_remove (req, on->request_list);
306 continue;
307 }
hasso48454372004-05-18 19:14:52 +0000308
hasso6452df02004-08-15 05:52:07 +0000309 /* If the new LSA is more recent, delete from request-list */
310 if (ospf6_lsa_compare (lsa, req) < 0)
311 {
hasso1e058382004-09-01 21:36:14 +0000312 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000313 zlog_debug ("Received is newer, remove requesting");
hasso6452df02004-08-15 05:52:07 +0000314 ospf6_lsdb_remove (req, on->request_list);
315 /* fall through */
hasso48454372004-05-18 19:14:52 +0000316 }
317 }
hasso48454372004-05-18 19:14:52 +0000318 }
319
hasso6452df02004-08-15 05:52:07 +0000320 /* (c) If the new LSA was received from this neighbor,
321 examin next neighbor */
322 if (from == on)
hasso48454372004-05-18 19:14:52 +0000323 {
hasso1e058382004-09-01 21:36:14 +0000324 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000325 zlog_debug ("Received is from the neighbor, next neighbor");
hasso6452df02004-08-15 05:52:07 +0000326 continue;
hasso48454372004-05-18 19:14:52 +0000327 }
hasso6452df02004-08-15 05:52:07 +0000328
329 /* (d) add retrans-list, schedule retransmission */
hasso1e058382004-09-01 21:36:14 +0000330 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000331 zlog_debug ("Add retrans-list of this neighbor");
hasso6452df02004-08-15 05:52:07 +0000332 ospf6_increment_retrans_count (lsa);
333 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
334 if (on->thread_send_lsupdate == NULL)
335 on->thread_send_lsupdate =
gdt6639a042004-11-05 18:42:27 +0000336 thread_add_timer (master, ospf6_lsupdate_send_neighbor,
hasso6452df02004-08-15 05:52:07 +0000337 on, on->ospf6_if->rxmt_interval);
338 retrans_added++;
hasso48454372004-05-18 19:14:52 +0000339 }
340
hasso6452df02004-08-15 05:52:07 +0000341 /* (2) examin next interface if not added to retrans-list */
342 if (retrans_added == 0)
343 {
hasso1e058382004-09-01 21:36:14 +0000344 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000345 zlog_debug ("No retransmission scheduled, next interface");
hasso6452df02004-08-15 05:52:07 +0000346 return;
347 }
348
349 /* (3) If the new LSA was received on this interface,
350 and it was from DR or BDR, examin next interface */
351 if (from && from->ospf6_if == oi &&
352 (from->router_id == oi->drouter || from->router_id == oi->bdrouter))
353 {
hasso1e058382004-09-01 21:36:14 +0000354 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000355 zlog_debug ("Received is from the I/F's DR or BDR, next interface");
hasso6452df02004-08-15 05:52:07 +0000356 return;
357 }
358
359 /* (4) If the new LSA was received on this interface,
360 and the interface state is BDR, examin next interface */
361 if (from && from->ospf6_if == oi && oi->state == OSPF6_INTERFACE_BDR)
362 {
hasso1e058382004-09-01 21:36:14 +0000363 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000364 zlog_debug ("Received is from the I/F, itself BDR, next interface");
hasso6452df02004-08-15 05:52:07 +0000365 return;
366 }
367
368 /* (5) flood the LSA out the interface. */
hasso1e058382004-09-01 21:36:14 +0000369 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000370 zlog_debug ("Schedule flooding for the interface");
hasso6452df02004-08-15 05:52:07 +0000371 if (if_is_broadcast (oi->interface))
372 {
373 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list);
374 if (oi->thread_send_lsupdate == NULL)
375 oi->thread_send_lsupdate =
376 thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
377 }
378 else
379 {
380 /* reschedule retransmissions to all neighbors */
paul1eb8ef22005-04-07 07:30:20 +0000381 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
hasso6452df02004-08-15 05:52:07 +0000382 {
hasso6452df02004-08-15 05:52:07 +0000383 THREAD_OFF (on->thread_send_lsupdate);
384 on->thread_send_lsupdate =
385 thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
386 }
387 }
hasso48454372004-05-18 19:14:52 +0000388}
389
Paul Jakma6ac29a52008-08-15 13:45:30 +0100390static void
hasso6452df02004-08-15 05:52:07 +0000391ospf6_flood_area (struct ospf6_neighbor *from,
392 struct ospf6_lsa *lsa, struct ospf6_area *oa)
393{
paul1eb8ef22005-04-07 07:30:20 +0000394 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000395 struct ospf6_interface *oi;
396
paul1eb8ef22005-04-07 07:30:20 +0000397 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
hasso6452df02004-08-15 05:52:07 +0000398 {
hasso6452df02004-08-15 05:52:07 +0000399 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
400 oi != OSPF6_INTERFACE (lsa->lsdb->data))
401 continue;
402
403#if 0
404 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
405 ospf6_is_interface_virtual_link (oi))
406 continue;
407#endif/*0*/
408
409 ospf6_flood_interface (from, lsa, oi);
410 }
411}
412
Paul Jakma6ac29a52008-08-15 13:45:30 +0100413static void
hasso6452df02004-08-15 05:52:07 +0000414ospf6_flood_process (struct ospf6_neighbor *from,
415 struct ospf6_lsa *lsa, struct ospf6 *process)
416{
paul1eb8ef22005-04-07 07:30:20 +0000417 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000418 struct ospf6_area *oa;
419
paul1eb8ef22005-04-07 07:30:20 +0000420 for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa))
hasso6452df02004-08-15 05:52:07 +0000421 {
hasso6452df02004-08-15 05:52:07 +0000422 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
423 oa != OSPF6_AREA (lsa->lsdb->data))
424 continue;
425 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
426 oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
427 continue;
428
429 if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
430 IS_AREA_STUB (oa))
431 continue;
432
433 ospf6_flood_area (from, lsa, oa);
434 }
435}
436
437void
438ospf6_flood (struct ospf6_neighbor *from, struct ospf6_lsa *lsa)
439{
440 ospf6_flood_process (from, lsa, ospf6);
441}
442
Paul Jakma6ac29a52008-08-15 13:45:30 +0100443static void
hasso6452df02004-08-15 05:52:07 +0000444ospf6_flood_clear_interface (struct ospf6_lsa *lsa, struct ospf6_interface *oi)
445{
paul1eb8ef22005-04-07 07:30:20 +0000446 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000447 struct ospf6_neighbor *on;
448 struct ospf6_lsa *rem;
449
paul1eb8ef22005-04-07 07:30:20 +0000450 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
hasso6452df02004-08-15 05:52:07 +0000451 {
hasso6452df02004-08-15 05:52:07 +0000452 rem = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
453 lsa->header->adv_router, on->retrans_list);
454 if (rem && ! ospf6_lsa_compare (rem, lsa))
455 {
hasso1e058382004-09-01 21:36:14 +0000456 if (IS_OSPF6_DEBUG_FLOODING ||
457 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
hassoc6487d62004-12-24 06:00:11 +0000458 zlog_debug ("Remove %s from retrans_list of %s",
hasso6452df02004-08-15 05:52:07 +0000459 rem->name, on->name);
460 ospf6_decrement_retrans_count (rem);
461 ospf6_lsdb_remove (rem, on->retrans_list);
462 }
463 }
464}
465
Paul Jakma6ac29a52008-08-15 13:45:30 +0100466static void
hasso6452df02004-08-15 05:52:07 +0000467ospf6_flood_clear_area (struct ospf6_lsa *lsa, struct ospf6_area *oa)
468{
paul1eb8ef22005-04-07 07:30:20 +0000469 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000470 struct ospf6_interface *oi;
471
paul1eb8ef22005-04-07 07:30:20 +0000472 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
hasso6452df02004-08-15 05:52:07 +0000473 {
hasso6452df02004-08-15 05:52:07 +0000474 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
475 oi != OSPF6_INTERFACE (lsa->lsdb->data))
476 continue;
477
478#if 0
479 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
480 ospf6_is_interface_virtual_link (oi))
481 continue;
482#endif/*0*/
483
484 ospf6_flood_clear_interface (lsa, oi);
485 }
486}
487
Paul Jakma6ac29a52008-08-15 13:45:30 +0100488static void
hasso6452df02004-08-15 05:52:07 +0000489ospf6_flood_clear_process (struct ospf6_lsa *lsa, struct ospf6 *process)
490{
paul1eb8ef22005-04-07 07:30:20 +0000491 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000492 struct ospf6_area *oa;
493
paul1eb8ef22005-04-07 07:30:20 +0000494 for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa))
hasso6452df02004-08-15 05:52:07 +0000495 {
hasso6452df02004-08-15 05:52:07 +0000496 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
497 oa != OSPF6_AREA (lsa->lsdb->data))
498 continue;
499 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
500 oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
501 continue;
502
503 if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
504 IS_AREA_STUB (oa))
505 continue;
506
507 ospf6_flood_clear_area (lsa, oa);
508 }
509}
510
511void
512ospf6_flood_clear (struct ospf6_lsa *lsa)
513{
514 ospf6_flood_clear_process (lsa, ospf6);
515}
516
517
hasso48454372004-05-18 19:14:52 +0000518/* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
519static void
520ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
521 struct ospf6_neighbor *from)
522{
523 struct ospf6_interface *oi;
hasso1e058382004-09-01 21:36:14 +0000524 int is_debug = 0;
525
526 if (IS_OSPF6_DEBUG_FLOODING ||
527 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
528 is_debug++;
hasso48454372004-05-18 19:14:52 +0000529
530 assert (from && from->ospf6_if);
531 oi = from->ospf6_if;
532
533 /* LSA has been flood back out receiving interface.
534 No acknowledgement sent. */
535 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
536 {
hasso1e058382004-09-01 21:36:14 +0000537 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000538 zlog_debug ("No acknowledgement (BDR & FloodBack)");
hasso48454372004-05-18 19:14:52 +0000539 return;
540 }
541
542 /* LSA is more recent than database copy, but was not flooded
543 back out receiving interface. Delayed acknowledgement sent
544 if advertisement received from Designated Router,
545 otherwide do nothing. */
546 if (ismore_recent < 0)
547 {
hasso48454372004-05-18 19:14:52 +0000548 if (oi->drouter == from->router_id)
549 {
hasso1e058382004-09-01 21:36:14 +0000550 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000551 zlog_debug ("Delayed acknowledgement (BDR & MoreRecent & from DR)");
hasso48454372004-05-18 19:14:52 +0000552 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000553 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
554 if (oi->thread_send_lsack == NULL)
555 oi->thread_send_lsack =
556 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
557 }
558 else
559 {
hasso1e058382004-09-01 21:36:14 +0000560 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000561 zlog_debug ("No acknowledgement (BDR & MoreRecent & ! from DR)");
hasso48454372004-05-18 19:14:52 +0000562 }
563 return;
564 }
565
566 /* LSA is a duplicate, and was treated as an implied acknowledgement.
567 Delayed acknowledgement sent if advertisement received from
568 Designated Router, otherwise do nothing */
569 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
570 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
571 {
hasso48454372004-05-18 19:14:52 +0000572 if (oi->drouter == from->router_id)
573 {
hasso1e058382004-09-01 21:36:14 +0000574 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000575 zlog_debug ("Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
hasso48454372004-05-18 19:14:52 +0000576 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000577 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
578 if (oi->thread_send_lsack == NULL)
579 oi->thread_send_lsack =
580 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
581 }
582 else
583 {
hasso1e058382004-09-01 21:36:14 +0000584 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000585 zlog_debug ("No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
hasso48454372004-05-18 19:14:52 +0000586 }
587 return;
588 }
589
590 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
591 Direct acknowledgement sent */
592 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
593 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
594 {
hasso1e058382004-09-01 21:36:14 +0000595 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000596 zlog_debug ("Direct acknowledgement (BDR & Duplicate)");
hasso48454372004-05-18 19:14:52 +0000597 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
598 if (from->thread_send_lsack == NULL)
599 from->thread_send_lsack =
600 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
601 return;
602 }
603
604 /* LSA's LS age is equal to Maxage, and there is no current instance
605 of the LSA in the link state database, and none of router's
606 neighbors are in states Exchange or Loading */
607 /* Direct acknowledgement sent, but this case is handled in
608 early of ospf6_receive_lsa () */
609}
610
611static void
612ospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent,
613 struct ospf6_neighbor *from)
614{
615 struct ospf6_interface *oi;
hasso1e058382004-09-01 21:36:14 +0000616 int is_debug = 0;
617
618 if (IS_OSPF6_DEBUG_FLOODING ||
619 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
620 is_debug++;
hasso48454372004-05-18 19:14:52 +0000621
622 assert (from && from->ospf6_if);
623 oi = from->ospf6_if;
624
625 /* LSA has been flood back out receiving interface.
626 No acknowledgement sent. */
627 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
628 {
hasso1e058382004-09-01 21:36:14 +0000629 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000630 zlog_debug ("No acknowledgement (AllOther & FloodBack)");
hasso48454372004-05-18 19:14:52 +0000631 return;
632 }
633
634 /* LSA is more recent than database copy, but was not flooded
635 back out receiving interface. Delayed acknowledgement sent. */
636 if (ismore_recent < 0)
637 {
hasso1e058382004-09-01 21:36:14 +0000638 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000639 zlog_debug ("Delayed acknowledgement (AllOther & MoreRecent)");
hasso48454372004-05-18 19:14:52 +0000640 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000641 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
642 if (oi->thread_send_lsack == NULL)
643 oi->thread_send_lsack =
644 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
645 return;
646 }
647
648 /* LSA is a duplicate, and was treated as an implied acknowledgement.
649 No acknowledgement sent. */
650 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
651 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
652 {
hasso1e058382004-09-01 21:36:14 +0000653 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000654 zlog_debug ("No acknowledgement (AllOther & Duplicate & ImpliedAck)");
hasso48454372004-05-18 19:14:52 +0000655 return;
656 }
657
658 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
659 Direct acknowledgement sent */
660 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
661 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
662 {
hasso1e058382004-09-01 21:36:14 +0000663 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000664 zlog_debug ("Direct acknowledgement (AllOther & Duplicate)");
hasso48454372004-05-18 19:14:52 +0000665 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
666 if (from->thread_send_lsack == NULL)
667 from->thread_send_lsack =
668 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
669 return;
670 }
671
672 /* LSA's LS age is equal to Maxage, and there is no current instance
673 of the LSA in the link state database, and none of router's
674 neighbors are in states Exchange or Loading */
675 /* Direct acknowledgement sent, but this case is handled in
676 early of ospf6_receive_lsa () */
677}
678
Paul Jakma6ac29a52008-08-15 13:45:30 +0100679static void
hasso48454372004-05-18 19:14:52 +0000680ospf6_acknowledge_lsa (struct ospf6_lsa *lsa, int ismore_recent,
681 struct ospf6_neighbor *from)
682{
683 struct ospf6_interface *oi;
684
685 assert (from && from->ospf6_if);
686 oi = from->ospf6_if;
687
688 if (oi->state == OSPF6_INTERFACE_BDR)
689 ospf6_acknowledge_lsa_bdrouter (lsa, ismore_recent, from);
690 else
691 ospf6_acknowledge_lsa_allother (lsa, ismore_recent, from);
692}
693
694/* RFC2328 section 13 (4):
695 if MaxAge LSA and if we have no instance, and no neighbor
696 is in states Exchange or Loading
697 returns 1 if match this case, else returns 0 */
698static int
hasso6452df02004-08-15 05:52:07 +0000699ospf6_is_maxage_lsa_drop (struct ospf6_lsa *lsa, struct ospf6_neighbor *from)
hasso48454372004-05-18 19:14:52 +0000700{
hasso48454372004-05-18 19:14:52 +0000701 struct ospf6_neighbor *on;
hasso6452df02004-08-15 05:52:07 +0000702 struct ospf6_interface *oi;
703 struct ospf6_area *oa;
704 struct ospf6 *process = NULL;
hasso52dc7ee2004-09-23 19:18:23 +0000705 struct listnode *i, *j, *k;
hasso48454372004-05-18 19:14:52 +0000706 int count = 0;
707
708 if (! OSPF6_LSA_IS_MAXAGE (lsa))
709 return 0;
710
hasso48454372004-05-18 19:14:52 +0000711 if (ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
hasso6452df02004-08-15 05:52:07 +0000712 lsa->header->adv_router, lsa->lsdb))
hasso48454372004-05-18 19:14:52 +0000713 return 0;
714
hasso6452df02004-08-15 05:52:07 +0000715 process = from->ospf6_if->area->ospf6;
paul1eb8ef22005-04-07 07:30:20 +0000716
717 for (ALL_LIST_ELEMENTS_RO (process->area_list, i, oa))
718 for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
719 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on))
720 if (on->state == OSPF6_NEIGHBOR_EXCHANGE ||
721 on->state == OSPF6_NEIGHBOR_LOADING)
722 count++;
hasso48454372004-05-18 19:14:52 +0000723
hasso48454372004-05-18 19:14:52 +0000724 if (count == 0)
725 return 1;
hasso48454372004-05-18 19:14:52 +0000726 return 0;
727}
728
729/* RFC2328 section 13 The Flooding Procedure */
730void
hasso6452df02004-08-15 05:52:07 +0000731ospf6_receive_lsa (struct ospf6_neighbor *from,
732 struct ospf6_lsa_header *lsa_header)
hasso48454372004-05-18 19:14:52 +0000733{
734 struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
735 int ismore_recent;
hasso1e058382004-09-01 21:36:14 +0000736 int is_debug = 0;
hasso48454372004-05-18 19:14:52 +0000737
738 ismore_recent = 1;
hasso6452df02004-08-15 05:52:07 +0000739 assert (from);
hasso48454372004-05-18 19:14:52 +0000740
741 /* make lsa structure for received lsa */
742 new = ospf6_lsa_create (lsa_header);
743
hasso1e058382004-09-01 21:36:14 +0000744 if (IS_OSPF6_DEBUG_FLOODING ||
745 IS_OSPF6_DEBUG_FLOOD_TYPE (new->header->type))
hasso48454372004-05-18 19:14:52 +0000746 {
hasso1e058382004-09-01 21:36:14 +0000747 is_debug++;
hassoc6487d62004-12-24 06:00:11 +0000748 zlog_debug ("LSA Receive from %s", from->name);
hasso48454372004-05-18 19:14:52 +0000749 ospf6_lsa_header_print (new);
750 }
751
hasso48454372004-05-18 19:14:52 +0000752 /* (1) LSA Checksum */
JR Riversd8a4e422012-09-13 17:17:36 +0000753 if (! ospf6_lsa_checksum_valid (new->header))
hasso48454372004-05-18 19:14:52 +0000754 {
hasso1e058382004-09-01 21:36:14 +0000755 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000756 zlog_debug ("Wrong LSA Checksum, discard");
hasso48454372004-05-18 19:14:52 +0000757 ospf6_lsa_delete (new);
758 return;
759 }
760
hasso6452df02004-08-15 05:52:07 +0000761 /* (2) Examine the LSA's LS type.
762 RFC2470 3.5.1. Receiving Link State Update packets */
763 if (IS_AREA_STUB (from->ospf6_if->area) &&
764 OSPF6_LSA_SCOPE (new->header->type) == OSPF6_SCOPE_AS)
hasso48454372004-05-18 19:14:52 +0000765 {
hasso1e058382004-09-01 21:36:14 +0000766 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000767 zlog_debug ("AS-External-LSA (or AS-scope LSA) in stub area, discard");
hasso6452df02004-08-15 05:52:07 +0000768 ospf6_lsa_delete (new);
769 return;
770 }
771
772 /* (3) LSA which have reserved scope is discarded
773 RFC2470 3.5.1. Receiving Link State Update packets */
774 /* Flooding scope check. LSAs with unknown scope are discarded here.
775 Set appropriate LSDB for the LSA */
776 switch (OSPF6_LSA_SCOPE (new->header->type))
777 {
778 case OSPF6_SCOPE_LINKLOCAL:
779 new->lsdb = from->ospf6_if->lsdb;
780 break;
781 case OSPF6_SCOPE_AREA:
782 new->lsdb = from->ospf6_if->area->lsdb;
783 break;
784 case OSPF6_SCOPE_AS:
785 new->lsdb = from->ospf6_if->area->ospf6->lsdb;
786 break;
787 default:
hasso1e058382004-09-01 21:36:14 +0000788 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000789 zlog_debug ("LSA has reserved scope, discard");
hasso48454372004-05-18 19:14:52 +0000790 ospf6_lsa_delete (new);
791 return;
792 }
793
794 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
795 is in states Exchange or Loading */
796 if (ospf6_is_maxage_lsa_drop (new, from))
797 {
798 /* log */
hasso1e058382004-09-01 21:36:14 +0000799 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000800 zlog_debug ("Drop MaxAge LSA with direct acknowledgement.");
hasso48454372004-05-18 19:14:52 +0000801
802 /* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */
hasso6452df02004-08-15 05:52:07 +0000803 ospf6_lsdb_add (ospf6_lsa_copy (new), from->lsack_list);
hasso48454372004-05-18 19:14:52 +0000804 if (from->thread_send_lsack == NULL)
805 from->thread_send_lsack =
806 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
807
808 /* b) Discard */
hasso6452df02004-08-15 05:52:07 +0000809 ospf6_lsa_delete (new);
hasso48454372004-05-18 19:14:52 +0000810 return;
811 }
812
813 /* (5) */
814 /* lookup the same database copy in lsdb */
hasso48454372004-05-18 19:14:52 +0000815 old = ospf6_lsdb_lookup (new->header->type, new->header->id,
hasso6452df02004-08-15 05:52:07 +0000816 new->header->adv_router, new->lsdb);
hasso48454372004-05-18 19:14:52 +0000817 if (old)
818 {
819 ismore_recent = ospf6_lsa_compare (new, old);
820 if (ntohl (new->header->seqnum) == ntohl (old->header->seqnum))
821 {
hasso1e058382004-09-01 21:36:14 +0000822 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000823 zlog_debug ("Received is duplicated LSA");
hasso48454372004-05-18 19:14:52 +0000824 SET_FLAG (new->flag, OSPF6_LSA_DUPLICATE);
825 }
826 }
827
828 /* if no database copy or received is more recent */
829 if (old == NULL || ismore_recent < 0)
830 {
831 /* in case we have no database copy */
832 ismore_recent = -1;
833
834 /* (a) MinLSArrival check */
835 if (old)
836 {
837 struct timeval now, res;
Takashi Sogabe86f72dc2009-06-22 13:07:02 +0900838 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
hasso48454372004-05-18 19:14:52 +0000839 timersub (&now, &old->installed, &res);
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700840 if (res.tv_sec < OSPF_MIN_LS_ARRIVAL)
hasso48454372004-05-18 19:14:52 +0000841 {
hasso1e058382004-09-01 21:36:14 +0000842 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000843 zlog_debug ("LSA can't be updated within MinLSArrival, discard");
hasso48454372004-05-18 19:14:52 +0000844 ospf6_lsa_delete (new);
845 return; /* examin next lsa */
846 }
847 }
848
Takashi Sogabe86f72dc2009-06-22 13:07:02 +0900849 quagga_gettime (QUAGGA_CLK_MONOTONIC, &new->received);
hassoccb59b12004-08-25 09:10:37 +0000850
hasso1e058382004-09-01 21:36:14 +0000851 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000852 zlog_debug ("Flood, Install, Possibly acknowledge the received LSA");
hasso6452df02004-08-15 05:52:07 +0000853
hasso48454372004-05-18 19:14:52 +0000854 /* (b) immediately flood and (c) remove from all retrans-list */
hassoccb59b12004-08-25 09:10:37 +0000855 /* Prevent self-originated LSA to be flooded. this is to make
856 reoriginated instance of the LSA not to be rejected by other routers
857 due to MinLSArrival. */
858 if (new->header->adv_router != from->ospf6_if->area->ospf6->router_id)
859 ospf6_flood (from, new);
hasso6452df02004-08-15 05:52:07 +0000860
861 /* (c) Remove the current database copy from all neighbors' Link
862 state retransmission lists. */
863 /* XXX, flood_clear ? */
hasso48454372004-05-18 19:14:52 +0000864
865 /* (d), installing lsdb, which may cause routing
866 table calculation (replacing database copy) */
hasso6452df02004-08-15 05:52:07 +0000867 ospf6_install_lsa (new);
hasso48454372004-05-18 19:14:52 +0000868
869 /* (e) possibly acknowledge */
870 ospf6_acknowledge_lsa (new, ismore_recent, from);
871
hasso6452df02004-08-15 05:52:07 +0000872 /* (f) Self Originated LSA, section 13.4 */
873 if (new->header->adv_router == from->ospf6_if->area->ospf6->router_id)
hasso48454372004-05-18 19:14:52 +0000874 {
hasso6452df02004-08-15 05:52:07 +0000875 /* Self-originated LSA (newer than ours) is received from
876 another router. We have to make a new instance of the LSA
hasso48454372004-05-18 19:14:52 +0000877 or have to flush this LSA. */
hasso1e058382004-09-01 21:36:14 +0000878 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000879 {
hassoc6487d62004-12-24 06:00:11 +0000880 zlog_debug ("Newer instance of the self-originated LSA");
881 zlog_debug ("Schedule reorigination");
hasso6452df02004-08-15 05:52:07 +0000882 }
883 new->refresh = thread_add_event (master, ospf6_lsa_refresh, new, 0);
hasso48454372004-05-18 19:14:52 +0000884 }
hasso6452df02004-08-15 05:52:07 +0000885
hasso48454372004-05-18 19:14:52 +0000886 return;
887 }
888
889 /* (6) if there is instance on sending neighbor's request list */
890 if (ospf6_lsdb_lookup (new->header->type, new->header->id,
891 new->header->adv_router, from->request_list))
892 {
893 /* if no database copy, should go above state (5) */
894 assert (old);
895
hasso1e058382004-09-01 21:36:14 +0000896 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000897 {
hassoc6487d62004-12-24 06:00:11 +0000898 zlog_debug ("Received is not newer, on the neighbor's request-list");
899 zlog_debug ("BadLSReq, discard the received LSA");
hasso6452df02004-08-15 05:52:07 +0000900 }
hasso48454372004-05-18 19:14:52 +0000901
902 /* BadLSReq */
903 thread_add_event (master, bad_lsreq, from, 0);
904
905 ospf6_lsa_delete (new);
906 return;
907 }
908
909 /* (7) if neither one is more recent */
910 if (ismore_recent == 0)
911 {
hasso1e058382004-09-01 21:36:14 +0000912 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000913 zlog_debug ("The same instance as database copy (neither recent)");
hasso48454372004-05-18 19:14:52 +0000914
915 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack */
916 rem = ospf6_lsdb_lookup (new->header->type, new->header->id,
917 new->header->adv_router, from->retrans_list);
918 if (rem)
919 {
hasso1e058382004-09-01 21:36:14 +0000920 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000921 {
hassoc6487d62004-12-24 06:00:11 +0000922 zlog_debug ("It is on the neighbor's retrans-list.");
923 zlog_debug ("Treat as an Implied acknowledgement");
hasso6452df02004-08-15 05:52:07 +0000924 }
hasso48454372004-05-18 19:14:52 +0000925 SET_FLAG (new->flag, OSPF6_LSA_IMPLIEDACK);
hasso6452df02004-08-15 05:52:07 +0000926 ospf6_decrement_retrans_count (rem);
hasso48454372004-05-18 19:14:52 +0000927 ospf6_lsdb_remove (rem, from->retrans_list);
928 }
929
hasso1e058382004-09-01 21:36:14 +0000930 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000931 zlog_debug ("Possibly acknowledge and then discard");
hasso6452df02004-08-15 05:52:07 +0000932
hasso48454372004-05-18 19:14:52 +0000933 /* (b) possibly acknowledge */
934 ospf6_acknowledge_lsa (new, ismore_recent, from);
935
936 ospf6_lsa_delete (new);
937 return;
938 }
939
940 /* (8) previous database copy is more recent */
941 {
942 assert (old);
943
944 /* If database copy is in 'Seqnumber Wrapping',
945 simply discard the received LSA */
946 if (OSPF6_LSA_IS_MAXAGE (old) &&
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700947 old->header->seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
hasso48454372004-05-18 19:14:52 +0000948 {
hasso1e058382004-09-01 21:36:14 +0000949 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000950 {
hassoc6487d62004-12-24 06:00:11 +0000951 zlog_debug ("The LSA is in Seqnumber Wrapping");
952 zlog_debug ("MaxAge & MaxSeqNum, discard");
hasso6452df02004-08-15 05:52:07 +0000953 }
hasso48454372004-05-18 19:14:52 +0000954 ospf6_lsa_delete (new);
955 return;
956 }
957
958 /* Otherwise, Send database copy of this LSA to this neighbor */
959 {
hasso1e058382004-09-01 21:36:14 +0000960 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000961 {
hassoc6487d62004-12-24 06:00:11 +0000962 zlog_debug ("Database copy is more recent.");
963 zlog_debug ("Send back directly and then discard");
hasso6452df02004-08-15 05:52:07 +0000964 }
hasso48454372004-05-18 19:14:52 +0000965
966 /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
967
hasso48454372004-05-18 19:14:52 +0000968 ospf6_lsdb_add (ospf6_lsa_copy (old), from->lsupdate_list);
969 if (from->thread_send_lsupdate == NULL)
970 from->thread_send_lsupdate =
971 thread_add_event (master, ospf6_lsupdate_send_neighbor, from, 0);
972 ospf6_lsa_delete (new);
973 return;
974 }
975 return;
976 }
977}
978
979
hasso1e058382004-09-01 21:36:14 +0000980DEFUN (debug_ospf6_flooding,
981 debug_ospf6_flooding_cmd,
982 "debug ospf6 flooding",
983 DEBUG_STR
984 OSPF6_STR
985 "Debug OSPFv3 flooding function\n"
986 )
987{
988 OSPF6_DEBUG_FLOODING_ON ();
989 return CMD_SUCCESS;
990}
991
992DEFUN (no_debug_ospf6_flooding,
993 no_debug_ospf6_flooding_cmd,
994 "no debug ospf6 flooding",
995 NO_STR
996 DEBUG_STR
997 OSPF6_STR
998 "Debug OSPFv3 flooding function\n"
999 )
1000{
1001 OSPF6_DEBUG_FLOODING_OFF ();
1002 return CMD_SUCCESS;
1003}
1004
1005int
1006config_write_ospf6_debug_flood (struct vty *vty)
1007{
1008 if (IS_OSPF6_DEBUG_FLOODING)
1009 vty_out (vty, "debug ospf6 flooding%s", VNL);
1010 return 0;
1011}
1012
1013void
Paul Jakma6ac29a52008-08-15 13:45:30 +01001014install_element_ospf6_debug_flood (void)
hasso1e058382004-09-01 21:36:14 +00001015{
1016 install_element (ENABLE_NODE, &debug_ospf6_flooding_cmd);
1017 install_element (ENABLE_NODE, &no_debug_ospf6_flooding_cmd);
1018 install_element (CONFIG_NODE, &debug_ospf6_flooding_cmd);
1019 install_element (CONFIG_NODE, &no_debug_ospf6_flooding_cmd);
1020}
1021
1022
1023
1024
hasso48454372004-05-18 19:14:52 +00001025