blob: e0494552e39d1320979f9ccbdf3ac2158444d006 [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"
28
29#include "ospf6d.h"
30#include "ospf6_proto.h"
31#include "ospf6_lsa.h"
32#include "ospf6_lsdb.h"
33#include "ospf6_message.h"
34#include "ospf6_route.h"
35#include "ospf6_spf.h"
36
37#include "ospf6_top.h"
38#include "ospf6_area.h"
39#include "ospf6_interface.h"
40#include "ospf6_neighbor.h"
41
42
43void *
44ospf6_get_lsa_scope (u_int16_t type, struct ospf6_neighbor *from)
45{
46 void *scope = NULL;
47
48 if (from == NULL)
49 return NULL;
50
51 switch (OSPF6_LSA_SCOPE (type))
52 {
53 case OSPF6_LSA_SCOPE_AS:
54 scope = (from)->ospf6_if->area->ospf6;
55 break;
56 case OSPF6_LSA_SCOPE_AREA:
57 scope = (from)->ospf6_if->area;
58 break;
59 case OSPF6_LSA_SCOPE_LINKLOCAL:
60 scope = (from)->ospf6_if;
61 break;
62 default:
63 break;
64 }
65
66 return scope;
67}
68
69struct ospf6_lsdb *
70ospf6_get_scoped_lsdb (u_int16_t type, void *scope)
71{
72 struct ospf6_lsdb *lsdb = NULL;
73
74 if (scope == NULL)
75 return NULL;
76
77 switch (OSPF6_LSA_SCOPE (type))
78 {
79 case OSPF6_LSA_SCOPE_AS:
80 lsdb = ((struct ospf6 *)(scope))->lsdb;
81 break;
82 case OSPF6_LSA_SCOPE_AREA:
83 lsdb = ((struct ospf6_area *)(scope))->lsdb;
84 break;
85 case OSPF6_LSA_SCOPE_LINKLOCAL:
86 lsdb = ((struct ospf6_interface *)(scope))->lsdb;
87 break;
88 default:
89 break;
90 }
91
92 return lsdb;
93}
94
95void
96ospf6_flood_clear (struct ospf6_lsa *lsa)
97{
98 struct ospf6_neighbor *on;
99 struct ospf6_interface *oi, *ospf6_if = NULL;
100 struct ospf6_area *oa, *area = NULL;
101 struct ospf6 *ospf6 = NULL;
102 u_int16_t scope_type;
103 list scoped_interfaces;
104 struct ospf6_lsa *rxmt;
105 listnode i, j;
106
107 scoped_interfaces = list_new ();
108 scope_type = OSPF6_LSA_SCOPE (lsa->header->type);
109
110 if (scope_type == OSPF6_LSA_SCOPE_LINKLOCAL)
111 {
112 ospf6_if = (struct ospf6_interface *) lsa->scope;
113 area = ospf6_if->area;
114 ospf6 = area->ospf6;
115 }
116 else if (scope_type == OSPF6_LSA_SCOPE_AREA)
117 {
118 area = (struct ospf6_area *) lsa->scope;
119 ospf6 = area->ospf6;
120 }
121 else if (scope_type == OSPF6_LSA_SCOPE_AS)
122 {
123 ospf6 = (struct ospf6 *) lsa->scope;
124 }
125 else
126 {
127 zlog_warn ("Can't decide LSA scope, quit ospf6_flood_clear ()");
128 return;
129 }
130
131 /* Collect eligible interfaces */
132 for (i = listhead (ospf6->area_list); i; nextnode (i))
133 {
134 oa = (struct ospf6_area *) getdata (i);
135 if (scope_type != OSPF6_LSA_SCOPE_AS && oa != area)
136 continue;
137
138 for (j = listhead (oa->if_list); j; nextnode (j))
139 {
140 oi = (struct ospf6_interface *) getdata (j);
141 if (scope_type != OSPF6_LSA_SCOPE_AS &&
142 scope_type != OSPF6_LSA_SCOPE_AREA && oi != ospf6_if)
143 continue;
144
145 listnode_add (scoped_interfaces, oi);
146 }
147 }
148
149 for (i = listhead (scoped_interfaces); i; nextnode (i))
150 {
151 oi = (struct ospf6_interface *) getdata (i);
152 for (j = listhead (oi->neighbor_list); j; nextnode (j))
153 {
154 on = (struct ospf6_neighbor *) getdata (j);
155 rxmt = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
156 lsa->header->adv_router, on->retrans_list);
157 if (rxmt && ! ospf6_lsa_compare (rxmt, lsa))
158 {
159 if (IS_OSPF6_DEBUG_LSA (DATABASE))
160 zlog_info ("Remove %s from retrans_list of %s",
161 rxmt->name, on->name);
162 ospf6_lsdb_remove (rxmt, on->retrans_list);
163 }
164 }
165 }
166
167 list_delete (scoped_interfaces);
168}
169
170/* RFC2328 section 13.2 Installing LSAs in the database */
171void
172ospf6_install_lsa (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
173{
174 struct ospf6_lsa *old;
175
176 if (IS_OSPF6_DEBUG_LSA (RECV) || IS_OSPF6_DEBUG_LSA (DATABASE))
177 zlog_info ("Install LSA: %s", lsa->name);
178
179 /* Remove the old instance from all neighbors' Link state
180 retransmission list (RFC2328 13.2 last paragraph) */
181 old = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
182 lsa->header->adv_router, lsdb);
183 if (old)
184 ospf6_flood_clear (old);
185
186 /* actually install */
187 gettimeofday (&lsa->installed, (struct timezone *) NULL);
188 ospf6_lsdb_add (lsa, lsdb);
189
190 return;
191}
192
193/* RFC2328 section 13.3 Next step in the flooding procedure */
194void
195ospf6_flood_lsa (struct ospf6_lsa *lsa, struct ospf6_neighbor *from)
196{
197 struct ospf6 *scope_as = NULL;
198 struct ospf6_area *oa, *scope_area = NULL;
199 struct ospf6_interface *oi, *scope_linklocal = NULL;
200 struct ospf6_neighbor *on;
201 list eligible_interfaces;
202 listnode i, j;
203 u_int16_t scope_type;
204 struct ospf6_lsa *req;
205 int retrans_added = 0;
206
207 scope_type = OSPF6_LSA_SCOPE (lsa->header->type);
208 switch (scope_type)
209 {
210 case OSPF6_LSA_SCOPE_AS:
211 scope_as = (struct ospf6 *) lsa->scope;
212 break;
213 case OSPF6_LSA_SCOPE_AREA:
214 scope_as = ((struct ospf6_area *) lsa->scope)->ospf6;
215 scope_area = (struct ospf6_area *) lsa->scope;
216 break;
217 case OSPF6_LSA_SCOPE_LINKLOCAL:
218 scope_as = ((struct ospf6_interface *) lsa->scope)->area->ospf6;
219 scope_area = ((struct ospf6_interface *) lsa->scope)->area;
220 scope_linklocal = (struct ospf6_interface *) lsa->scope;
221 break;
222 default:
223 if (IS_OSPF6_DEBUG_LSA (SEND))
224 zlog_info ("Can't decide LSA scope");
225 return;
226 }
227
228 if (IS_OSPF6_DEBUG_LSA (SEND))
229 zlog_info ("Flood %s", lsa->name);
230
231 /* Collect eligible interfaces */
232 eligible_interfaces = list_new ();
233 for (i = listhead (scope_as->area_list); i; nextnode (i))
234 {
235 oa = (struct ospf6_area *) getdata (i);
236 if (scope_type != OSPF6_LSA_SCOPE_AS &&
237 oa != scope_area)
238 continue;
239
240 for (j = listhead (oa->if_list); j; nextnode (j))
241 {
242 oi = (struct ospf6_interface *) getdata (j);
243 if (scope_type != OSPF6_LSA_SCOPE_AS &&
244 scope_type != OSPF6_LSA_SCOPE_AREA &&
245 oi != scope_linklocal)
246 continue;
247
248 listnode_add (eligible_interfaces, oi);
249 }
250 }
251
252 /* For each eligible interface: */
253 for (i = listhead (eligible_interfaces); i; nextnode (i))
254 {
255 oi = (struct ospf6_interface *) getdata (i);
256
257 /* (1) For each neighbor */
258 for (j = listhead (oi->neighbor_list); j; nextnode (j))
259 {
260 on = (struct ospf6_neighbor *) getdata (j);
261
262 /* (a) if neighbor state < Exchange, examin next */
263 if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
264 continue;
265
266 /* (b) if neighbor not yet Full, check request-list */
267 if (on->state != OSPF6_NEIGHBOR_FULL)
268 {
269 req = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
270 lsa->header->adv_router,
271 on->request_list);
272 if (req)
273 {
274 /* If new LSA less recent, examin next neighbor */
275 if (ospf6_lsa_compare (lsa, req) > 0)
276 continue;
277
278 /* If the same instance, delete from request-list and
279 examin next neighbor */
280 if (ospf6_lsa_compare (lsa, req) == 0)
281 {
282 if (IS_OSPF6_DEBUG_LSA (SEND) || IS_OSPF6_DEBUG_LSA (DATABASE))
283 zlog_info ("Remove %s from request-list of %s: "
284 "the same instance", req->name, on->name);
285 ospf6_lsdb_remove (req, on->request_list);
286 continue;
287 }
288
289 /* If the new LSA is more recent, delete from
290 request-list */
291 if (ospf6_lsa_compare (lsa, req) < 0)
292 {
293 if (IS_OSPF6_DEBUG_LSA (SEND) || IS_OSPF6_DEBUG_LSA (DATABASE))
294 zlog_info ("Remove %s from request-list of %s: "
295 "newer instance", req->name, on->name);
296 ospf6_lsdb_remove (req, on->request_list);
297 /* fall through */
298 }
299 }
300 }
301
302 /* (c) If the new LSA was received from this neighbor,
303 examin next neighbor */
304 if (from == on)
305 continue;
306
307 /* (d) add retrans-list, schedule retransmission */
308 if (IS_OSPF6_DEBUG_LSA (SEND) || IS_OSPF6_DEBUG_LSA (DATABASE))
309 zlog_info (" Add copy of %s to retrans-list of %s",
310 lsa->name, on->name);
311 ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
312 if (on->thread_send_lsupdate == NULL)
313 on->thread_send_lsupdate =
314 thread_add_event (master, ospf6_lsupdate_send_neighbor,
315 on, on->ospf6_if->rxmt_interval);
316 retrans_added++;
317 }
318
319 /* (2) examin next interface if not added to retrans-list */
320 if (retrans_added == 0)
321 continue;
322
323 /* (3) If the new LSA was received on this interface,
324 and it was from DR or BDR, examin next interface */
325 if (from && from->ospf6_if == oi &&
326 (from->router_id == oi->drouter || from->router_id == oi->bdrouter))
327 continue;
328
329 /* (4) If the new LSA was received on this interface,
330 and the interface state is BDR, examin next interface */
331 if (from && from->ospf6_if == oi && oi->state == OSPF6_INTERFACE_BDR)
332 continue;
333
334 /* (5) flood the LSA out the interface. */
335 if (if_is_broadcast (oi->interface))
336 {
337 if (IS_OSPF6_DEBUG_LSA (SEND) || IS_OSPF6_DEBUG_LSA (DATABASE))
338 zlog_info (" Add copy of %s to lsupdate_list of %s",
339 lsa->name, oi->interface->name);
340 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list);
341 if (oi->thread_send_lsupdate == NULL)
342 oi->thread_send_lsupdate =
343 thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
344 }
345 else
346 {
347 for (j = listhead (oi->neighbor_list); j; nextnode (j))
348 {
349 on = (struct ospf6_neighbor *) getdata (j);
350 THREAD_OFF (on->thread_send_lsupdate);
351 on->thread_send_lsupdate =
352 thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
353 }
354 }
355 }
356
357 list_delete (eligible_interfaces);
358}
359
360/* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
361static void
362ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
363 struct ospf6_neighbor *from)
364{
365 struct ospf6_interface *oi;
366
367 assert (from && from->ospf6_if);
368 oi = from->ospf6_if;
369
370 /* LSA has been flood back out receiving interface.
371 No acknowledgement sent. */
372 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
373 {
374 if (IS_OSPF6_DEBUG_LSA (RECV))
375 zlog_info (" BDR, FloodBack, No acknowledgement.");
376 return;
377 }
378
379 /* LSA is more recent than database copy, but was not flooded
380 back out receiving interface. Delayed acknowledgement sent
381 if advertisement received from Designated Router,
382 otherwide do nothing. */
383 if (ismore_recent < 0)
384 {
385 if (IS_OSPF6_DEBUG_LSA (RECV))
386 zlog_info (" BDR, Not FloodBack, MoreRecent, ");
387 if (oi->drouter == from->router_id)
388 {
389 if (IS_OSPF6_DEBUG_LSA (RECV))
390 zlog_info (" From DR, Delayed acknowledgement.");
391 /* Delayed acknowledgement */
392 if (IS_OSPF6_DEBUG_LSA (DATABASE))
393 zlog_info (" Add copy of %s to lsack_list of %s",
394 lsa->name, oi->interface->name);
395 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
396 if (oi->thread_send_lsack == NULL)
397 oi->thread_send_lsack =
398 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
399 }
400 else
401 {
402 if (IS_OSPF6_DEBUG_LSA (RECV))
403 zlog_info (" Not From DR, No acknowledgement.");
404 }
405 return;
406 }
407
408 /* LSA is a duplicate, and was treated as an implied acknowledgement.
409 Delayed acknowledgement sent if advertisement received from
410 Designated Router, otherwise do nothing */
411 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
412 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
413 {
414 if (IS_OSPF6_DEBUG_LSA (RECV))
415 zlog_info (" BDR, Duplicate, ImpliedAck, ");
416 if (oi->drouter == from->router_id)
417 {
418 if (IS_OSPF6_DEBUG_LSA (RECV))
419 zlog_info (" From DR, Delayed acknowledgement.");
420 /* Delayed acknowledgement */
421 if (IS_OSPF6_DEBUG_LSA (DATABASE))
422 zlog_info (" Add copy of %s to lsack_list of %s",
423 lsa->name, oi->interface->name);
424 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
425 if (oi->thread_send_lsack == NULL)
426 oi->thread_send_lsack =
427 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
428 }
429 else
430 {
431 if (IS_OSPF6_DEBUG_LSA (RECV))
432 zlog_info (" Not From DR, No acknowledgement.");
433 }
434 return;
435 }
436
437 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
438 Direct acknowledgement sent */
439 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
440 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
441 {
442 if (IS_OSPF6_DEBUG_LSA (RECV))
443 zlog_info (" BDR, Duplicate, Not ImpliedAck, Direct acknowledgement.");
444 if (IS_OSPF6_DEBUG_LSA (DATABASE))
445 zlog_info (" Add copy of %s to lsack_list of %s",
446 lsa->name, from->name);
447 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
448 if (from->thread_send_lsack == NULL)
449 from->thread_send_lsack =
450 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
451 return;
452 }
453
454 /* LSA's LS age is equal to Maxage, and there is no current instance
455 of the LSA in the link state database, and none of router's
456 neighbors are in states Exchange or Loading */
457 /* Direct acknowledgement sent, but this case is handled in
458 early of ospf6_receive_lsa () */
459}
460
461static void
462ospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent,
463 struct ospf6_neighbor *from)
464{
465 struct ospf6_interface *oi;
466
467 assert (from && from->ospf6_if);
468 oi = from->ospf6_if;
469
470 /* LSA has been flood back out receiving interface.
471 No acknowledgement sent. */
472 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
473 {
474 if (IS_OSPF6_DEBUG_LSA (RECV))
475 zlog_info (" AllOther, FloodBack, No acknowledgement.");
476 return;
477 }
478
479 /* LSA is more recent than database copy, but was not flooded
480 back out receiving interface. Delayed acknowledgement sent. */
481 if (ismore_recent < 0)
482 {
483 if (IS_OSPF6_DEBUG_LSA (RECV))
484 zlog_info (" AllOther, Not FloodBack, Delayed acknowledgement.");
485 /* Delayed acknowledgement */
486 if (IS_OSPF6_DEBUG_LSA (DATABASE))
487 zlog_info (" Add copy of %s to lsack_list of %s",
488 lsa->name, oi->interface->name);
489 ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
490 if (oi->thread_send_lsack == NULL)
491 oi->thread_send_lsack =
492 thread_add_timer (master, ospf6_lsack_send_interface, oi, 3);
493 return;
494 }
495
496 /* LSA is a duplicate, and was treated as an implied acknowledgement.
497 No acknowledgement sent. */
498 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
499 CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
500 {
501 if (IS_OSPF6_DEBUG_LSA (RECV))
502 zlog_info (" AllOther, Duplicate, ImpliedAck, No acknowledgement.");
503 return;
504 }
505
506 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
507 Direct acknowledgement sent */
508 if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
509 ! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
510 {
511 if (IS_OSPF6_DEBUG_LSA (RECV))
512 zlog_info (" AllOther, Duplicate, Not ImpliedAck, Direct acknowledgement.");
513 if (IS_OSPF6_DEBUG_LSA (DATABASE))
514 zlog_info (" Add copy of %s to lsack_list of %s",
515 lsa->name, from->name);
516 ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
517 if (from->thread_send_lsack == NULL)
518 from->thread_send_lsack =
519 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
520 return;
521 }
522
523 /* LSA's LS age is equal to Maxage, and there is no current instance
524 of the LSA in the link state database, and none of router's
525 neighbors are in states Exchange or Loading */
526 /* Direct acknowledgement sent, but this case is handled in
527 early of ospf6_receive_lsa () */
528}
529
530void
531ospf6_acknowledge_lsa (struct ospf6_lsa *lsa, int ismore_recent,
532 struct ospf6_neighbor *from)
533{
534 struct ospf6_interface *oi;
535
536 assert (from && from->ospf6_if);
537 oi = from->ospf6_if;
538
539 if (oi->state == OSPF6_INTERFACE_BDR)
540 ospf6_acknowledge_lsa_bdrouter (lsa, ismore_recent, from);
541 else
542 ospf6_acknowledge_lsa_allother (lsa, ismore_recent, from);
543}
544
545/* RFC2328 section 13 (4):
546 if MaxAge LSA and if we have no instance, and no neighbor
547 is in states Exchange or Loading
548 returns 1 if match this case, else returns 0 */
549static int
550ospf6_is_maxage_lsa_drop (struct ospf6_lsa *lsa,
551 struct ospf6_neighbor *from)
552{
553 struct ospf6_lsdb *lsdb = NULL;
554 struct ospf6_neighbor *on;
555 struct ospf6_interface *oi, *ospf6_if = NULL;
556 struct ospf6_area *oa, *area = NULL;
557 struct ospf6 *ospf6 = NULL;
558 u_int16_t scope_type;
559 list scoped_interfaces;
560 listnode i, j;
561 int count = 0;
562
563 if (! OSPF6_LSA_IS_MAXAGE (lsa))
564 return 0;
565
566 lsdb = ospf6_get_scoped_lsdb (lsa->header->type, lsa->scope);
567 if (lsdb == NULL)
568 {
569 zlog_info ("Can't decide scoped LSDB");
570 return 0;
571 }
572
573 if (ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
574 lsa->header->adv_router, lsdb))
575 return 0;
576
577 scoped_interfaces = list_new ();
578 scope_type = OSPF6_LSA_SCOPE (lsa->header->type);
579
580 if (scope_type == OSPF6_LSA_SCOPE_LINKLOCAL)
581 {
582 ospf6_if = (struct ospf6_interface *) lsa->scope;
583 area = ospf6_if->area;
584 ospf6 = area->ospf6;
585 }
586 else if (scope_type == OSPF6_LSA_SCOPE_AREA)
587 {
588 area = (struct ospf6_area *) lsa->scope;
589 ospf6 = area->ospf6;
590 }
591 else if (scope_type == OSPF6_LSA_SCOPE_AS)
592 {
593 ospf6 = (struct ospf6 *) lsa->scope;
594 }
595 else
596 {
597 zlog_info ("Can't decide LSA scope");
598 return 0;
599 }
600
601 /* Collect eligible interfaces */
602 for (i = listhead (ospf6->area_list); i; nextnode (i))
603 {
604 oa = (struct ospf6_area *) getdata (i);
605 if (scope_type != OSPF6_LSA_SCOPE_AS && oa != area)
606 continue;
607
608 for (j = listhead (oa->if_list); j; nextnode (j))
609 {
610 oi = (struct ospf6_interface *) getdata (j);
611 if (scope_type != OSPF6_LSA_SCOPE_AS &&
612 scope_type != OSPF6_LSA_SCOPE_AREA && oi != ospf6_if)
613 continue;
614
615 listnode_add (scoped_interfaces, oi);
616 }
617 }
618
619 for (i = listhead (scoped_interfaces); i; nextnode (i))
620 {
621 oi = (struct ospf6_interface *) getdata (i);
622 for (j = listhead (oi->neighbor_list); j; nextnode (j))
623 {
624 on = (struct ospf6_neighbor *) getdata (j);
625 if (on->state == OSPF6_NEIGHBOR_EXCHANGE ||
626 on->state == OSPF6_NEIGHBOR_LOADING)
627 count ++;
628 }
629 }
630
631 list_delete (scoped_interfaces);
632
633 if (count == 0)
634 return 1;
635
636 return 0;
637}
638
639/* RFC2328 section 13 The Flooding Procedure */
640void
641ospf6_receive_lsa (struct ospf6_lsa_header *lsa_header,
642 struct ospf6_neighbor *from)
643{
644 struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
645 int ismore_recent;
646 unsigned short cksum;
647 struct ospf6_lsdb *lsdb = NULL;
648
649 ismore_recent = 1;
650
651 /* make lsa structure for received lsa */
652 new = ospf6_lsa_create (lsa_header);
653
654 if (IS_OSPF6_DEBUG_LSA (RECV))
655 {
656 zlog_info ("LSA Receive from %s", from->name);
657 ospf6_lsa_header_print (new);
658 }
659
660 new->scope = ospf6_get_lsa_scope (new->header->type, from);
661 if (new->scope == NULL)
662 {
663 zlog_warn ("Can't decide LSA scope, ignore");
664 ospf6_lsa_delete (new);
665 return;
666 }
667
668 /* (1) LSA Checksum */
669 cksum = ntohs (new->header->checksum);
670 if (ntohs (ospf6_lsa_checksum (new->header)) != cksum)
671 {
672 if (IS_OSPF6_DEBUG_LSA (RECV))
673 zlog_info ("Wrong LSA Checksum");
674 ospf6_lsa_delete (new);
675 return;
676 }
677
678 /* (3) Ebit Missmatch: AS-External-LSA */
679 if (ntohs (new->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
680 ospf6_area_is_stub (from->ospf6_if->area))
681 {
682 if (IS_OSPF6_DEBUG_LSA (RECV))
683 zlog_info ("AS-External-LSA in stub area");
684 ospf6_lsa_delete (new);
685 return;
686 }
687
688 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
689 is in states Exchange or Loading */
690 if (ospf6_is_maxage_lsa_drop (new, from))
691 {
692 /* log */
693 if (IS_OSPF6_DEBUG_LSA (RECV))
694 zlog_info ("Drop MaxAge LSA with Direct acknowledgement.");
695
696 /* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */
697 if (IS_OSPF6_DEBUG_LSA (DATABASE))
698 zlog_info (" Add %s to lsack_list of %s",
699 new->name, from->name);
700 ospf6_lsdb_add (new, from->lsack_list);
701 if (from->thread_send_lsack == NULL)
702 from->thread_send_lsack =
703 thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
704
705 /* b) Discard */
706 /* "new" LSA will be discarded just after the LSAck sent */
707 return;
708 }
709
710 /* (5) */
711 /* lookup the same database copy in lsdb */
712 lsdb = ospf6_get_scoped_lsdb (new->header->type, new->scope);
713 if (lsdb == NULL)
714 {
715 zlog_warn ("Can't decide scoped LSDB, ignore");
716 ospf6_lsa_delete (new);
717 return;
718 }
719
720 old = ospf6_lsdb_lookup (new->header->type, new->header->id,
721 new->header->adv_router, lsdb);
722 if (old)
723 {
724 ismore_recent = ospf6_lsa_compare (new, old);
725 if (ntohl (new->header->seqnum) == ntohl (old->header->seqnum))
726 {
727 if (IS_OSPF6_DEBUG_LSA (RECV))
728 zlog_info ("Duplicated LSA");
729 SET_FLAG (new->flag, OSPF6_LSA_DUPLICATE);
730 }
731 }
732
733 /* if no database copy or received is more recent */
734 if (old == NULL || ismore_recent < 0)
735 {
736 /* in case we have no database copy */
737 ismore_recent = -1;
738
739 /* (a) MinLSArrival check */
740 if (old)
741 {
742 struct timeval now, res;
743 gettimeofday (&now, (struct timezone *) NULL);
744 timersub (&now, &old->installed, &res);
745 if (res.tv_sec < MIN_LS_ARRIVAL)
746 {
747 if (IS_OSPF6_DEBUG_LSA (RECV) || IS_OSPF6_DEBUG_LSA (TIMER))
748 zlog_info ("LSA can't be updated within MinLSArrival");
749 ospf6_lsa_delete (new);
750 return; /* examin next lsa */
751 }
752 }
753
754 /* (b) immediately flood and (c) remove from all retrans-list */
755 ospf6_flood_lsa (new, from);
756
757 /* (d), installing lsdb, which may cause routing
758 table calculation (replacing database copy) */
759 ospf6_install_lsa (new, lsdb);
760
761 /* (e) possibly acknowledge */
762 ospf6_acknowledge_lsa (new, ismore_recent, from);
763
764 /* (f) */
765 /* Self Originated LSA, section 13.4 */
766 if (new->header->adv_router == from->ospf6_if->area->ospf6->router_id
767 && (! old || ismore_recent < 0))
768 {
769 /* We have to make a new instance of the LSA
770 or have to flush this LSA. */
771 if (IS_OSPF6_DEBUG_LSA (RECV))
772 zlog_info ("New instance of the self-originated LSA");
773
774 SET_FLAG (new->flag, OSPF6_LSA_REFRESH);
775 ospf6_lsa_re_originate (new);
776 }
777 return;
778 }
779
780 /* (6) if there is instance on sending neighbor's request list */
781 if (ospf6_lsdb_lookup (new->header->type, new->header->id,
782 new->header->adv_router, from->request_list))
783 {
784 /* if no database copy, should go above state (5) */
785 assert (old);
786
787 if (IS_OSPF6_DEBUG_LSA (RECV))
788 zlog_info ("LSA is not newer and on request-list of sending neighbor");
789
790 /* BadLSReq */
791 thread_add_event (master, bad_lsreq, from, 0);
792
793 ospf6_lsa_delete (new);
794 return;
795 }
796
797 /* (7) if neither one is more recent */
798 if (ismore_recent == 0)
799 {
800 if (IS_OSPF6_DEBUG_LSA (RECV))
801 zlog_info ("The same instance as database copy");
802
803 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack */
804 rem = ospf6_lsdb_lookup (new->header->type, new->header->id,
805 new->header->adv_router, from->retrans_list);
806 if (rem)
807 {
808 if (IS_OSPF6_DEBUG_LSA (RECV))
809 zlog_info ("Treat as an Implied acknowledgement");
810 SET_FLAG (new->flag, OSPF6_LSA_IMPLIEDACK);
811 if (IS_OSPF6_DEBUG_LSA (DATABASE))
812 zlog_info ("Remove %s from retrans_list of %s",
813 rem->name, from->name);
814 ospf6_lsdb_remove (rem, from->retrans_list);
815 }
816
817 /* (b) possibly acknowledge */
818 ospf6_acknowledge_lsa (new, ismore_recent, from);
819
820 ospf6_lsa_delete (new);
821 return;
822 }
823
824 /* (8) previous database copy is more recent */
825 {
826 assert (old);
827
828 /* If database copy is in 'Seqnumber Wrapping',
829 simply discard the received LSA */
830 if (OSPF6_LSA_IS_MAXAGE (old) &&
831 old->header->seqnum == htonl (MAX_SEQUENCE_NUMBER))
832 {
833 if (IS_OSPF6_DEBUG_LSA (RECV))
834 zlog_info ("Database copy is in Seqnumber Wrapping");
835 ospf6_lsa_delete (new);
836 return;
837 }
838
839 /* Otherwise, Send database copy of this LSA to this neighbor */
840 {
841 if (IS_OSPF6_DEBUG_LSA (RECV))
842 zlog_info ("Database is more recent, send back directly");
843
844 /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
845
846 if (IS_OSPF6_DEBUG_LSA (DATABASE))
847 zlog_info (" Add copy of %s to lsupdate_list of %s",
848 old->name, from->name);
849 ospf6_lsdb_add (ospf6_lsa_copy (old), from->lsupdate_list);
850 if (from->thread_send_lsupdate == NULL)
851 from->thread_send_lsupdate =
852 thread_add_event (master, ospf6_lsupdate_send_neighbor, from, 0);
853 ospf6_lsa_delete (new);
854 return;
855 }
856 return;
857 }
858}
859
860
861