blob: e02a432f96ce2b64fcda988f92e1b8a58888d334 [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{
hasso3b687352004-08-19 06:56:53 +0000209 struct timeval now;
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000210 struct ospf6_lsa *old;
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)
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000293 zlog_debug ("Requesting is older, 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 {
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000301 if (is_debug)
302 zlog_debug ("Requesting the same, remove it, next neighbor");
303 if (req == on->last_ls_req)
304 {
305 ospf6_lsa_unlock (req);
306 on->last_ls_req = NULL;
307 }
hasso6452df02004-08-15 05:52:07 +0000308 ospf6_lsdb_remove (req, on->request_list);
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000309 ospf6_check_nbr_loading (on);
hasso6452df02004-08-15 05:52:07 +0000310 continue;
311 }
hasso48454372004-05-18 19:14:52 +0000312
hasso6452df02004-08-15 05:52:07 +0000313 /* If the new LSA is more recent, delete from request-list */
314 if (ospf6_lsa_compare (lsa, req) < 0)
315 {
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000316 if (is_debug)
317 zlog_debug ("Received is newer, remove requesting");
318 if (req == on->last_ls_req)
319 {
320 ospf6_lsa_unlock (req);
321 on->last_ls_req = NULL;
322 }
hasso6452df02004-08-15 05:52:07 +0000323 ospf6_lsdb_remove (req, on->request_list);
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000324 ospf6_check_nbr_loading (on);
hasso6452df02004-08-15 05:52:07 +0000325 /* fall through */
hasso48454372004-05-18 19:14:52 +0000326 }
327 }
hasso48454372004-05-18 19:14:52 +0000328 }
329
hasso6452df02004-08-15 05:52:07 +0000330 /* (c) If the new LSA was received from this neighbor,
331 examin next neighbor */
332 if (from == on)
hasso48454372004-05-18 19:14:52 +0000333 {
hasso1e058382004-09-01 21:36:14 +0000334 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000335 zlog_debug ("Received is from the neighbor, next neighbor");
hasso6452df02004-08-15 05:52:07 +0000336 continue;
hasso48454372004-05-18 19:14:52 +0000337 }
hasso6452df02004-08-15 05:52:07 +0000338
339 /* (d) add retrans-list, schedule retransmission */
hasso1e058382004-09-01 21:36:14 +0000340 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000341 zlog_debug ("Add retrans-list of this neighbor");
hasso6452df02004-08-15 05:52:07 +0000342 ospf6_increment_retrans_count (lsa);
343 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
344 if (on->thread_send_lsupdate == NULL)
345 on->thread_send_lsupdate =
gdt6639a042004-11-05 18:42:27 +0000346 thread_add_timer (master, ospf6_lsupdate_send_neighbor,
hasso6452df02004-08-15 05:52:07 +0000347 on, on->ospf6_if->rxmt_interval);
348 retrans_added++;
hasso48454372004-05-18 19:14:52 +0000349 }
350
hasso6452df02004-08-15 05:52:07 +0000351 /* (2) examin next interface if not added to retrans-list */
352 if (retrans_added == 0)
353 {
hasso1e058382004-09-01 21:36:14 +0000354 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000355 zlog_debug ("No retransmission scheduled, next interface");
hasso6452df02004-08-15 05:52:07 +0000356 return;
357 }
358
359 /* (3) If the new LSA was received on this interface,
360 and it was from DR or BDR, examin next interface */
361 if (from && from->ospf6_if == oi &&
362 (from->router_id == oi->drouter || from->router_id == oi->bdrouter))
363 {
hasso1e058382004-09-01 21:36:14 +0000364 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000365 zlog_debug ("Received is from the I/F's DR or BDR, next interface");
hasso6452df02004-08-15 05:52:07 +0000366 return;
367 }
368
369 /* (4) If the new LSA was received on this interface,
370 and the interface state is BDR, examin next interface */
371 if (from && from->ospf6_if == oi && oi->state == OSPF6_INTERFACE_BDR)
372 {
hasso1e058382004-09-01 21:36:14 +0000373 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000374 zlog_debug ("Received is from the I/F, itself BDR, next interface");
hasso6452df02004-08-15 05:52:07 +0000375 return;
376 }
377
378 /* (5) flood the LSA out the interface. */
hasso1e058382004-09-01 21:36:14 +0000379 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000380 zlog_debug ("Schedule flooding for the interface");
Dinesh Duttc5926a92013-08-24 07:55:00 +0000381 if ((oi->type == OSPF_IFTYPE_BROADCAST) ||
382 (oi->type == OSPF_IFTYPE_POINTOPOINT))
hasso6452df02004-08-15 05:52:07 +0000383 {
384 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list);
385 if (oi->thread_send_lsupdate == NULL)
386 oi->thread_send_lsupdate =
387 thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
388 }
389 else
390 {
391 /* reschedule retransmissions to all neighbors */
paul1eb8ef22005-04-07 07:30:20 +0000392 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
hasso6452df02004-08-15 05:52:07 +0000393 {
hasso6452df02004-08-15 05:52:07 +0000394 THREAD_OFF (on->thread_send_lsupdate);
395 on->thread_send_lsupdate =
396 thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
397 }
398 }
hasso48454372004-05-18 19:14:52 +0000399}
400
Paul Jakma6ac29a52008-08-15 13:45:30 +0100401static void
hasso6452df02004-08-15 05:52:07 +0000402ospf6_flood_area (struct ospf6_neighbor *from,
403 struct ospf6_lsa *lsa, struct ospf6_area *oa)
404{
paul1eb8ef22005-04-07 07:30:20 +0000405 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000406 struct ospf6_interface *oi;
407
paul1eb8ef22005-04-07 07:30:20 +0000408 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
hasso6452df02004-08-15 05:52:07 +0000409 {
hasso6452df02004-08-15 05:52:07 +0000410 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
411 oi != OSPF6_INTERFACE (lsa->lsdb->data))
412 continue;
413
414#if 0
415 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
416 ospf6_is_interface_virtual_link (oi))
417 continue;
418#endif/*0*/
419
420 ospf6_flood_interface (from, lsa, oi);
421 }
422}
423
Paul Jakma6ac29a52008-08-15 13:45:30 +0100424static void
hasso6452df02004-08-15 05:52:07 +0000425ospf6_flood_process (struct ospf6_neighbor *from,
426 struct ospf6_lsa *lsa, struct ospf6 *process)
427{
paul1eb8ef22005-04-07 07:30:20 +0000428 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000429 struct ospf6_area *oa;
430
paul1eb8ef22005-04-07 07:30:20 +0000431 for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa))
hasso6452df02004-08-15 05:52:07 +0000432 {
hasso6452df02004-08-15 05:52:07 +0000433 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
434 oa != OSPF6_AREA (lsa->lsdb->data))
435 continue;
436 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
437 oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
438 continue;
439
440 if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
441 IS_AREA_STUB (oa))
442 continue;
443
444 ospf6_flood_area (from, lsa, oa);
445 }
446}
447
448void
449ospf6_flood (struct ospf6_neighbor *from, struct ospf6_lsa *lsa)
450{
451 ospf6_flood_process (from, lsa, ospf6);
452}
453
Paul Jakma6ac29a52008-08-15 13:45:30 +0100454static void
hasso6452df02004-08-15 05:52:07 +0000455ospf6_flood_clear_interface (struct ospf6_lsa *lsa, struct ospf6_interface *oi)
456{
paul1eb8ef22005-04-07 07:30:20 +0000457 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000458 struct ospf6_neighbor *on;
459 struct ospf6_lsa *rem;
460
paul1eb8ef22005-04-07 07:30:20 +0000461 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
hasso6452df02004-08-15 05:52:07 +0000462 {
hasso6452df02004-08-15 05:52:07 +0000463 rem = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
464 lsa->header->adv_router, on->retrans_list);
465 if (rem && ! ospf6_lsa_compare (rem, lsa))
466 {
hasso1e058382004-09-01 21:36:14 +0000467 if (IS_OSPF6_DEBUG_FLOODING ||
468 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
hassoc6487d62004-12-24 06:00:11 +0000469 zlog_debug ("Remove %s from retrans_list of %s",
hasso6452df02004-08-15 05:52:07 +0000470 rem->name, on->name);
471 ospf6_decrement_retrans_count (rem);
472 ospf6_lsdb_remove (rem, on->retrans_list);
473 }
474 }
475}
476
Paul Jakma6ac29a52008-08-15 13:45:30 +0100477static void
hasso6452df02004-08-15 05:52:07 +0000478ospf6_flood_clear_area (struct ospf6_lsa *lsa, struct ospf6_area *oa)
479{
paul1eb8ef22005-04-07 07:30:20 +0000480 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000481 struct ospf6_interface *oi;
482
paul1eb8ef22005-04-07 07:30:20 +0000483 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
hasso6452df02004-08-15 05:52:07 +0000484 {
hasso6452df02004-08-15 05:52:07 +0000485 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
486 oi != OSPF6_INTERFACE (lsa->lsdb->data))
487 continue;
488
489#if 0
490 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
491 ospf6_is_interface_virtual_link (oi))
492 continue;
493#endif/*0*/
494
495 ospf6_flood_clear_interface (lsa, oi);
496 }
497}
498
Paul Jakma6ac29a52008-08-15 13:45:30 +0100499static void
hasso6452df02004-08-15 05:52:07 +0000500ospf6_flood_clear_process (struct ospf6_lsa *lsa, struct ospf6 *process)
501{
paul1eb8ef22005-04-07 07:30:20 +0000502 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000503 struct ospf6_area *oa;
504
paul1eb8ef22005-04-07 07:30:20 +0000505 for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa))
hasso6452df02004-08-15 05:52:07 +0000506 {
hasso6452df02004-08-15 05:52:07 +0000507 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
508 oa != OSPF6_AREA (lsa->lsdb->data))
509 continue;
510 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
511 oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
512 continue;
513
514 if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
515 IS_AREA_STUB (oa))
516 continue;
517
518 ospf6_flood_clear_area (lsa, oa);
519 }
520}
521
522void
523ospf6_flood_clear (struct ospf6_lsa *lsa)
524{
525 ospf6_flood_clear_process (lsa, ospf6);
526}
527
528
hasso48454372004-05-18 19:14:52 +0000529/* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
530static void
531ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
532 struct ospf6_neighbor *from)
533{
534 struct ospf6_interface *oi;
hasso1e058382004-09-01 21:36:14 +0000535 int is_debug = 0;
536
537 if (IS_OSPF6_DEBUG_FLOODING ||
538 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
539 is_debug++;
hasso48454372004-05-18 19:14:52 +0000540
541 assert (from && from->ospf6_if);
542 oi = from->ospf6_if;
543
544 /* LSA has been flood back out receiving interface.
545 No acknowledgement sent. */
546 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
547 {
hasso1e058382004-09-01 21:36:14 +0000548 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000549 zlog_debug ("No acknowledgement (BDR & FloodBack)");
hasso48454372004-05-18 19:14:52 +0000550 return;
551 }
552
553 /* LSA is more recent than database copy, but was not flooded
554 back out receiving interface. Delayed acknowledgement sent
555 if advertisement received from Designated Router,
556 otherwide do nothing. */
557 if (ismore_recent < 0)
558 {
hasso48454372004-05-18 19:14:52 +0000559 if (oi->drouter == from->router_id)
560 {
hasso1e058382004-09-01 21:36:14 +0000561 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000562 zlog_debug ("Delayed acknowledgement (BDR & MoreRecent & from DR)");
hasso48454372004-05-18 19:14:52 +0000563 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000564 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
565 if (oi->thread_send_lsack == NULL)
566 oi->thread_send_lsack =
567 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
568 }
569 else
570 {
hasso1e058382004-09-01 21:36:14 +0000571 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000572 zlog_debug ("No acknowledgement (BDR & MoreRecent & ! from DR)");
hasso48454372004-05-18 19:14:52 +0000573 }
574 return;
575 }
576
577 /* LSA is a duplicate, and was treated as an implied acknowledgement.
578 Delayed acknowledgement sent if advertisement received from
579 Designated Router, otherwise do nothing */
580 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
581 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
582 {
hasso48454372004-05-18 19:14:52 +0000583 if (oi->drouter == from->router_id)
584 {
hasso1e058382004-09-01 21:36:14 +0000585 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000586 zlog_debug ("Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
hasso48454372004-05-18 19:14:52 +0000587 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000588 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
589 if (oi->thread_send_lsack == NULL)
590 oi->thread_send_lsack =
591 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
592 }
593 else
594 {
hasso1e058382004-09-01 21:36:14 +0000595 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000596 zlog_debug ("No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
hasso48454372004-05-18 19:14:52 +0000597 }
598 return;
599 }
600
601 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
602 Direct acknowledgement sent */
603 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
604 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
605 {
hasso1e058382004-09-01 21:36:14 +0000606 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000607 zlog_debug ("Direct acknowledgement (BDR & Duplicate)");
hasso48454372004-05-18 19:14:52 +0000608 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
609 if (from->thread_send_lsack == NULL)
610 from->thread_send_lsack =
611 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
612 return;
613 }
614
615 /* LSA's LS age is equal to Maxage, and there is no current instance
616 of the LSA in the link state database, and none of router's
617 neighbors are in states Exchange or Loading */
618 /* Direct acknowledgement sent, but this case is handled in
619 early of ospf6_receive_lsa () */
620}
621
622static void
623ospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent,
624 struct ospf6_neighbor *from)
625{
626 struct ospf6_interface *oi;
hasso1e058382004-09-01 21:36:14 +0000627 int is_debug = 0;
628
629 if (IS_OSPF6_DEBUG_FLOODING ||
630 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
631 is_debug++;
hasso48454372004-05-18 19:14:52 +0000632
633 assert (from && from->ospf6_if);
634 oi = from->ospf6_if;
635
636 /* LSA has been flood back out receiving interface.
637 No acknowledgement sent. */
638 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
639 {
hasso1e058382004-09-01 21:36:14 +0000640 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000641 zlog_debug ("No acknowledgement (AllOther & FloodBack)");
hasso48454372004-05-18 19:14:52 +0000642 return;
643 }
644
645 /* LSA is more recent than database copy, but was not flooded
646 back out receiving interface. Delayed acknowledgement sent. */
647 if (ismore_recent < 0)
648 {
hasso1e058382004-09-01 21:36:14 +0000649 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000650 zlog_debug ("Delayed acknowledgement (AllOther & MoreRecent)");
hasso48454372004-05-18 19:14:52 +0000651 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000652 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
653 if (oi->thread_send_lsack == NULL)
654 oi->thread_send_lsack =
655 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
656 return;
657 }
658
659 /* LSA is a duplicate, and was treated as an implied acknowledgement.
660 No acknowledgement sent. */
661 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
662 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
663 {
hasso1e058382004-09-01 21:36:14 +0000664 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000665 zlog_debug ("No acknowledgement (AllOther & Duplicate & ImpliedAck)");
hasso48454372004-05-18 19:14:52 +0000666 return;
667 }
668
669 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
670 Direct acknowledgement sent */
671 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
672 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
673 {
hasso1e058382004-09-01 21:36:14 +0000674 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000675 zlog_debug ("Direct acknowledgement (AllOther & Duplicate)");
hasso48454372004-05-18 19:14:52 +0000676 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
677 if (from->thread_send_lsack == NULL)
678 from->thread_send_lsack =
679 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
680 return;
681 }
682
683 /* LSA's LS age is equal to Maxage, and there is no current instance
684 of the LSA in the link state database, and none of router's
685 neighbors are in states Exchange or Loading */
686 /* Direct acknowledgement sent, but this case is handled in
687 early of ospf6_receive_lsa () */
688}
689
Paul Jakma6ac29a52008-08-15 13:45:30 +0100690static void
hasso48454372004-05-18 19:14:52 +0000691ospf6_acknowledge_lsa (struct ospf6_lsa *lsa, int ismore_recent,
692 struct ospf6_neighbor *from)
693{
694 struct ospf6_interface *oi;
695
696 assert (from && from->ospf6_if);
697 oi = from->ospf6_if;
698
699 if (oi->state == OSPF6_INTERFACE_BDR)
700 ospf6_acknowledge_lsa_bdrouter (lsa, ismore_recent, from);
701 else
702 ospf6_acknowledge_lsa_allother (lsa, ismore_recent, from);
703}
704
705/* RFC2328 section 13 (4):
706 if MaxAge LSA and if we have no instance, and no neighbor
707 is in states Exchange or Loading
708 returns 1 if match this case, else returns 0 */
709static int
hasso6452df02004-08-15 05:52:07 +0000710ospf6_is_maxage_lsa_drop (struct ospf6_lsa *lsa, struct ospf6_neighbor *from)
hasso48454372004-05-18 19:14:52 +0000711{
hasso48454372004-05-18 19:14:52 +0000712 struct ospf6_neighbor *on;
hasso6452df02004-08-15 05:52:07 +0000713 struct ospf6_interface *oi;
714 struct ospf6_area *oa;
715 struct ospf6 *process = NULL;
hasso52dc7ee2004-09-23 19:18:23 +0000716 struct listnode *i, *j, *k;
hasso48454372004-05-18 19:14:52 +0000717 int count = 0;
718
719 if (! OSPF6_LSA_IS_MAXAGE (lsa))
720 return 0;
721
hasso48454372004-05-18 19:14:52 +0000722 if (ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
hasso6452df02004-08-15 05:52:07 +0000723 lsa->header->adv_router, lsa->lsdb))
hasso48454372004-05-18 19:14:52 +0000724 return 0;
725
hasso6452df02004-08-15 05:52:07 +0000726 process = from->ospf6_if->area->ospf6;
paul1eb8ef22005-04-07 07:30:20 +0000727
728 for (ALL_LIST_ELEMENTS_RO (process->area_list, i, oa))
729 for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
730 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on))
731 if (on->state == OSPF6_NEIGHBOR_EXCHANGE ||
732 on->state == OSPF6_NEIGHBOR_LOADING)
733 count++;
hasso48454372004-05-18 19:14:52 +0000734
hasso48454372004-05-18 19:14:52 +0000735 if (count == 0)
736 return 1;
hasso48454372004-05-18 19:14:52 +0000737 return 0;
738}
739
740/* RFC2328 section 13 The Flooding Procedure */
741void
hasso6452df02004-08-15 05:52:07 +0000742ospf6_receive_lsa (struct ospf6_neighbor *from,
743 struct ospf6_lsa_header *lsa_header)
hasso48454372004-05-18 19:14:52 +0000744{
745 struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
746 int ismore_recent;
hasso1e058382004-09-01 21:36:14 +0000747 int is_debug = 0;
hasso48454372004-05-18 19:14:52 +0000748
749 ismore_recent = 1;
hasso6452df02004-08-15 05:52:07 +0000750 assert (from);
hasso48454372004-05-18 19:14:52 +0000751
752 /* make lsa structure for received lsa */
753 new = ospf6_lsa_create (lsa_header);
754
hasso1e058382004-09-01 21:36:14 +0000755 if (IS_OSPF6_DEBUG_FLOODING ||
756 IS_OSPF6_DEBUG_FLOOD_TYPE (new->header->type))
hasso48454372004-05-18 19:14:52 +0000757 {
hasso1e058382004-09-01 21:36:14 +0000758 is_debug++;
hassoc6487d62004-12-24 06:00:11 +0000759 zlog_debug ("LSA Receive from %s", from->name);
hasso48454372004-05-18 19:14:52 +0000760 ospf6_lsa_header_print (new);
761 }
762
hasso48454372004-05-18 19:14:52 +0000763 /* (1) LSA Checksum */
JR Riversd8a4e422012-09-13 17:17:36 +0000764 if (! ospf6_lsa_checksum_valid (new->header))
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 ("Wrong LSA Checksum, discard");
hasso48454372004-05-18 19:14:52 +0000768 ospf6_lsa_delete (new);
769 return;
770 }
771
hasso6452df02004-08-15 05:52:07 +0000772 /* (2) Examine the LSA's LS type.
773 RFC2470 3.5.1. Receiving Link State Update packets */
774 if (IS_AREA_STUB (from->ospf6_if->area) &&
775 OSPF6_LSA_SCOPE (new->header->type) == OSPF6_SCOPE_AS)
hasso48454372004-05-18 19:14:52 +0000776 {
hasso1e058382004-09-01 21:36:14 +0000777 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000778 zlog_debug ("AS-External-LSA (or AS-scope LSA) in stub area, discard");
hasso6452df02004-08-15 05:52:07 +0000779 ospf6_lsa_delete (new);
780 return;
781 }
782
783 /* (3) LSA which have reserved scope is discarded
784 RFC2470 3.5.1. Receiving Link State Update packets */
785 /* Flooding scope check. LSAs with unknown scope are discarded here.
786 Set appropriate LSDB for the LSA */
787 switch (OSPF6_LSA_SCOPE (new->header->type))
788 {
789 case OSPF6_SCOPE_LINKLOCAL:
790 new->lsdb = from->ospf6_if->lsdb;
791 break;
792 case OSPF6_SCOPE_AREA:
793 new->lsdb = from->ospf6_if->area->lsdb;
794 break;
795 case OSPF6_SCOPE_AS:
796 new->lsdb = from->ospf6_if->area->ospf6->lsdb;
797 break;
798 default:
hasso1e058382004-09-01 21:36:14 +0000799 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000800 zlog_debug ("LSA has reserved scope, discard");
hasso48454372004-05-18 19:14:52 +0000801 ospf6_lsa_delete (new);
802 return;
803 }
804
805 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
806 is in states Exchange or Loading */
807 if (ospf6_is_maxage_lsa_drop (new, from))
808 {
809 /* log */
hasso1e058382004-09-01 21:36:14 +0000810 if (is_debug)
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000811 zlog_debug ("Drop MaxAge LSA with direct acknowledgement.");
hasso48454372004-05-18 19:14:52 +0000812
813 /* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */
hasso6452df02004-08-15 05:52:07 +0000814 ospf6_lsdb_add (ospf6_lsa_copy (new), from->lsack_list);
hasso48454372004-05-18 19:14:52 +0000815 if (from->thread_send_lsack == NULL)
816 from->thread_send_lsack =
817 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
818
819 /* b) Discard */
hasso6452df02004-08-15 05:52:07 +0000820 ospf6_lsa_delete (new);
hasso48454372004-05-18 19:14:52 +0000821 return;
822 }
823
824 /* (5) */
825 /* lookup the same database copy in lsdb */
hasso48454372004-05-18 19:14:52 +0000826 old = ospf6_lsdb_lookup (new->header->type, new->header->id,
hasso6452df02004-08-15 05:52:07 +0000827 new->header->adv_router, new->lsdb);
hasso48454372004-05-18 19:14:52 +0000828 if (old)
829 {
830 ismore_recent = ospf6_lsa_compare (new, old);
831 if (ntohl (new->header->seqnum) == ntohl (old->header->seqnum))
832 {
hasso1e058382004-09-01 21:36:14 +0000833 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000834 zlog_debug ("Received is duplicated LSA");
hasso48454372004-05-18 19:14:52 +0000835 SET_FLAG (new->flag, OSPF6_LSA_DUPLICATE);
836 }
837 }
838
839 /* if no database copy or received is more recent */
840 if (old == NULL || ismore_recent < 0)
841 {
842 /* in case we have no database copy */
843 ismore_recent = -1;
844
845 /* (a) MinLSArrival check */
846 if (old)
847 {
848 struct timeval now, res;
Takashi Sogabe86f72dc2009-06-22 13:07:02 +0900849 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
hasso48454372004-05-18 19:14:52 +0000850 timersub (&now, &old->installed, &res);
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700851 if (res.tv_sec < OSPF_MIN_LS_ARRIVAL)
hasso48454372004-05-18 19:14:52 +0000852 {
hasso1e058382004-09-01 21:36:14 +0000853 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000854 zlog_debug ("LSA can't be updated within MinLSArrival, discard");
hasso48454372004-05-18 19:14:52 +0000855 ospf6_lsa_delete (new);
856 return; /* examin next lsa */
857 }
858 }
859
Takashi Sogabe86f72dc2009-06-22 13:07:02 +0900860 quagga_gettime (QUAGGA_CLK_MONOTONIC, &new->received);
hassoccb59b12004-08-25 09:10:37 +0000861
hasso1e058382004-09-01 21:36:14 +0000862 if (is_debug)
Dinesh Duttbf986da2013-08-24 07:54:50 +0000863 zlog_debug ("Install, Flood, Possibly acknowledge the received LSA");
864
865 /* Remove older copies of this LSA from retx lists */
866 if (old)
867 ospf6_flood_clear (old);
hasso6452df02004-08-15 05:52:07 +0000868
hasso48454372004-05-18 19:14:52 +0000869 /* (b) immediately flood and (c) remove from all retrans-list */
hassoccb59b12004-08-25 09:10:37 +0000870 /* Prevent self-originated LSA to be flooded. this is to make
871 reoriginated instance of the LSA not to be rejected by other routers
872 due to MinLSArrival. */
873 if (new->header->adv_router != from->ospf6_if->area->ospf6->router_id)
874 ospf6_flood (from, new);
hasso6452df02004-08-15 05:52:07 +0000875
hasso48454372004-05-18 19:14:52 +0000876 /* (d), installing lsdb, which may cause routing
877 table calculation (replacing database copy) */
hasso6452df02004-08-15 05:52:07 +0000878 ospf6_install_lsa (new);
hasso48454372004-05-18 19:14:52 +0000879
880 /* (e) possibly acknowledge */
881 ospf6_acknowledge_lsa (new, ismore_recent, from);
882
hasso6452df02004-08-15 05:52:07 +0000883 /* (f) Self Originated LSA, section 13.4 */
884 if (new->header->adv_router == from->ospf6_if->area->ospf6->router_id)
hasso48454372004-05-18 19:14:52 +0000885 {
hasso6452df02004-08-15 05:52:07 +0000886 /* Self-originated LSA (newer than ours) is received from
887 another router. We have to make a new instance of the LSA
hasso48454372004-05-18 19:14:52 +0000888 or have to flush this LSA. */
hasso1e058382004-09-01 21:36:14 +0000889 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000890 {
hassoc6487d62004-12-24 06:00:11 +0000891 zlog_debug ("Newer instance of the self-originated LSA");
892 zlog_debug ("Schedule reorigination");
hasso6452df02004-08-15 05:52:07 +0000893 }
894 new->refresh = thread_add_event (master, ospf6_lsa_refresh, new, 0);
hasso48454372004-05-18 19:14:52 +0000895 }
hasso6452df02004-08-15 05:52:07 +0000896
hasso48454372004-05-18 19:14:52 +0000897 return;
898 }
899
900 /* (6) if there is instance on sending neighbor's request list */
901 if (ospf6_lsdb_lookup (new->header->type, new->header->id,
902 new->header->adv_router, from->request_list))
903 {
904 /* if no database copy, should go above state (5) */
905 assert (old);
906
hasso1e058382004-09-01 21:36:14 +0000907 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000908 {
hassoc6487d62004-12-24 06:00:11 +0000909 zlog_debug ("Received is not newer, on the neighbor's request-list");
910 zlog_debug ("BadLSReq, discard the received LSA");
hasso6452df02004-08-15 05:52:07 +0000911 }
hasso48454372004-05-18 19:14:52 +0000912
913 /* BadLSReq */
914 thread_add_event (master, bad_lsreq, from, 0);
915
916 ospf6_lsa_delete (new);
917 return;
918 }
919
920 /* (7) if neither one is more recent */
921 if (ismore_recent == 0)
922 {
hasso1e058382004-09-01 21:36:14 +0000923 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000924 zlog_debug ("The same instance as database copy (neither recent)");
hasso48454372004-05-18 19:14:52 +0000925
926 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack */
927 rem = ospf6_lsdb_lookup (new->header->type, new->header->id,
928 new->header->adv_router, from->retrans_list);
929 if (rem)
930 {
hasso1e058382004-09-01 21:36:14 +0000931 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000932 {
hassoc6487d62004-12-24 06:00:11 +0000933 zlog_debug ("It is on the neighbor's retrans-list.");
934 zlog_debug ("Treat as an Implied acknowledgement");
hasso6452df02004-08-15 05:52:07 +0000935 }
hasso48454372004-05-18 19:14:52 +0000936 SET_FLAG (new->flag, OSPF6_LSA_IMPLIEDACK);
hasso6452df02004-08-15 05:52:07 +0000937 ospf6_decrement_retrans_count (rem);
hasso48454372004-05-18 19:14:52 +0000938 ospf6_lsdb_remove (rem, from->retrans_list);
939 }
940
hasso1e058382004-09-01 21:36:14 +0000941 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000942 zlog_debug ("Possibly acknowledge and then discard");
hasso6452df02004-08-15 05:52:07 +0000943
hasso48454372004-05-18 19:14:52 +0000944 /* (b) possibly acknowledge */
945 ospf6_acknowledge_lsa (new, ismore_recent, from);
946
947 ospf6_lsa_delete (new);
948 return;
949 }
950
951 /* (8) previous database copy is more recent */
952 {
953 assert (old);
954
955 /* If database copy is in 'Seqnumber Wrapping',
956 simply discard the received LSA */
957 if (OSPF6_LSA_IS_MAXAGE (old) &&
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700958 old->header->seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
hasso48454372004-05-18 19:14:52 +0000959 {
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 ("The LSA is in Seqnumber Wrapping");
963 zlog_debug ("MaxAge & MaxSeqNum, discard");
hasso6452df02004-08-15 05:52:07 +0000964 }
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000965 ospf6_lsa_delete (new);
966 return;
hasso48454372004-05-18 19:14:52 +0000967 }
968
969 /* Otherwise, Send database copy of this LSA to this neighbor */
970 {
hasso1e058382004-09-01 21:36:14 +0000971 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000972 {
hassoc6487d62004-12-24 06:00:11 +0000973 zlog_debug ("Database copy is more recent.");
974 zlog_debug ("Send back directly and then discard");
hasso6452df02004-08-15 05:52:07 +0000975 }
hasso48454372004-05-18 19:14:52 +0000976
977 /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
978
hasso48454372004-05-18 19:14:52 +0000979 ospf6_lsdb_add (ospf6_lsa_copy (old), from->lsupdate_list);
980 if (from->thread_send_lsupdate == NULL)
981 from->thread_send_lsupdate =
982 thread_add_event (master, ospf6_lsupdate_send_neighbor, from, 0);
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000983 ospf6_lsa_delete (new);
984 return;
hasso48454372004-05-18 19:14:52 +0000985 }
986 return;
987 }
988}
989
990
hasso1e058382004-09-01 21:36:14 +0000991DEFUN (debug_ospf6_flooding,
992 debug_ospf6_flooding_cmd,
993 "debug ospf6 flooding",
994 DEBUG_STR
995 OSPF6_STR
996 "Debug OSPFv3 flooding function\n"
997 )
998{
999 OSPF6_DEBUG_FLOODING_ON ();
1000 return CMD_SUCCESS;
1001}
1002
1003DEFUN (no_debug_ospf6_flooding,
1004 no_debug_ospf6_flooding_cmd,
1005 "no debug ospf6 flooding",
1006 NO_STR
1007 DEBUG_STR
1008 OSPF6_STR
1009 "Debug OSPFv3 flooding function\n"
1010 )
1011{
1012 OSPF6_DEBUG_FLOODING_OFF ();
1013 return CMD_SUCCESS;
1014}
1015
1016int
1017config_write_ospf6_debug_flood (struct vty *vty)
1018{
1019 if (IS_OSPF6_DEBUG_FLOODING)
1020 vty_out (vty, "debug ospf6 flooding%s", VNL);
1021 return 0;
1022}
1023
1024void
Paul Jakma6ac29a52008-08-15 13:45:30 +01001025install_element_ospf6_debug_flood (void)
hasso1e058382004-09-01 21:36:14 +00001026{
1027 install_element (ENABLE_NODE, &debug_ospf6_flooding_cmd);
1028 install_element (ENABLE_NODE, &no_debug_ospf6_flooding_cmd);
1029 install_element (CONFIG_NODE, &debug_ospf6_flooding_cmd);
1030 install_element (CONFIG_NODE, &no_debug_ospf6_flooding_cmd);
1031}
1032
1033
1034
1035
hasso48454372004-05-18 19:14:52 +00001036