blob: beae699274be2ea5748abb5b6889cc2dab1f8826 [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");
Dinesh Duttc5926a92013-08-24 07:55:00 +0000369 if ((oi->type == OSPF_IFTYPE_BROADCAST) ||
370 (oi->type == OSPF_IFTYPE_POINTOPOINT))
hasso6452df02004-08-15 05:52:07 +0000371 {
372 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list);
373 if (oi->thread_send_lsupdate == NULL)
374 oi->thread_send_lsupdate =
375 thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
376 }
377 else
378 {
379 /* reschedule retransmissions to all neighbors */
paul1eb8ef22005-04-07 07:30:20 +0000380 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
hasso6452df02004-08-15 05:52:07 +0000381 {
hasso6452df02004-08-15 05:52:07 +0000382 THREAD_OFF (on->thread_send_lsupdate);
383 on->thread_send_lsupdate =
384 thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
385 }
386 }
hasso48454372004-05-18 19:14:52 +0000387}
388
Paul Jakma6ac29a52008-08-15 13:45:30 +0100389static void
hasso6452df02004-08-15 05:52:07 +0000390ospf6_flood_area (struct ospf6_neighbor *from,
391 struct ospf6_lsa *lsa, struct ospf6_area *oa)
392{
paul1eb8ef22005-04-07 07:30:20 +0000393 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000394 struct ospf6_interface *oi;
395
paul1eb8ef22005-04-07 07:30:20 +0000396 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
hasso6452df02004-08-15 05:52:07 +0000397 {
hasso6452df02004-08-15 05:52:07 +0000398 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
399 oi != OSPF6_INTERFACE (lsa->lsdb->data))
400 continue;
401
402#if 0
403 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
404 ospf6_is_interface_virtual_link (oi))
405 continue;
406#endif/*0*/
407
408 ospf6_flood_interface (from, lsa, oi);
409 }
410}
411
Paul Jakma6ac29a52008-08-15 13:45:30 +0100412static void
hasso6452df02004-08-15 05:52:07 +0000413ospf6_flood_process (struct ospf6_neighbor *from,
414 struct ospf6_lsa *lsa, struct ospf6 *process)
415{
paul1eb8ef22005-04-07 07:30:20 +0000416 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000417 struct ospf6_area *oa;
418
paul1eb8ef22005-04-07 07:30:20 +0000419 for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa))
hasso6452df02004-08-15 05:52:07 +0000420 {
hasso6452df02004-08-15 05:52:07 +0000421 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
422 oa != OSPF6_AREA (lsa->lsdb->data))
423 continue;
424 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
425 oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
426 continue;
427
428 if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
429 IS_AREA_STUB (oa))
430 continue;
431
432 ospf6_flood_area (from, lsa, oa);
433 }
434}
435
436void
437ospf6_flood (struct ospf6_neighbor *from, struct ospf6_lsa *lsa)
438{
439 ospf6_flood_process (from, lsa, ospf6);
440}
441
Paul Jakma6ac29a52008-08-15 13:45:30 +0100442static void
hasso6452df02004-08-15 05:52:07 +0000443ospf6_flood_clear_interface (struct ospf6_lsa *lsa, struct ospf6_interface *oi)
444{
paul1eb8ef22005-04-07 07:30:20 +0000445 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000446 struct ospf6_neighbor *on;
447 struct ospf6_lsa *rem;
448
paul1eb8ef22005-04-07 07:30:20 +0000449 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
hasso6452df02004-08-15 05:52:07 +0000450 {
hasso6452df02004-08-15 05:52:07 +0000451 rem = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
452 lsa->header->adv_router, on->retrans_list);
453 if (rem && ! ospf6_lsa_compare (rem, lsa))
454 {
hasso1e058382004-09-01 21:36:14 +0000455 if (IS_OSPF6_DEBUG_FLOODING ||
456 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
hassoc6487d62004-12-24 06:00:11 +0000457 zlog_debug ("Remove %s from retrans_list of %s",
hasso6452df02004-08-15 05:52:07 +0000458 rem->name, on->name);
459 ospf6_decrement_retrans_count (rem);
460 ospf6_lsdb_remove (rem, on->retrans_list);
461 }
462 }
463}
464
Paul Jakma6ac29a52008-08-15 13:45:30 +0100465static void
hasso6452df02004-08-15 05:52:07 +0000466ospf6_flood_clear_area (struct ospf6_lsa *lsa, struct ospf6_area *oa)
467{
paul1eb8ef22005-04-07 07:30:20 +0000468 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000469 struct ospf6_interface *oi;
470
paul1eb8ef22005-04-07 07:30:20 +0000471 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
hasso6452df02004-08-15 05:52:07 +0000472 {
hasso6452df02004-08-15 05:52:07 +0000473 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
474 oi != OSPF6_INTERFACE (lsa->lsdb->data))
475 continue;
476
477#if 0
478 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
479 ospf6_is_interface_virtual_link (oi))
480 continue;
481#endif/*0*/
482
483 ospf6_flood_clear_interface (lsa, oi);
484 }
485}
486
Paul Jakma6ac29a52008-08-15 13:45:30 +0100487static void
hasso6452df02004-08-15 05:52:07 +0000488ospf6_flood_clear_process (struct ospf6_lsa *lsa, struct ospf6 *process)
489{
paul1eb8ef22005-04-07 07:30:20 +0000490 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000491 struct ospf6_area *oa;
492
paul1eb8ef22005-04-07 07:30:20 +0000493 for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa))
hasso6452df02004-08-15 05:52:07 +0000494 {
hasso6452df02004-08-15 05:52:07 +0000495 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
496 oa != OSPF6_AREA (lsa->lsdb->data))
497 continue;
498 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
499 oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
500 continue;
501
502 if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
503 IS_AREA_STUB (oa))
504 continue;
505
506 ospf6_flood_clear_area (lsa, oa);
507 }
508}
509
510void
511ospf6_flood_clear (struct ospf6_lsa *lsa)
512{
513 ospf6_flood_clear_process (lsa, ospf6);
514}
515
516
hasso48454372004-05-18 19:14:52 +0000517/* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
518static void
519ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
520 struct ospf6_neighbor *from)
521{
522 struct ospf6_interface *oi;
hasso1e058382004-09-01 21:36:14 +0000523 int is_debug = 0;
524
525 if (IS_OSPF6_DEBUG_FLOODING ||
526 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
527 is_debug++;
hasso48454372004-05-18 19:14:52 +0000528
529 assert (from && from->ospf6_if);
530 oi = from->ospf6_if;
531
532 /* LSA has been flood back out receiving interface.
533 No acknowledgement sent. */
534 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
535 {
hasso1e058382004-09-01 21:36:14 +0000536 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000537 zlog_debug ("No acknowledgement (BDR & FloodBack)");
hasso48454372004-05-18 19:14:52 +0000538 return;
539 }
540
541 /* LSA is more recent than database copy, but was not flooded
542 back out receiving interface. Delayed acknowledgement sent
543 if advertisement received from Designated Router,
544 otherwide do nothing. */
545 if (ismore_recent < 0)
546 {
hasso48454372004-05-18 19:14:52 +0000547 if (oi->drouter == from->router_id)
548 {
hasso1e058382004-09-01 21:36:14 +0000549 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000550 zlog_debug ("Delayed acknowledgement (BDR & MoreRecent & from DR)");
hasso48454372004-05-18 19:14:52 +0000551 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000552 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
553 if (oi->thread_send_lsack == NULL)
554 oi->thread_send_lsack =
555 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
556 }
557 else
558 {
hasso1e058382004-09-01 21:36:14 +0000559 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000560 zlog_debug ("No acknowledgement (BDR & MoreRecent & ! from DR)");
hasso48454372004-05-18 19:14:52 +0000561 }
562 return;
563 }
564
565 /* LSA is a duplicate, and was treated as an implied acknowledgement.
566 Delayed acknowledgement sent if advertisement received from
567 Designated Router, otherwise do nothing */
568 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
569 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
570 {
hasso48454372004-05-18 19:14:52 +0000571 if (oi->drouter == from->router_id)
572 {
hasso1e058382004-09-01 21:36:14 +0000573 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000574 zlog_debug ("Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
hasso48454372004-05-18 19:14:52 +0000575 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000576 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
577 if (oi->thread_send_lsack == NULL)
578 oi->thread_send_lsack =
579 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
580 }
581 else
582 {
hasso1e058382004-09-01 21:36:14 +0000583 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000584 zlog_debug ("No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
hasso48454372004-05-18 19:14:52 +0000585 }
586 return;
587 }
588
589 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
590 Direct acknowledgement sent */
591 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
592 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
593 {
hasso1e058382004-09-01 21:36:14 +0000594 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000595 zlog_debug ("Direct acknowledgement (BDR & Duplicate)");
hasso48454372004-05-18 19:14:52 +0000596 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
597 if (from->thread_send_lsack == NULL)
598 from->thread_send_lsack =
599 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
600 return;
601 }
602
603 /* LSA's LS age is equal to Maxage, and there is no current instance
604 of the LSA in the link state database, and none of router's
605 neighbors are in states Exchange or Loading */
606 /* Direct acknowledgement sent, but this case is handled in
607 early of ospf6_receive_lsa () */
608}
609
610static void
611ospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent,
612 struct ospf6_neighbor *from)
613{
614 struct ospf6_interface *oi;
hasso1e058382004-09-01 21:36:14 +0000615 int is_debug = 0;
616
617 if (IS_OSPF6_DEBUG_FLOODING ||
618 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
619 is_debug++;
hasso48454372004-05-18 19:14:52 +0000620
621 assert (from && from->ospf6_if);
622 oi = from->ospf6_if;
623
624 /* LSA has been flood back out receiving interface.
625 No acknowledgement sent. */
626 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
627 {
hasso1e058382004-09-01 21:36:14 +0000628 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000629 zlog_debug ("No acknowledgement (AllOther & FloodBack)");
hasso48454372004-05-18 19:14:52 +0000630 return;
631 }
632
633 /* LSA is more recent than database copy, but was not flooded
634 back out receiving interface. Delayed acknowledgement sent. */
635 if (ismore_recent < 0)
636 {
hasso1e058382004-09-01 21:36:14 +0000637 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000638 zlog_debug ("Delayed acknowledgement (AllOther & MoreRecent)");
hasso48454372004-05-18 19:14:52 +0000639 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000640 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
641 if (oi->thread_send_lsack == NULL)
642 oi->thread_send_lsack =
643 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
644 return;
645 }
646
647 /* LSA is a duplicate, and was treated as an implied acknowledgement.
648 No acknowledgement sent. */
649 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
650 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
651 {
hasso1e058382004-09-01 21:36:14 +0000652 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000653 zlog_debug ("No acknowledgement (AllOther & Duplicate & ImpliedAck)");
hasso48454372004-05-18 19:14:52 +0000654 return;
655 }
656
657 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
658 Direct acknowledgement sent */
659 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
660 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
661 {
hasso1e058382004-09-01 21:36:14 +0000662 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000663 zlog_debug ("Direct acknowledgement (AllOther & Duplicate)");
hasso48454372004-05-18 19:14:52 +0000664 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
665 if (from->thread_send_lsack == NULL)
666 from->thread_send_lsack =
667 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
668 return;
669 }
670
671 /* LSA's LS age is equal to Maxage, and there is no current instance
672 of the LSA in the link state database, and none of router's
673 neighbors are in states Exchange or Loading */
674 /* Direct acknowledgement sent, but this case is handled in
675 early of ospf6_receive_lsa () */
676}
677
Paul Jakma6ac29a52008-08-15 13:45:30 +0100678static void
hasso48454372004-05-18 19:14:52 +0000679ospf6_acknowledge_lsa (struct ospf6_lsa *lsa, int ismore_recent,
680 struct ospf6_neighbor *from)
681{
682 struct ospf6_interface *oi;
683
684 assert (from && from->ospf6_if);
685 oi = from->ospf6_if;
686
687 if (oi->state == OSPF6_INTERFACE_BDR)
688 ospf6_acknowledge_lsa_bdrouter (lsa, ismore_recent, from);
689 else
690 ospf6_acknowledge_lsa_allother (lsa, ismore_recent, from);
691}
692
693/* RFC2328 section 13 (4):
694 if MaxAge LSA and if we have no instance, and no neighbor
695 is in states Exchange or Loading
696 returns 1 if match this case, else returns 0 */
697static int
hasso6452df02004-08-15 05:52:07 +0000698ospf6_is_maxage_lsa_drop (struct ospf6_lsa *lsa, struct ospf6_neighbor *from)
hasso48454372004-05-18 19:14:52 +0000699{
hasso48454372004-05-18 19:14:52 +0000700 struct ospf6_neighbor *on;
hasso6452df02004-08-15 05:52:07 +0000701 struct ospf6_interface *oi;
702 struct ospf6_area *oa;
703 struct ospf6 *process = NULL;
hasso52dc7ee2004-09-23 19:18:23 +0000704 struct listnode *i, *j, *k;
hasso48454372004-05-18 19:14:52 +0000705 int count = 0;
706
707 if (! OSPF6_LSA_IS_MAXAGE (lsa))
708 return 0;
709
hasso48454372004-05-18 19:14:52 +0000710 if (ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
hasso6452df02004-08-15 05:52:07 +0000711 lsa->header->adv_router, lsa->lsdb))
hasso48454372004-05-18 19:14:52 +0000712 return 0;
713
hasso6452df02004-08-15 05:52:07 +0000714 process = from->ospf6_if->area->ospf6;
paul1eb8ef22005-04-07 07:30:20 +0000715
716 for (ALL_LIST_ELEMENTS_RO (process->area_list, i, oa))
717 for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
718 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on))
719 if (on->state == OSPF6_NEIGHBOR_EXCHANGE ||
720 on->state == OSPF6_NEIGHBOR_LOADING)
721 count++;
hasso48454372004-05-18 19:14:52 +0000722
hasso48454372004-05-18 19:14:52 +0000723 if (count == 0)
724 return 1;
hasso48454372004-05-18 19:14:52 +0000725 return 0;
726}
727
728/* RFC2328 section 13 The Flooding Procedure */
729void
hasso6452df02004-08-15 05:52:07 +0000730ospf6_receive_lsa (struct ospf6_neighbor *from,
731 struct ospf6_lsa_header *lsa_header)
hasso48454372004-05-18 19:14:52 +0000732{
733 struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
734 int ismore_recent;
hasso1e058382004-09-01 21:36:14 +0000735 int is_debug = 0;
hasso48454372004-05-18 19:14:52 +0000736
737 ismore_recent = 1;
hasso6452df02004-08-15 05:52:07 +0000738 assert (from);
hasso48454372004-05-18 19:14:52 +0000739
740 /* make lsa structure for received lsa */
741 new = ospf6_lsa_create (lsa_header);
742
hasso1e058382004-09-01 21:36:14 +0000743 if (IS_OSPF6_DEBUG_FLOODING ||
744 IS_OSPF6_DEBUG_FLOOD_TYPE (new->header->type))
hasso48454372004-05-18 19:14:52 +0000745 {
hasso1e058382004-09-01 21:36:14 +0000746 is_debug++;
hassoc6487d62004-12-24 06:00:11 +0000747 zlog_debug ("LSA Receive from %s", from->name);
hasso48454372004-05-18 19:14:52 +0000748 ospf6_lsa_header_print (new);
749 }
750
hasso48454372004-05-18 19:14:52 +0000751 /* (1) LSA Checksum */
JR Riversd8a4e422012-09-13 17:17:36 +0000752 if (! ospf6_lsa_checksum_valid (new->header))
hasso48454372004-05-18 19:14:52 +0000753 {
hasso1e058382004-09-01 21:36:14 +0000754 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000755 zlog_debug ("Wrong LSA Checksum, discard");
hasso48454372004-05-18 19:14:52 +0000756 ospf6_lsa_delete (new);
757 return;
758 }
759
hasso6452df02004-08-15 05:52:07 +0000760 /* (2) Examine the LSA's LS type.
761 RFC2470 3.5.1. Receiving Link State Update packets */
762 if (IS_AREA_STUB (from->ospf6_if->area) &&
763 OSPF6_LSA_SCOPE (new->header->type) == OSPF6_SCOPE_AS)
hasso48454372004-05-18 19:14:52 +0000764 {
hasso1e058382004-09-01 21:36:14 +0000765 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000766 zlog_debug ("AS-External-LSA (or AS-scope LSA) in stub area, discard");
hasso6452df02004-08-15 05:52:07 +0000767 ospf6_lsa_delete (new);
768 return;
769 }
770
771 /* (3) LSA which have reserved scope is discarded
772 RFC2470 3.5.1. Receiving Link State Update packets */
773 /* Flooding scope check. LSAs with unknown scope are discarded here.
774 Set appropriate LSDB for the LSA */
775 switch (OSPF6_LSA_SCOPE (new->header->type))
776 {
777 case OSPF6_SCOPE_LINKLOCAL:
778 new->lsdb = from->ospf6_if->lsdb;
779 break;
780 case OSPF6_SCOPE_AREA:
781 new->lsdb = from->ospf6_if->area->lsdb;
782 break;
783 case OSPF6_SCOPE_AS:
784 new->lsdb = from->ospf6_if->area->ospf6->lsdb;
785 break;
786 default:
hasso1e058382004-09-01 21:36:14 +0000787 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000788 zlog_debug ("LSA has reserved scope, discard");
hasso48454372004-05-18 19:14:52 +0000789 ospf6_lsa_delete (new);
790 return;
791 }
792
793 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
794 is in states Exchange or Loading */
795 if (ospf6_is_maxage_lsa_drop (new, from))
796 {
797 /* log */
hasso1e058382004-09-01 21:36:14 +0000798 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000799 zlog_debug ("Drop MaxAge LSA with direct acknowledgement.");
hasso48454372004-05-18 19:14:52 +0000800
801 /* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */
hasso6452df02004-08-15 05:52:07 +0000802 ospf6_lsdb_add (ospf6_lsa_copy (new), from->lsack_list);
hasso48454372004-05-18 19:14:52 +0000803 if (from->thread_send_lsack == NULL)
804 from->thread_send_lsack =
805 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
806
807 /* b) Discard */
hasso6452df02004-08-15 05:52:07 +0000808 ospf6_lsa_delete (new);
hasso48454372004-05-18 19:14:52 +0000809 return;
810 }
811
812 /* (5) */
813 /* lookup the same database copy in lsdb */
hasso48454372004-05-18 19:14:52 +0000814 old = ospf6_lsdb_lookup (new->header->type, new->header->id,
hasso6452df02004-08-15 05:52:07 +0000815 new->header->adv_router, new->lsdb);
hasso48454372004-05-18 19:14:52 +0000816 if (old)
817 {
818 ismore_recent = ospf6_lsa_compare (new, old);
819 if (ntohl (new->header->seqnum) == ntohl (old->header->seqnum))
820 {
hasso1e058382004-09-01 21:36:14 +0000821 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000822 zlog_debug ("Received is duplicated LSA");
hasso48454372004-05-18 19:14:52 +0000823 SET_FLAG (new->flag, OSPF6_LSA_DUPLICATE);
824 }
825 }
826
827 /* if no database copy or received is more recent */
828 if (old == NULL || ismore_recent < 0)
829 {
830 /* in case we have no database copy */
831 ismore_recent = -1;
832
833 /* (a) MinLSArrival check */
834 if (old)
835 {
836 struct timeval now, res;
Takashi Sogabe86f72dc2009-06-22 13:07:02 +0900837 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
hasso48454372004-05-18 19:14:52 +0000838 timersub (&now, &old->installed, &res);
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700839 if (res.tv_sec < OSPF_MIN_LS_ARRIVAL)
hasso48454372004-05-18 19:14:52 +0000840 {
hasso1e058382004-09-01 21:36:14 +0000841 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000842 zlog_debug ("LSA can't be updated within MinLSArrival, discard");
hasso48454372004-05-18 19:14:52 +0000843 ospf6_lsa_delete (new);
844 return; /* examin next lsa */
845 }
846 }
847
Takashi Sogabe86f72dc2009-06-22 13:07:02 +0900848 quagga_gettime (QUAGGA_CLK_MONOTONIC, &new->received);
hassoccb59b12004-08-25 09:10:37 +0000849
hasso1e058382004-09-01 21:36:14 +0000850 if (is_debug)
Dinesh Duttbf986da2013-08-24 07:54:50 +0000851 zlog_debug ("Install, Flood, Possibly acknowledge the received LSA");
852
853 /* Remove older copies of this LSA from retx lists */
854 if (old)
855 ospf6_flood_clear (old);
hasso6452df02004-08-15 05:52:07 +0000856
hasso48454372004-05-18 19:14:52 +0000857 /* (b) immediately flood and (c) remove from all retrans-list */
hassoccb59b12004-08-25 09:10:37 +0000858 /* Prevent self-originated LSA to be flooded. this is to make
859 reoriginated instance of the LSA not to be rejected by other routers
860 due to MinLSArrival. */
861 if (new->header->adv_router != from->ospf6_if->area->ospf6->router_id)
862 ospf6_flood (from, new);
hasso6452df02004-08-15 05:52:07 +0000863
hasso48454372004-05-18 19:14:52 +0000864 /* (d), installing lsdb, which may cause routing
865 table calculation (replacing database copy) */
hasso6452df02004-08-15 05:52:07 +0000866 ospf6_install_lsa (new);
hasso48454372004-05-18 19:14:52 +0000867
868 /* (e) possibly acknowledge */
869 ospf6_acknowledge_lsa (new, ismore_recent, from);
870
hasso6452df02004-08-15 05:52:07 +0000871 /* (f) Self Originated LSA, section 13.4 */
872 if (new->header->adv_router == from->ospf6_if->area->ospf6->router_id)
hasso48454372004-05-18 19:14:52 +0000873 {
hasso6452df02004-08-15 05:52:07 +0000874 /* Self-originated LSA (newer than ours) is received from
875 another router. We have to make a new instance of the LSA
hasso48454372004-05-18 19:14:52 +0000876 or have to flush this LSA. */
hasso1e058382004-09-01 21:36:14 +0000877 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000878 {
hassoc6487d62004-12-24 06:00:11 +0000879 zlog_debug ("Newer instance of the self-originated LSA");
880 zlog_debug ("Schedule reorigination");
hasso6452df02004-08-15 05:52:07 +0000881 }
882 new->refresh = thread_add_event (master, ospf6_lsa_refresh, new, 0);
hasso48454372004-05-18 19:14:52 +0000883 }
hasso6452df02004-08-15 05:52:07 +0000884
hasso48454372004-05-18 19:14:52 +0000885 return;
886 }
887
888 /* (6) if there is instance on sending neighbor's request list */
889 if (ospf6_lsdb_lookup (new->header->type, new->header->id,
890 new->header->adv_router, from->request_list))
891 {
892 /* if no database copy, should go above state (5) */
893 assert (old);
894
hasso1e058382004-09-01 21:36:14 +0000895 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000896 {
hassoc6487d62004-12-24 06:00:11 +0000897 zlog_debug ("Received is not newer, on the neighbor's request-list");
898 zlog_debug ("BadLSReq, discard the received LSA");
hasso6452df02004-08-15 05:52:07 +0000899 }
hasso48454372004-05-18 19:14:52 +0000900
901 /* BadLSReq */
902 thread_add_event (master, bad_lsreq, from, 0);
903
904 ospf6_lsa_delete (new);
905 return;
906 }
907
908 /* (7) if neither one is more recent */
909 if (ismore_recent == 0)
910 {
hasso1e058382004-09-01 21:36:14 +0000911 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000912 zlog_debug ("The same instance as database copy (neither recent)");
hasso48454372004-05-18 19:14:52 +0000913
914 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack */
915 rem = ospf6_lsdb_lookup (new->header->type, new->header->id,
916 new->header->adv_router, from->retrans_list);
917 if (rem)
918 {
hasso1e058382004-09-01 21:36:14 +0000919 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000920 {
hassoc6487d62004-12-24 06:00:11 +0000921 zlog_debug ("It is on the neighbor's retrans-list.");
922 zlog_debug ("Treat as an Implied acknowledgement");
hasso6452df02004-08-15 05:52:07 +0000923 }
hasso48454372004-05-18 19:14:52 +0000924 SET_FLAG (new->flag, OSPF6_LSA_IMPLIEDACK);
hasso6452df02004-08-15 05:52:07 +0000925 ospf6_decrement_retrans_count (rem);
hasso48454372004-05-18 19:14:52 +0000926 ospf6_lsdb_remove (rem, from->retrans_list);
927 }
928
hasso1e058382004-09-01 21:36:14 +0000929 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000930 zlog_debug ("Possibly acknowledge and then discard");
hasso6452df02004-08-15 05:52:07 +0000931
hasso48454372004-05-18 19:14:52 +0000932 /* (b) possibly acknowledge */
933 ospf6_acknowledge_lsa (new, ismore_recent, from);
934
935 ospf6_lsa_delete (new);
936 return;
937 }
938
939 /* (8) previous database copy is more recent */
940 {
941 assert (old);
942
943 /* If database copy is in 'Seqnumber Wrapping',
944 simply discard the received LSA */
945 if (OSPF6_LSA_IS_MAXAGE (old) &&
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700946 old->header->seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
hasso48454372004-05-18 19:14:52 +0000947 {
hasso1e058382004-09-01 21:36:14 +0000948 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000949 {
hassoc6487d62004-12-24 06:00:11 +0000950 zlog_debug ("The LSA is in Seqnumber Wrapping");
951 zlog_debug ("MaxAge & MaxSeqNum, discard");
hasso6452df02004-08-15 05:52:07 +0000952 }
hasso48454372004-05-18 19:14:52 +0000953 ospf6_lsa_delete (new);
954 return;
955 }
956
957 /* Otherwise, Send database copy of this LSA to this neighbor */
958 {
hasso1e058382004-09-01 21:36:14 +0000959 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000960 {
hassoc6487d62004-12-24 06:00:11 +0000961 zlog_debug ("Database copy is more recent.");
962 zlog_debug ("Send back directly and then discard");
hasso6452df02004-08-15 05:52:07 +0000963 }
hasso48454372004-05-18 19:14:52 +0000964
965 /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
966
hasso48454372004-05-18 19:14:52 +0000967 ospf6_lsdb_add (ospf6_lsa_copy (old), from->lsupdate_list);
968 if (from->thread_send_lsupdate == NULL)
969 from->thread_send_lsupdate =
970 thread_add_event (master, ospf6_lsupdate_send_neighbor, from, 0);
971 ospf6_lsa_delete (new);
972 return;
973 }
974 return;
975 }
976}
977
978
hasso1e058382004-09-01 21:36:14 +0000979DEFUN (debug_ospf6_flooding,
980 debug_ospf6_flooding_cmd,
981 "debug ospf6 flooding",
982 DEBUG_STR
983 OSPF6_STR
984 "Debug OSPFv3 flooding function\n"
985 )
986{
987 OSPF6_DEBUG_FLOODING_ON ();
988 return CMD_SUCCESS;
989}
990
991DEFUN (no_debug_ospf6_flooding,
992 no_debug_ospf6_flooding_cmd,
993 "no debug ospf6 flooding",
994 NO_STR
995 DEBUG_STR
996 OSPF6_STR
997 "Debug OSPFv3 flooding function\n"
998 )
999{
1000 OSPF6_DEBUG_FLOODING_OFF ();
1001 return CMD_SUCCESS;
1002}
1003
1004int
1005config_write_ospf6_debug_flood (struct vty *vty)
1006{
1007 if (IS_OSPF6_DEBUG_FLOODING)
1008 vty_out (vty, "debug ospf6 flooding%s", VNL);
1009 return 0;
1010}
1011
1012void
Paul Jakma6ac29a52008-08-15 13:45:30 +01001013install_element_ospf6_debug_flood (void)
hasso1e058382004-09-01 21:36:14 +00001014{
1015 install_element (ENABLE_NODE, &debug_ospf6_flooding_cmd);
1016 install_element (ENABLE_NODE, &no_debug_ospf6_flooding_cmd);
1017 install_element (CONFIG_NODE, &debug_ospf6_flooding_cmd);
1018 install_element (CONFIG_NODE, &no_debug_ospf6_flooding_cmd);
1019}
1020
1021
1022
1023
hasso48454372004-05-18 19:14:52 +00001024