blob: 815db7b75a4d1bf4f58f56379dbc91d0dc249a07 [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);
David Lamparter11b4f012013-12-09 16:48:55 +0100223 THREAD_OFF (old->refresh);
hasso3b687352004-08-19 06:56:53 +0000224 ospf6_flood_clear (old);
225 }
226
Takashi Sogabe86f72dc2009-06-22 13:07:02 +0900227 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
hassoccb59b12004-08-25 09:10:37 +0000228 if (! OSPF6_LSA_IS_MAXAGE (lsa))
hasso3b687352004-08-19 06:56:53 +0000229 lsa->expire = thread_add_timer (master, ospf6_lsa_expire, lsa,
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700230 OSPF_LSA_MAXAGE + lsa->birth.tv_sec - now.tv_sec);
hasso3b687352004-08-19 06:56:53 +0000231 else
232 lsa->expire = NULL;
hasso48454372004-05-18 19:14:52 +0000233
Dinesh Dutt3b220282013-08-24 08:00:44 +0000234 if (OSPF6_LSA_IS_SEQWRAP(lsa) &&
235 ! (CHECK_FLAG(lsa->flag,OSPF6_LSA_SEQWRAPPED) &&
236 lsa->header->seqnum == htonl(OSPF_MAX_SEQUENCE_NUMBER)))
237 {
238 if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
239 zlog_debug("lsa install wrapping: sequence 0x%x",
240 ntohl(lsa->header->seqnum));
241 SET_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED);
242 /* in lieu of premature_aging, since we do not want to recreate this lsa
243 * and/or mess with timers etc, we just want to wrap the sequence number
244 * and reflood the lsa before continuing.
245 * NOTE: Flood needs to be called right after this function call, by the
246 * caller
247 */
248 lsa->header->seqnum = htonl (OSPF_MAX_SEQUENCE_NUMBER);
249 lsa->header->age = htons (OSPF_LSA_MAXAGE);
250 ospf6_lsa_checksum (lsa->header);
251 }
252
hasso48454372004-05-18 19:14:52 +0000253 /* actually install */
hasso3b687352004-08-19 06:56:53 +0000254 lsa->installed = now;
hasso6452df02004-08-15 05:52:07 +0000255 ospf6_lsdb_add (lsa, lsa->lsdb);
hasso48454372004-05-18 19:14:52 +0000256
257 return;
258}
259
hasso6452df02004-08-15 05:52:07 +0000260/* RFC2740 section 3.5.2. Sending Link State Update packets */
hasso48454372004-05-18 19:14:52 +0000261/* RFC2328 section 13.3 Next step in the flooding procedure */
Paul Jakma6ac29a52008-08-15 13:45:30 +0100262static void
hasso6452df02004-08-15 05:52:07 +0000263ospf6_flood_interface (struct ospf6_neighbor *from,
264 struct ospf6_lsa *lsa, struct ospf6_interface *oi)
hasso48454372004-05-18 19:14:52 +0000265{
paul1eb8ef22005-04-07 07:30:20 +0000266 struct listnode *node, *nnode;
hasso48454372004-05-18 19:14:52 +0000267 struct ospf6_neighbor *on;
hasso48454372004-05-18 19:14:52 +0000268 struct ospf6_lsa *req;
269 int retrans_added = 0;
hasso1e058382004-09-01 21:36:14 +0000270 int is_debug = 0;
hasso48454372004-05-18 19:14:52 +0000271
hasso1e058382004-09-01 21:36:14 +0000272 if (IS_OSPF6_DEBUG_FLOODING ||
273 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
274 {
275 is_debug++;
hassoc6487d62004-12-24 06:00:11 +0000276 zlog_debug ("Flooding on %s: %s", oi->interface->name, lsa->name);
hasso1e058382004-09-01 21:36:14 +0000277 }
hasso48454372004-05-18 19:14:52 +0000278
hasso6452df02004-08-15 05:52:07 +0000279 /* (1) For each neighbor */
paul1eb8ef22005-04-07 07:30:20 +0000280 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
hasso48454372004-05-18 19:14:52 +0000281 {
hasso1e058382004-09-01 21:36:14 +0000282 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000283 zlog_debug ("To neighbor %s", on->name);
hasso6452df02004-08-15 05:52:07 +0000284
285 /* (a) if neighbor state < Exchange, examin next */
286 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
hasso48454372004-05-18 19:14:52 +0000287 {
hasso1e058382004-09-01 21:36:14 +0000288 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000289 zlog_debug ("Neighbor state less than ExChange, next neighbor");
hasso6452df02004-08-15 05:52:07 +0000290 continue;
hasso48454372004-05-18 19:14:52 +0000291 }
hasso48454372004-05-18 19:14:52 +0000292
hasso6452df02004-08-15 05:52:07 +0000293 /* (b) if neighbor not yet Full, check request-list */
294 if (on->state != OSPF6_NEIGHBOR_FULL)
hasso48454372004-05-18 19:14:52 +0000295 {
hasso1e058382004-09-01 21:36:14 +0000296 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000297 zlog_debug ("Neighbor not yet Full");
hasso48454372004-05-18 19:14:52 +0000298
hasso6452df02004-08-15 05:52:07 +0000299 req = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
300 lsa->header->adv_router, on->request_list);
301 if (req == NULL)
hasso48454372004-05-18 19:14:52 +0000302 {
hasso1e058382004-09-01 21:36:14 +0000303 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000304 zlog_debug ("Not on request-list for this neighbor");
hasso6452df02004-08-15 05:52:07 +0000305 /* fall through */
306 }
307 else
308 {
309 /* If new LSA less recent, examin next neighbor */
310 if (ospf6_lsa_compare (lsa, req) > 0)
hasso48454372004-05-18 19:14:52 +0000311 {
hasso1e058382004-09-01 21:36:14 +0000312 if (is_debug)
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000313 zlog_debug ("Requesting is older, next neighbor");
hasso6452df02004-08-15 05:52:07 +0000314 continue;
315 }
hasso48454372004-05-18 19:14:52 +0000316
hasso6452df02004-08-15 05:52:07 +0000317 /* If the same instance, delete from request-list and
318 examin next neighbor */
319 if (ospf6_lsa_compare (lsa, req) == 0)
320 {
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000321 if (is_debug)
322 zlog_debug ("Requesting the same, remove it, next neighbor");
323 if (req == on->last_ls_req)
324 {
325 ospf6_lsa_unlock (req);
326 on->last_ls_req = NULL;
327 }
hasso6452df02004-08-15 05:52:07 +0000328 ospf6_lsdb_remove (req, on->request_list);
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000329 ospf6_check_nbr_loading (on);
hasso6452df02004-08-15 05:52:07 +0000330 continue;
331 }
hasso48454372004-05-18 19:14:52 +0000332
hasso6452df02004-08-15 05:52:07 +0000333 /* If the new LSA is more recent, delete from request-list */
334 if (ospf6_lsa_compare (lsa, req) < 0)
335 {
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000336 if (is_debug)
337 zlog_debug ("Received is newer, remove requesting");
338 if (req == on->last_ls_req)
339 {
340 ospf6_lsa_unlock (req);
341 on->last_ls_req = NULL;
342 }
hasso6452df02004-08-15 05:52:07 +0000343 ospf6_lsdb_remove (req, on->request_list);
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000344 ospf6_check_nbr_loading (on);
hasso6452df02004-08-15 05:52:07 +0000345 /* fall through */
hasso48454372004-05-18 19:14:52 +0000346 }
347 }
hasso48454372004-05-18 19:14:52 +0000348 }
349
hasso6452df02004-08-15 05:52:07 +0000350 /* (c) If the new LSA was received from this neighbor,
351 examin next neighbor */
352 if (from == on)
hasso48454372004-05-18 19:14:52 +0000353 {
hasso1e058382004-09-01 21:36:14 +0000354 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000355 zlog_debug ("Received is from the neighbor, next neighbor");
hasso6452df02004-08-15 05:52:07 +0000356 continue;
hasso48454372004-05-18 19:14:52 +0000357 }
hasso6452df02004-08-15 05:52:07 +0000358
359 /* (d) add retrans-list, schedule retransmission */
hasso1e058382004-09-01 21:36:14 +0000360 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000361 zlog_debug ("Add retrans-list of this neighbor");
hasso6452df02004-08-15 05:52:07 +0000362 ospf6_increment_retrans_count (lsa);
363 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
364 if (on->thread_send_lsupdate == NULL)
365 on->thread_send_lsupdate =
gdt6639a042004-11-05 18:42:27 +0000366 thread_add_timer (master, ospf6_lsupdate_send_neighbor,
hasso6452df02004-08-15 05:52:07 +0000367 on, on->ospf6_if->rxmt_interval);
368 retrans_added++;
hasso48454372004-05-18 19:14:52 +0000369 }
370
hasso6452df02004-08-15 05:52:07 +0000371 /* (2) examin next interface if not added to retrans-list */
372 if (retrans_added == 0)
373 {
hasso1e058382004-09-01 21:36:14 +0000374 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000375 zlog_debug ("No retransmission scheduled, next interface");
hasso6452df02004-08-15 05:52:07 +0000376 return;
377 }
378
379 /* (3) If the new LSA was received on this interface,
380 and it was from DR or BDR, examin next interface */
381 if (from && from->ospf6_if == oi &&
382 (from->router_id == oi->drouter || from->router_id == oi->bdrouter))
383 {
hasso1e058382004-09-01 21:36:14 +0000384 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000385 zlog_debug ("Received is from the I/F's DR or BDR, next interface");
hasso6452df02004-08-15 05:52:07 +0000386 return;
387 }
388
389 /* (4) If the new LSA was received on this interface,
390 and the interface state is BDR, examin next interface */
Dinesh Dutt7cf99722013-08-25 03:03:39 +0000391 if (from && from->ospf6_if == oi)
hasso6452df02004-08-15 05:52:07 +0000392 {
Dinesh Dutt7cf99722013-08-25 03:03:39 +0000393 if (oi->state == OSPF6_INTERFACE_BDR)
394 {
395 if (is_debug)
396 zlog_debug ("Received is from the I/F, itself BDR, next interface");
397 return;
398 }
399 SET_FLAG(lsa->flag, OSPF6_LSA_FLOODBACK);
hasso6452df02004-08-15 05:52:07 +0000400 }
401
402 /* (5) flood the LSA out the interface. */
hasso1e058382004-09-01 21:36:14 +0000403 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000404 zlog_debug ("Schedule flooding for the interface");
Dinesh Duttc5926a92013-08-24 07:55:00 +0000405 if ((oi->type == OSPF_IFTYPE_BROADCAST) ||
406 (oi->type == OSPF_IFTYPE_POINTOPOINT))
hasso6452df02004-08-15 05:52:07 +0000407 {
408 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list);
409 if (oi->thread_send_lsupdate == NULL)
410 oi->thread_send_lsupdate =
411 thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
412 }
413 else
414 {
415 /* reschedule retransmissions to all neighbors */
paul1eb8ef22005-04-07 07:30:20 +0000416 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
hasso6452df02004-08-15 05:52:07 +0000417 {
hasso6452df02004-08-15 05:52:07 +0000418 THREAD_OFF (on->thread_send_lsupdate);
419 on->thread_send_lsupdate =
420 thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
421 }
422 }
hasso48454372004-05-18 19:14:52 +0000423}
424
Paul Jakma6ac29a52008-08-15 13:45:30 +0100425static void
hasso6452df02004-08-15 05:52:07 +0000426ospf6_flood_area (struct ospf6_neighbor *from,
427 struct ospf6_lsa *lsa, struct ospf6_area *oa)
428{
paul1eb8ef22005-04-07 07:30:20 +0000429 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000430 struct ospf6_interface *oi;
431
paul1eb8ef22005-04-07 07:30:20 +0000432 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
hasso6452df02004-08-15 05:52:07 +0000433 {
hasso6452df02004-08-15 05:52:07 +0000434 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
435 oi != OSPF6_INTERFACE (lsa->lsdb->data))
436 continue;
437
438#if 0
439 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
440 ospf6_is_interface_virtual_link (oi))
441 continue;
442#endif/*0*/
443
444 ospf6_flood_interface (from, lsa, oi);
445 }
446}
447
Paul Jakma6ac29a52008-08-15 13:45:30 +0100448static void
hasso6452df02004-08-15 05:52:07 +0000449ospf6_flood_process (struct ospf6_neighbor *from,
450 struct ospf6_lsa *lsa, struct ospf6 *process)
451{
paul1eb8ef22005-04-07 07:30:20 +0000452 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000453 struct ospf6_area *oa;
454
paul1eb8ef22005-04-07 07:30:20 +0000455 for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa))
hasso6452df02004-08-15 05:52:07 +0000456 {
hasso6452df02004-08-15 05:52:07 +0000457 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
458 oa != OSPF6_AREA (lsa->lsdb->data))
459 continue;
460 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
461 oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
462 continue;
463
464 if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
465 IS_AREA_STUB (oa))
466 continue;
467
468 ospf6_flood_area (from, lsa, oa);
469 }
470}
471
472void
473ospf6_flood (struct ospf6_neighbor *from, struct ospf6_lsa *lsa)
474{
475 ospf6_flood_process (from, lsa, ospf6);
476}
477
Paul Jakma6ac29a52008-08-15 13:45:30 +0100478static void
hasso6452df02004-08-15 05:52:07 +0000479ospf6_flood_clear_interface (struct ospf6_lsa *lsa, struct ospf6_interface *oi)
480{
paul1eb8ef22005-04-07 07:30:20 +0000481 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000482 struct ospf6_neighbor *on;
483 struct ospf6_lsa *rem;
484
paul1eb8ef22005-04-07 07:30:20 +0000485 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
hasso6452df02004-08-15 05:52:07 +0000486 {
hasso6452df02004-08-15 05:52:07 +0000487 rem = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
488 lsa->header->adv_router, on->retrans_list);
489 if (rem && ! ospf6_lsa_compare (rem, lsa))
490 {
hasso1e058382004-09-01 21:36:14 +0000491 if (IS_OSPF6_DEBUG_FLOODING ||
492 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
hassoc6487d62004-12-24 06:00:11 +0000493 zlog_debug ("Remove %s from retrans_list of %s",
hasso6452df02004-08-15 05:52:07 +0000494 rem->name, on->name);
495 ospf6_decrement_retrans_count (rem);
496 ospf6_lsdb_remove (rem, on->retrans_list);
497 }
498 }
499}
500
Paul Jakma6ac29a52008-08-15 13:45:30 +0100501static void
hasso6452df02004-08-15 05:52:07 +0000502ospf6_flood_clear_area (struct ospf6_lsa *lsa, struct ospf6_area *oa)
503{
paul1eb8ef22005-04-07 07:30:20 +0000504 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000505 struct ospf6_interface *oi;
506
paul1eb8ef22005-04-07 07:30:20 +0000507 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
hasso6452df02004-08-15 05:52:07 +0000508 {
hasso6452df02004-08-15 05:52:07 +0000509 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
510 oi != OSPF6_INTERFACE (lsa->lsdb->data))
511 continue;
512
513#if 0
514 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
515 ospf6_is_interface_virtual_link (oi))
516 continue;
517#endif/*0*/
518
519 ospf6_flood_clear_interface (lsa, oi);
520 }
521}
522
Paul Jakma6ac29a52008-08-15 13:45:30 +0100523static void
hasso6452df02004-08-15 05:52:07 +0000524ospf6_flood_clear_process (struct ospf6_lsa *lsa, struct ospf6 *process)
525{
paul1eb8ef22005-04-07 07:30:20 +0000526 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000527 struct ospf6_area *oa;
528
paul1eb8ef22005-04-07 07:30:20 +0000529 for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa))
hasso6452df02004-08-15 05:52:07 +0000530 {
hasso6452df02004-08-15 05:52:07 +0000531 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
532 oa != OSPF6_AREA (lsa->lsdb->data))
533 continue;
534 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
535 oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
536 continue;
537
538 if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
539 IS_AREA_STUB (oa))
540 continue;
541
542 ospf6_flood_clear_area (lsa, oa);
543 }
544}
545
546void
547ospf6_flood_clear (struct ospf6_lsa *lsa)
548{
549 ospf6_flood_clear_process (lsa, ospf6);
550}
551
552
hasso48454372004-05-18 19:14:52 +0000553/* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
554static void
555ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
556 struct ospf6_neighbor *from)
557{
558 struct ospf6_interface *oi;
hasso1e058382004-09-01 21:36:14 +0000559 int is_debug = 0;
560
561 if (IS_OSPF6_DEBUG_FLOODING ||
562 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
563 is_debug++;
hasso48454372004-05-18 19:14:52 +0000564
565 assert (from && from->ospf6_if);
566 oi = from->ospf6_if;
567
hasso48454372004-05-18 19:14:52 +0000568 /* LSA is more recent than database copy, but was not flooded
569 back out receiving interface. Delayed acknowledgement sent
570 if advertisement received from Designated Router,
571 otherwide do nothing. */
572 if (ismore_recent < 0)
573 {
hasso48454372004-05-18 19:14:52 +0000574 if (oi->drouter == from->router_id)
575 {
hasso1e058382004-09-01 21:36:14 +0000576 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000577 zlog_debug ("Delayed acknowledgement (BDR & MoreRecent & from DR)");
hasso48454372004-05-18 19:14:52 +0000578 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000579 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
580 if (oi->thread_send_lsack == NULL)
581 oi->thread_send_lsack =
582 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
583 }
584 else
585 {
hasso1e058382004-09-01 21:36:14 +0000586 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000587 zlog_debug ("No acknowledgement (BDR & MoreRecent & ! from DR)");
hasso48454372004-05-18 19:14:52 +0000588 }
589 return;
590 }
591
592 /* LSA is a duplicate, and was treated as an implied acknowledgement.
593 Delayed acknowledgement sent if advertisement received from
594 Designated Router, otherwise do nothing */
595 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
596 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
597 {
hasso48454372004-05-18 19:14:52 +0000598 if (oi->drouter == from->router_id)
599 {
hasso1e058382004-09-01 21:36:14 +0000600 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000601 zlog_debug ("Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
hasso48454372004-05-18 19:14:52 +0000602 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000603 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
604 if (oi->thread_send_lsack == NULL)
605 oi->thread_send_lsack =
606 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
607 }
608 else
609 {
hasso1e058382004-09-01 21:36:14 +0000610 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000611 zlog_debug ("No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
hasso48454372004-05-18 19:14:52 +0000612 }
613 return;
614 }
615
616 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
617 Direct acknowledgement sent */
618 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
619 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
620 {
hasso1e058382004-09-01 21:36:14 +0000621 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000622 zlog_debug ("Direct acknowledgement (BDR & Duplicate)");
hasso48454372004-05-18 19:14:52 +0000623 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
624 if (from->thread_send_lsack == NULL)
625 from->thread_send_lsack =
626 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
627 return;
628 }
629
630 /* LSA's LS age is equal to Maxage, and there is no current instance
631 of the LSA in the link state database, and none of router's
632 neighbors are in states Exchange or Loading */
633 /* Direct acknowledgement sent, but this case is handled in
634 early of ospf6_receive_lsa () */
635}
636
637static void
638ospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent,
639 struct ospf6_neighbor *from)
640{
641 struct ospf6_interface *oi;
hasso1e058382004-09-01 21:36:14 +0000642 int is_debug = 0;
643
644 if (IS_OSPF6_DEBUG_FLOODING ||
645 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
646 is_debug++;
hasso48454372004-05-18 19:14:52 +0000647
648 assert (from && from->ospf6_if);
649 oi = from->ospf6_if;
650
651 /* LSA has been flood back out receiving interface.
652 No acknowledgement sent. */
653 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
654 {
hasso1e058382004-09-01 21:36:14 +0000655 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000656 zlog_debug ("No acknowledgement (AllOther & FloodBack)");
hasso48454372004-05-18 19:14:52 +0000657 return;
658 }
659
660 /* LSA is more recent than database copy, but was not flooded
661 back out receiving interface. Delayed acknowledgement sent. */
662 if (ismore_recent < 0)
663 {
hasso1e058382004-09-01 21:36:14 +0000664 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000665 zlog_debug ("Delayed acknowledgement (AllOther & MoreRecent)");
hasso48454372004-05-18 19:14:52 +0000666 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000667 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
668 if (oi->thread_send_lsack == NULL)
669 oi->thread_send_lsack =
670 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
671 return;
672 }
673
674 /* LSA is a duplicate, and was treated as an implied acknowledgement.
675 No acknowledgement sent. */
676 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
677 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
678 {
hasso1e058382004-09-01 21:36:14 +0000679 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000680 zlog_debug ("No acknowledgement (AllOther & Duplicate & ImpliedAck)");
hasso48454372004-05-18 19:14:52 +0000681 return;
682 }
683
684 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
685 Direct acknowledgement sent */
686 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
687 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
688 {
hasso1e058382004-09-01 21:36:14 +0000689 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000690 zlog_debug ("Direct acknowledgement (AllOther & Duplicate)");
hasso48454372004-05-18 19:14:52 +0000691 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
692 if (from->thread_send_lsack == NULL)
693 from->thread_send_lsack =
694 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
695 return;
696 }
697
698 /* LSA's LS age is equal to Maxage, and there is no current instance
699 of the LSA in the link state database, and none of router's
700 neighbors are in states Exchange or Loading */
701 /* Direct acknowledgement sent, but this case is handled in
702 early of ospf6_receive_lsa () */
703}
704
Paul Jakma6ac29a52008-08-15 13:45:30 +0100705static void
hasso48454372004-05-18 19:14:52 +0000706ospf6_acknowledge_lsa (struct ospf6_lsa *lsa, int ismore_recent,
707 struct ospf6_neighbor *from)
708{
709 struct ospf6_interface *oi;
710
711 assert (from && from->ospf6_if);
712 oi = from->ospf6_if;
713
714 if (oi->state == OSPF6_INTERFACE_BDR)
715 ospf6_acknowledge_lsa_bdrouter (lsa, ismore_recent, from);
716 else
717 ospf6_acknowledge_lsa_allother (lsa, ismore_recent, from);
718}
719
720/* RFC2328 section 13 (4):
721 if MaxAge LSA and if we have no instance, and no neighbor
722 is in states Exchange or Loading
723 returns 1 if match this case, else returns 0 */
724static int
hasso6452df02004-08-15 05:52:07 +0000725ospf6_is_maxage_lsa_drop (struct ospf6_lsa *lsa, struct ospf6_neighbor *from)
hasso48454372004-05-18 19:14:52 +0000726{
hasso48454372004-05-18 19:14:52 +0000727 struct ospf6_neighbor *on;
hasso6452df02004-08-15 05:52:07 +0000728 struct ospf6_interface *oi;
729 struct ospf6_area *oa;
730 struct ospf6 *process = NULL;
hasso52dc7ee2004-09-23 19:18:23 +0000731 struct listnode *i, *j, *k;
hasso48454372004-05-18 19:14:52 +0000732 int count = 0;
733
734 if (! OSPF6_LSA_IS_MAXAGE (lsa))
735 return 0;
736
hasso48454372004-05-18 19:14:52 +0000737 if (ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
hasso6452df02004-08-15 05:52:07 +0000738 lsa->header->adv_router, lsa->lsdb))
hasso48454372004-05-18 19:14:52 +0000739 return 0;
740
hasso6452df02004-08-15 05:52:07 +0000741 process = from->ospf6_if->area->ospf6;
paul1eb8ef22005-04-07 07:30:20 +0000742
743 for (ALL_LIST_ELEMENTS_RO (process->area_list, i, oa))
744 for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
745 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on))
746 if (on->state == OSPF6_NEIGHBOR_EXCHANGE ||
747 on->state == OSPF6_NEIGHBOR_LOADING)
748 count++;
hasso48454372004-05-18 19:14:52 +0000749
hasso48454372004-05-18 19:14:52 +0000750 if (count == 0)
751 return 1;
hasso48454372004-05-18 19:14:52 +0000752 return 0;
753}
754
755/* RFC2328 section 13 The Flooding Procedure */
756void
hasso6452df02004-08-15 05:52:07 +0000757ospf6_receive_lsa (struct ospf6_neighbor *from,
758 struct ospf6_lsa_header *lsa_header)
hasso48454372004-05-18 19:14:52 +0000759{
760 struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
761 int ismore_recent;
hasso1e058382004-09-01 21:36:14 +0000762 int is_debug = 0;
hasso48454372004-05-18 19:14:52 +0000763
764 ismore_recent = 1;
hasso6452df02004-08-15 05:52:07 +0000765 assert (from);
hasso48454372004-05-18 19:14:52 +0000766
767 /* make lsa structure for received lsa */
768 new = ospf6_lsa_create (lsa_header);
769
hasso1e058382004-09-01 21:36:14 +0000770 if (IS_OSPF6_DEBUG_FLOODING ||
771 IS_OSPF6_DEBUG_FLOOD_TYPE (new->header->type))
hasso48454372004-05-18 19:14:52 +0000772 {
hasso1e058382004-09-01 21:36:14 +0000773 is_debug++;
hassoc6487d62004-12-24 06:00:11 +0000774 zlog_debug ("LSA Receive from %s", from->name);
hasso48454372004-05-18 19:14:52 +0000775 ospf6_lsa_header_print (new);
776 }
777
hasso48454372004-05-18 19:14:52 +0000778 /* (1) LSA Checksum */
JR Riversd8a4e422012-09-13 17:17:36 +0000779 if (! ospf6_lsa_checksum_valid (new->header))
hasso48454372004-05-18 19:14:52 +0000780 {
hasso1e058382004-09-01 21:36:14 +0000781 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000782 zlog_debug ("Wrong LSA Checksum, discard");
hasso48454372004-05-18 19:14:52 +0000783 ospf6_lsa_delete (new);
784 return;
785 }
786
hasso6452df02004-08-15 05:52:07 +0000787 /* (2) Examine the LSA's LS type.
788 RFC2470 3.5.1. Receiving Link State Update packets */
789 if (IS_AREA_STUB (from->ospf6_if->area) &&
790 OSPF6_LSA_SCOPE (new->header->type) == OSPF6_SCOPE_AS)
hasso48454372004-05-18 19:14:52 +0000791 {
hasso1e058382004-09-01 21:36:14 +0000792 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000793 zlog_debug ("AS-External-LSA (or AS-scope LSA) in stub area, discard");
hasso6452df02004-08-15 05:52:07 +0000794 ospf6_lsa_delete (new);
795 return;
796 }
797
798 /* (3) LSA which have reserved scope is discarded
799 RFC2470 3.5.1. Receiving Link State Update packets */
800 /* Flooding scope check. LSAs with unknown scope are discarded here.
801 Set appropriate LSDB for the LSA */
802 switch (OSPF6_LSA_SCOPE (new->header->type))
803 {
804 case OSPF6_SCOPE_LINKLOCAL:
805 new->lsdb = from->ospf6_if->lsdb;
806 break;
807 case OSPF6_SCOPE_AREA:
808 new->lsdb = from->ospf6_if->area->lsdb;
809 break;
810 case OSPF6_SCOPE_AS:
811 new->lsdb = from->ospf6_if->area->ospf6->lsdb;
812 break;
813 default:
hasso1e058382004-09-01 21:36:14 +0000814 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000815 zlog_debug ("LSA has reserved scope, discard");
hasso48454372004-05-18 19:14:52 +0000816 ospf6_lsa_delete (new);
817 return;
818 }
819
820 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
821 is in states Exchange or Loading */
822 if (ospf6_is_maxage_lsa_drop (new, from))
823 {
824 /* log */
hasso1e058382004-09-01 21:36:14 +0000825 if (is_debug)
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000826 zlog_debug ("Drop MaxAge LSA with direct acknowledgement.");
hasso48454372004-05-18 19:14:52 +0000827
828 /* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */
hasso6452df02004-08-15 05:52:07 +0000829 ospf6_lsdb_add (ospf6_lsa_copy (new), from->lsack_list);
hasso48454372004-05-18 19:14:52 +0000830 if (from->thread_send_lsack == NULL)
831 from->thread_send_lsack =
832 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
833
834 /* b) Discard */
hasso6452df02004-08-15 05:52:07 +0000835 ospf6_lsa_delete (new);
hasso48454372004-05-18 19:14:52 +0000836 return;
837 }
838
839 /* (5) */
840 /* lookup the same database copy in lsdb */
hasso48454372004-05-18 19:14:52 +0000841 old = ospf6_lsdb_lookup (new->header->type, new->header->id,
hasso6452df02004-08-15 05:52:07 +0000842 new->header->adv_router, new->lsdb);
hasso48454372004-05-18 19:14:52 +0000843 if (old)
844 {
845 ismore_recent = ospf6_lsa_compare (new, old);
846 if (ntohl (new->header->seqnum) == ntohl (old->header->seqnum))
847 {
hasso1e058382004-09-01 21:36:14 +0000848 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000849 zlog_debug ("Received is duplicated LSA");
hasso48454372004-05-18 19:14:52 +0000850 SET_FLAG (new->flag, OSPF6_LSA_DUPLICATE);
851 }
852 }
853
854 /* if no database copy or received is more recent */
855 if (old == NULL || ismore_recent < 0)
856 {
857 /* in case we have no database copy */
858 ismore_recent = -1;
859
860 /* (a) MinLSArrival check */
861 if (old)
862 {
863 struct timeval now, res;
Takashi Sogabe86f72dc2009-06-22 13:07:02 +0900864 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
hasso48454372004-05-18 19:14:52 +0000865 timersub (&now, &old->installed, &res);
Michael Rossbergca8ec202015-09-29 14:32:14 +0200866 if (res.tv_sec < (OSPF_MIN_LS_ARRIVAL / 1000))
hasso48454372004-05-18 19:14:52 +0000867 {
hasso1e058382004-09-01 21:36:14 +0000868 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000869 zlog_debug ("LSA can't be updated within MinLSArrival, discard");
hasso48454372004-05-18 19:14:52 +0000870 ospf6_lsa_delete (new);
871 return; /* examin next lsa */
872 }
873 }
874
Takashi Sogabe86f72dc2009-06-22 13:07:02 +0900875 quagga_gettime (QUAGGA_CLK_MONOTONIC, &new->received);
hassoccb59b12004-08-25 09:10:37 +0000876
hasso1e058382004-09-01 21:36:14 +0000877 if (is_debug)
Dinesh Duttbf986da2013-08-24 07:54:50 +0000878 zlog_debug ("Install, Flood, Possibly acknowledge the received LSA");
879
880 /* Remove older copies of this LSA from retx lists */
881 if (old)
882 ospf6_flood_clear (old);
hasso6452df02004-08-15 05:52:07 +0000883
hasso48454372004-05-18 19:14:52 +0000884 /* (b) immediately flood and (c) remove from all retrans-list */
hassoccb59b12004-08-25 09:10:37 +0000885 /* Prevent self-originated LSA to be flooded. this is to make
886 reoriginated instance of the LSA not to be rejected by other routers
887 due to MinLSArrival. */
888 if (new->header->adv_router != from->ospf6_if->area->ospf6->router_id)
889 ospf6_flood (from, new);
hasso6452df02004-08-15 05:52:07 +0000890
hasso48454372004-05-18 19:14:52 +0000891 /* (d), installing lsdb, which may cause routing
892 table calculation (replacing database copy) */
hasso6452df02004-08-15 05:52:07 +0000893 ospf6_install_lsa (new);
hasso48454372004-05-18 19:14:52 +0000894
895 /* (e) possibly acknowledge */
896 ospf6_acknowledge_lsa (new, ismore_recent, from);
897
hasso6452df02004-08-15 05:52:07 +0000898 /* (f) Self Originated LSA, section 13.4 */
899 if (new->header->adv_router == from->ospf6_if->area->ospf6->router_id)
hasso48454372004-05-18 19:14:52 +0000900 {
hasso6452df02004-08-15 05:52:07 +0000901 /* Self-originated LSA (newer than ours) is received from
902 another router. We have to make a new instance of the LSA
hasso48454372004-05-18 19:14:52 +0000903 or have to flush this LSA. */
hasso1e058382004-09-01 21:36:14 +0000904 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000905 {
hassoc6487d62004-12-24 06:00:11 +0000906 zlog_debug ("Newer instance of the self-originated LSA");
907 zlog_debug ("Schedule reorigination");
hasso6452df02004-08-15 05:52:07 +0000908 }
909 new->refresh = thread_add_event (master, ospf6_lsa_refresh, new, 0);
hasso48454372004-05-18 19:14:52 +0000910 }
hasso6452df02004-08-15 05:52:07 +0000911
hasso48454372004-05-18 19:14:52 +0000912 return;
913 }
914
915 /* (6) if there is instance on sending neighbor's request list */
916 if (ospf6_lsdb_lookup (new->header->type, new->header->id,
917 new->header->adv_router, from->request_list))
918 {
919 /* if no database copy, should go above state (5) */
920 assert (old);
921
hasso1e058382004-09-01 21:36:14 +0000922 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000923 {
hassoc6487d62004-12-24 06:00:11 +0000924 zlog_debug ("Received is not newer, on the neighbor's request-list");
925 zlog_debug ("BadLSReq, discard the received LSA");
hasso6452df02004-08-15 05:52:07 +0000926 }
hasso48454372004-05-18 19:14:52 +0000927
928 /* BadLSReq */
929 thread_add_event (master, bad_lsreq, from, 0);
930
931 ospf6_lsa_delete (new);
932 return;
933 }
934
935 /* (7) if neither one is more recent */
936 if (ismore_recent == 0)
937 {
hasso1e058382004-09-01 21:36:14 +0000938 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000939 zlog_debug ("The same instance as database copy (neither recent)");
hasso48454372004-05-18 19:14:52 +0000940
941 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack */
942 rem = ospf6_lsdb_lookup (new->header->type, new->header->id,
943 new->header->adv_router, from->retrans_list);
944 if (rem)
945 {
hasso1e058382004-09-01 21:36:14 +0000946 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000947 {
hassoc6487d62004-12-24 06:00:11 +0000948 zlog_debug ("It is on the neighbor's retrans-list.");
949 zlog_debug ("Treat as an Implied acknowledgement");
hasso6452df02004-08-15 05:52:07 +0000950 }
hasso48454372004-05-18 19:14:52 +0000951 SET_FLAG (new->flag, OSPF6_LSA_IMPLIEDACK);
hasso6452df02004-08-15 05:52:07 +0000952 ospf6_decrement_retrans_count (rem);
hasso48454372004-05-18 19:14:52 +0000953 ospf6_lsdb_remove (rem, from->retrans_list);
954 }
955
hasso1e058382004-09-01 21:36:14 +0000956 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000957 zlog_debug ("Possibly acknowledge and then discard");
hasso6452df02004-08-15 05:52:07 +0000958
hasso48454372004-05-18 19:14:52 +0000959 /* (b) possibly acknowledge */
960 ospf6_acknowledge_lsa (new, ismore_recent, from);
961
962 ospf6_lsa_delete (new);
963 return;
964 }
965
966 /* (8) previous database copy is more recent */
967 {
968 assert (old);
969
970 /* If database copy is in 'Seqnumber Wrapping',
971 simply discard the received LSA */
972 if (OSPF6_LSA_IS_MAXAGE (old) &&
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700973 old->header->seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
hasso48454372004-05-18 19:14:52 +0000974 {
hasso1e058382004-09-01 21:36:14 +0000975 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000976 {
hassoc6487d62004-12-24 06:00:11 +0000977 zlog_debug ("The LSA is in Seqnumber Wrapping");
978 zlog_debug ("MaxAge & MaxSeqNum, discard");
hasso6452df02004-08-15 05:52:07 +0000979 }
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000980 ospf6_lsa_delete (new);
981 return;
hasso48454372004-05-18 19:14:52 +0000982 }
983
984 /* Otherwise, Send database copy of this LSA to this neighbor */
985 {
hasso1e058382004-09-01 21:36:14 +0000986 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000987 {
hassoc6487d62004-12-24 06:00:11 +0000988 zlog_debug ("Database copy is more recent.");
989 zlog_debug ("Send back directly and then discard");
hasso6452df02004-08-15 05:52:07 +0000990 }
hasso48454372004-05-18 19:14:52 +0000991
992 /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
993
hasso48454372004-05-18 19:14:52 +0000994 ospf6_lsdb_add (ospf6_lsa_copy (old), from->lsupdate_list);
995 if (from->thread_send_lsupdate == NULL)
996 from->thread_send_lsupdate =
997 thread_add_event (master, ospf6_lsupdate_send_neighbor, from, 0);
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000998 ospf6_lsa_delete (new);
999 return;
hasso48454372004-05-18 19:14:52 +00001000 }
1001 return;
1002 }
1003}
1004
1005
hasso1e058382004-09-01 21:36:14 +00001006DEFUN (debug_ospf6_flooding,
1007 debug_ospf6_flooding_cmd,
1008 "debug ospf6 flooding",
1009 DEBUG_STR
1010 OSPF6_STR
1011 "Debug OSPFv3 flooding function\n"
1012 )
1013{
1014 OSPF6_DEBUG_FLOODING_ON ();
1015 return CMD_SUCCESS;
1016}
1017
1018DEFUN (no_debug_ospf6_flooding,
1019 no_debug_ospf6_flooding_cmd,
1020 "no debug ospf6 flooding",
1021 NO_STR
1022 DEBUG_STR
1023 OSPF6_STR
1024 "Debug OSPFv3 flooding function\n"
1025 )
1026{
1027 OSPF6_DEBUG_FLOODING_OFF ();
1028 return CMD_SUCCESS;
1029}
1030
1031int
1032config_write_ospf6_debug_flood (struct vty *vty)
1033{
1034 if (IS_OSPF6_DEBUG_FLOODING)
1035 vty_out (vty, "debug ospf6 flooding%s", VNL);
1036 return 0;
1037}
1038
1039void
Paul Jakma6ac29a52008-08-15 13:45:30 +01001040install_element_ospf6_debug_flood (void)
hasso1e058382004-09-01 21:36:14 +00001041{
1042 install_element (ENABLE_NODE, &debug_ospf6_flooding_cmd);
1043 install_element (ENABLE_NODE, &no_debug_ospf6_flooding_cmd);
1044 install_element (CONFIG_NODE, &debug_ospf6_flooding_cmd);
1045 install_element (CONFIG_NODE, &no_debug_ospf6_flooding_cmd);
1046}
1047
1048
1049
1050
hasso48454372004-05-18 19:14:52 +00001051