blob: ba770092465fc9ff0207979d599cb54021bf16d9 [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 ospf6_install_lsa (lsa);
Dinesh Duttbf986da2013-08-24 07:54:50 +0000126 ospf6_flood (NULL, lsa);
hasso6452df02004-08-15 05:52:07 +0000127}
128
129void
130ospf6_lsa_originate_process (struct ospf6_lsa *lsa,
131 struct ospf6 *process)
132{
133 lsa->lsdb = process->lsdb;
134 ospf6_lsa_originate (lsa);
135}
136
137void
138ospf6_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
145void
146ospf6_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
153void
154ospf6_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)
hasso48454372004-05-18 19:14:52 +0000164 {
hasso6452df02004-08-15 05:52:07 +0000165 THREAD_OFF (self->expire);
166 THREAD_OFF (self->refresh);
167 ospf6_lsdb_remove (self, lsdb_self);
hasso48454372004-05-18 19:14:52 +0000168 }
169
hasso6452df02004-08-15 05:52:07 +0000170 ospf6_lsa_premature_aging (lsa);
171}
172
173
174void
175ospf6_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
182void
183ospf6_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
hasso1e058382004-09-01 21:36:14 +0000190 retransmission count of the original one (instead of this "lsa"'s).
hasso6452df02004-08-15 05:52:07 +0000191 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,
hasso1e058382004-09-01 21:36:14 +0000197 lsa->header->adv_router, lsdb);
hasso6452df02004-08-15 05:52:07 +0000198 if (orig)
hasso6861b302004-08-26 18:19:59 +0000199 {
200 orig->retrans_count--;
201 assert (orig->retrans_count >= 0);
202 }
hasso48454372004-05-18 19:14:52 +0000203}
204
205/* RFC2328 section 13.2 Installing LSAs in the database */
206void
hasso6452df02004-08-15 05:52:07 +0000207ospf6_install_lsa (struct ospf6_lsa *lsa)
hasso48454372004-05-18 19:14:52 +0000208{
209 struct ospf6_lsa *old;
hasso3b687352004-08-19 06:56:53 +0000210 struct timeval now;
hasso48454372004-05-18 19:14:52 +0000211
hasso1e058382004-09-01 21:36:14 +0000212 if (IS_OSPF6_DEBUG_LSA_TYPE (lsa->header->type) ||
213 IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
hassoc6487d62004-12-24 06:00:11 +0000214 zlog_debug ("Install LSA: %s", lsa->name);
hasso48454372004-05-18 19:14:52 +0000215
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,
hasso6452df02004-08-15 05:52:07 +0000219 lsa->header->adv_router, lsa->lsdb);
hasso48454372004-05-18 19:14:52 +0000220 if (old)
hasso3b687352004-08-19 06:56:53 +0000221 {
222 THREAD_OFF (old->expire);
223 ospf6_flood_clear (old);
224 }
225
Takashi Sogabe86f72dc2009-06-22 13:07:02 +0900226 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
hassoccb59b12004-08-25 09:10:37 +0000227 if (! OSPF6_LSA_IS_MAXAGE (lsa))
hasso3b687352004-08-19 06:56:53 +0000228 lsa->expire = thread_add_timer (master, ospf6_lsa_expire, lsa,
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700229 OSPF_LSA_MAXAGE + lsa->birth.tv_sec - now.tv_sec);
hasso3b687352004-08-19 06:56:53 +0000230 else
231 lsa->expire = NULL;
hasso48454372004-05-18 19:14:52 +0000232
233 /* actually install */
hasso3b687352004-08-19 06:56:53 +0000234 lsa->installed = now;
hasso6452df02004-08-15 05:52:07 +0000235 ospf6_lsdb_add (lsa, lsa->lsdb);
hasso48454372004-05-18 19:14:52 +0000236
237 return;
238}
239
hasso6452df02004-08-15 05:52:07 +0000240/* RFC2740 section 3.5.2. Sending Link State Update packets */
hasso48454372004-05-18 19:14:52 +0000241/* RFC2328 section 13.3 Next step in the flooding procedure */
Paul Jakma6ac29a52008-08-15 13:45:30 +0100242static void
hasso6452df02004-08-15 05:52:07 +0000243ospf6_flood_interface (struct ospf6_neighbor *from,
244 struct ospf6_lsa *lsa, struct ospf6_interface *oi)
hasso48454372004-05-18 19:14:52 +0000245{
paul1eb8ef22005-04-07 07:30:20 +0000246 struct listnode *node, *nnode;
hasso48454372004-05-18 19:14:52 +0000247 struct ospf6_neighbor *on;
hasso48454372004-05-18 19:14:52 +0000248 struct ospf6_lsa *req;
249 int retrans_added = 0;
hasso1e058382004-09-01 21:36:14 +0000250 int is_debug = 0;
hasso48454372004-05-18 19:14:52 +0000251
hasso1e058382004-09-01 21:36:14 +0000252 if (IS_OSPF6_DEBUG_FLOODING ||
253 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
254 {
255 is_debug++;
hassoc6487d62004-12-24 06:00:11 +0000256 zlog_debug ("Flooding on %s: %s", oi->interface->name, lsa->name);
hasso1e058382004-09-01 21:36:14 +0000257 }
hasso48454372004-05-18 19:14:52 +0000258
hasso6452df02004-08-15 05:52:07 +0000259 /* (1) For each neighbor */
paul1eb8ef22005-04-07 07:30:20 +0000260 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
hasso48454372004-05-18 19:14:52 +0000261 {
hasso1e058382004-09-01 21:36:14 +0000262 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000263 zlog_debug ("To neighbor %s", on->name);
hasso6452df02004-08-15 05:52:07 +0000264
265 /* (a) if neighbor state < Exchange, examin next */
266 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
hasso48454372004-05-18 19:14:52 +0000267 {
hasso1e058382004-09-01 21:36:14 +0000268 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000269 zlog_debug ("Neighbor state less than ExChange, next neighbor");
hasso6452df02004-08-15 05:52:07 +0000270 continue;
hasso48454372004-05-18 19:14:52 +0000271 }
hasso48454372004-05-18 19:14:52 +0000272
hasso6452df02004-08-15 05:52:07 +0000273 /* (b) if neighbor not yet Full, check request-list */
274 if (on->state != OSPF6_NEIGHBOR_FULL)
hasso48454372004-05-18 19:14:52 +0000275 {
hasso1e058382004-09-01 21:36:14 +0000276 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000277 zlog_debug ("Neighbor not yet Full");
hasso48454372004-05-18 19:14:52 +0000278
hasso6452df02004-08-15 05:52:07 +0000279 req = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
280 lsa->header->adv_router, on->request_list);
281 if (req == NULL)
hasso48454372004-05-18 19:14:52 +0000282 {
hasso1e058382004-09-01 21:36:14 +0000283 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000284 zlog_debug ("Not on request-list for this neighbor");
hasso6452df02004-08-15 05:52:07 +0000285 /* fall through */
286 }
287 else
288 {
289 /* If new LSA less recent, examin next neighbor */
290 if (ospf6_lsa_compare (lsa, req) > 0)
hasso48454372004-05-18 19:14:52 +0000291 {
hasso1e058382004-09-01 21:36:14 +0000292 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000293 zlog_debug ("Requesting is newer, next neighbor");
hasso6452df02004-08-15 05:52:07 +0000294 continue;
295 }
hasso48454372004-05-18 19:14:52 +0000296
hasso6452df02004-08-15 05:52:07 +0000297 /* If the same instance, delete from request-list and
298 examin next neighbor */
299 if (ospf6_lsa_compare (lsa, req) == 0)
300 {
hasso1e058382004-09-01 21:36:14 +0000301 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000302 zlog_debug ("Requesting the same, remove it, next neighbor");
hasso6452df02004-08-15 05:52:07 +0000303 ospf6_lsdb_remove (req, on->request_list);
304 continue;
305 }
hasso48454372004-05-18 19:14:52 +0000306
hasso6452df02004-08-15 05:52:07 +0000307 /* If the new LSA is more recent, delete from request-list */
308 if (ospf6_lsa_compare (lsa, req) < 0)
309 {
hasso1e058382004-09-01 21:36:14 +0000310 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000311 zlog_debug ("Received is newer, remove requesting");
hasso6452df02004-08-15 05:52:07 +0000312 ospf6_lsdb_remove (req, on->request_list);
313 /* fall through */
hasso48454372004-05-18 19:14:52 +0000314 }
315 }
hasso48454372004-05-18 19:14:52 +0000316 }
317
hasso6452df02004-08-15 05:52:07 +0000318 /* (c) If the new LSA was received from this neighbor,
319 examin next neighbor */
320 if (from == on)
hasso48454372004-05-18 19:14:52 +0000321 {
hasso1e058382004-09-01 21:36:14 +0000322 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000323 zlog_debug ("Received is from the neighbor, next neighbor");
hasso6452df02004-08-15 05:52:07 +0000324 continue;
hasso48454372004-05-18 19:14:52 +0000325 }
hasso6452df02004-08-15 05:52:07 +0000326
327 /* (d) add retrans-list, schedule retransmission */
hasso1e058382004-09-01 21:36:14 +0000328 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000329 zlog_debug ("Add retrans-list of this neighbor");
hasso6452df02004-08-15 05:52:07 +0000330 ospf6_increment_retrans_count (lsa);
331 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
332 if (on->thread_send_lsupdate == NULL)
333 on->thread_send_lsupdate =
gdt6639a042004-11-05 18:42:27 +0000334 thread_add_timer (master, ospf6_lsupdate_send_neighbor,
hasso6452df02004-08-15 05:52:07 +0000335 on, on->ospf6_if->rxmt_interval);
336 retrans_added++;
hasso48454372004-05-18 19:14:52 +0000337 }
338
hasso6452df02004-08-15 05:52:07 +0000339 /* (2) examin next interface if not added to retrans-list */
340 if (retrans_added == 0)
341 {
hasso1e058382004-09-01 21:36:14 +0000342 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000343 zlog_debug ("No retransmission scheduled, next interface");
hasso6452df02004-08-15 05:52:07 +0000344 return;
345 }
346
347 /* (3) If the new LSA was received on this interface,
348 and it was from DR or BDR, examin next interface */
349 if (from && from->ospf6_if == oi &&
350 (from->router_id == oi->drouter || from->router_id == oi->bdrouter))
351 {
hasso1e058382004-09-01 21:36:14 +0000352 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000353 zlog_debug ("Received is from the I/F's DR or BDR, next interface");
hasso6452df02004-08-15 05:52:07 +0000354 return;
355 }
356
357 /* (4) If the new LSA was received on this interface,
358 and the interface state is BDR, examin next interface */
359 if (from && from->ospf6_if == oi && oi->state == OSPF6_INTERFACE_BDR)
360 {
hasso1e058382004-09-01 21:36:14 +0000361 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000362 zlog_debug ("Received is from the I/F, itself BDR, next interface");
hasso6452df02004-08-15 05:52:07 +0000363 return;
364 }
365
366 /* (5) flood the LSA out the interface. */
hasso1e058382004-09-01 21:36:14 +0000367 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000368 zlog_debug ("Schedule flooding for the interface");
hasso6452df02004-08-15 05:52:07 +0000369 if (if_is_broadcast (oi->interface))
370 {
371 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list);
372 if (oi->thread_send_lsupdate == NULL)
373 oi->thread_send_lsupdate =
374 thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
375 }
376 else
377 {
378 /* reschedule retransmissions to all neighbors */
paul1eb8ef22005-04-07 07:30:20 +0000379 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
hasso6452df02004-08-15 05:52:07 +0000380 {
hasso6452df02004-08-15 05:52:07 +0000381 THREAD_OFF (on->thread_send_lsupdate);
382 on->thread_send_lsupdate =
383 thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
384 }
385 }
hasso48454372004-05-18 19:14:52 +0000386}
387
Paul Jakma6ac29a52008-08-15 13:45:30 +0100388static void
hasso6452df02004-08-15 05:52:07 +0000389ospf6_flood_area (struct ospf6_neighbor *from,
390 struct ospf6_lsa *lsa, struct ospf6_area *oa)
391{
paul1eb8ef22005-04-07 07:30:20 +0000392 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000393 struct ospf6_interface *oi;
394
paul1eb8ef22005-04-07 07:30:20 +0000395 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
hasso6452df02004-08-15 05:52:07 +0000396 {
hasso6452df02004-08-15 05:52:07 +0000397 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
398 oi != OSPF6_INTERFACE (lsa->lsdb->data))
399 continue;
400
401#if 0
402 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
403 ospf6_is_interface_virtual_link (oi))
404 continue;
405#endif/*0*/
406
407 ospf6_flood_interface (from, lsa, oi);
408 }
409}
410
Paul Jakma6ac29a52008-08-15 13:45:30 +0100411static void
hasso6452df02004-08-15 05:52:07 +0000412ospf6_flood_process (struct ospf6_neighbor *from,
413 struct ospf6_lsa *lsa, struct ospf6 *process)
414{
paul1eb8ef22005-04-07 07:30:20 +0000415 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000416 struct ospf6_area *oa;
417
paul1eb8ef22005-04-07 07:30:20 +0000418 for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa))
hasso6452df02004-08-15 05:52:07 +0000419 {
hasso6452df02004-08-15 05:52:07 +0000420 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
421 oa != OSPF6_AREA (lsa->lsdb->data))
422 continue;
423 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
424 oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
425 continue;
426
427 if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
428 IS_AREA_STUB (oa))
429 continue;
430
431 ospf6_flood_area (from, lsa, oa);
432 }
433}
434
435void
436ospf6_flood (struct ospf6_neighbor *from, struct ospf6_lsa *lsa)
437{
438 ospf6_flood_process (from, lsa, ospf6);
439}
440
Paul Jakma6ac29a52008-08-15 13:45:30 +0100441static void
hasso6452df02004-08-15 05:52:07 +0000442ospf6_flood_clear_interface (struct ospf6_lsa *lsa, struct ospf6_interface *oi)
443{
paul1eb8ef22005-04-07 07:30:20 +0000444 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000445 struct ospf6_neighbor *on;
446 struct ospf6_lsa *rem;
447
paul1eb8ef22005-04-07 07:30:20 +0000448 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
hasso6452df02004-08-15 05:52:07 +0000449 {
hasso6452df02004-08-15 05:52:07 +0000450 rem = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
451 lsa->header->adv_router, on->retrans_list);
452 if (rem && ! ospf6_lsa_compare (rem, lsa))
453 {
hasso1e058382004-09-01 21:36:14 +0000454 if (IS_OSPF6_DEBUG_FLOODING ||
455 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
hassoc6487d62004-12-24 06:00:11 +0000456 zlog_debug ("Remove %s from retrans_list of %s",
hasso6452df02004-08-15 05:52:07 +0000457 rem->name, on->name);
458 ospf6_decrement_retrans_count (rem);
459 ospf6_lsdb_remove (rem, on->retrans_list);
460 }
461 }
462}
463
Paul Jakma6ac29a52008-08-15 13:45:30 +0100464static void
hasso6452df02004-08-15 05:52:07 +0000465ospf6_flood_clear_area (struct ospf6_lsa *lsa, struct ospf6_area *oa)
466{
paul1eb8ef22005-04-07 07:30:20 +0000467 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000468 struct ospf6_interface *oi;
469
paul1eb8ef22005-04-07 07:30:20 +0000470 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
hasso6452df02004-08-15 05:52:07 +0000471 {
hasso6452df02004-08-15 05:52:07 +0000472 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
473 oi != OSPF6_INTERFACE (lsa->lsdb->data))
474 continue;
475
476#if 0
477 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
478 ospf6_is_interface_virtual_link (oi))
479 continue;
480#endif/*0*/
481
482 ospf6_flood_clear_interface (lsa, oi);
483 }
484}
485
Paul Jakma6ac29a52008-08-15 13:45:30 +0100486static void
hasso6452df02004-08-15 05:52:07 +0000487ospf6_flood_clear_process (struct ospf6_lsa *lsa, struct ospf6 *process)
488{
paul1eb8ef22005-04-07 07:30:20 +0000489 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000490 struct ospf6_area *oa;
491
paul1eb8ef22005-04-07 07:30:20 +0000492 for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa))
hasso6452df02004-08-15 05:52:07 +0000493 {
hasso6452df02004-08-15 05:52:07 +0000494 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
495 oa != OSPF6_AREA (lsa->lsdb->data))
496 continue;
497 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
498 oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
499 continue;
500
501 if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
502 IS_AREA_STUB (oa))
503 continue;
504
505 ospf6_flood_clear_area (lsa, oa);
506 }
507}
508
509void
510ospf6_flood_clear (struct ospf6_lsa *lsa)
511{
512 ospf6_flood_clear_process (lsa, ospf6);
513}
514
515
hasso48454372004-05-18 19:14:52 +0000516/* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
517static void
518ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
519 struct ospf6_neighbor *from)
520{
521 struct ospf6_interface *oi;
hasso1e058382004-09-01 21:36:14 +0000522 int is_debug = 0;
523
524 if (IS_OSPF6_DEBUG_FLOODING ||
525 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
526 is_debug++;
hasso48454372004-05-18 19:14:52 +0000527
528 assert (from && from->ospf6_if);
529 oi = from->ospf6_if;
530
531 /* LSA has been flood back out receiving interface.
532 No acknowledgement sent. */
533 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
534 {
hasso1e058382004-09-01 21:36:14 +0000535 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000536 zlog_debug ("No acknowledgement (BDR & FloodBack)");
hasso48454372004-05-18 19:14:52 +0000537 return;
538 }
539
540 /* LSA is more recent than database copy, but was not flooded
541 back out receiving interface. Delayed acknowledgement sent
542 if advertisement received from Designated Router,
543 otherwide do nothing. */
544 if (ismore_recent < 0)
545 {
hasso48454372004-05-18 19:14:52 +0000546 if (oi->drouter == from->router_id)
547 {
hasso1e058382004-09-01 21:36:14 +0000548 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000549 zlog_debug ("Delayed acknowledgement (BDR & MoreRecent & from DR)");
hasso48454372004-05-18 19:14:52 +0000550 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000551 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
552 if (oi->thread_send_lsack == NULL)
553 oi->thread_send_lsack =
554 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
555 }
556 else
557 {
hasso1e058382004-09-01 21:36:14 +0000558 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000559 zlog_debug ("No acknowledgement (BDR & MoreRecent & ! from DR)");
hasso48454372004-05-18 19:14:52 +0000560 }
561 return;
562 }
563
564 /* LSA is a duplicate, and was treated as an implied acknowledgement.
565 Delayed acknowledgement sent if advertisement received from
566 Designated Router, otherwise do nothing */
567 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
568 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
569 {
hasso48454372004-05-18 19:14:52 +0000570 if (oi->drouter == from->router_id)
571 {
hasso1e058382004-09-01 21:36:14 +0000572 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000573 zlog_debug ("Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
hasso48454372004-05-18 19:14:52 +0000574 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000575 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
576 if (oi->thread_send_lsack == NULL)
577 oi->thread_send_lsack =
578 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
579 }
580 else
581 {
hasso1e058382004-09-01 21:36:14 +0000582 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000583 zlog_debug ("No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
hasso48454372004-05-18 19:14:52 +0000584 }
585 return;
586 }
587
588 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
589 Direct acknowledgement sent */
590 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
591 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
592 {
hasso1e058382004-09-01 21:36:14 +0000593 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000594 zlog_debug ("Direct acknowledgement (BDR & Duplicate)");
hasso48454372004-05-18 19:14:52 +0000595 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
596 if (from->thread_send_lsack == NULL)
597 from->thread_send_lsack =
598 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
599 return;
600 }
601
602 /* LSA's LS age is equal to Maxage, and there is no current instance
603 of the LSA in the link state database, and none of router's
604 neighbors are in states Exchange or Loading */
605 /* Direct acknowledgement sent, but this case is handled in
606 early of ospf6_receive_lsa () */
607}
608
609static void
610ospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent,
611 struct ospf6_neighbor *from)
612{
613 struct ospf6_interface *oi;
hasso1e058382004-09-01 21:36:14 +0000614 int is_debug = 0;
615
616 if (IS_OSPF6_DEBUG_FLOODING ||
617 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
618 is_debug++;
hasso48454372004-05-18 19:14:52 +0000619
620 assert (from && from->ospf6_if);
621 oi = from->ospf6_if;
622
623 /* LSA has been flood back out receiving interface.
624 No acknowledgement sent. */
625 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
626 {
hasso1e058382004-09-01 21:36:14 +0000627 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000628 zlog_debug ("No acknowledgement (AllOther & FloodBack)");
hasso48454372004-05-18 19:14:52 +0000629 return;
630 }
631
632 /* LSA is more recent than database copy, but was not flooded
633 back out receiving interface. Delayed acknowledgement sent. */
634 if (ismore_recent < 0)
635 {
hasso1e058382004-09-01 21:36:14 +0000636 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000637 zlog_debug ("Delayed acknowledgement (AllOther & MoreRecent)");
hasso48454372004-05-18 19:14:52 +0000638 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000639 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
640 if (oi->thread_send_lsack == NULL)
641 oi->thread_send_lsack =
642 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
643 return;
644 }
645
646 /* LSA is a duplicate, and was treated as an implied acknowledgement.
647 No acknowledgement sent. */
648 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
649 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
650 {
hasso1e058382004-09-01 21:36:14 +0000651 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000652 zlog_debug ("No acknowledgement (AllOther & Duplicate & ImpliedAck)");
hasso48454372004-05-18 19:14:52 +0000653 return;
654 }
655
656 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
657 Direct acknowledgement sent */
658 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
659 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
660 {
hasso1e058382004-09-01 21:36:14 +0000661 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000662 zlog_debug ("Direct acknowledgement (AllOther & Duplicate)");
hasso48454372004-05-18 19:14:52 +0000663 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
664 if (from->thread_send_lsack == NULL)
665 from->thread_send_lsack =
666 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
667 return;
668 }
669
670 /* LSA's LS age is equal to Maxage, and there is no current instance
671 of the LSA in the link state database, and none of router's
672 neighbors are in states Exchange or Loading */
673 /* Direct acknowledgement sent, but this case is handled in
674 early of ospf6_receive_lsa () */
675}
676
Paul Jakma6ac29a52008-08-15 13:45:30 +0100677static void
hasso48454372004-05-18 19:14:52 +0000678ospf6_acknowledge_lsa (struct ospf6_lsa *lsa, int ismore_recent,
679 struct ospf6_neighbor *from)
680{
681 struct ospf6_interface *oi;
682
683 assert (from && from->ospf6_if);
684 oi = from->ospf6_if;
685
686 if (oi->state == OSPF6_INTERFACE_BDR)
687 ospf6_acknowledge_lsa_bdrouter (lsa, ismore_recent, from);
688 else
689 ospf6_acknowledge_lsa_allother (lsa, ismore_recent, from);
690}
691
692/* RFC2328 section 13 (4):
693 if MaxAge LSA and if we have no instance, and no neighbor
694 is in states Exchange or Loading
695 returns 1 if match this case, else returns 0 */
696static int
hasso6452df02004-08-15 05:52:07 +0000697ospf6_is_maxage_lsa_drop (struct ospf6_lsa *lsa, struct ospf6_neighbor *from)
hasso48454372004-05-18 19:14:52 +0000698{
hasso48454372004-05-18 19:14:52 +0000699 struct ospf6_neighbor *on;
hasso6452df02004-08-15 05:52:07 +0000700 struct ospf6_interface *oi;
701 struct ospf6_area *oa;
702 struct ospf6 *process = NULL;
hasso52dc7ee2004-09-23 19:18:23 +0000703 struct listnode *i, *j, *k;
hasso48454372004-05-18 19:14:52 +0000704 int count = 0;
705
706 if (! OSPF6_LSA_IS_MAXAGE (lsa))
707 return 0;
708
hasso48454372004-05-18 19:14:52 +0000709 if (ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
hasso6452df02004-08-15 05:52:07 +0000710 lsa->header->adv_router, lsa->lsdb))
hasso48454372004-05-18 19:14:52 +0000711 return 0;
712
hasso6452df02004-08-15 05:52:07 +0000713 process = from->ospf6_if->area->ospf6;
paul1eb8ef22005-04-07 07:30:20 +0000714
715 for (ALL_LIST_ELEMENTS_RO (process->area_list, i, oa))
716 for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
717 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on))
718 if (on->state == OSPF6_NEIGHBOR_EXCHANGE ||
719 on->state == OSPF6_NEIGHBOR_LOADING)
720 count++;
hasso48454372004-05-18 19:14:52 +0000721
hasso48454372004-05-18 19:14:52 +0000722 if (count == 0)
723 return 1;
hasso48454372004-05-18 19:14:52 +0000724 return 0;
725}
726
727/* RFC2328 section 13 The Flooding Procedure */
728void
hasso6452df02004-08-15 05:52:07 +0000729ospf6_receive_lsa (struct ospf6_neighbor *from,
730 struct ospf6_lsa_header *lsa_header)
hasso48454372004-05-18 19:14:52 +0000731{
732 struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
733 int ismore_recent;
hasso1e058382004-09-01 21:36:14 +0000734 int is_debug = 0;
hasso48454372004-05-18 19:14:52 +0000735
736 ismore_recent = 1;
hasso6452df02004-08-15 05:52:07 +0000737 assert (from);
hasso48454372004-05-18 19:14:52 +0000738
739 /* make lsa structure for received lsa */
740 new = ospf6_lsa_create (lsa_header);
741
hasso1e058382004-09-01 21:36:14 +0000742 if (IS_OSPF6_DEBUG_FLOODING ||
743 IS_OSPF6_DEBUG_FLOOD_TYPE (new->header->type))
hasso48454372004-05-18 19:14:52 +0000744 {
hasso1e058382004-09-01 21:36:14 +0000745 is_debug++;
hassoc6487d62004-12-24 06:00:11 +0000746 zlog_debug ("LSA Receive from %s", from->name);
hasso48454372004-05-18 19:14:52 +0000747 ospf6_lsa_header_print (new);
748 }
749
hasso48454372004-05-18 19:14:52 +0000750 /* (1) LSA Checksum */
JR Riversd8a4e422012-09-13 17:17:36 +0000751 if (! ospf6_lsa_checksum_valid (new->header))
hasso48454372004-05-18 19:14:52 +0000752 {
hasso1e058382004-09-01 21:36:14 +0000753 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000754 zlog_debug ("Wrong LSA Checksum, discard");
hasso48454372004-05-18 19:14:52 +0000755 ospf6_lsa_delete (new);
756 return;
757 }
758
hasso6452df02004-08-15 05:52:07 +0000759 /* (2) Examine the LSA's LS type.
760 RFC2470 3.5.1. Receiving Link State Update packets */
761 if (IS_AREA_STUB (from->ospf6_if->area) &&
762 OSPF6_LSA_SCOPE (new->header->type) == OSPF6_SCOPE_AS)
hasso48454372004-05-18 19:14:52 +0000763 {
hasso1e058382004-09-01 21:36:14 +0000764 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000765 zlog_debug ("AS-External-LSA (or AS-scope LSA) in stub area, discard");
hasso6452df02004-08-15 05:52:07 +0000766 ospf6_lsa_delete (new);
767 return;
768 }
769
770 /* (3) LSA which have reserved scope is discarded
771 RFC2470 3.5.1. Receiving Link State Update packets */
772 /* Flooding scope check. LSAs with unknown scope are discarded here.
773 Set appropriate LSDB for the LSA */
774 switch (OSPF6_LSA_SCOPE (new->header->type))
775 {
776 case OSPF6_SCOPE_LINKLOCAL:
777 new->lsdb = from->ospf6_if->lsdb;
778 break;
779 case OSPF6_SCOPE_AREA:
780 new->lsdb = from->ospf6_if->area->lsdb;
781 break;
782 case OSPF6_SCOPE_AS:
783 new->lsdb = from->ospf6_if->area->ospf6->lsdb;
784 break;
785 default:
hasso1e058382004-09-01 21:36:14 +0000786 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000787 zlog_debug ("LSA has reserved scope, discard");
hasso48454372004-05-18 19:14:52 +0000788 ospf6_lsa_delete (new);
789 return;
790 }
791
792 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
793 is in states Exchange or Loading */
794 if (ospf6_is_maxage_lsa_drop (new, from))
795 {
796 /* log */
hasso1e058382004-09-01 21:36:14 +0000797 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000798 zlog_debug ("Drop MaxAge LSA with direct acknowledgement.");
hasso48454372004-05-18 19:14:52 +0000799
800 /* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */
hasso6452df02004-08-15 05:52:07 +0000801 ospf6_lsdb_add (ospf6_lsa_copy (new), from->lsack_list);
hasso48454372004-05-18 19:14:52 +0000802 if (from->thread_send_lsack == NULL)
803 from->thread_send_lsack =
804 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
805
806 /* b) Discard */
hasso6452df02004-08-15 05:52:07 +0000807 ospf6_lsa_delete (new);
hasso48454372004-05-18 19:14:52 +0000808 return;
809 }
810
811 /* (5) */
812 /* lookup the same database copy in lsdb */
hasso48454372004-05-18 19:14:52 +0000813 old = ospf6_lsdb_lookup (new->header->type, new->header->id,
hasso6452df02004-08-15 05:52:07 +0000814 new->header->adv_router, new->lsdb);
hasso48454372004-05-18 19:14:52 +0000815 if (old)
816 {
817 ismore_recent = ospf6_lsa_compare (new, old);
818 if (ntohl (new->header->seqnum) == ntohl (old->header->seqnum))
819 {
hasso1e058382004-09-01 21:36:14 +0000820 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000821 zlog_debug ("Received is duplicated LSA");
hasso48454372004-05-18 19:14:52 +0000822 SET_FLAG (new->flag, OSPF6_LSA_DUPLICATE);
823 }
824 }
825
826 /* if no database copy or received is more recent */
827 if (old == NULL || ismore_recent < 0)
828 {
829 /* in case we have no database copy */
830 ismore_recent = -1;
831
832 /* (a) MinLSArrival check */
833 if (old)
834 {
835 struct timeval now, res;
Takashi Sogabe86f72dc2009-06-22 13:07:02 +0900836 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
hasso48454372004-05-18 19:14:52 +0000837 timersub (&now, &old->installed, &res);
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700838 if (res.tv_sec < OSPF_MIN_LS_ARRIVAL)
hasso48454372004-05-18 19:14:52 +0000839 {
hasso1e058382004-09-01 21:36:14 +0000840 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000841 zlog_debug ("LSA can't be updated within MinLSArrival, discard");
hasso48454372004-05-18 19:14:52 +0000842 ospf6_lsa_delete (new);
843 return; /* examin next lsa */
844 }
845 }
846
Takashi Sogabe86f72dc2009-06-22 13:07:02 +0900847 quagga_gettime (QUAGGA_CLK_MONOTONIC, &new->received);
hassoccb59b12004-08-25 09:10:37 +0000848
hasso1e058382004-09-01 21:36:14 +0000849 if (is_debug)
Dinesh Duttbf986da2013-08-24 07:54:50 +0000850 zlog_debug ("Install, Flood, Possibly acknowledge the received LSA");
851
852 /* Remove older copies of this LSA from retx lists */
853 if (old)
854 ospf6_flood_clear (old);
hasso6452df02004-08-15 05:52:07 +0000855
hasso48454372004-05-18 19:14:52 +0000856 /* (b) immediately flood and (c) remove from all retrans-list */
hassoccb59b12004-08-25 09:10:37 +0000857 /* Prevent self-originated LSA to be flooded. this is to make
858 reoriginated instance of the LSA not to be rejected by other routers
859 due to MinLSArrival. */
860 if (new->header->adv_router != from->ospf6_if->area->ospf6->router_id)
861 ospf6_flood (from, new);
hasso6452df02004-08-15 05:52:07 +0000862
hasso48454372004-05-18 19:14:52 +0000863 /* (d), installing lsdb, which may cause routing
864 table calculation (replacing database copy) */
hasso6452df02004-08-15 05:52:07 +0000865 ospf6_install_lsa (new);
hasso48454372004-05-18 19:14:52 +0000866
867 /* (e) possibly acknowledge */
868 ospf6_acknowledge_lsa (new, ismore_recent, from);
869
hasso6452df02004-08-15 05:52:07 +0000870 /* (f) Self Originated LSA, section 13.4 */
871 if (new->header->adv_router == from->ospf6_if->area->ospf6->router_id)
hasso48454372004-05-18 19:14:52 +0000872 {
hasso6452df02004-08-15 05:52:07 +0000873 /* Self-originated LSA (newer than ours) is received from
874 another router. We have to make a new instance of the LSA
hasso48454372004-05-18 19:14:52 +0000875 or have to flush this LSA. */
hasso1e058382004-09-01 21:36:14 +0000876 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000877 {
hassoc6487d62004-12-24 06:00:11 +0000878 zlog_debug ("Newer instance of the self-originated LSA");
879 zlog_debug ("Schedule reorigination");
hasso6452df02004-08-15 05:52:07 +0000880 }
881 new->refresh = thread_add_event (master, ospf6_lsa_refresh, new, 0);
hasso48454372004-05-18 19:14:52 +0000882 }
hasso6452df02004-08-15 05:52:07 +0000883
hasso48454372004-05-18 19:14:52 +0000884 return;
885 }
886
887 /* (6) if there is instance on sending neighbor's request list */
888 if (ospf6_lsdb_lookup (new->header->type, new->header->id,
889 new->header->adv_router, from->request_list))
890 {
891 /* if no database copy, should go above state (5) */
892 assert (old);
893
hasso1e058382004-09-01 21:36:14 +0000894 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000895 {
hassoc6487d62004-12-24 06:00:11 +0000896 zlog_debug ("Received is not newer, on the neighbor's request-list");
897 zlog_debug ("BadLSReq, discard the received LSA");
hasso6452df02004-08-15 05:52:07 +0000898 }
hasso48454372004-05-18 19:14:52 +0000899
900 /* BadLSReq */
901 thread_add_event (master, bad_lsreq, from, 0);
902
903 ospf6_lsa_delete (new);
904 return;
905 }
906
907 /* (7) if neither one is more recent */
908 if (ismore_recent == 0)
909 {
hasso1e058382004-09-01 21:36:14 +0000910 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000911 zlog_debug ("The same instance as database copy (neither recent)");
hasso48454372004-05-18 19:14:52 +0000912
913 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack */
914 rem = ospf6_lsdb_lookup (new->header->type, new->header->id,
915 new->header->adv_router, from->retrans_list);
916 if (rem)
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 ("It is on the neighbor's retrans-list.");
921 zlog_debug ("Treat as an Implied acknowledgement");
hasso6452df02004-08-15 05:52:07 +0000922 }
hasso48454372004-05-18 19:14:52 +0000923 SET_FLAG (new->flag, OSPF6_LSA_IMPLIEDACK);
hasso6452df02004-08-15 05:52:07 +0000924 ospf6_decrement_retrans_count (rem);
hasso48454372004-05-18 19:14:52 +0000925 ospf6_lsdb_remove (rem, from->retrans_list);
926 }
927
hasso1e058382004-09-01 21:36:14 +0000928 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000929 zlog_debug ("Possibly acknowledge and then discard");
hasso6452df02004-08-15 05:52:07 +0000930
hasso48454372004-05-18 19:14:52 +0000931 /* (b) possibly acknowledge */
932 ospf6_acknowledge_lsa (new, ismore_recent, from);
933
934 ospf6_lsa_delete (new);
935 return;
936 }
937
938 /* (8) previous database copy is more recent */
939 {
940 assert (old);
941
942 /* If database copy is in 'Seqnumber Wrapping',
943 simply discard the received LSA */
944 if (OSPF6_LSA_IS_MAXAGE (old) &&
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700945 old->header->seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
hasso48454372004-05-18 19:14:52 +0000946 {
hasso1e058382004-09-01 21:36:14 +0000947 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000948 {
hassoc6487d62004-12-24 06:00:11 +0000949 zlog_debug ("The LSA is in Seqnumber Wrapping");
950 zlog_debug ("MaxAge & MaxSeqNum, discard");
hasso6452df02004-08-15 05:52:07 +0000951 }
hasso48454372004-05-18 19:14:52 +0000952 ospf6_lsa_delete (new);
953 return;
954 }
955
956 /* Otherwise, Send database copy of this LSA to this neighbor */
957 {
hasso1e058382004-09-01 21:36:14 +0000958 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000959 {
hassoc6487d62004-12-24 06:00:11 +0000960 zlog_debug ("Database copy is more recent.");
961 zlog_debug ("Send back directly and then discard");
hasso6452df02004-08-15 05:52:07 +0000962 }
hasso48454372004-05-18 19:14:52 +0000963
964 /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
965
hasso48454372004-05-18 19:14:52 +0000966 ospf6_lsdb_add (ospf6_lsa_copy (old), from->lsupdate_list);
967 if (from->thread_send_lsupdate == NULL)
968 from->thread_send_lsupdate =
969 thread_add_event (master, ospf6_lsupdate_send_neighbor, from, 0);
970 ospf6_lsa_delete (new);
971 return;
972 }
973 return;
974 }
975}
976
977
hasso1e058382004-09-01 21:36:14 +0000978DEFUN (debug_ospf6_flooding,
979 debug_ospf6_flooding_cmd,
980 "debug ospf6 flooding",
981 DEBUG_STR
982 OSPF6_STR
983 "Debug OSPFv3 flooding function\n"
984 )
985{
986 OSPF6_DEBUG_FLOODING_ON ();
987 return CMD_SUCCESS;
988}
989
990DEFUN (no_debug_ospf6_flooding,
991 no_debug_ospf6_flooding_cmd,
992 "no debug ospf6 flooding",
993 NO_STR
994 DEBUG_STR
995 OSPF6_STR
996 "Debug OSPFv3 flooding function\n"
997 )
998{
999 OSPF6_DEBUG_FLOODING_OFF ();
1000 return CMD_SUCCESS;
1001}
1002
1003int
1004config_write_ospf6_debug_flood (struct vty *vty)
1005{
1006 if (IS_OSPF6_DEBUG_FLOODING)
1007 vty_out (vty, "debug ospf6 flooding%s", VNL);
1008 return 0;
1009}
1010
1011void
Paul Jakma6ac29a52008-08-15 13:45:30 +01001012install_element_ospf6_debug_flood (void)
hasso1e058382004-09-01 21:36:14 +00001013{
1014 install_element (ENABLE_NODE, &debug_ospf6_flooding_cmd);
1015 install_element (ENABLE_NODE, &no_debug_ospf6_flooding_cmd);
1016 install_element (CONFIG_NODE, &debug_ospf6_flooding_cmd);
1017 install_element (CONFIG_NODE, &no_debug_ospf6_flooding_cmd);
1018}
1019
1020
1021
1022
hasso48454372004-05-18 19:14:52 +00001023