2 * Copyright (C) 2003 Yasuhiro Ohara
4 * This file is part of GNU Zebra.
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
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.
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.
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"
37 #include "ospf6_top.h"
38 #include "ospf6_area.h"
39 #include "ospf6_interface.h"
40 #include "ospf6_neighbor.h"
44 ospf6_get_lsa_scope (u_int16_t type
, struct ospf6_neighbor
*from
)
51 switch (OSPF6_LSA_SCOPE (type
))
53 case OSPF6_LSA_SCOPE_AS
:
54 scope
= (from
)->ospf6_if
->area
->ospf6
;
56 case OSPF6_LSA_SCOPE_AREA
:
57 scope
= (from
)->ospf6_if
->area
;
59 case OSPF6_LSA_SCOPE_LINKLOCAL
:
60 scope
= (from
)->ospf6_if
;
70 ospf6_get_scoped_lsdb (u_int16_t type
, void *scope
)
72 struct ospf6_lsdb
*lsdb
= NULL
;
77 switch (OSPF6_LSA_SCOPE (type
))
79 case OSPF6_LSA_SCOPE_AS
:
80 lsdb
= ((struct ospf6
*)(scope
))->lsdb
;
82 case OSPF6_LSA_SCOPE_AREA
:
83 lsdb
= ((struct ospf6_area
*)(scope
))->lsdb
;
85 case OSPF6_LSA_SCOPE_LINKLOCAL
:
86 lsdb
= ((struct ospf6_interface
*)(scope
))->lsdb
;
96 ospf6_decrement_onretrans (struct ospf6_lsa
*lsa
)
98 struct ospf6_lsdb
*lsdb
;
99 struct ospf6_lsa
*src
;
101 lsdb
= ospf6_get_scoped_lsdb (lsa
->header
->type
, lsa
->scope
);
104 zlog_warn ("Decrement onretrans: no such scope: %s", lsa
->name
);
108 src
= ospf6_lsdb_lookup (lsa
->header
->type
, lsa
->header
->id
,
109 lsa
->header
->adv_router
, lsdb
);
110 if (src
&& src
!= lsa
)
113 if (src
->onretrans
< 0)
114 zlog_warn ("internal error: onretrans");
118 ospf6_flood_clear (struct ospf6_lsa
*lsa
)
120 struct ospf6_neighbor
*on
;
121 struct ospf6_interface
*oi
, *ospf6_if
= NULL
;
122 struct ospf6_area
*oa
, *area
= NULL
;
123 struct ospf6
*ospf6
= NULL
;
124 u_int16_t scope_type
;
125 list scoped_interfaces
;
126 struct ospf6_lsa
*rxmt
;
129 scoped_interfaces
= list_new ();
130 scope_type
= OSPF6_LSA_SCOPE (lsa
->header
->type
);
132 if (scope_type
== OSPF6_LSA_SCOPE_LINKLOCAL
)
134 ospf6_if
= (struct ospf6_interface
*) lsa
->scope
;
135 area
= ospf6_if
->area
;
138 else if (scope_type
== OSPF6_LSA_SCOPE_AREA
)
140 area
= (struct ospf6_area
*) lsa
->scope
;
143 else if (scope_type
== OSPF6_LSA_SCOPE_AS
)
145 ospf6
= (struct ospf6
*) lsa
->scope
;
149 zlog_warn ("Can't decide LSA scope, quit ospf6_flood_clear ()");
153 /* Collect eligible interfaces */
154 for (i
= listhead (ospf6
->area_list
); i
; nextnode (i
))
156 oa
= (struct ospf6_area
*) getdata (i
);
157 if (scope_type
!= OSPF6_LSA_SCOPE_AS
&& oa
!= area
)
160 for (j
= listhead (oa
->if_list
); j
; nextnode (j
))
162 oi
= (struct ospf6_interface
*) getdata (j
);
163 if (scope_type
!= OSPF6_LSA_SCOPE_AS
&&
164 scope_type
!= OSPF6_LSA_SCOPE_AREA
&& oi
!= ospf6_if
)
167 listnode_add (scoped_interfaces
, oi
);
171 for (i
= listhead (scoped_interfaces
); i
; nextnode (i
))
173 oi
= (struct ospf6_interface
*) getdata (i
);
174 for (j
= listhead (oi
->neighbor_list
); j
; nextnode (j
))
176 on
= (struct ospf6_neighbor
*) getdata (j
);
177 rxmt
= ospf6_lsdb_lookup (lsa
->header
->type
, lsa
->header
->id
,
178 lsa
->header
->adv_router
, on
->retrans_list
);
179 if (rxmt
&& ! ospf6_lsa_compare (rxmt
, lsa
))
181 if (IS_OSPF6_DEBUG_LSA (DATABASE
))
182 zlog_info ("Remove %s from retrans_list of %s",
183 rxmt
->name
, on
->name
);
184 ospf6_decrement_onretrans (rxmt
);
185 ospf6_lsdb_remove (rxmt
, on
->retrans_list
);
190 list_delete (scoped_interfaces
);
193 /* RFC2328 section 13.2 Installing LSAs in the database */
195 ospf6_install_lsa (struct ospf6_lsa
*lsa
, struct ospf6_lsdb
*lsdb
)
197 struct ospf6_lsa
*old
;
199 if (IS_OSPF6_DEBUG_LSA (RECV
) || IS_OSPF6_DEBUG_LSA (DATABASE
))
200 zlog_info ("Install LSA: %s", lsa
->name
);
202 /* Remove the old instance from all neighbors' Link state
203 retransmission list (RFC2328 13.2 last paragraph) */
204 old
= ospf6_lsdb_lookup (lsa
->header
->type
, lsa
->header
->id
,
205 lsa
->header
->adv_router
, lsdb
);
207 ospf6_flood_clear (old
);
209 /* actually install */
210 gettimeofday (&lsa
->installed
, (struct timezone
*) NULL
);
211 ospf6_lsdb_add (lsa
, lsdb
);
216 /* RFC2328 section 13.3 Next step in the flooding procedure */
218 ospf6_flood_lsa (struct ospf6_lsa
*lsa
, struct ospf6_neighbor
*from
)
220 struct ospf6
*scope_as
= NULL
;
221 struct ospf6_area
*oa
, *scope_area
= NULL
;
222 struct ospf6_interface
*oi
, *scope_linklocal
= NULL
;
223 struct ospf6_neighbor
*on
;
224 list eligible_interfaces
;
226 u_int16_t scope_type
;
227 struct ospf6_lsa
*req
;
228 int retrans_added
= 0;
230 scope_type
= OSPF6_LSA_SCOPE (lsa
->header
->type
);
233 case OSPF6_LSA_SCOPE_AS
:
234 scope_as
= (struct ospf6
*) lsa
->scope
;
236 case OSPF6_LSA_SCOPE_AREA
:
237 scope_as
= ((struct ospf6_area
*) lsa
->scope
)->ospf6
;
238 scope_area
= (struct ospf6_area
*) lsa
->scope
;
240 case OSPF6_LSA_SCOPE_LINKLOCAL
:
241 scope_as
= ((struct ospf6_interface
*) lsa
->scope
)->area
->ospf6
;
242 scope_area
= ((struct ospf6_interface
*) lsa
->scope
)->area
;
243 scope_linklocal
= (struct ospf6_interface
*) lsa
->scope
;
246 if (IS_OSPF6_DEBUG_LSA (SEND
))
247 zlog_info ("Can't decide LSA scope");
251 if (IS_OSPF6_DEBUG_LSA (SEND
))
252 zlog_info ("Flood %s", lsa
->name
);
254 /* Collect eligible interfaces */
255 eligible_interfaces
= list_new ();
256 for (i
= listhead (scope_as
->area_list
); i
; nextnode (i
))
258 oa
= (struct ospf6_area
*) getdata (i
);
259 if (scope_type
!= OSPF6_LSA_SCOPE_AS
&&
263 for (j
= listhead (oa
->if_list
); j
; nextnode (j
))
265 oi
= (struct ospf6_interface
*) getdata (j
);
266 if (scope_type
!= OSPF6_LSA_SCOPE_AS
&&
267 scope_type
!= OSPF6_LSA_SCOPE_AREA
&&
268 oi
!= scope_linklocal
)
271 listnode_add (eligible_interfaces
, oi
);
275 /* For each eligible interface: */
276 for (i
= listhead (eligible_interfaces
); i
; nextnode (i
))
278 oi
= (struct ospf6_interface
*) getdata (i
);
280 /* (1) For each neighbor */
281 for (j
= listhead (oi
->neighbor_list
); j
; nextnode (j
))
283 on
= (struct ospf6_neighbor
*) getdata (j
);
285 /* (a) if neighbor state < Exchange, examin next */
286 if (on
->state
< OSPF6_NEIGHBOR_EXCHANGE
)
289 /* (b) if neighbor not yet Full, check request-list */
290 if (on
->state
!= OSPF6_NEIGHBOR_FULL
)
292 req
= ospf6_lsdb_lookup (lsa
->header
->type
, lsa
->header
->id
,
293 lsa
->header
->adv_router
,
297 /* If new LSA less recent, examin next neighbor */
298 if (ospf6_lsa_compare (lsa
, req
) > 0)
301 /* If the same instance, delete from request-list and
302 examin next neighbor */
303 if (ospf6_lsa_compare (lsa
, req
) == 0)
305 if (IS_OSPF6_DEBUG_LSA (SEND
) || IS_OSPF6_DEBUG_LSA (DATABASE
))
306 zlog_info ("Remove %s from request-list of %s: "
307 "the same instance", req
->name
, on
->name
);
308 ospf6_lsdb_remove (req
, on
->request_list
);
312 /* If the new LSA is more recent, delete from
314 if (ospf6_lsa_compare (lsa
, req
) < 0)
316 if (IS_OSPF6_DEBUG_LSA (SEND
) || IS_OSPF6_DEBUG_LSA (DATABASE
))
317 zlog_info ("Remove %s from request-list of %s: "
318 "newer instance", req
->name
, on
->name
);
319 ospf6_lsdb_remove (req
, on
->request_list
);
325 /* (c) If the new LSA was received from this neighbor,
326 examin next neighbor */
330 /* (d) add retrans-list, schedule retransmission */
331 if (IS_OSPF6_DEBUG_LSA (SEND
) || IS_OSPF6_DEBUG_LSA (DATABASE
))
332 zlog_info (" Add copy of %s to retrans-list of %s",
333 lsa
->name
, on
->name
);
335 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), on
->retrans_list
);
336 if (on
->thread_send_lsupdate
== NULL
)
337 on
->thread_send_lsupdate
=
338 thread_add_event (master
, ospf6_lsupdate_send_neighbor
,
339 on
, on
->ospf6_if
->rxmt_interval
);
343 /* (2) examin next interface if not added to retrans-list */
344 if (retrans_added
== 0)
347 /* (3) If the new LSA was received on this interface,
348 and it was from DR or BDR, examin next interface */
349 if (from
&& from
->ospf6_if
== oi
&&
350 (from
->router_id
== oi
->drouter
|| from
->router_id
== oi
->bdrouter
))
353 /* (4) If the new LSA was received on this interface,
354 and the interface state is BDR, examin next interface */
355 if (from
&& from
->ospf6_if
== oi
&& oi
->state
== OSPF6_INTERFACE_BDR
)
358 /* (5) flood the LSA out the interface. */
359 if (if_is_broadcast (oi
->interface
))
361 if (IS_OSPF6_DEBUG_LSA (SEND
) || IS_OSPF6_DEBUG_LSA (DATABASE
))
362 zlog_info (" Add copy of %s to lsupdate_list of %s",
363 lsa
->name
, oi
->interface
->name
);
364 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), oi
->lsupdate_list
);
365 if (oi
->thread_send_lsupdate
== NULL
)
366 oi
->thread_send_lsupdate
=
367 thread_add_event (master
, ospf6_lsupdate_send_interface
, oi
, 0);
371 for (j
= listhead (oi
->neighbor_list
); j
; nextnode (j
))
373 on
= (struct ospf6_neighbor
*) getdata (j
);
374 THREAD_OFF (on
->thread_send_lsupdate
);
375 on
->thread_send_lsupdate
=
376 thread_add_event (master
, ospf6_lsupdate_send_neighbor
, on
, 0);
381 list_delete (eligible_interfaces
);
384 /* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
386 ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa
*lsa
, int ismore_recent
,
387 struct ospf6_neighbor
*from
)
389 struct ospf6_interface
*oi
;
391 assert (from
&& from
->ospf6_if
);
394 /* LSA has been flood back out receiving interface.
395 No acknowledgement sent. */
396 if (CHECK_FLAG (lsa
->flag
, OSPF6_LSA_FLOODBACK
))
398 if (IS_OSPF6_DEBUG_LSA (RECV
))
399 zlog_info (" BDR, FloodBack, No acknowledgement.");
403 /* LSA is more recent than database copy, but was not flooded
404 back out receiving interface. Delayed acknowledgement sent
405 if advertisement received from Designated Router,
406 otherwide do nothing. */
407 if (ismore_recent
< 0)
409 if (IS_OSPF6_DEBUG_LSA (RECV
))
410 zlog_info (" BDR, Not FloodBack, MoreRecent, ");
411 if (oi
->drouter
== from
->router_id
)
413 if (IS_OSPF6_DEBUG_LSA (RECV
))
414 zlog_info (" From DR, Delayed acknowledgement.");
415 /* Delayed acknowledgement */
416 if (IS_OSPF6_DEBUG_LSA (DATABASE
))
417 zlog_info (" Add copy of %s to lsack_list of %s",
418 lsa
->name
, oi
->interface
->name
);
419 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), oi
->lsack_list
);
420 if (oi
->thread_send_lsack
== NULL
)
421 oi
->thread_send_lsack
=
422 thread_add_timer (master
, ospf6_lsack_send_interface
, oi
, 3);
426 if (IS_OSPF6_DEBUG_LSA (RECV
))
427 zlog_info (" Not From DR, No acknowledgement.");
432 /* LSA is a duplicate, and was treated as an implied acknowledgement.
433 Delayed acknowledgement sent if advertisement received from
434 Designated Router, otherwise do nothing */
435 if (CHECK_FLAG (lsa
->flag
, OSPF6_LSA_DUPLICATE
) &&
436 CHECK_FLAG (lsa
->flag
, OSPF6_LSA_IMPLIEDACK
))
438 if (IS_OSPF6_DEBUG_LSA (RECV
))
439 zlog_info (" BDR, Duplicate, ImpliedAck, ");
440 if (oi
->drouter
== from
->router_id
)
442 if (IS_OSPF6_DEBUG_LSA (RECV
))
443 zlog_info (" From DR, Delayed acknowledgement.");
444 /* Delayed acknowledgement */
445 if (IS_OSPF6_DEBUG_LSA (DATABASE
))
446 zlog_info (" Add copy of %s to lsack_list of %s",
447 lsa
->name
, oi
->interface
->name
);
448 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), oi
->lsack_list
);
449 if (oi
->thread_send_lsack
== NULL
)
450 oi
->thread_send_lsack
=
451 thread_add_timer (master
, ospf6_lsack_send_interface
, oi
, 3);
455 if (IS_OSPF6_DEBUG_LSA (RECV
))
456 zlog_info (" Not From DR, No acknowledgement.");
461 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
462 Direct acknowledgement sent */
463 if (CHECK_FLAG (lsa
->flag
, OSPF6_LSA_DUPLICATE
) &&
464 ! CHECK_FLAG (lsa
->flag
, OSPF6_LSA_IMPLIEDACK
))
466 if (IS_OSPF6_DEBUG_LSA (RECV
))
467 zlog_info (" BDR, Duplicate, Not ImpliedAck, Direct acknowledgement.");
468 if (IS_OSPF6_DEBUG_LSA (DATABASE
))
469 zlog_info (" Add copy of %s to lsack_list of %s",
470 lsa
->name
, from
->name
);
471 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), from
->lsack_list
);
472 if (from
->thread_send_lsack
== NULL
)
473 from
->thread_send_lsack
=
474 thread_add_event (master
, ospf6_lsack_send_neighbor
, from
, 0);
478 /* LSA's LS age is equal to Maxage, and there is no current instance
479 of the LSA in the link state database, and none of router's
480 neighbors are in states Exchange or Loading */
481 /* Direct acknowledgement sent, but this case is handled in
482 early of ospf6_receive_lsa () */
486 ospf6_acknowledge_lsa_allother (struct ospf6_lsa
*lsa
, int ismore_recent
,
487 struct ospf6_neighbor
*from
)
489 struct ospf6_interface
*oi
;
491 assert (from
&& from
->ospf6_if
);
494 /* LSA has been flood back out receiving interface.
495 No acknowledgement sent. */
496 if (CHECK_FLAG (lsa
->flag
, OSPF6_LSA_FLOODBACK
))
498 if (IS_OSPF6_DEBUG_LSA (RECV
))
499 zlog_info (" AllOther, FloodBack, No acknowledgement.");
503 /* LSA is more recent than database copy, but was not flooded
504 back out receiving interface. Delayed acknowledgement sent. */
505 if (ismore_recent
< 0)
507 if (IS_OSPF6_DEBUG_LSA (RECV
))
508 zlog_info (" AllOther, Not FloodBack, Delayed acknowledgement.");
509 /* Delayed acknowledgement */
510 if (IS_OSPF6_DEBUG_LSA (DATABASE
))
511 zlog_info (" Add copy of %s to lsack_list of %s",
512 lsa
->name
, oi
->interface
->name
);
513 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), oi
->lsack_list
);
514 if (oi
->thread_send_lsack
== NULL
)
515 oi
->thread_send_lsack
=
516 thread_add_timer (master
, ospf6_lsack_send_interface
, oi
, 3);
520 /* LSA is a duplicate, and was treated as an implied acknowledgement.
521 No acknowledgement sent. */
522 if (CHECK_FLAG (lsa
->flag
, OSPF6_LSA_DUPLICATE
) &&
523 CHECK_FLAG (lsa
->flag
, OSPF6_LSA_IMPLIEDACK
))
525 if (IS_OSPF6_DEBUG_LSA (RECV
))
526 zlog_info (" AllOther, Duplicate, ImpliedAck, No acknowledgement.");
530 /* LSA is a duplicate, and was not treated as an implied acknowledgement.
531 Direct acknowledgement sent */
532 if (CHECK_FLAG (lsa
->flag
, OSPF6_LSA_DUPLICATE
) &&
533 ! CHECK_FLAG (lsa
->flag
, OSPF6_LSA_IMPLIEDACK
))
535 if (IS_OSPF6_DEBUG_LSA (RECV
))
536 zlog_info (" AllOther, Duplicate, Not ImpliedAck, Direct acknowledgement.");
537 if (IS_OSPF6_DEBUG_LSA (DATABASE
))
538 zlog_info (" Add copy of %s to lsack_list of %s",
539 lsa
->name
, from
->name
);
540 ospf6_lsdb_add (ospf6_lsa_copy (lsa
), from
->lsack_list
);
541 if (from
->thread_send_lsack
== NULL
)
542 from
->thread_send_lsack
=
543 thread_add_event (master
, ospf6_lsack_send_neighbor
, from
, 0);
547 /* LSA's LS age is equal to Maxage, and there is no current instance
548 of the LSA in the link state database, and none of router's
549 neighbors are in states Exchange or Loading */
550 /* Direct acknowledgement sent, but this case is handled in
551 early of ospf6_receive_lsa () */
555 ospf6_acknowledge_lsa (struct ospf6_lsa
*lsa
, int ismore_recent
,
556 struct ospf6_neighbor
*from
)
558 struct ospf6_interface
*oi
;
560 assert (from
&& from
->ospf6_if
);
563 if (oi
->state
== OSPF6_INTERFACE_BDR
)
564 ospf6_acknowledge_lsa_bdrouter (lsa
, ismore_recent
, from
);
566 ospf6_acknowledge_lsa_allother (lsa
, ismore_recent
, from
);
569 /* RFC2328 section 13 (4):
570 if MaxAge LSA and if we have no instance, and no neighbor
571 is in states Exchange or Loading
572 returns 1 if match this case, else returns 0 */
574 ospf6_is_maxage_lsa_drop (struct ospf6_lsa
*lsa
,
575 struct ospf6_neighbor
*from
)
577 struct ospf6_lsdb
*lsdb
= NULL
;
578 struct ospf6_neighbor
*on
;
579 struct ospf6_interface
*oi
, *ospf6_if
= NULL
;
580 struct ospf6_area
*oa
, *area
= NULL
;
581 struct ospf6
*ospf6
= NULL
;
582 u_int16_t scope_type
;
583 list scoped_interfaces
;
587 if (! OSPF6_LSA_IS_MAXAGE (lsa
))
590 lsdb
= ospf6_get_scoped_lsdb (lsa
->header
->type
, lsa
->scope
);
593 zlog_info ("Can't decide scoped LSDB");
597 if (ospf6_lsdb_lookup (lsa
->header
->type
, lsa
->header
->id
,
598 lsa
->header
->adv_router
, lsdb
))
601 scoped_interfaces
= list_new ();
602 scope_type
= OSPF6_LSA_SCOPE (lsa
->header
->type
);
604 if (scope_type
== OSPF6_LSA_SCOPE_LINKLOCAL
)
606 ospf6_if
= (struct ospf6_interface
*) lsa
->scope
;
607 area
= ospf6_if
->area
;
610 else if (scope_type
== OSPF6_LSA_SCOPE_AREA
)
612 area
= (struct ospf6_area
*) lsa
->scope
;
615 else if (scope_type
== OSPF6_LSA_SCOPE_AS
)
617 ospf6
= (struct ospf6
*) lsa
->scope
;
621 zlog_info ("Can't decide LSA scope");
625 /* Collect eligible interfaces */
626 for (i
= listhead (ospf6
->area_list
); i
; nextnode (i
))
628 oa
= (struct ospf6_area
*) getdata (i
);
629 if (scope_type
!= OSPF6_LSA_SCOPE_AS
&& oa
!= area
)
632 for (j
= listhead (oa
->if_list
); j
; nextnode (j
))
634 oi
= (struct ospf6_interface
*) getdata (j
);
635 if (scope_type
!= OSPF6_LSA_SCOPE_AS
&&
636 scope_type
!= OSPF6_LSA_SCOPE_AREA
&& oi
!= ospf6_if
)
639 listnode_add (scoped_interfaces
, oi
);
643 for (i
= listhead (scoped_interfaces
); i
; nextnode (i
))
645 oi
= (struct ospf6_interface
*) getdata (i
);
646 for (j
= listhead (oi
->neighbor_list
); j
; nextnode (j
))
648 on
= (struct ospf6_neighbor
*) getdata (j
);
649 if (on
->state
== OSPF6_NEIGHBOR_EXCHANGE
||
650 on
->state
== OSPF6_NEIGHBOR_LOADING
)
655 list_delete (scoped_interfaces
);
663 /* RFC2328 section 13 The Flooding Procedure */
665 ospf6_receive_lsa (struct ospf6_lsa_header
*lsa_header
,
666 struct ospf6_neighbor
*from
)
668 struct ospf6_lsa
*new = NULL
, *old
= NULL
, *rem
= NULL
;
670 unsigned short cksum
;
671 struct ospf6_lsdb
*lsdb
= NULL
;
675 /* make lsa structure for received lsa */
676 new = ospf6_lsa_create (lsa_header
);
678 if (IS_OSPF6_DEBUG_LSA (RECV
))
680 zlog_info ("LSA Receive from %s", from
->name
);
681 ospf6_lsa_header_print (new);
684 new->scope
= ospf6_get_lsa_scope (new->header
->type
, from
);
685 if (new->scope
== NULL
)
687 zlog_warn ("Can't decide LSA scope, ignore");
688 ospf6_lsa_delete (new);
692 /* (1) LSA Checksum */
693 cksum
= ntohs (new->header
->checksum
);
694 if (ntohs (ospf6_lsa_checksum (new->header
)) != cksum
)
696 if (IS_OSPF6_DEBUG_LSA (RECV
))
697 zlog_info ("Wrong LSA Checksum");
698 ospf6_lsa_delete (new);
702 /* (3) Ebit Missmatch: AS-External-LSA */
703 if (ntohs (new->header
->type
) == OSPF6_LSTYPE_AS_EXTERNAL
&&
704 ospf6_area_is_stub (from
->ospf6_if
->area
))
706 if (IS_OSPF6_DEBUG_LSA (RECV
))
707 zlog_info ("AS-External-LSA in stub area");
708 ospf6_lsa_delete (new);
712 /* (4) if MaxAge LSA and if we have no instance, and no neighbor
713 is in states Exchange or Loading */
714 if (ospf6_is_maxage_lsa_drop (new, from
))
717 if (IS_OSPF6_DEBUG_LSA (RECV
))
718 zlog_info ("Drop MaxAge LSA with Direct acknowledgement.");
720 /* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */
721 if (IS_OSPF6_DEBUG_LSA (DATABASE
))
722 zlog_info (" Add %s to lsack_list of %s",
723 new->name
, from
->name
);
724 ospf6_lsdb_add (new, from
->lsack_list
);
725 if (from
->thread_send_lsack
== NULL
)
726 from
->thread_send_lsack
=
727 thread_add_event (master
, ospf6_lsack_send_neighbor
, from
, 0);
730 /* "new" LSA will be discarded just after the LSAck sent */
735 /* lookup the same database copy in lsdb */
736 lsdb
= ospf6_get_scoped_lsdb (new->header
->type
, new->scope
);
739 zlog_warn ("Can't decide scoped LSDB, ignore");
740 ospf6_lsa_delete (new);
744 old
= ospf6_lsdb_lookup (new->header
->type
, new->header
->id
,
745 new->header
->adv_router
, lsdb
);
748 ismore_recent
= ospf6_lsa_compare (new, old
);
749 if (ntohl (new->header
->seqnum
) == ntohl (old
->header
->seqnum
))
751 if (IS_OSPF6_DEBUG_LSA (RECV
))
752 zlog_info ("Duplicated LSA");
753 SET_FLAG (new->flag
, OSPF6_LSA_DUPLICATE
);
757 /* if no database copy or received is more recent */
758 if (old
== NULL
|| ismore_recent
< 0)
760 /* in case we have no database copy */
763 /* (a) MinLSArrival check */
766 struct timeval now
, res
;
767 gettimeofday (&now
, (struct timezone
*) NULL
);
768 timersub (&now
, &old
->installed
, &res
);
769 if (res
.tv_sec
< MIN_LS_ARRIVAL
)
771 if (IS_OSPF6_DEBUG_LSA (RECV
) || IS_OSPF6_DEBUG_LSA (TIMER
))
772 zlog_info ("LSA can't be updated within MinLSArrival");
773 ospf6_lsa_delete (new);
774 return; /* examin next lsa */
778 /* (b) immediately flood and (c) remove from all retrans-list */
779 ospf6_flood_lsa (new, from
);
781 /* (d), installing lsdb, which may cause routing
782 table calculation (replacing database copy) */
783 ospf6_install_lsa (new, lsdb
);
785 /* (e) possibly acknowledge */
786 ospf6_acknowledge_lsa (new, ismore_recent
, from
);
789 /* Self Originated LSA, section 13.4 */
790 if (new->header
->adv_router
== from
->ospf6_if
->area
->ospf6
->router_id
791 && (! old
|| ismore_recent
< 0))
793 /* We have to make a new instance of the LSA
794 or have to flush this LSA. */
795 if (IS_OSPF6_DEBUG_LSA (RECV
))
796 zlog_info ("New instance of the self-originated LSA");
798 SET_FLAG (new->flag
, OSPF6_LSA_REFRESH
);
799 ospf6_lsa_re_originate (new);
804 /* (6) if there is instance on sending neighbor's request list */
805 if (ospf6_lsdb_lookup (new->header
->type
, new->header
->id
,
806 new->header
->adv_router
, from
->request_list
))
808 /* if no database copy, should go above state (5) */
811 if (IS_OSPF6_DEBUG_LSA (RECV
))
812 zlog_info ("LSA is not newer and on request-list of sending neighbor");
815 thread_add_event (master
, bad_lsreq
, from
, 0);
817 ospf6_lsa_delete (new);
821 /* (7) if neither one is more recent */
822 if (ismore_recent
== 0)
824 if (IS_OSPF6_DEBUG_LSA (RECV
))
825 zlog_info ("The same instance as database copy");
827 /* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack */
828 rem
= ospf6_lsdb_lookup (new->header
->type
, new->header
->id
,
829 new->header
->adv_router
, from
->retrans_list
);
832 if (IS_OSPF6_DEBUG_LSA (RECV
))
833 zlog_info ("Treat as an Implied acknowledgement");
834 SET_FLAG (new->flag
, OSPF6_LSA_IMPLIEDACK
);
835 if (IS_OSPF6_DEBUG_LSA (DATABASE
))
836 zlog_info ("Remove %s from retrans_list of %s",
837 rem
->name
, from
->name
);
838 ospf6_decrement_onretrans (rem
);
839 ospf6_lsdb_remove (rem
, from
->retrans_list
);
842 /* (b) possibly acknowledge */
843 ospf6_acknowledge_lsa (new, ismore_recent
, from
);
845 ospf6_lsa_delete (new);
849 /* (8) previous database copy is more recent */
853 /* If database copy is in 'Seqnumber Wrapping',
854 simply discard the received LSA */
855 if (OSPF6_LSA_IS_MAXAGE (old
) &&
856 old
->header
->seqnum
== htonl (MAX_SEQUENCE_NUMBER
))
858 if (IS_OSPF6_DEBUG_LSA (RECV
))
859 zlog_info ("Database copy is in Seqnumber Wrapping");
860 ospf6_lsa_delete (new);
864 /* Otherwise, Send database copy of this LSA to this neighbor */
866 if (IS_OSPF6_DEBUG_LSA (RECV
))
867 zlog_info ("Database is more recent, send back directly");
869 /* XXX, MinLSArrival check !? RFC 2328 13 (8) */
871 if (IS_OSPF6_DEBUG_LSA (DATABASE
))
872 zlog_info (" Add copy of %s to lsupdate_list of %s",
873 old
->name
, from
->name
);
874 ospf6_lsdb_add (ospf6_lsa_copy (old
), from
->lsupdate_list
);
875 if (from
->thread_send_lsupdate
== NULL
)
876 from
->thread_send_lsupdate
=
877 thread_add_event (master
, ospf6_lsupdate_send_neighbor
, from
, 0);
878 ospf6_lsa_delete (new);