blob: 7f6b2850c1b93b015d837cfbb8aaf778ac87f2b4 [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 */
390 if (from && from->ospf6_if == oi && oi->state == OSPF6_INTERFACE_BDR)
391 {
hasso1e058382004-09-01 21:36:14 +0000392 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000393 zlog_debug ("Received is from the I/F, itself BDR, next interface");
hasso6452df02004-08-15 05:52:07 +0000394 return;
395 }
396
397 /* (5) flood the LSA out the interface. */
hasso1e058382004-09-01 21:36:14 +0000398 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000399 zlog_debug ("Schedule flooding for the interface");
Dinesh Duttc5926a92013-08-24 07:55:00 +0000400 if ((oi->type == OSPF_IFTYPE_BROADCAST) ||
401 (oi->type == OSPF_IFTYPE_POINTOPOINT))
hasso6452df02004-08-15 05:52:07 +0000402 {
403 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list);
404 if (oi->thread_send_lsupdate == NULL)
405 oi->thread_send_lsupdate =
406 thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
407 }
408 else
409 {
410 /* reschedule retransmissions to all neighbors */
paul1eb8ef22005-04-07 07:30:20 +0000411 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
hasso6452df02004-08-15 05:52:07 +0000412 {
hasso6452df02004-08-15 05:52:07 +0000413 THREAD_OFF (on->thread_send_lsupdate);
414 on->thread_send_lsupdate =
415 thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
416 }
417 }
hasso48454372004-05-18 19:14:52 +0000418}
419
Paul Jakma6ac29a52008-08-15 13:45:30 +0100420static void
hasso6452df02004-08-15 05:52:07 +0000421ospf6_flood_area (struct ospf6_neighbor *from,
422 struct ospf6_lsa *lsa, struct ospf6_area *oa)
423{
paul1eb8ef22005-04-07 07:30:20 +0000424 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000425 struct ospf6_interface *oi;
426
paul1eb8ef22005-04-07 07:30:20 +0000427 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
hasso6452df02004-08-15 05:52:07 +0000428 {
hasso6452df02004-08-15 05:52:07 +0000429 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
430 oi != OSPF6_INTERFACE (lsa->lsdb->data))
431 continue;
432
433#if 0
434 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
435 ospf6_is_interface_virtual_link (oi))
436 continue;
437#endif/*0*/
438
439 ospf6_flood_interface (from, lsa, oi);
440 }
441}
442
Paul Jakma6ac29a52008-08-15 13:45:30 +0100443static void
hasso6452df02004-08-15 05:52:07 +0000444ospf6_flood_process (struct ospf6_neighbor *from,
445 struct ospf6_lsa *lsa, struct ospf6 *process)
446{
paul1eb8ef22005-04-07 07:30:20 +0000447 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000448 struct ospf6_area *oa;
449
paul1eb8ef22005-04-07 07:30:20 +0000450 for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa))
hasso6452df02004-08-15 05:52:07 +0000451 {
hasso6452df02004-08-15 05:52:07 +0000452 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
453 oa != OSPF6_AREA (lsa->lsdb->data))
454 continue;
455 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
456 oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
457 continue;
458
459 if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
460 IS_AREA_STUB (oa))
461 continue;
462
463 ospf6_flood_area (from, lsa, oa);
464 }
465}
466
467void
468ospf6_flood (struct ospf6_neighbor *from, struct ospf6_lsa *lsa)
469{
470 ospf6_flood_process (from, lsa, ospf6);
471}
472
Paul Jakma6ac29a52008-08-15 13:45:30 +0100473static void
hasso6452df02004-08-15 05:52:07 +0000474ospf6_flood_clear_interface (struct ospf6_lsa *lsa, struct ospf6_interface *oi)
475{
paul1eb8ef22005-04-07 07:30:20 +0000476 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000477 struct ospf6_neighbor *on;
478 struct ospf6_lsa *rem;
479
paul1eb8ef22005-04-07 07:30:20 +0000480 for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
hasso6452df02004-08-15 05:52:07 +0000481 {
hasso6452df02004-08-15 05:52:07 +0000482 rem = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
483 lsa->header->adv_router, on->retrans_list);
484 if (rem && ! ospf6_lsa_compare (rem, lsa))
485 {
hasso1e058382004-09-01 21:36:14 +0000486 if (IS_OSPF6_DEBUG_FLOODING ||
487 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
hassoc6487d62004-12-24 06:00:11 +0000488 zlog_debug ("Remove %s from retrans_list of %s",
hasso6452df02004-08-15 05:52:07 +0000489 rem->name, on->name);
490 ospf6_decrement_retrans_count (rem);
491 ospf6_lsdb_remove (rem, on->retrans_list);
492 }
493 }
494}
495
Paul Jakma6ac29a52008-08-15 13:45:30 +0100496static void
hasso6452df02004-08-15 05:52:07 +0000497ospf6_flood_clear_area (struct ospf6_lsa *lsa, struct ospf6_area *oa)
498{
paul1eb8ef22005-04-07 07:30:20 +0000499 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000500 struct ospf6_interface *oi;
501
paul1eb8ef22005-04-07 07:30:20 +0000502 for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi))
hasso6452df02004-08-15 05:52:07 +0000503 {
hasso6452df02004-08-15 05:52:07 +0000504 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
505 oi != OSPF6_INTERFACE (lsa->lsdb->data))
506 continue;
507
508#if 0
509 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
510 ospf6_is_interface_virtual_link (oi))
511 continue;
512#endif/*0*/
513
514 ospf6_flood_clear_interface (lsa, oi);
515 }
516}
517
Paul Jakma6ac29a52008-08-15 13:45:30 +0100518static void
hasso6452df02004-08-15 05:52:07 +0000519ospf6_flood_clear_process (struct ospf6_lsa *lsa, struct ospf6 *process)
520{
paul1eb8ef22005-04-07 07:30:20 +0000521 struct listnode *node, *nnode;
hasso6452df02004-08-15 05:52:07 +0000522 struct ospf6_area *oa;
523
paul1eb8ef22005-04-07 07:30:20 +0000524 for (ALL_LIST_ELEMENTS (process->area_list, node, nnode, oa))
hasso6452df02004-08-15 05:52:07 +0000525 {
hasso6452df02004-08-15 05:52:07 +0000526 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
527 oa != OSPF6_AREA (lsa->lsdb->data))
528 continue;
529 if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
530 oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
531 continue;
532
533 if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
534 IS_AREA_STUB (oa))
535 continue;
536
537 ospf6_flood_clear_area (lsa, oa);
538 }
539}
540
541void
542ospf6_flood_clear (struct ospf6_lsa *lsa)
543{
544 ospf6_flood_clear_process (lsa, ospf6);
545}
546
547
hasso48454372004-05-18 19:14:52 +0000548/* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
549static void
550ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
551 struct ospf6_neighbor *from)
552{
553 struct ospf6_interface *oi;
hasso1e058382004-09-01 21:36:14 +0000554 int is_debug = 0;
555
556 if (IS_OSPF6_DEBUG_FLOODING ||
557 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
558 is_debug++;
hasso48454372004-05-18 19:14:52 +0000559
560 assert (from && from->ospf6_if);
561 oi = from->ospf6_if;
562
563 /* LSA has been flood back out receiving interface.
564 No acknowledgement sent. */
565 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
566 {
hasso1e058382004-09-01 21:36:14 +0000567 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000568 zlog_debug ("No acknowledgement (BDR & FloodBack)");
hasso48454372004-05-18 19:14:52 +0000569 return;
570 }
571
572 /* LSA is more recent than database copy, but was not flooded
573 back out receiving interface. Delayed acknowledgement sent
574 if advertisement received from Designated Router,
575 otherwide do nothing. */
576 if (ismore_recent < 0)
577 {
hasso48454372004-05-18 19:14:52 +0000578 if (oi->drouter == from->router_id)
579 {
hasso1e058382004-09-01 21:36:14 +0000580 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000581 zlog_debug ("Delayed acknowledgement (BDR & MoreRecent & from DR)");
hasso48454372004-05-18 19:14:52 +0000582 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000583 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
584 if (oi->thread_send_lsack == NULL)
585 oi->thread_send_lsack =
586 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
587 }
588 else
589 {
hasso1e058382004-09-01 21:36:14 +0000590 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000591 zlog_debug ("No acknowledgement (BDR & MoreRecent & ! from DR)");
hasso48454372004-05-18 19:14:52 +0000592 }
593 return;
594 }
595
596 /* LSA is a duplicate, and was treated as an implied acknowledgement.
597 Delayed acknowledgement sent if advertisement received from
598 Designated Router, otherwise do nothing */
599 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
600 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
601 {
hasso48454372004-05-18 19:14:52 +0000602 if (oi->drouter == from->router_id)
603 {
hasso1e058382004-09-01 21:36:14 +0000604 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000605 zlog_debug ("Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
hasso48454372004-05-18 19:14:52 +0000606 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000607 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
608 if (oi->thread_send_lsack == NULL)
609 oi->thread_send_lsack =
610 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
611 }
612 else
613 {
hasso1e058382004-09-01 21:36:14 +0000614 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000615 zlog_debug ("No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
hasso48454372004-05-18 19:14:52 +0000616 }
617 return;
618 }
619
620 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
621 Direct acknowledgement sent */
622 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
623 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
624 {
hasso1e058382004-09-01 21:36:14 +0000625 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000626 zlog_debug ("Direct acknowledgement (BDR & Duplicate)");
hasso48454372004-05-18 19:14:52 +0000627 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
628 if (from->thread_send_lsack == NULL)
629 from->thread_send_lsack =
630 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
631 return;
632 }
633
634 /* LSA's LS age is equal to Maxage, and there is no current instance
635 of the LSA in the link state database, and none of router's
636 neighbors are in states Exchange or Loading */
637 /* Direct acknowledgement sent, but this case is handled in
638 early of ospf6_receive_lsa () */
639}
640
641static void
642ospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent,
643 struct ospf6_neighbor *from)
644{
645 struct ospf6_interface *oi;
hasso1e058382004-09-01 21:36:14 +0000646 int is_debug = 0;
647
648 if (IS_OSPF6_DEBUG_FLOODING ||
649 IS_OSPF6_DEBUG_FLOOD_TYPE (lsa->header->type))
650 is_debug++;
hasso48454372004-05-18 19:14:52 +0000651
652 assert (from && from->ospf6_if);
653 oi = from->ospf6_if;
654
655 /* LSA has been flood back out receiving interface.
656 No acknowledgement sent. */
657 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
658 {
hasso1e058382004-09-01 21:36:14 +0000659 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000660 zlog_debug ("No acknowledgement (AllOther & FloodBack)");
hasso48454372004-05-18 19:14:52 +0000661 return;
662 }
663
664 /* LSA is more recent than database copy, but was not flooded
665 back out receiving interface. Delayed acknowledgement sent. */
666 if (ismore_recent < 0)
667 {
hasso1e058382004-09-01 21:36:14 +0000668 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000669 zlog_debug ("Delayed acknowledgement (AllOther & MoreRecent)");
hasso48454372004-05-18 19:14:52 +0000670 /* Delayed acknowledgement */
hasso48454372004-05-18 19:14:52 +0000671 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
672 if (oi->thread_send_lsack == NULL)
673 oi->thread_send_lsack =
674 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
675 return;
676 }
677
678 /* LSA is a duplicate, and was treated as an implied acknowledgement.
679 No acknowledgement sent. */
680 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
681 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
682 {
hasso1e058382004-09-01 21:36:14 +0000683 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000684 zlog_debug ("No acknowledgement (AllOther & Duplicate & ImpliedAck)");
hasso48454372004-05-18 19:14:52 +0000685 return;
686 }
687
688 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
689 Direct acknowledgement sent */
690 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
691 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
692 {
hasso1e058382004-09-01 21:36:14 +0000693 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000694 zlog_debug ("Direct acknowledgement (AllOther & Duplicate)");
hasso48454372004-05-18 19:14:52 +0000695 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
696 if (from->thread_send_lsack == NULL)
697 from->thread_send_lsack =
698 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
699 return;
700 }
701
702 /* LSA's LS age is equal to Maxage, and there is no current instance
703 of the LSA in the link state database, and none of router's
704 neighbors are in states Exchange or Loading */
705 /* Direct acknowledgement sent, but this case is handled in
706 early of ospf6_receive_lsa () */
707}
708
Paul Jakma6ac29a52008-08-15 13:45:30 +0100709static void
hasso48454372004-05-18 19:14:52 +0000710ospf6_acknowledge_lsa (struct ospf6_lsa *lsa, int ismore_recent,
711 struct ospf6_neighbor *from)
712{
713 struct ospf6_interface *oi;
714
715 assert (from && from->ospf6_if);
716 oi = from->ospf6_if;
717
718 if (oi->state == OSPF6_INTERFACE_BDR)
719 ospf6_acknowledge_lsa_bdrouter (lsa, ismore_recent, from);
720 else
721 ospf6_acknowledge_lsa_allother (lsa, ismore_recent, from);
722}
723
724/* RFC2328 section 13 (4):
725 if MaxAge LSA and if we have no instance, and no neighbor
726 is in states Exchange or Loading
727 returns 1 if match this case, else returns 0 */
728static int
hasso6452df02004-08-15 05:52:07 +0000729ospf6_is_maxage_lsa_drop (struct ospf6_lsa *lsa, struct ospf6_neighbor *from)
hasso48454372004-05-18 19:14:52 +0000730{
hasso48454372004-05-18 19:14:52 +0000731 struct ospf6_neighbor *on;
hasso6452df02004-08-15 05:52:07 +0000732 struct ospf6_interface *oi;
733 struct ospf6_area *oa;
734 struct ospf6 *process = NULL;
hasso52dc7ee2004-09-23 19:18:23 +0000735 struct listnode *i, *j, *k;
hasso48454372004-05-18 19:14:52 +0000736 int count = 0;
737
738 if (! OSPF6_LSA_IS_MAXAGE (lsa))
739 return 0;
740
hasso48454372004-05-18 19:14:52 +0000741 if (ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
hasso6452df02004-08-15 05:52:07 +0000742 lsa->header->adv_router, lsa->lsdb))
hasso48454372004-05-18 19:14:52 +0000743 return 0;
744
hasso6452df02004-08-15 05:52:07 +0000745 process = from->ospf6_if->area->ospf6;
paul1eb8ef22005-04-07 07:30:20 +0000746
747 for (ALL_LIST_ELEMENTS_RO (process->area_list, i, oa))
748 for (ALL_LIST_ELEMENTS_RO (oa->if_list, j, oi))
749 for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, k, on))
750 if (on->state == OSPF6_NEIGHBOR_EXCHANGE ||
751 on->state == OSPF6_NEIGHBOR_LOADING)
752 count++;
hasso48454372004-05-18 19:14:52 +0000753
hasso48454372004-05-18 19:14:52 +0000754 if (count == 0)
755 return 1;
hasso48454372004-05-18 19:14:52 +0000756 return 0;
757}
758
759/* RFC2328 section 13 The Flooding Procedure */
760void
hasso6452df02004-08-15 05:52:07 +0000761ospf6_receive_lsa (struct ospf6_neighbor *from,
762 struct ospf6_lsa_header *lsa_header)
hasso48454372004-05-18 19:14:52 +0000763{
764 struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
765 int ismore_recent;
hasso1e058382004-09-01 21:36:14 +0000766 int is_debug = 0;
hasso48454372004-05-18 19:14:52 +0000767
768 ismore_recent = 1;
hasso6452df02004-08-15 05:52:07 +0000769 assert (from);
hasso48454372004-05-18 19:14:52 +0000770
771 /* make lsa structure for received lsa */
772 new = ospf6_lsa_create (lsa_header);
773
hasso1e058382004-09-01 21:36:14 +0000774 if (IS_OSPF6_DEBUG_FLOODING ||
775 IS_OSPF6_DEBUG_FLOOD_TYPE (new->header->type))
hasso48454372004-05-18 19:14:52 +0000776 {
hasso1e058382004-09-01 21:36:14 +0000777 is_debug++;
hassoc6487d62004-12-24 06:00:11 +0000778 zlog_debug ("LSA Receive from %s", from->name);
hasso48454372004-05-18 19:14:52 +0000779 ospf6_lsa_header_print (new);
780 }
781
hasso48454372004-05-18 19:14:52 +0000782 /* (1) LSA Checksum */
JR Riversd8a4e422012-09-13 17:17:36 +0000783 if (! ospf6_lsa_checksum_valid (new->header))
hasso48454372004-05-18 19:14:52 +0000784 {
hasso1e058382004-09-01 21:36:14 +0000785 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000786 zlog_debug ("Wrong LSA Checksum, discard");
hasso48454372004-05-18 19:14:52 +0000787 ospf6_lsa_delete (new);
788 return;
789 }
790
hasso6452df02004-08-15 05:52:07 +0000791 /* (2) Examine the LSA's LS type.
792 RFC2470 3.5.1. Receiving Link State Update packets */
793 if (IS_AREA_STUB (from->ospf6_if->area) &&
794 OSPF6_LSA_SCOPE (new->header->type) == OSPF6_SCOPE_AS)
hasso48454372004-05-18 19:14:52 +0000795 {
hasso1e058382004-09-01 21:36:14 +0000796 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000797 zlog_debug ("AS-External-LSA (or AS-scope LSA) in stub area, discard");
hasso6452df02004-08-15 05:52:07 +0000798 ospf6_lsa_delete (new);
799 return;
800 }
801
802 /* (3) LSA which have reserved scope is discarded
803 RFC2470 3.5.1. Receiving Link State Update packets */
804 /* Flooding scope check. LSAs with unknown scope are discarded here.
805 Set appropriate LSDB for the LSA */
806 switch (OSPF6_LSA_SCOPE (new->header->type))
807 {
808 case OSPF6_SCOPE_LINKLOCAL:
809 new->lsdb = from->ospf6_if->lsdb;
810 break;
811 case OSPF6_SCOPE_AREA:
812 new->lsdb = from->ospf6_if->area->lsdb;
813 break;
814 case OSPF6_SCOPE_AS:
815 new->lsdb = from->ospf6_if->area->ospf6->lsdb;
816 break;
817 default:
hasso1e058382004-09-01 21:36:14 +0000818 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000819 zlog_debug ("LSA has reserved scope, discard");
hasso48454372004-05-18 19:14:52 +0000820 ospf6_lsa_delete (new);
821 return;
822 }
823
824 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
825 is in states Exchange or Loading */
826 if (ospf6_is_maxage_lsa_drop (new, from))
827 {
828 /* log */
hasso1e058382004-09-01 21:36:14 +0000829 if (is_debug)
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000830 zlog_debug ("Drop MaxAge LSA with direct acknowledgement.");
hasso48454372004-05-18 19:14:52 +0000831
832 /* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */
hasso6452df02004-08-15 05:52:07 +0000833 ospf6_lsdb_add (ospf6_lsa_copy (new), from->lsack_list);
hasso48454372004-05-18 19:14:52 +0000834 if (from->thread_send_lsack == NULL)
835 from->thread_send_lsack =
836 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
837
838 /* b) Discard */
hasso6452df02004-08-15 05:52:07 +0000839 ospf6_lsa_delete (new);
hasso48454372004-05-18 19:14:52 +0000840 return;
841 }
842
843 /* (5) */
844 /* lookup the same database copy in lsdb */
hasso48454372004-05-18 19:14:52 +0000845 old = ospf6_lsdb_lookup (new->header->type, new->header->id,
hasso6452df02004-08-15 05:52:07 +0000846 new->header->adv_router, new->lsdb);
hasso48454372004-05-18 19:14:52 +0000847 if (old)
848 {
849 ismore_recent = ospf6_lsa_compare (new, old);
850 if (ntohl (new->header->seqnum) == ntohl (old->header->seqnum))
851 {
hasso1e058382004-09-01 21:36:14 +0000852 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000853 zlog_debug ("Received is duplicated LSA");
hasso48454372004-05-18 19:14:52 +0000854 SET_FLAG (new->flag, OSPF6_LSA_DUPLICATE);
855 }
856 }
857
858 /* if no database copy or received is more recent */
859 if (old == NULL || ismore_recent < 0)
860 {
861 /* in case we have no database copy */
862 ismore_recent = -1;
863
864 /* (a) MinLSArrival check */
865 if (old)
866 {
867 struct timeval now, res;
Takashi Sogabe86f72dc2009-06-22 13:07:02 +0900868 quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
hasso48454372004-05-18 19:14:52 +0000869 timersub (&now, &old->installed, &res);
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700870 if (res.tv_sec < OSPF_MIN_LS_ARRIVAL)
hasso48454372004-05-18 19:14:52 +0000871 {
hasso1e058382004-09-01 21:36:14 +0000872 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000873 zlog_debug ("LSA can't be updated within MinLSArrival, discard");
hasso48454372004-05-18 19:14:52 +0000874 ospf6_lsa_delete (new);
875 return; /* examin next lsa */
876 }
877 }
878
Takashi Sogabe86f72dc2009-06-22 13:07:02 +0900879 quagga_gettime (QUAGGA_CLK_MONOTONIC, &new->received);
hassoccb59b12004-08-25 09:10:37 +0000880
hasso1e058382004-09-01 21:36:14 +0000881 if (is_debug)
Dinesh Duttbf986da2013-08-24 07:54:50 +0000882 zlog_debug ("Install, Flood, Possibly acknowledge the received LSA");
883
884 /* Remove older copies of this LSA from retx lists */
885 if (old)
886 ospf6_flood_clear (old);
hasso6452df02004-08-15 05:52:07 +0000887
hasso48454372004-05-18 19:14:52 +0000888 /* (b) immediately flood and (c) remove from all retrans-list */
hassoccb59b12004-08-25 09:10:37 +0000889 /* Prevent self-originated LSA to be flooded. this is to make
890 reoriginated instance of the LSA not to be rejected by other routers
891 due to MinLSArrival. */
892 if (new->header->adv_router != from->ospf6_if->area->ospf6->router_id)
893 ospf6_flood (from, new);
hasso6452df02004-08-15 05:52:07 +0000894
hasso48454372004-05-18 19:14:52 +0000895 /* (d), installing lsdb, which may cause routing
896 table calculation (replacing database copy) */
hasso6452df02004-08-15 05:52:07 +0000897 ospf6_install_lsa (new);
hasso48454372004-05-18 19:14:52 +0000898
899 /* (e) possibly acknowledge */
900 ospf6_acknowledge_lsa (new, ismore_recent, from);
901
hasso6452df02004-08-15 05:52:07 +0000902 /* (f) Self Originated LSA, section 13.4 */
903 if (new->header->adv_router == from->ospf6_if->area->ospf6->router_id)
hasso48454372004-05-18 19:14:52 +0000904 {
hasso6452df02004-08-15 05:52:07 +0000905 /* Self-originated LSA (newer than ours) is received from
906 another router. We have to make a new instance of the LSA
hasso48454372004-05-18 19:14:52 +0000907 or have to flush this LSA. */
hasso1e058382004-09-01 21:36:14 +0000908 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000909 {
hassoc6487d62004-12-24 06:00:11 +0000910 zlog_debug ("Newer instance of the self-originated LSA");
911 zlog_debug ("Schedule reorigination");
hasso6452df02004-08-15 05:52:07 +0000912 }
913 new->refresh = thread_add_event (master, ospf6_lsa_refresh, new, 0);
hasso48454372004-05-18 19:14:52 +0000914 }
hasso6452df02004-08-15 05:52:07 +0000915
hasso48454372004-05-18 19:14:52 +0000916 return;
917 }
918
919 /* (6) if there is instance on sending neighbor's request list */
920 if (ospf6_lsdb_lookup (new->header->type, new->header->id,
921 new->header->adv_router, from->request_list))
922 {
923 /* if no database copy, should go above state (5) */
924 assert (old);
925
hasso1e058382004-09-01 21:36:14 +0000926 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000927 {
hassoc6487d62004-12-24 06:00:11 +0000928 zlog_debug ("Received is not newer, on the neighbor's request-list");
929 zlog_debug ("BadLSReq, discard the received LSA");
hasso6452df02004-08-15 05:52:07 +0000930 }
hasso48454372004-05-18 19:14:52 +0000931
932 /* BadLSReq */
933 thread_add_event (master, bad_lsreq, from, 0);
934
935 ospf6_lsa_delete (new);
936 return;
937 }
938
939 /* (7) if neither one is more recent */
940 if (ismore_recent == 0)
941 {
hasso1e058382004-09-01 21:36:14 +0000942 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000943 zlog_debug ("The same instance as database copy (neither recent)");
hasso48454372004-05-18 19:14:52 +0000944
945 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack */
946 rem = ospf6_lsdb_lookup (new->header->type, new->header->id,
947 new->header->adv_router, from->retrans_list);
948 if (rem)
949 {
hasso1e058382004-09-01 21:36:14 +0000950 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000951 {
hassoc6487d62004-12-24 06:00:11 +0000952 zlog_debug ("It is on the neighbor's retrans-list.");
953 zlog_debug ("Treat as an Implied acknowledgement");
hasso6452df02004-08-15 05:52:07 +0000954 }
hasso48454372004-05-18 19:14:52 +0000955 SET_FLAG (new->flag, OSPF6_LSA_IMPLIEDACK);
hasso6452df02004-08-15 05:52:07 +0000956 ospf6_decrement_retrans_count (rem);
hasso48454372004-05-18 19:14:52 +0000957 ospf6_lsdb_remove (rem, from->retrans_list);
958 }
959
hasso1e058382004-09-01 21:36:14 +0000960 if (is_debug)
hassoc6487d62004-12-24 06:00:11 +0000961 zlog_debug ("Possibly acknowledge and then discard");
hasso6452df02004-08-15 05:52:07 +0000962
hasso48454372004-05-18 19:14:52 +0000963 /* (b) possibly acknowledge */
964 ospf6_acknowledge_lsa (new, ismore_recent, from);
965
966 ospf6_lsa_delete (new);
967 return;
968 }
969
970 /* (8) previous database copy is more recent */
971 {
972 assert (old);
973
974 /* If database copy is in 'Seqnumber Wrapping',
975 simply discard the received LSA */
976 if (OSPF6_LSA_IS_MAXAGE (old) &&
Dinesh Dutt8551e6d2013-10-22 17:42:18 -0700977 old->header->seqnum == htonl (OSPF_MAX_SEQUENCE_NUMBER))
hasso48454372004-05-18 19:14:52 +0000978 {
hasso1e058382004-09-01 21:36:14 +0000979 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000980 {
hassoc6487d62004-12-24 06:00:11 +0000981 zlog_debug ("The LSA is in Seqnumber Wrapping");
982 zlog_debug ("MaxAge & MaxSeqNum, discard");
hasso6452df02004-08-15 05:52:07 +0000983 }
Dinesh Dutteb82e9e2013-08-24 07:55:07 +0000984 ospf6_lsa_delete (new);
985 return;
hasso48454372004-05-18 19:14:52 +0000986 }
987
988 /* Otherwise, Send database copy of this LSA to this neighbor */
989 {
hasso1e058382004-09-01 21:36:14 +0000990 if (is_debug)
hasso6452df02004-08-15 05:52:07 +0000991 {
hassoc6487d62004-12-24 06:00:11 +0000992 zlog_debug ("Database copy is more recent.");
993 zlog_debug ("Send back directly and then discard");
hasso6452df02004-08-15 05:52:07 +0000994 }
hasso48454372004-05-18 19:14:52 +0000995
996 /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
997
hasso48454372004-05-18 19:14:52 +0000998 ospf6_lsdb_add (ospf6_lsa_copy (old), from->lsupdate_list);
999 if (from->thread_send_lsupdate == NULL)
1000 from->thread_send_lsupdate =
1001 thread_add_event (master, ospf6_lsupdate_send_neighbor, from, 0);
Dinesh Dutteb82e9e2013-08-24 07:55:07 +00001002 ospf6_lsa_delete (new);
1003 return;
hasso48454372004-05-18 19:14:52 +00001004 }
1005 return;
1006 }
1007}
1008
1009
hasso1e058382004-09-01 21:36:14 +00001010DEFUN (debug_ospf6_flooding,
1011 debug_ospf6_flooding_cmd,
1012 "debug ospf6 flooding",
1013 DEBUG_STR
1014 OSPF6_STR
1015 "Debug OSPFv3 flooding function\n"
1016 )
1017{
1018 OSPF6_DEBUG_FLOODING_ON ();
1019 return CMD_SUCCESS;
1020}
1021
1022DEFUN (no_debug_ospf6_flooding,
1023 no_debug_ospf6_flooding_cmd,
1024 "no debug ospf6 flooding",
1025 NO_STR
1026 DEBUG_STR
1027 OSPF6_STR
1028 "Debug OSPFv3 flooding function\n"
1029 )
1030{
1031 OSPF6_DEBUG_FLOODING_OFF ();
1032 return CMD_SUCCESS;
1033}
1034
1035int
1036config_write_ospf6_debug_flood (struct vty *vty)
1037{
1038 if (IS_OSPF6_DEBUG_FLOODING)
1039 vty_out (vty, "debug ospf6 flooding%s", VNL);
1040 return 0;
1041}
1042
1043void
Paul Jakma6ac29a52008-08-15 13:45:30 +01001044install_element_ospf6_debug_flood (void)
hasso1e058382004-09-01 21:36:14 +00001045{
1046 install_element (ENABLE_NODE, &debug_ospf6_flooding_cmd);
1047 install_element (ENABLE_NODE, &no_debug_ospf6_flooding_cmd);
1048 install_element (CONFIG_NODE, &debug_ospf6_flooding_cmd);
1049 install_element (CONFIG_NODE, &no_debug_ospf6_flooding_cmd);
1050}
1051
1052
1053
1054
hasso48454372004-05-18 19:14:52 +00001055