blob: dc9ecbfb04ef40436b9867c3993bfd599a384d07 [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
Dinesh Dutt3b220282013-08-24 08:00:44 +0000233 if (OSPF6_LSA_IS_SEQWRAP(lsa) &&
234 ! (CHECK_FLAG(lsa->flag,OSPF6_LSA_SEQWRAPPED) &&
235 lsa->header->seqnum == htonl(OSPF_MAX_SEQUENCE_NUMBER)))
236 {
237 if (IS_OSPF6_DEBUG_EXAMIN_TYPE (lsa->header->type))
238 zlog_debug("lsa install wrapping: sequence 0x%x",
239 ntohl(lsa->header->seqnum));
240 SET_FLAG(lsa->flag, OSPF6_LSA_SEQWRAPPED);
241 /* in lieu of premature_aging, since we do not want to recreate this lsa
242 * and/or mess with timers etc, we just want to wrap the sequence number
243 * and reflood the lsa before continuing.
244 * NOTE: Flood needs to be called right after this function call, by the
245 * caller
246 */
247 lsa->header->seqnum = htonl (OSPF_MAX_SEQUENCE_NUMBER);
248 lsa->header->age = htons (OSPF_LSA_MAXAGE);
249 ospf6_lsa_checksum (lsa->header);
250 }
251
hasso48454372004-05-18 19:14:52 +0000252 /* actually install */
hasso3b687352004-08-19 06:56:53 +0000253 lsa->installed = now;
hasso6452df02004-08-15 05:52:07 +0000254 ospf6_lsdb_add (lsa, lsa->lsdb);
hasso48454372004-05-18 19:14:52 +0000255
256 return;
257}
258
hasso6452df02004-08-15 05:52:07 +0000259/* RFC2740 section 3.5.2. Sending Link State Update packets */
hasso48454372004-05-18 19:14:52 +0000260/* RFC2328 section 13.3 Next step in the flooding procedure */
Paul Jakma6ac29a52008-08-15 13:45:30 +0100261static void
hasso6452df02004-08-15 05:52:07 +0000262ospf6_flood_interface (struct ospf6_neighbor *from,
263 struct ospf6_lsa *lsa, struct ospf6_interface *oi)
hasso48454372004-05-18 19:14:52 +0000264{
paul1eb8ef22005-04-07 07:30:20 +0000265 struct listnode *node, *nnode;
hasso48454372004-05-18 19:14:52 +0000266 struct ospf6_neighbor *on;
hasso48454372004-05-18 19:14:52 +0000267 struct ospf6_lsa *req;
268 int retrans_added = 0;
hasso1e058382004-09-01 21:36:14 +0000269 int is_debug = 0;
hasso48454372004-05-18 19:14:52 +0000270
hasso1e058382004-09-01 21:36:14 +0000271 if (IS_OSPF6_DEBUG_FLOODING ||
272 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
273 {
274 is_debug++;
hassoc6487d62004-12-24 06:00:11 +0000275 zlog_debug ("Flooding on %s: %s", oi->interface->name, lsa->name);
hasso1e058382004-09-01 21:36:14 +0000276 }
hasso48454372004-05-18 19:14:52 +0000277
hasso6452df02004-08-15 05:52:07 +0000278 /* (1) For each neighbor */
paul1eb8ef22005-04-07 07:30:20 +0000279 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
hasso48454372004-05-18 19:14:52 +0000280 {
hasso1e058382004-09-01 21:36:14 +0000281 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000282 zlog_debug ("To neighbor %s", on->name);
hasso6452df02004-08-15 05:52:07 +0000283
284 /* (a) if neighbor state < Exchange, examin next */
285 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
hasso48454372004-05-18 19:14:52 +0000286 {
hasso1e058382004-09-01 21:36:14 +0000287 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000288 zlog_debug ("Neighbor state less than ExChange, next neighbor");
hasso6452df02004-08-15 05:52:07 +0000289 continue;
hasso48454372004-05-18 19:14:52 +0000290 }
hasso48454372004-05-18 19:14:52 +0000291
hasso6452df02004-08-15 05:52:07 +0000292 /* (b) if neighbor not yet Full, check request-list */
293 if (on->state != OSPF6_NEIGHBOR_FULL)
hasso48454372004-05-18 19:14:52 +0000294 {
hasso1e058382004-09-01 21:36:14 +0000295 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000296 zlog_debug ("Neighbor not yet Full");
hasso48454372004-05-18 19:14:52 +0000297
hasso6452df02004-08-15 05:52:07 +0000298 req = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
299 lsa->header->adv_router, on->request_list);
300 if (req == NULL)
hasso48454372004-05-18 19:14:52 +0000301 {
hasso1e058382004-09-01 21:36:14 +0000302 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000303 zlog_debug ("Not on request-list for this neighbor");
hasso6452df02004-08-15 05:52:07 +0000304 /* fall through */
305 }
306 else
307 {
308 /* If new LSA less recent, examin next neighbor */
309 if (ospf6_lsa_compare (lsa, req) > 0)
hasso48454372004-05-18 19:14:52 +0000310 {
hasso1e058382004-09-01 21:36:14 +0000311 if (is_debug)
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000312 zlog_debug ("Requesting is older, next neighbor");
hasso6452df02004-08-15 05:52:07 +0000313 continue;
314 }
hasso48454372004-05-18 19:14:52 +0000315
hasso6452df02004-08-15 05:52:07 +0000316 /* If the same instance, delete from request-list and
317 examin next neighbor */
318 if (ospf6_lsa_compare (lsa, req) == 0)
319 {
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000320 if (is_debug)
321 zlog_debug ("Requesting the same, remove it, next neighbor");
322 if (req == on->last_ls_req)
323 {
324 ospf6_lsa_unlock (req);
325 on->last_ls_req = NULL;
326 }
hasso6452df02004-08-15 05:52:07 +0000327 ospf6_lsdb_remove (req, on->request_list);
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000328 ospf6_check_nbr_loading (on);
hasso6452df02004-08-15 05:52:07 +0000329 continue;
330 }
hasso48454372004-05-18 19:14:52 +0000331
hasso6452df02004-08-15 05:52:07 +0000332 /* If the new LSA is more recent, delete from request-list */
333 if (ospf6_lsa_compare (lsa, req) < 0)
334 {
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000335 if (is_debug)
336 zlog_debug ("Received is newer, remove requesting");
337 if (req == on->last_ls_req)
338 {
339 ospf6_lsa_unlock (req);
340 on->last_ls_req = NULL;
341 }
hasso6452df02004-08-15 05:52:07 +0000342 ospf6_lsdb_remove (req, on->request_list);
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000343 ospf6_check_nbr_loading (on);
hasso6452df02004-08-15 05:52:07 +0000344 /* fall through */
hasso48454372004-05-18 19:14:52 +0000345 }
346 }
hasso48454372004-05-18 19:14:52 +0000347 }
348
hasso6452df02004-08-15 05:52:07 +0000349 /* (c) If the new LSA was received from this neighbor,
350 examin next neighbor */
351 if (from == on)
hasso48454372004-05-18 19:14:52 +0000352 {
hasso1e058382004-09-01 21:36:14 +0000353 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000354 zlog_debug ("Received is from the neighbor, next neighbor");
hasso6452df02004-08-15 05:52:07 +0000355 continue;
hasso48454372004-05-18 19:14:52 +0000356 }
hasso6452df02004-08-15 05:52:07 +0000357
358 /* (d) add retrans-list, schedule retransmission */
hasso1e058382004-09-01 21:36:14 +0000359 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000360 zlog_debug ("Add retrans-list of this neighbor");
hasso6452df02004-08-15 05:52:07 +0000361 ospf6_increment_retrans_count (lsa);
362 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
363 if (on->thread_send_lsupdate == NULL)
364 on->thread_send_lsupdate =
gdt6639a042004-11-05 18:42:27 +0000365 thread_add_timer (master, ospf6_lsupdate_send_neighbor,
hasso6452df02004-08-15 05:52:07 +0000366 on, on->ospf6_if->rxmt_interval);
367 retrans_added++;
hasso48454372004-05-18 19:14:52 +0000368 }
369
hasso6452df02004-08-15 05:52:07 +0000370 /* (2) examin next interface if not added to retrans-list */
371 if (retrans_added == 0)
372 {
hasso1e058382004-09-01 21:36:14 +0000373 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000374 zlog_debug ("No retransmission scheduled, next interface");
hasso6452df02004-08-15 05:52:07 +0000375 return;
376 }
377
378 /* (3) If the new LSA was received on this interface,
379 and it was from DR or BDR, examin next interface */
380 if (from && from->ospf6_if == oi &&
381 (from->router_id == oi->drouter || from->router_id == oi->bdrouter))
382 {
hasso1e058382004-09-01 21:36:14 +0000383 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000384 zlog_debug ("Received is from the I/F's DR or BDR, next interface");
hasso6452df02004-08-15 05:52:07 +0000385 return;
386 }
387
388 /* (4) If the new LSA was received on this interface,
389 and the interface state is BDR, examin next interface */
Dinesh Dutt7cf99722013-08-25 03:03:39 +0000390 if (from && from->ospf6_if == oi)
hasso6452df02004-08-15 05:52:07 +0000391 {
Dinesh Dutt7cf99722013-08-25 03:03:39 +0000392 if (oi->state == OSPF6_INTERFACE_BDR)
393 {
394 if (is_debug)
395 zlog_debug ("Received is from the I/F, itself BDR, next interface");
396 return;
397 }
398 SET_FLAG(lsa->flag, OSPF6_LSA_FLOODBACK);
hasso6452df02004-08-15 05:52:07 +0000399 }
400
401 /* (5) flood the LSA out the interface. */
hasso1e058382004-09-01 21:36:14 +0000402 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000403 zlog_debug ("Schedule flooding for the interface");
Dinesh Duttc5926a92013-08-24 07:55:00 +0000404 if ((oi->type == OSPF_IFTYPE_BROADCAST) ||
405 (oi->type == OSPF_IFTYPE_POINTOPOINT))
hasso6452df02004-08-15 05:52:07 +0000406 {
407 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list);
408 if (oi->thread_send_lsupdate == NULL)
409 oi->thread_send_lsupdate =
410 thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
411 }
412 else
413 {
414 /* reschedule retransmissions to all neighbors */
paul1eb8ef22005-04-07 07:30:20 +0000415 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
hasso6452df02004-08-15 05:52:07 +0000416 {
hasso6452df02004-08-15 05:52:07 +0000417 THREAD_OFF (on->thread_send_lsupdate);
418 on->thread_send_lsupdate =
419 thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
420 }
421 }
hasso48454372004-05-18 19:14:52 +0000422}
423
Paul Jakma6ac29a52008-08-15 13:45:30 +0100424static void
hasso6452df02004-08-15 05:52:07 +0000425ospf6_flood_area (struct ospf6_neighbor *from,
426 struct ospf6_lsa *lsa, struct ospf6_area *oa)
427{
paul1eb8ef22005-04-07 07:30:20 +0000428 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000429 struct ospf6_interface *oi;
430
paul1eb8ef22005-04-07 07:30:20 +0000431 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
hasso6452df02004-08-15 05:52:07 +0000432 {
hasso6452df02004-08-15 05:52:07 +0000433 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
434 oi != OSPF6_INTERFACE (lsa->lsdb->data))
435 continue;
436
437#if 0
438 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
439 ospf6_is_interface_virtual_link (oi))
440 continue;
441#endif/*0*/
442
443 ospf6_flood_interface (from, lsa, oi);
444 }
445}
446
Paul Jakma6ac29a52008-08-15 13:45:30 +0100447static void
hasso6452df02004-08-15 05:52:07 +0000448ospf6_flood_process (struct ospf6_neighbor *from,
449 struct ospf6_lsa *lsa, struct ospf6 *process)
450{
paul1eb8ef22005-04-07 07:30:20 +0000451 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000452 struct ospf6_area *oa;
453
paul1eb8ef22005-04-07 07:30:20 +0000454 for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa))
hasso6452df02004-08-15 05:52:07 +0000455 {
hasso6452df02004-08-15 05:52:07 +0000456 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
457 oa != OSPF6_AREA (lsa->lsdb->data))
458 continue;
459 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
460 oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
461 continue;
462
463 if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
464 IS_AREA_STUB (oa))
465 continue;
466
467 ospf6_flood_area (from, lsa, oa);
468 }
469}
470
471void
472ospf6_flood (struct ospf6_neighbor *from, struct ospf6_lsa *lsa)
473{
474 ospf6_flood_process (from, lsa, ospf6);
475}
476
Paul Jakma6ac29a52008-08-15 13:45:30 +0100477static void
hasso6452df02004-08-15 05:52:07 +0000478ospf6_flood_clear_interface (struct ospf6_lsa *lsa, struct ospf6_interface *oi)
479{
paul1eb8ef22005-04-07 07:30:20 +0000480 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000481 struct ospf6_neighbor *on;
482 struct ospf6_lsa *rem;
483
paul1eb8ef22005-04-07 07:30:20 +0000484 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
hasso6452df02004-08-15 05:52:07 +0000485 {
hasso6452df02004-08-15 05:52:07 +0000486 rem = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
487 lsa->header->adv_router, on->retrans_list);
488 if (rem && ! ospf6_lsa_compare (rem, lsa))
489 {
hasso1e058382004-09-01 21:36:14 +0000490 if (IS_OSPF6_DEBUG_FLOODING ||
491 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
hassoc6487d62004-12-24 06:00:11 +0000492 zlog_debug ("Remove %s from retrans_list of %s",
hasso6452df02004-08-15 05:52:07 +0000493 rem->name, on->name);
494 ospf6_decrement_retrans_count (rem);
495 ospf6_lsdb_remove (rem, on->retrans_list);
496 }
497 }
498}
499
Paul Jakma6ac29a52008-08-15 13:45:30 +0100500static void
hasso6452df02004-08-15 05:52:07 +0000501ospf6_flood_clear_area (struct ospf6_lsa *lsa, struct ospf6_area *oa)
502{
paul1eb8ef22005-04-07 07:30:20 +0000503 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000504 struct ospf6_interface *oi;
505
paul1eb8ef22005-04-07 07:30:20 +0000506 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
hasso6452df02004-08-15 05:52:07 +0000507 {
hasso6452df02004-08-15 05:52:07 +0000508 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
509 oi != OSPF6_INTERFACE (lsa->lsdb->data))
510 continue;
511
512#if 0
513 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
514 ospf6_is_interface_virtual_link (oi))
515 continue;
516#endif/*0*/
517
518 ospf6_flood_clear_interface (lsa, oi);
519 }
520}
521
Paul Jakma6ac29a52008-08-15 13:45:30 +0100522static void
hasso6452df02004-08-15 05:52:07 +0000523ospf6_flood_clear_process (struct ospf6_lsa *lsa, struct ospf6 *process)
524{
paul1eb8ef22005-04-07 07:30:20 +0000525 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000526 struct ospf6_area *oa;
527
paul1eb8ef22005-04-07 07:30:20 +0000528 for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa))
hasso6452df02004-08-15 05:52:07 +0000529 {
hasso6452df02004-08-15 05:52:07 +0000530 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
531 oa != OSPF6_AREA (lsa->lsdb->data))
532 continue;
533 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
534 oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
535 continue;
536
537 if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
538 IS_AREA_STUB (oa))
539 continue;
540
541 ospf6_flood_clear_area (lsa, oa);
542 }
543}
544
545void
546ospf6_flood_clear (struct ospf6_lsa *lsa)
547{
548 ospf6_flood_clear_process (lsa, ospf6);
549}
550
551
hasso48454372004-05-18 19:14:52 +0000552/* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
553static void
554ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
555 struct ospf6_neighbor *from)
556{
557 struct ospf6_interface *oi;
hasso1e058382004-09-01 21:36:14 +0000558 int is_debug = 0;
559
560 if (IS_OSPF6_DEBUG_FLOODING ||
561 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
562 is_debug++;
hasso48454372004-05-18 19:14:52 +0000563
564 assert (from && from->ospf6_if);
565 oi = from->ospf6_if;
566
hasso48454372004-05-18 19:14:52 +0000567 /* LSA is more recent than database copy, but was not flooded
568 back out receiving interface. Delayed acknowledgement sent
569 if advertisement received from Designated Router,
570 otherwide do nothing. */
571 if (ismore_recent < 0)
572 {
hasso48454372004-05-18 19:14:52 +0000573 if (oi->drouter == from->router_id)
574 {
hasso1e058382004-09-01 21:36:14 +0000575 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000576 zlog_debug ("Delayed acknowledgement (BDR & MoreRecent & from DR)");
hasso48454372004-05-18 19:14:52 +0000577 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000578 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
579 if (oi->thread_send_lsack == NULL)
580 oi->thread_send_lsack =
581 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
582 }
583 else
584 {
hasso1e058382004-09-01 21:36:14 +0000585 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000586 zlog_debug ("No acknowledgement (BDR & MoreRecent & ! from DR)");
hasso48454372004-05-18 19:14:52 +0000587 }
588 return;
589 }
590
591 /* LSA is a duplicate, and was treated as an implied acknowledgement.
592 Delayed acknowledgement sent if advertisement received from
593 Designated Router, otherwise do nothing */
594 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
595 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
596 {
hasso48454372004-05-18 19:14:52 +0000597 if (oi->drouter == from->router_id)
598 {
hasso1e058382004-09-01 21:36:14 +0000599 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000600 zlog_debug ("Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
hasso48454372004-05-18 19:14:52 +0000601 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000602 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
603 if (oi->thread_send_lsack == NULL)
604 oi->thread_send_lsack =
605 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
606 }
607 else
608 {
hasso1e058382004-09-01 21:36:14 +0000609 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000610 zlog_debug ("No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
hasso48454372004-05-18 19:14:52 +0000611 }
612 return;
613 }
614
615 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
616 Direct acknowledgement sent */
617 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
618 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
619 {
hasso1e058382004-09-01 21:36:14 +0000620 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000621 zlog_debug ("Direct acknowledgement (BDR & Duplicate)");
hasso48454372004-05-18 19:14:52 +0000622 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
623 if (from->thread_send_lsack == NULL)
624 from->thread_send_lsack =
625 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
626 return;
627 }
628
629 /* LSA's LS age is equal to Maxage, and there is no current instance
630 of the LSA in the link state database, and none of router's
631 neighbors are in states Exchange or Loading */
632 /* Direct acknowledgement sent, but this case is handled in
633 early of ospf6_receive_lsa () */
634}
635
636static void
637ospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent,
638 struct ospf6_neighbor *from)
639{
640 struct ospf6_interface *oi;
hasso1e058382004-09-01 21:36:14 +0000641 int is_debug = 0;
642
643 if (IS_OSPF6_DEBUG_FLOODING ||
644 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
645 is_debug++;
hasso48454372004-05-18 19:14:52 +0000646
647 assert (from && from->ospf6_if);
648 oi = from->ospf6_if;
649
650 /* LSA has been flood back out receiving interface.
651 No acknowledgement sent. */
652 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
653 {
hasso1e058382004-09-01 21:36:14 +0000654 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000655 zlog_debug ("No acknowledgement (AllOther & FloodBack)");
hasso48454372004-05-18 19:14:52 +0000656 return;
657 }
658
659 /* LSA is more recent than database copy, but was not flooded
660 back out receiving interface. Delayed acknowledgement sent. */
661 if (ismore_recent < 0)
662 {
hasso1e058382004-09-01 21:36:14 +0000663 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000664 zlog_debug ("Delayed acknowledgement (AllOther & MoreRecent)");
hasso48454372004-05-18 19:14:52 +0000665 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000666 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
667 if (oi->thread_send_lsack == NULL)
668 oi->thread_send_lsack =
669 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
670 return;
671 }
672
673 /* LSA is a duplicate, and was treated as an implied acknowledgement.
674 No acknowledgement sent. */
675 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
676 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
677 {
hasso1e058382004-09-01 21:36:14 +0000678 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000679 zlog_debug ("No acknowledgement (AllOther & Duplicate & ImpliedAck)");
hasso48454372004-05-18 19:14:52 +0000680 return;
681 }
682
683 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
684 Direct acknowledgement sent */
685 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
686 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
687 {
hasso1e058382004-09-01 21:36:14 +0000688 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000689 zlog_debug ("Direct acknowledgement (AllOther & Duplicate)");
hasso48454372004-05-18 19:14:52 +0000690 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
691 if (from->thread_send_lsack == NULL)
692 from->thread_send_lsack =
693 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
694 return;
695 }
696
697 /* LSA's LS age is equal to Maxage, and there is no current instance
698 of the LSA in the link state database, and none of router's
699 neighbors are in states Exchange or Loading */
700 /* Direct acknowledgement sent, but this case is handled in
701 early of ospf6_receive_lsa () */
702}
703
Paul Jakma6ac29a52008-08-15 13:45:30 +0100704static void
hasso48454372004-05-18 19:14:52 +0000705ospf6_acknowledge_lsa (struct ospf6_lsa *lsa, int ismore_recent,
706 struct ospf6_neighbor *from)
707{
708 struct ospf6_interface *oi;
709
710 assert (from && from->ospf6_if);
711 oi = from->ospf6_if;
712
713 if (oi->state == OSPF6_INTERFACE_BDR)
714 ospf6_acknowledge_lsa_bdrouter (lsa, ismore_recent, from);
715 else
716 ospf6_acknowledge_lsa_allother (lsa, ismore_recent, from);
717}
718
719/* RFC2328 section 13 (4):
720 if MaxAge LSA and if we have no instance, and no neighbor
721 is in states Exchange or Loading
722 returns 1 if match this case, else returns 0 */
723static int
hasso6452df02004-08-15 05:52:07 +0000724ospf6_is_maxage_lsa_drop (struct ospf6_lsa *lsa, struct ospf6_neighbor *from)
hasso48454372004-05-18 19:14:52 +0000725{
hasso48454372004-05-18 19:14:52 +0000726 struct ospf6_neighbor *on;
hasso6452df02004-08-15 05:52:07 +0000727 struct ospf6_interface *oi;
728 struct ospf6_area *oa;
729 struct ospf6 *process = NULL;
hasso52dc7ee2004-09-23 19:18:23 +0000730 struct listnode *i, *j, *k;
hasso48454372004-05-18 19:14:52 +0000731 int count = 0;
732
733 if (! OSPF6_LSA_IS_MAXAGE (lsa))
734 return 0;
735
hasso48454372004-05-18 19:14:52 +0000736 if (ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
hasso6452df02004-08-15 05:52:07 +0000737 lsa->header->adv_router, lsa->lsdb))
hasso48454372004-05-18 19:14:52 +0000738 return 0;
739
hasso6452df02004-08-15 05:52:07 +0000740 process = from->ospf6_if->area->ospf6;
paul1eb8ef22005-04-07 07:30:20 +0000741
742 for (ALL_LIST_ELEMENTS_RO (process->area_list, i, oa))
743 for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
744 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on))
745 if (on->state == OSPF6_NEIGHBOR_EXCHANGE ||
746 on->state == OSPF6_NEIGHBOR_LOADING)
747 count++;
hasso48454372004-05-18 19:14:52 +0000748
hasso48454372004-05-18 19:14:52 +0000749 if (count == 0)
750 return 1;
hasso48454372004-05-18 19:14:52 +0000751 return 0;
752}
753
754/* RFC2328 section 13 The Flooding Procedure */
755void
hasso6452df02004-08-15 05:52:07 +0000756ospf6_receive_lsa (struct ospf6_neighbor *from,
757 struct ospf6_lsa_header *lsa_header)
hasso48454372004-05-18 19:14:52 +0000758{
759 struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
760 int ismore_recent;
hasso1e058382004-09-01 21:36:14 +0000761 int is_debug = 0;
hasso48454372004-05-18 19:14:52 +0000762
763 ismore_recent = 1;
hasso6452df02004-08-15 05:52:07 +0000764 assert (from);
hasso48454372004-05-18 19:14:52 +0000765
766 /* make lsa structure for received lsa */
767 new = ospf6_lsa_create (lsa_header);
768
hasso1e058382004-09-01 21:36:14 +0000769 if (IS_OSPF6_DEBUG_FLOODING ||
770 IS_OSPF6_DEBUG_FLOOD_TYPE (new->header->type))
hasso48454372004-05-18 19:14:52 +0000771 {
hasso1e058382004-09-01 21:36:14 +0000772 is_debug++;
hassoc6487d62004-12-24 06:00:11 +0000773 zlog_debug ("LSA Receive from %s", from->name);
hasso48454372004-05-18 19:14:52 +0000774 ospf6_lsa_header_print (new);
775 }
776
hasso48454372004-05-18 19:14:52 +0000777 /* (1) LSA Checksum */
JR Riversd8a4e422012-09-13 17:17:36 +0000778 if (! ospf6_lsa_checksum_valid (new->header))
hasso48454372004-05-18 19:14:52 +0000779 {
hasso1e058382004-09-01 21:36:14 +0000780 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000781 zlog_debug ("Wrong LSA Checksum, discard");
hasso48454372004-05-18 19:14:52 +0000782 ospf6_lsa_delete (new);
783 return;
784 }
785
hasso6452df02004-08-15 05:52:07 +0000786 /* (2) Examine the LSA's LS type.
787 RFC2470 3.5.1. Receiving Link State Update packets */
788 if (IS_AREA_STUB (from->ospf6_if->area) &&
789 OSPF6_LSA_SCOPE (new->header->type) == OSPF6_SCOPE_AS)
hasso48454372004-05-18 19:14:52 +0000790 {
hasso1e058382004-09-01 21:36:14 +0000791 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000792 zlog_debug ("AS-External-LSA (or AS-scope LSA) in stub area, discard");
hasso6452df02004-08-15 05:52:07 +0000793 ospf6_lsa_delete (new);
794 return;
795 }
796
797 /* (3) LSA which have reserved scope is discarded
798 RFC2470 3.5.1. Receiving Link State Update packets */
799 /* Flooding scope check. LSAs with unknown scope are discarded here.
800 Set appropriate LSDB for the LSA */
801 switch (OSPF6_LSA_SCOPE (new->header->type))
802 {
803 case OSPF6_SCOPE_LINKLOCAL:
804 new->lsdb = from->ospf6_if->lsdb;
805 break;
806 case OSPF6_SCOPE_AREA:
807 new->lsdb = from->ospf6_if->area->lsdb;
808 break;
809 case OSPF6_SCOPE_AS:
810 new->lsdb = from->ospf6_if->area->ospf6->lsdb;
811 break;
812 default:
hasso1e058382004-09-01 21:36:14 +0000813 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000814 zlog_debug ("LSA has reserved scope, discard");
hasso48454372004-05-18 19:14:52 +0000815 ospf6_lsa_delete (new);
816 return;
817 }
818
819 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
820 is in states Exchange or Loading */
821 if (ospf6_is_maxage_lsa_drop (new, from))
822 {
823 /* log */
hasso1e058382004-09-01 21:36:14 +0000824 if (is_debug)
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000825 zlog_debug ("Drop MaxAge LSA with direct acknowledgement.");
hasso48454372004-05-18 19:14:52 +0000826
827 /* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */
hasso6452df02004-08-15 05:52:07 +0000828 ospf6_lsdb_add (ospf6_lsa_copy (new), from->lsack_list);
hasso48454372004-05-18 19:14:52 +0000829 if (from->thread_send_lsack == NULL)
830 from->thread_send_lsack =
831 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
832
833 /* b) Discard */
hasso6452df02004-08-15 05:52:07 +0000834 ospf6_lsa_delete (new);
hasso48454372004-05-18 19:14:52 +0000835 return;
836 }
837
838 /* (5) */
839 /* lookup the same database copy in lsdb */
hasso48454372004-05-18 19:14:52 +0000840 old = ospf6_lsdb_lookup (new->header->type, new->header->id,
hasso6452df02004-08-15 05:52:07 +0000841 new->header->adv_router, new->lsdb);
hasso48454372004-05-18 19:14:52 +0000842 if (old)
843 {
844 ismore_recent = ospf6_lsa_compare (new, old);
845 if (ntohl (new->header->seqnum) == ntohl (old->header->seqnum))
846 {
hasso1e058382004-09-01 21:36:14 +0000847 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000848 zlog_debug ("Received is duplicated LSA");
hasso48454372004-05-18 19:14:52 +0000849 SET_FLAG (new->flag, OSPF6_LSA_DUPLICATE);
850 }
851 }
852
853 /* if no database copy or received is more recent */
854 if (old == NULL || ismore_recent < 0)
855 {
856 /* in case we have no database copy */
857 ismore_recent = -1;
858
859 /* (a) MinLSArrival check */
860 if (old)
861 {
862 struct timeval now, res;
Takashi Sogabe86f72dc2009-06-22 13:07:02 +0900863 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
hasso48454372004-05-18 19:14:52 +0000864 timersub (&now, &old->installed, &res);
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700865 if (res.tv_sec < OSPF_MIN_LS_ARRIVAL)
hasso48454372004-05-18 19:14:52 +0000866 {
hasso1e058382004-09-01 21:36:14 +0000867 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000868 zlog_debug ("LSA can't be updated within MinLSArrival, discard");
hasso48454372004-05-18 19:14:52 +0000869 ospf6_lsa_delete (new);
870 return; /* examin next lsa */
871 }
872 }
873
Takashi Sogabe86f72dc2009-06-22 13:07:02 +0900874 quagga_gettime (QUAGGA_CLK_MONOTONIC, &new->received);
hassoccb59b12004-08-25 09:10:37 +0000875
hasso1e058382004-09-01 21:36:14 +0000876 if (is_debug)
Dinesh Duttbf986da2013-08-24 07:54:50 +0000877 zlog_debug ("Install, Flood, Possibly acknowledge the received LSA");
878
879 /* Remove older copies of this LSA from retx lists */
880 if (old)
881 ospf6_flood_clear (old);
hasso6452df02004-08-15 05:52:07 +0000882
hasso48454372004-05-18 19:14:52 +0000883 /* (b) immediately flood and (c) remove from all retrans-list */
hassoccb59b12004-08-25 09:10:37 +0000884 /* Prevent self-originated LSA to be flooded. this is to make
885 reoriginated instance of the LSA not to be rejected by other routers
886 due to MinLSArrival. */
887 if (new->header->adv_router != from->ospf6_if->area->ospf6->router_id)
888 ospf6_flood (from, new);
hasso6452df02004-08-15 05:52:07 +0000889
hasso48454372004-05-18 19:14:52 +0000890 /* (d), installing lsdb, which may cause routing
891 table calculation (replacing database copy) */
hasso6452df02004-08-15 05:52:07 +0000892 ospf6_install_lsa (new);
hasso48454372004-05-18 19:14:52 +0000893
894 /* (e) possibly acknowledge */
895 ospf6_acknowledge_lsa (new, ismore_recent, from);
896
hasso6452df02004-08-15 05:52:07 +0000897 /* (f) Self Originated LSA, section 13.4 */
898 if (new->header->adv_router == from->ospf6_if->area->ospf6->router_id)
hasso48454372004-05-18 19:14:52 +0000899 {
hasso6452df02004-08-15 05:52:07 +0000900 /* Self-originated LSA (newer than ours) is received from
901 another router. We have to make a new instance of the LSA
hasso48454372004-05-18 19:14:52 +0000902 or have to flush this LSA. */
hasso1e058382004-09-01 21:36:14 +0000903 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000904 {
hassoc6487d62004-12-24 06:00:11 +0000905 zlog_debug ("Newer instance of the self-originated LSA");
906 zlog_debug ("Schedule reorigination");
hasso6452df02004-08-15 05:52:07 +0000907 }
908 new->refresh = thread_add_event (master, ospf6_lsa_refresh, new, 0);
hasso48454372004-05-18 19:14:52 +0000909 }
hasso6452df02004-08-15 05:52:07 +0000910
hasso48454372004-05-18 19:14:52 +0000911 return;
912 }
913
914 /* (6) if there is instance on sending neighbor's request list */
915 if (ospf6_lsdb_lookup (new->header->type, new->header->id,
916 new->header->adv_router, from->request_list))
917 {
918 /* if no database copy, should go above state (5) */
919 assert (old);
920
hasso1e058382004-09-01 21:36:14 +0000921 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000922 {
hassoc6487d62004-12-24 06:00:11 +0000923 zlog_debug ("Received is not newer, on the neighbor's request-list");
924 zlog_debug ("BadLSReq, discard the received LSA");
hasso6452df02004-08-15 05:52:07 +0000925 }
hasso48454372004-05-18 19:14:52 +0000926
927 /* BadLSReq */
928 thread_add_event (master, bad_lsreq, from, 0);
929
930 ospf6_lsa_delete (new);
931 return;
932 }
933
934 /* (7) if neither one is more recent */
935 if (ismore_recent == 0)
936 {
hasso1e058382004-09-01 21:36:14 +0000937 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000938 zlog_debug ("The same instance as database copy (neither recent)");
hasso48454372004-05-18 19:14:52 +0000939
940 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack */
941 rem = ospf6_lsdb_lookup (new->header->type, new->header->id,
942 new->header->adv_router, from->retrans_list);
943 if (rem)
944 {
hasso1e058382004-09-01 21:36:14 +0000945 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000946 {
hassoc6487d62004-12-24 06:00:11 +0000947 zlog_debug ("It is on the neighbor's retrans-list.");
948 zlog_debug ("Treat as an Implied acknowledgement");
hasso6452df02004-08-15 05:52:07 +0000949 }
hasso48454372004-05-18 19:14:52 +0000950 SET_FLAG (new->flag, OSPF6_LSA_IMPLIEDACK);
hasso6452df02004-08-15 05:52:07 +0000951 ospf6_decrement_retrans_count (rem);
hasso48454372004-05-18 19:14:52 +0000952 ospf6_lsdb_remove (rem, from->retrans_list);
953 }
954
hasso1e058382004-09-01 21:36:14 +0000955 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000956 zlog_debug ("Possibly acknowledge and then discard");
hasso6452df02004-08-15 05:52:07 +0000957
hasso48454372004-05-18 19:14:52 +0000958 /* (b) possibly acknowledge */
959 ospf6_acknowledge_lsa (new, ismore_recent, from);
960
961 ospf6_lsa_delete (new);
962 return;
963 }
964
965 /* (8) previous database copy is more recent */
966 {
967 assert (old);
968
969 /* If database copy is in 'Seqnumber Wrapping',
970 simply discard the received LSA */
971 if (OSPF6_LSA_IS_MAXAGE (old) &&
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700972 old->header->seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
hasso48454372004-05-18 19:14:52 +0000973 {
hasso1e058382004-09-01 21:36:14 +0000974 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000975 {
hassoc6487d62004-12-24 06:00:11 +0000976 zlog_debug ("The LSA is in Seqnumber Wrapping");
977 zlog_debug ("MaxAge & MaxSeqNum, discard");
hasso6452df02004-08-15 05:52:07 +0000978 }
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000979 ospf6_lsa_delete (new);
980 return;
hasso48454372004-05-18 19:14:52 +0000981 }
982
983 /* Otherwise, Send database copy of this LSA to this neighbor */
984 {
hasso1e058382004-09-01 21:36:14 +0000985 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000986 {
hassoc6487d62004-12-24 06:00:11 +0000987 zlog_debug ("Database copy is more recent.");
988 zlog_debug ("Send back directly and then discard");
hasso6452df02004-08-15 05:52:07 +0000989 }
hasso48454372004-05-18 19:14:52 +0000990
991 /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
992
hasso48454372004-05-18 19:14:52 +0000993 ospf6_lsdb_add (ospf6_lsa_copy (old), from->lsupdate_list);
994 if (from->thread_send_lsupdate == NULL)
995 from->thread_send_lsupdate =
996 thread_add_event (master, ospf6_lsupdate_send_neighbor, from, 0);
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000997 ospf6_lsa_delete (new);
998 return;
hasso48454372004-05-18 19:14:52 +0000999 }
1000 return;
1001 }
1002}
1003
1004
hasso1e058382004-09-01 21:36:14 +00001005DEFUN (debug_ospf6_flooding,
1006 debug_ospf6_flooding_cmd,
1007 "debug ospf6 flooding",
1008 DEBUG_STR
1009 OSPF6_STR
1010 "Debug OSPFv3 flooding function\n"
1011 )
1012{
1013 OSPF6_DEBUG_FLOODING_ON ();
1014 return CMD_SUCCESS;
1015}
1016
1017DEFUN (no_debug_ospf6_flooding,
1018 no_debug_ospf6_flooding_cmd,
1019 "no debug ospf6 flooding",
1020 NO_STR
1021 DEBUG_STR
1022 OSPF6_STR
1023 "Debug OSPFv3 flooding function\n"
1024 )
1025{
1026 OSPF6_DEBUG_FLOODING_OFF ();
1027 return CMD_SUCCESS;
1028}
1029
1030int
1031config_write_ospf6_debug_flood (struct vty *vty)
1032{
1033 if (IS_OSPF6_DEBUG_FLOODING)
1034 vty_out (vty, "debug ospf6 flooding%s", VNL);
1035 return 0;
1036}
1037
1038void
Paul Jakma6ac29a52008-08-15 13:45:30 +01001039install_element_ospf6_debug_flood (void)
hasso1e058382004-09-01 21:36:14 +00001040{
1041 install_element (ENABLE_NODE, &debug_ospf6_flooding_cmd);
1042 install_element (ENABLE_NODE, &no_debug_ospf6_flooding_cmd);
1043 install_element (CONFIG_NODE, &debug_ospf6_flooding_cmd);
1044 install_element (CONFIG_NODE, &no_debug_ospf6_flooding_cmd);
1045}
1046
1047
1048
1049
hasso48454372004-05-18 19:14:52 +00001050