summaryrefslogtreecommitdiffstats
path: root/ospf6d/ospf6_flood.c
diff options
context:
space:
mode:
authorhasso <hasso>2004-08-15 07:52:07 +0200
committerhasso <hasso>2004-08-15 07:52:07 +0200
commit6452df092bf6b694ea62a0423ac242f10ab997f9 (patch)
tree087490eb5e58209ca207f28b626c4a4a84ad4c9c /ospf6d/ospf6_flood.c
parentInclude padding in control message length. (diff)
downloadfrr-6452df092bf6b694ea62a0423ac242f10ab997f9.tar.xz
frr-6452df092bf6b694ea62a0423ac242f10ab997f9.zip
SVN revisions 916-920 from Zebra. ABR support is almost done.
Diffstat (limited to 'ospf6d/ospf6_flood.c')
-rw-r--r--ospf6d/ospf6_flood.c886
1 files changed, 480 insertions, 406 deletions
diff --git a/ospf6d/ospf6_flood.c b/ospf6d/ospf6_flood.c
index 6e84a0345..aeff15bcb 100644
--- a/ospf6d/ospf6_flood.c
+++ b/ospf6d/ospf6_flood.c
@@ -39,160 +39,169 @@
#include "ospf6_interface.h"
#include "ospf6_neighbor.h"
+#include "ospf6_flood.h"
-void *
-ospf6_get_lsa_scope (u_int16_t type, struct ospf6_neighbor *from)
+struct ospf6_lsdb *
+ospf6_get_scoped_lsdb (struct ospf6_lsa *lsa)
{
- void *scope = NULL;
-
- if (from == NULL)
- return NULL;
-
- switch (OSPF6_LSA_SCOPE (type))
- {
- case OSPF6_LSA_SCOPE_AS:
- scope = (from)->ospf6_if->area->ospf6;
- break;
- case OSPF6_LSA_SCOPE_AREA:
- scope = (from)->ospf6_if->area;
- break;
- case OSPF6_LSA_SCOPE_LINKLOCAL:
- scope = (from)->ospf6_if;
- break;
- default:
- break;
+ struct ospf6_lsdb *lsdb = NULL;
+ switch (OSPF6_LSA_SCOPE (lsa->header->type))
+ {
+ case OSPF6_SCOPE_LINKLOCAL:
+ lsdb = OSPF6_INTERFACE (lsa->lsdb->data)->lsdb;
+ break;
+ case OSPF6_SCOPE_AREA:
+ lsdb = OSPF6_AREA (lsa->lsdb->data)->lsdb;
+ break;
+ case OSPF6_SCOPE_AS:
+ lsdb = OSPF6_PROCESS (lsa->lsdb->data)->lsdb;
+ break;
+ default:
+ assert (0);
+ break;
}
-
- return scope;
+ return lsdb;
}
struct ospf6_lsdb *
-ospf6_get_scoped_lsdb (u_int16_t type, void *scope)
+ospf6_get_scoped_lsdb_self (struct ospf6_lsa *lsa)
{
- struct ospf6_lsdb *lsdb = NULL;
+ struct ospf6_lsdb *lsdb_self = NULL;
+ switch (OSPF6_LSA_SCOPE (lsa->header->type))
+ {
+ case OSPF6_SCOPE_LINKLOCAL:
+ lsdb_self = OSPF6_INTERFACE (lsa->lsdb->data)->lsdb_self;
+ break;
+ case OSPF6_SCOPE_AREA:
+ lsdb_self = OSPF6_AREA (lsa->lsdb->data)->lsdb_self;
+ break;
+ case OSPF6_SCOPE_AS:
+ lsdb_self = OSPF6_PROCESS (lsa->lsdb->data)->lsdb_self;
+ break;
+ default:
+ assert (0);
+ break;
+ }
+ return lsdb_self;
+}
+
+void
+ospf6_lsa_originate (struct ospf6_lsa *lsa)
+{
+ struct ospf6_lsa *old;
+ struct ospf6_lsdb *lsdb_self;
- if (scope == NULL)
- return NULL;
+ /* find previous LSA */
+ old = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
+ lsa->header->adv_router, lsa->lsdb);
- switch (OSPF6_LSA_SCOPE (type))
+ /* if the new LSA does not differ from previous,
+ suppress this update of the LSA */
+ if (old && ! OSPF6_LSA_IS_DIFFER (lsa, old))
{
- case OSPF6_LSA_SCOPE_AS:
- lsdb = ((struct ospf6 *)(scope))->lsdb;
- break;
- case OSPF6_LSA_SCOPE_AREA:
- lsdb = ((struct ospf6_area *)(scope))->lsdb;
- break;
- case OSPF6_LSA_SCOPE_LINKLOCAL:
- lsdb = ((struct ospf6_interface *)(scope))->lsdb;
- break;
- default:
- break;
+ if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
+ zlog_info ("Suppress updating LSA: %s", lsa->name);
+ ospf6_lsa_delete (lsa);
+ return;
}
- return lsdb;
-}
+ /* store it in the LSDB for self-originated LSAs */
+ lsdb_self = ospf6_get_scoped_lsdb_self (lsa);
+ ospf6_lsdb_add (ospf6_lsa_copy (lsa), lsdb_self);
-void
-ospf6_decrement_onretrans (struct ospf6_lsa *lsa)
-{
- struct ospf6_lsdb *lsdb;
- struct ospf6_lsa *src;
+ lsa->refresh = thread_add_timer (master, ospf6_lsa_refresh, lsa,
+ LS_REFRESH_TIME);
- lsdb = ospf6_get_scoped_lsdb (lsa->header->type, lsa->scope);
- if (lsdb == NULL)
+ if (IS_OSPF6_DEBUG_LSA (ORIGINATE))
{
- zlog_warn ("Decrement onretrans: no such scope: %s", lsa->name);
- return;
+ zlog_info ("LSA Originate:");
+ ospf6_lsa_header_print (lsa);
}
- src = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
- lsa->header->adv_router, lsdb);
- if (src && src != lsa)
- src->onretrans--;
+ if (old)
+ ospf6_flood_clear (old);
+ ospf6_flood (NULL, lsa);
+ ospf6_install_lsa (lsa);
+}
- if (src->onretrans < 0)
- zlog_warn ("internal error: onretrans");
+void
+ospf6_lsa_originate_process (struct ospf6_lsa *lsa,
+ struct ospf6 *process)
+{
+ lsa->lsdb = process->lsdb;
+ ospf6_lsa_originate (lsa);
}
void
-ospf6_flood_clear (struct ospf6_lsa *lsa)
+ospf6_lsa_originate_area (struct ospf6_lsa *lsa,
+ struct ospf6_area *oa)
{
- struct ospf6_neighbor *on;
- struct ospf6_interface *oi, *ospf6_if = NULL;
- struct ospf6_area *oa, *area = NULL;
- struct ospf6 *ospf6 = NULL;
- u_int16_t scope_type;
- list scoped_interfaces;
- struct ospf6_lsa *rxmt;
- listnode i, j;
+ lsa->lsdb = oa->lsdb;
+ ospf6_lsa_originate (lsa);
+}
+
+void
+ospf6_lsa_originate_interface (struct ospf6_lsa *lsa,
+ struct ospf6_interface *oi)
+{
+ lsa->lsdb = oi->lsdb;
+ ospf6_lsa_originate (lsa);
+}
- scoped_interfaces = list_new ();
- scope_type = OSPF6_LSA_SCOPE (lsa->header->type);
+void
+ospf6_lsa_purge (struct ospf6_lsa *lsa)
+{
+ struct ospf6_lsa *self;
+ struct ospf6_lsdb *lsdb_self;
- if (scope_type == OSPF6_LSA_SCOPE_LINKLOCAL)
- {
- ospf6_if = (struct ospf6_interface *) lsa->scope;
- area = ospf6_if->area;
- ospf6 = area->ospf6;
- }
- else if (scope_type == OSPF6_LSA_SCOPE_AREA)
- {
- area = (struct ospf6_area *) lsa->scope;
- ospf6 = area->ospf6;
- }
- else if (scope_type == OSPF6_LSA_SCOPE_AS)
- {
- ospf6 = (struct ospf6 *) lsa->scope;
- }
- else
+ /* remove it from the LSDB for self-originated LSAs */
+ lsdb_self = ospf6_get_scoped_lsdb_self (lsa);
+ self = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
+ lsa->header->adv_router, lsdb_self);
+ if (self)
{
- zlog_warn ("Can't decide LSA scope, quit ospf6_flood_clear ()");
- return;
+ THREAD_OFF (self->expire);
+ THREAD_OFF (self->refresh);
+ ospf6_lsdb_remove (self, lsdb_self);
}
- /* Collect eligible interfaces */
- for (i = listhead (ospf6->area_list); i; nextnode (i))
- {
- oa = (struct ospf6_area *) getdata (i);
- if (scope_type != OSPF6_LSA_SCOPE_AS && oa != area)
- continue;
+ ospf6_lsa_premature_aging (lsa);
+}
- for (j = listhead (oa->if_list); j; nextnode (j))
- {
- oi = (struct ospf6_interface *) getdata (j);
- if (scope_type != OSPF6_LSA_SCOPE_AS &&
- scope_type != OSPF6_LSA_SCOPE_AREA && oi != ospf6_if)
- continue;
- listnode_add (scoped_interfaces, oi);
- }
- }
+void
+ospf6_increment_retrans_count (struct ospf6_lsa *lsa)
+{
+ /* The LSA must be the original one (see the description
+ in ospf6_decrement_retrans_count () below) */
+ lsa->retrans_count++;
+}
- for (i = listhead (scoped_interfaces); i; nextnode (i))
- {
- oi = (struct ospf6_interface *) getdata (i);
- for (j = listhead (oi->neighbor_list); j; nextnode (j))
- {
- on = (struct ospf6_neighbor *) getdata (j);
- rxmt = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
- lsa->header->adv_router, on->retrans_list);
- if (rxmt && ! ospf6_lsa_compare (rxmt, lsa))
- {
- if (IS_OSPF6_DEBUG_LSA (DATABASE))
- zlog_info ("Remove %s from retrans_list of %s",
- rxmt->name, on->name);
- ospf6_decrement_onretrans (rxmt);
- ospf6_lsdb_remove (rxmt, on->retrans_list);
- }
- }
- }
+void
+ospf6_decrement_retrans_count (struct ospf6_lsa *lsa)
+{
+ struct ospf6_lsdb *lsdb;
+ struct ospf6_lsa *orig;
+
+ /* The LSA must be on the retrans-list of a neighbor. It means
+ the "lsa" is a copied one, and we have to decrement the
+ retransmission count of the original one (instead of "lsa"'s).
+ In order to find the original LSA, first we have to find
+ appropriate LSDB that have the original LSA. */
+ lsdb = ospf6_get_scoped_lsdb (lsa);
+
+ /* Find the original LSA of which the retrans_count should be decremented */
+ orig = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
+ lsa->header->adv_router, lsdb);
+ if (orig)
+ orig->retrans_count--;
- list_delete (scoped_interfaces);
+ assert (orig->retrans_count >= 0);
}
/* RFC2328 section 13.2 Installing LSAs in the database */
void
-ospf6_install_lsa (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
+ospf6_install_lsa (struct ospf6_lsa *lsa)
{
struct ospf6_lsa *old;
@@ -202,185 +211,299 @@ ospf6_install_lsa (struct ospf6_lsa *lsa, struct ospf6_lsdb *lsdb)
/* Remove the old instance from all neighbors' Link state
retransmission list (RFC2328 13.2 last paragraph) */
old = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
- lsa->header->adv_router, lsdb);
+ lsa->header->adv_router, lsa->lsdb);
if (old)
ospf6_flood_clear (old);
/* actually install */
gettimeofday (&lsa->installed, (struct timezone *) NULL);
- ospf6_lsdb_add (lsa, lsdb);
+ ospf6_lsdb_add (lsa, lsa->lsdb);
return;
}
+/* RFC2740 section 3.5.2. Sending Link State Update packets */
/* RFC2328 section 13.3 Next step in the flooding procedure */
void
-ospf6_flood_lsa (struct ospf6_lsa *lsa, struct ospf6_neighbor *from)
+ospf6_flood_interface (struct ospf6_neighbor *from,
+ struct ospf6_lsa *lsa, struct ospf6_interface *oi)
{
- struct ospf6 *scope_as = NULL;
- struct ospf6_area *oa, *scope_area = NULL;
- struct ospf6_interface *oi, *scope_linklocal = NULL;
+ listnode node;
struct ospf6_neighbor *on;
- list eligible_interfaces;
- listnode i, j;
- u_int16_t scope_type;
struct ospf6_lsa *req;
int retrans_added = 0;
- scope_type = OSPF6_LSA_SCOPE (lsa->header->type);
- switch (scope_type)
- {
- case OSPF6_LSA_SCOPE_AS:
- scope_as = (struct ospf6 *) lsa->scope;
- break;
- case OSPF6_LSA_SCOPE_AREA:
- scope_as = ((struct ospf6_area *) lsa->scope)->ospf6;
- scope_area = (struct ospf6_area *) lsa->scope;
- break;
- case OSPF6_LSA_SCOPE_LINKLOCAL:
- scope_as = ((struct ospf6_interface *) lsa->scope)->area->ospf6;
- scope_area = ((struct ospf6_interface *) lsa->scope)->area;
- scope_linklocal = (struct ospf6_interface *) lsa->scope;
- break;
- default:
- if (IS_OSPF6_DEBUG_LSA (SEND))
- zlog_info ("Can't decide LSA scope");
- return;
- }
-
if (IS_OSPF6_DEBUG_LSA (SEND))
- zlog_info ("Flood %s", lsa->name);
+ zlog_info ("Flooding on %s: %s", oi->interface->name, lsa->name);
- /* Collect eligible interfaces */
- eligible_interfaces = list_new ();
- for (i = listhead (scope_as->area_list); i; nextnode (i))
+ /* (1) For each neighbor */
+ for (node = listhead (oi->neighbor_list); node; nextnode (node))
{
- oa = (struct ospf6_area *) getdata (i);
- if (scope_type != OSPF6_LSA_SCOPE_AS &&
- oa != scope_area)
- continue;
+ on = (struct ospf6_neighbor *) getdata (node);
- for (j = listhead (oa->if_list); j; nextnode (j))
- {
- oi = (struct ospf6_interface *) getdata (j);
- if (scope_type != OSPF6_LSA_SCOPE_AS &&
- scope_type != OSPF6_LSA_SCOPE_AREA &&
- oi != scope_linklocal)
- continue;
+ if (IS_OSPF6_DEBUG_LSA (SEND))
+ zlog_info ("To neighbor %s", on->name);
- listnode_add (eligible_interfaces, oi);
+ /* (a) if neighbor state < Exchange, examin next */
+ if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
+ {
+ if (IS_OSPF6_DEBUG_LSA (SEND))
+ zlog_info ("Neighbor state less than ExChange, next neighbor");
+ continue;
}
- }
- /* For each eligible interface: */
- for (i = listhead (eligible_interfaces); i; nextnode (i))
- {
- oi = (struct ospf6_interface *) getdata (i);
-
- /* (1) For each neighbor */
- for (j = listhead (oi->neighbor_list); j; nextnode (j))
+ /* (b) if neighbor not yet Full, check request-list */
+ if (on->state != OSPF6_NEIGHBOR_FULL)
{
- on = (struct ospf6_neighbor *) getdata (j);
+ if (IS_OSPF6_DEBUG_LSA (SEND))
+ zlog_info ("Neighbor not yet Full");
- /* (a) if neighbor state < Exchange, examin next */
- if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
- continue;
-
- /* (b) if neighbor not yet Full, check request-list */
- if (on->state != OSPF6_NEIGHBOR_FULL)
+ req = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
+ lsa->header->adv_router, on->request_list);
+ if (req == NULL)
{
- req = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
- lsa->header->adv_router,
- on->request_list);
- if (req)
+ if (IS_OSPF6_DEBUG_LSA (SEND))
+ zlog_info ("Not on request-list for this neighbor");
+ /* fall through */
+ }
+ else
+ {
+ /* If new LSA less recent, examin next neighbor */
+ if (ospf6_lsa_compare (lsa, req) > 0)
+ {
+ if (IS_OSPF6_DEBUG_LSA (SEND))
+ zlog_info ("Requesting is newer, next neighbor");
+ continue;
+ }
+
+ /* If the same instance, delete from request-list and
+ examin next neighbor */
+ if (ospf6_lsa_compare (lsa, req) == 0)
{
- /* If new LSA less recent, examin next neighbor */
- if (ospf6_lsa_compare (lsa, req) > 0)
- continue;
-
- /* If the same instance, delete from request-list and
- examin next neighbor */
- if (ospf6_lsa_compare (lsa, req) == 0)
- {
- if (IS_OSPF6_DEBUG_LSA (SEND) || IS_OSPF6_DEBUG_LSA (DATABASE))
- zlog_info ("Remove %s from request-list of %s: "
- "the same instance", req->name, on->name);
- ospf6_lsdb_remove (req, on->request_list);
- continue;
- }
-
- /* If the new LSA is more recent, delete from
- request-list */
- if (ospf6_lsa_compare (lsa, req) < 0)
- {
- if (IS_OSPF6_DEBUG_LSA (SEND) || IS_OSPF6_DEBUG_LSA (DATABASE))
- zlog_info ("Remove %s from request-list of %s: "
- "newer instance", req->name, on->name);
- ospf6_lsdb_remove (req, on->request_list);
- /* fall through */
- }
+ if (IS_OSPF6_DEBUG_LSA (SEND))
+ zlog_info ("Requesting the same, remove it, next neighbor");
+ ospf6_lsdb_remove (req, on->request_list);
+ continue;
+ }
+
+ /* If the new LSA is more recent, delete from request-list */
+ if (ospf6_lsa_compare (lsa, req) < 0)
+ {
+ if (IS_OSPF6_DEBUG_LSA (SEND))
+ zlog_info ("Received is newer, remove requesting");
+ ospf6_lsdb_remove (req, on->request_list);
+ /* fall through */
}
}
+ }
- /* (c) If the new LSA was received from this neighbor,
- examin next neighbor */
- if (from == on)
- continue;
-
- /* (d) add retrans-list, schedule retransmission */
- if (IS_OSPF6_DEBUG_LSA (SEND) || IS_OSPF6_DEBUG_LSA (DATABASE))
- zlog_info (" Add copy of %s to retrans-list of %s",
- lsa->name, on->name);
- lsa->onretrans++;
- ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
- if (on->thread_send_lsupdate == NULL)
- on->thread_send_lsupdate =
- thread_add_event (master, ospf6_lsupdate_send_neighbor,
- on, on->ospf6_if->rxmt_interval);
- retrans_added++;
+ /* (c) If the new LSA was received from this neighbor,
+ examin next neighbor */
+ if (from == on)
+ {
+ if (IS_OSPF6_DEBUG_LSA (SEND))
+ zlog_info ("Received is from the neighbor, next neighbor");
+ continue;
}
- /* (2) examin next interface if not added to retrans-list */
- if (retrans_added == 0)
+ /* (d) add retrans-list, schedule retransmission */
+ if (IS_OSPF6_DEBUG_LSA (SEND))
+ zlog_info ("Add retrans-list of this neighbor");
+ ospf6_increment_retrans_count (lsa);
+ ospf6_lsdb_add (ospf6_lsa_copy (lsa), on->retrans_list);
+ if (on->thread_send_lsupdate == NULL)
+ on->thread_send_lsupdate =
+ thread_add_event (master, ospf6_lsupdate_send_neighbor,
+ on, on->ospf6_if->rxmt_interval);
+ retrans_added++;
+ }
+
+ /* (2) examin next interface if not added to retrans-list */
+ if (retrans_added == 0)
+ {
+ if (IS_OSPF6_DEBUG_LSA (SEND))
+ zlog_info ("No retransmission scheduled, next interface");
+ return;
+ }
+
+ /* (3) If the new LSA was received on this interface,
+ and it was from DR or BDR, examin next interface */
+ if (from && from->ospf6_if == oi &&
+ (from->router_id == oi->drouter || from->router_id == oi->bdrouter))
+ {
+ if (IS_OSPF6_DEBUG_LSA (SEND))
+ zlog_info ("Received is from the I/F's DR or BDR, next interface");
+ return;
+ }
+
+ /* (4) If the new LSA was received on this interface,
+ and the interface state is BDR, examin next interface */
+ if (from && from->ospf6_if == oi && oi->state == OSPF6_INTERFACE_BDR)
+ {
+ if (IS_OSPF6_DEBUG_LSA (SEND))
+ zlog_info ("Received is from the I/F, itself BDR, next interface");
+ return;
+ }
+
+ /* (5) flood the LSA out the interface. */
+ if (IS_OSPF6_DEBUG_LSA (SEND))
+ zlog_info ("Schedule flooding for the interface");
+ if (if_is_broadcast (oi->interface))
+ {
+ ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list);
+ if (oi->thread_send_lsupdate == NULL)
+ oi->thread_send_lsupdate =
+ thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
+ }
+ else
+ {
+ /* reschedule retransmissions to all neighbors */
+ for (node = listhead (oi->neighbor_list); node; nextnode (node))
+ {
+ on = (struct ospf6_neighbor *) getdata (node);
+ THREAD_OFF (on->thread_send_lsupdate);
+ on->thread_send_lsupdate =
+ thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
+ }
+ }
+}
+
+void
+ospf6_flood_area (struct ospf6_neighbor *from,
+ struct ospf6_lsa *lsa, struct ospf6_area *oa)
+{
+ listnode node;
+ struct ospf6_interface *oi;
+
+ for (node = listhead (oa->if_list); node; nextnode (node))
+ {
+ oi = OSPF6_INTERFACE (getdata (node));
+
+ if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
+ oi != OSPF6_INTERFACE (lsa->lsdb->data))
continue;
- /* (3) If the new LSA was received on this interface,
- and it was from DR or BDR, examin next interface */
- if (from && from->ospf6_if == oi &&
- (from->router_id == oi->drouter || from->router_id == oi->bdrouter))
+#if 0
+ if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
+ ospf6_is_interface_virtual_link (oi))
continue;
+#endif/*0*/
+
+ ospf6_flood_interface (from, lsa, oi);
+ }
+}
+
+void
+ospf6_flood_process (struct ospf6_neighbor *from,
+ struct ospf6_lsa *lsa, struct ospf6 *process)
+{
+ listnode node;
+ struct ospf6_area *oa;
- /* (4) If the new LSA was received on this interface,
- and the interface state is BDR, examin next interface */
- if (from && from->ospf6_if == oi && oi->state == OSPF6_INTERFACE_BDR)
+ for (node = listhead (process->area_list); node; nextnode (node))
+ {
+ oa = OSPF6_AREA (getdata (node));
+
+ if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
+ oa != OSPF6_AREA (lsa->lsdb->data))
+ continue;
+ if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
+ oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
continue;
- /* (5) flood the LSA out the interface. */
- if (if_is_broadcast (oi->interface))
- {
- if (IS_OSPF6_DEBUG_LSA (SEND) || IS_OSPF6_DEBUG_LSA (DATABASE))
- zlog_info (" Add copy of %s to lsupdate_list of %s",
- lsa->name, oi->interface->name);
- ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list);
- if (oi->thread_send_lsupdate == NULL)
- oi->thread_send_lsupdate =
- thread_add_event (master, ospf6_lsupdate_send_interface, oi, 0);
- }
- else
+ if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
+ IS_AREA_STUB (oa))
+ continue;
+
+ ospf6_flood_area (from, lsa, oa);
+ }
+}
+
+void
+ospf6_flood (struct ospf6_neighbor *from, struct ospf6_lsa *lsa)
+{
+ ospf6_flood_process (from, lsa, ospf6);
+}
+
+void
+ospf6_flood_clear_interface (struct ospf6_lsa *lsa, struct ospf6_interface *oi)
+{
+ listnode node;
+ struct ospf6_neighbor *on;
+ struct ospf6_lsa *rem;
+
+ for (node = listhead (oi->neighbor_list); node; nextnode (node))
+ {
+ on = OSPF6_NEIGHBOR (getdata (node));
+ rem = ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
+ lsa->header->adv_router, on->retrans_list);
+ if (rem && ! ospf6_lsa_compare (rem, lsa))
{
- for (j = listhead (oi->neighbor_list); j; nextnode (j))
- {
- on = (struct ospf6_neighbor *) getdata (j);
- THREAD_OFF (on->thread_send_lsupdate);
- on->thread_send_lsupdate =
- thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
- }
+ if (IS_OSPF6_DEBUG_LSA (DATABASE))
+ zlog_info ("Remove %s from retrans_list of %s",
+ rem->name, on->name);
+ ospf6_decrement_retrans_count (rem);
+ ospf6_lsdb_remove (rem, on->retrans_list);
}
}
+}
+
+void
+ospf6_flood_clear_area (struct ospf6_lsa *lsa, struct ospf6_area *oa)
+{
+ listnode node;
+ struct ospf6_interface *oi;
+
+ for (node = listhead (oa->if_list); node; nextnode (node))
+ {
+ oi = OSPF6_INTERFACE (getdata (node));
- list_delete (eligible_interfaces);
+ if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
+ oi != OSPF6_INTERFACE (lsa->lsdb->data))
+ continue;
+
+#if 0
+ if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AS &&
+ ospf6_is_interface_virtual_link (oi))
+ continue;
+#endif/*0*/
+
+ ospf6_flood_clear_interface (lsa, oi);
+ }
+}
+
+void
+ospf6_flood_clear_process (struct ospf6_lsa *lsa, struct ospf6 *process)
+{
+ listnode node;
+ struct ospf6_area *oa;
+
+ for (node = listhead (process->area_list); node; nextnode (node))
+ {
+ oa = OSPF6_AREA (getdata (node));
+
+ if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_AREA &&
+ oa != OSPF6_AREA (lsa->lsdb->data))
+ continue;
+ if (OSPF6_LSA_SCOPE (lsa->header->type) == OSPF6_SCOPE_LINKLOCAL &&
+ oa != OSPF6_INTERFACE (lsa->lsdb->data)->area)
+ continue;
+
+ if (ntohs (lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
+ IS_AREA_STUB (oa))
+ continue;
+
+ ospf6_flood_clear_area (lsa, oa);
+ }
+}
+
+void
+ospf6_flood_clear (struct ospf6_lsa *lsa)
+{
+ ospf6_flood_clear_process (lsa, ospf6);
}
+
/* RFC2328 13.5 (Table 19): Sending link state acknowledgements. */
static void
ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
@@ -396,7 +519,7 @@ ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
{
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info (" BDR, FloodBack, No acknowledgement.");
+ zlog_info ("No acknowledgement (BDR & FloodBack)");
return;
}
@@ -406,16 +529,11 @@ ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
otherwide do nothing. */
if (ismore_recent < 0)
{
- if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info (" BDR, Not FloodBack, MoreRecent, ");
if (oi->drouter == from->router_id)
{
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info (" From DR, Delayed acknowledgement.");
+ zlog_info ("Delayed acknowledgement (BDR & MoreRecent & from DR)");
/* Delayed acknowledgement */
- if (IS_OSPF6_DEBUG_LSA (DATABASE))
- zlog_info (" Add copy of %s to lsack_list of %s",
- lsa->name, oi->interface->name);
ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
if (oi->thread_send_lsack == NULL)
oi->thread_send_lsack =
@@ -424,7 +542,7 @@ ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
else
{
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info (" Not From DR, No acknowledgement.");
+ zlog_info ("No acknowledgement (BDR & MoreRecent & ! from DR)");
}
return;
}
@@ -435,16 +553,11 @@ ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
if (CHECK_FLAG (lsa->flag, OSPF6_LSA_DUPLICATE) &&
CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
{
- if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info (" BDR, Duplicate, ImpliedAck, ");
if (oi->drouter == from->router_id)
{
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info (" From DR, Delayed acknowledgement.");
+ zlog_info ("Delayed acknowledgement (BDR & Duplicate & ImpliedAck & from DR)");
/* Delayed acknowledgement */
- if (IS_OSPF6_DEBUG_LSA (DATABASE))
- zlog_info (" Add copy of %s to lsack_list of %s",
- lsa->name, oi->interface->name);
ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
if (oi->thread_send_lsack == NULL)
oi->thread_send_lsack =
@@ -453,7 +566,7 @@ ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
else
{
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info (" Not From DR, No acknowledgement.");
+ zlog_info ("No acknowledgement (BDR & Duplicate & ImpliedAck & ! from DR)");
}
return;
}
@@ -464,10 +577,7 @@ ospf6_acknowledge_lsa_bdrouter (struct ospf6_lsa *lsa, int ismore_recent,
! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
{
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info (" BDR, Duplicate, Not ImpliedAck, Direct acknowledgement.");
- if (IS_OSPF6_DEBUG_LSA (DATABASE))
- zlog_info (" Add copy of %s to lsack_list of %s",
- lsa->name, from->name);
+ zlog_info ("Direct acknowledgement (BDR & Duplicate)");
ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
if (from->thread_send_lsack == NULL)
from->thread_send_lsack =
@@ -496,7 +606,7 @@ ospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent,
if (CHECK_FLAG (lsa->flag, OSPF6_LSA_FLOODBACK))
{
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info (" AllOther, FloodBack, No acknowledgement.");
+ zlog_info ("No acknowledgement (AllOther & FloodBack)");
return;
}
@@ -505,11 +615,8 @@ ospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent,
if (ismore_recent < 0)
{
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info (" AllOther, Not FloodBack, Delayed acknowledgement.");
+ zlog_info ("Delayed acknowledgement (AllOther & MoreRecent)");
/* Delayed acknowledgement */
- if (IS_OSPF6_DEBUG_LSA (DATABASE))
- zlog_info (" Add copy of %s to lsack_list of %s",
- lsa->name, oi->interface->name);
ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsack_list);
if (oi->thread_send_lsack == NULL)
oi->thread_send_lsack =
@@ -523,7 +630,7 @@ ospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent,
CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
{
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info (" AllOther, Duplicate, ImpliedAck, No acknowledgement.");
+ zlog_info ("No acknowledgement (AllOther & Duplicate & ImpliedAck)");
return;
}
@@ -533,10 +640,7 @@ ospf6_acknowledge_lsa_allother (struct ospf6_lsa *lsa, int ismore_recent,
! CHECK_FLAG (lsa->flag, OSPF6_LSA_IMPLIEDACK))
{
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info (" AllOther, Duplicate, Not ImpliedAck, Direct acknowledgement.");
- if (IS_OSPF6_DEBUG_LSA (DATABASE))
- zlog_info (" Add copy of %s to lsack_list of %s",
- lsa->name, from->name);
+ zlog_info ("Direct acknowledgement (AllOther & Duplicate)");
ospf6_lsdb_add (ospf6_lsa_copy (lsa), from->lsack_list);
if (from->thread_send_lsack == NULL)
from->thread_send_lsack =
@@ -571,106 +675,55 @@ ospf6_acknowledge_lsa (struct ospf6_lsa *lsa, int ismore_recent,
is in states Exchange or Loading
returns 1 if match this case, else returns 0 */
static int
-ospf6_is_maxage_lsa_drop (struct ospf6_lsa *lsa,
- struct ospf6_neighbor *from)
+ospf6_is_maxage_lsa_drop (struct ospf6_lsa *lsa, struct ospf6_neighbor *from)
{
- struct ospf6_lsdb *lsdb = NULL;
struct ospf6_neighbor *on;
- struct ospf6_interface *oi, *ospf6_if = NULL;
- struct ospf6_area *oa, *area = NULL;
- struct ospf6 *ospf6 = NULL;
- u_int16_t scope_type;
- list scoped_interfaces;
- listnode i, j;
+ struct ospf6_interface *oi;
+ struct ospf6_area *oa;
+ struct ospf6 *process = NULL;
+ listnode i, j, k;
int count = 0;
if (! OSPF6_LSA_IS_MAXAGE (lsa))
return 0;
- lsdb = ospf6_get_scoped_lsdb (lsa->header->type, lsa->scope);
- if (lsdb == NULL)
- {
- zlog_info ("Can't decide scoped LSDB");
- return 0;
- }
-
if (ospf6_lsdb_lookup (lsa->header->type, lsa->header->id,
- lsa->header->adv_router, lsdb))
+ lsa->header->adv_router, lsa->lsdb))
return 0;
- scoped_interfaces = list_new ();
- scope_type = OSPF6_LSA_SCOPE (lsa->header->type);
-
- if (scope_type == OSPF6_LSA_SCOPE_LINKLOCAL)
- {
- ospf6_if = (struct ospf6_interface *) lsa->scope;
- area = ospf6_if->area;
- ospf6 = area->ospf6;
- }
- else if (scope_type == OSPF6_LSA_SCOPE_AREA)
- {
- area = (struct ospf6_area *) lsa->scope;
- ospf6 = area->ospf6;
- }
- else if (scope_type == OSPF6_LSA_SCOPE_AS)
- {
- ospf6 = (struct ospf6 *) lsa->scope;
- }
- else
- {
- zlog_info ("Can't decide LSA scope");
- return 0;
- }
-
- /* Collect eligible interfaces */
- for (i = listhead (ospf6->area_list); i; nextnode (i))
+ process = from->ospf6_if->area->ospf6;
+ for (i = listhead (process->area_list); i; nextnode (i))
{
- oa = (struct ospf6_area *) getdata (i);
- if (scope_type != OSPF6_LSA_SCOPE_AS && oa != area)
- continue;
-
+ oa = OSPF6_AREA (getdata (i));
for (j = listhead (oa->if_list); j; nextnode (j))
{
- oi = (struct ospf6_interface *) getdata (j);
- if (scope_type != OSPF6_LSA_SCOPE_AS &&
- scope_type != OSPF6_LSA_SCOPE_AREA && oi != ospf6_if)
- continue;
-
- listnode_add (scoped_interfaces, oi);
- }
- }
-
- for (i = listhead (scoped_interfaces); i; nextnode (i))
- {
- oi = (struct ospf6_interface *) getdata (i);
- for (j = listhead (oi->neighbor_list); j; nextnode (j))
- {
- on = (struct ospf6_neighbor *) getdata (j);
- if (on->state == OSPF6_NEIGHBOR_EXCHANGE ||
- on->state == OSPF6_NEIGHBOR_LOADING)
- count ++;
+ oi = OSPF6_INTERFACE (getdata (j));
+ for (k = listhead (oi->neighbor_list); k; nextnode (k))
+ {
+ on = OSPF6_NEIGHBOR (getdata (k));
+ if (on->state == OSPF6_NEIGHBOR_EXCHANGE ||
+ on->state == OSPF6_NEIGHBOR_LOADING)
+ count++;
+ }
}
}
- list_delete (scoped_interfaces);
-
if (count == 0)
return 1;
-
return 0;
}
/* RFC2328 section 13 The Flooding Procedure */
void
-ospf6_receive_lsa (struct ospf6_lsa_header *lsa_header,
- struct ospf6_neighbor *from)
+ospf6_receive_lsa (struct ospf6_neighbor *from,
+ struct ospf6_lsa_header *lsa_header)
{
struct ospf6_lsa *new = NULL, *old = NULL, *rem = NULL;
int ismore_recent;
unsigned short cksum;
- struct ospf6_lsdb *lsdb = NULL;
ismore_recent = 1;
+ assert (from);
/* make lsa structure for received lsa */
new = ospf6_lsa_create (lsa_header);
@@ -681,30 +734,45 @@ ospf6_receive_lsa (struct ospf6_lsa_header *lsa_header,
ospf6_lsa_header_print (new);
}
- new->scope = ospf6_get_lsa_scope (new->header->type, from);
- if (new->scope == NULL)
+ /* (1) LSA Checksum */
+ cksum = ntohs (new->header->checksum);
+ if (ntohs (ospf6_lsa_checksum (new->header)) != cksum)
{
- zlog_warn ("Can't decide LSA scope, ignore");
+ if (IS_OSPF6_DEBUG_LSA (RECV))
+ zlog_info ("Wrong LSA Checksum, discard");
ospf6_lsa_delete (new);
return;
}
- /* (1) LSA Checksum */
- cksum = ntohs (new->header->checksum);
- if (ntohs (ospf6_lsa_checksum (new->header)) != cksum)
+ /* (2) Examine the LSA's LS type.
+ RFC2470 3.5.1. Receiving Link State Update packets */
+ if (IS_AREA_STUB (from->ospf6_if->area) &&
+ OSPF6_LSA_SCOPE (new->header->type) == OSPF6_SCOPE_AS)
{
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info ("Wrong LSA Checksum");
+ zlog_info ("AS-External-LSA (or AS-scope LSA) in stub area, discard");
ospf6_lsa_delete (new);
return;
}
- /* (3) Ebit Missmatch: AS-External-LSA */
- if (ntohs (new->header->type) == OSPF6_LSTYPE_AS_EXTERNAL &&
- ospf6_area_is_stub (from->ospf6_if->area))
- {
+ /* (3) LSA which have reserved scope is discarded
+ RFC2470 3.5.1. Receiving Link State Update packets */
+ /* Flooding scope check. LSAs with unknown scope are discarded here.
+ Set appropriate LSDB for the LSA */
+ switch (OSPF6_LSA_SCOPE (new->header->type))
+ {
+ case OSPF6_SCOPE_LINKLOCAL:
+ new->lsdb = from->ospf6_if->lsdb;
+ break;
+ case OSPF6_SCOPE_AREA:
+ new->lsdb = from->ospf6_if->area->lsdb;
+ break;
+ case OSPF6_SCOPE_AS:
+ new->lsdb = from->ospf6_if->area->ospf6->lsdb;
+ break;
+ default:
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info ("AS-External-LSA in stub area");
+ zlog_info ("LSA has reserved scope, discard");
ospf6_lsa_delete (new);
return;
}
@@ -715,41 +783,30 @@ ospf6_receive_lsa (struct ospf6_lsa_header *lsa_header,
{
/* log */
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info ("Drop MaxAge LSA with Direct acknowledgement.");
+ zlog_info ("Drop MaxAge LSA with direct acknowledgement.");
/* a) Acknowledge back to neighbor (Direct acknowledgement, 13.5) */
- if (IS_OSPF6_DEBUG_LSA (DATABASE))
- zlog_info (" Add %s to lsack_list of %s",
- new->name, from->name);
- ospf6_lsdb_add (new, from->lsack_list);
+ ospf6_lsdb_add (ospf6_lsa_copy (new), from->lsack_list);
if (from->thread_send_lsack == NULL)
from->thread_send_lsack =
thread_add_event (master, ospf6_lsack_send_neighbor, from, 0);
/* b) Discard */
- /* "new" LSA will be discarded just after the LSAck sent */
+ ospf6_lsa_delete (new);
return;
}
/* (5) */
/* lookup the same database copy in lsdb */
- lsdb = ospf6_get_scoped_lsdb (new->header->type, new->scope);
- if (lsdb == NULL)
- {
- zlog_warn ("Can't decide scoped LSDB, ignore");
- ospf6_lsa_delete (new);
- return;
- }
-
old = ospf6_lsdb_lookup (new->header->type, new->header->id,
- new->header->adv_router, lsdb);
+ new->header->adv_router, new->lsdb);
if (old)
{
ismore_recent = ospf6_lsa_compare (new, old);
if (ntohl (new->header->seqnum) == ntohl (old->header->seqnum))
{
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info ("Duplicated LSA");
+ zlog_info ("Received is duplicated LSA");
SET_FLAG (new->flag, OSPF6_LSA_DUPLICATE);
}
}
@@ -769,35 +826,43 @@ ospf6_receive_lsa (struct ospf6_lsa_header *lsa_header,
if (res.tv_sec < MIN_LS_ARRIVAL)
{
if (IS_OSPF6_DEBUG_LSA (RECV) || IS_OSPF6_DEBUG_LSA (TIMER))
- zlog_info ("LSA can't be updated within MinLSArrival");
+ zlog_info ("LSA can't be updated within MinLSArrival, discard");
ospf6_lsa_delete (new);
return; /* examin next lsa */
}
}
+ if (IS_OSPF6_DEBUG_LSA (RECV))
+ zlog_info ("Flood, Install, Possibly acknowledge the received LSA");
+
/* (b) immediately flood and (c) remove from all retrans-list */
- ospf6_flood_lsa (new, from);
+ ospf6_flood (from, new);
+
+ /* (c) Remove the current database copy from all neighbors' Link
+ state retransmission lists. */
+ /* XXX, flood_clear ? */
/* (d), installing lsdb, which may cause routing
table calculation (replacing database copy) */
- ospf6_install_lsa (new, lsdb);
+ ospf6_install_lsa (new);
/* (e) possibly acknowledge */
ospf6_acknowledge_lsa (new, ismore_recent, from);
- /* (f) */
- /* Self Originated LSA, section 13.4 */
- if (new->header->adv_router == from->ospf6_if->area->ospf6->router_id
- && (! old || ismore_recent < 0))
+ /* (f) Self Originated LSA, section 13.4 */
+ if (new->header->adv_router == from->ospf6_if->area->ospf6->router_id)
{
- /* We have to make a new instance of the LSA
+ /* Self-originated LSA (newer than ours) is received from
+ another router. We have to make a new instance of the LSA
or have to flush this LSA. */
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info ("New instance of the self-originated LSA");
-
- SET_FLAG (new->flag, OSPF6_LSA_REFRESH);
- ospf6_lsa_re_originate (new);
+ {
+ zlog_info ("Newer instance of the self-originated LSA");
+ zlog_info ("Schedule reorigination");
+ }
+ new->refresh = thread_add_event (master, ospf6_lsa_refresh, new, 0);
}
+
return;
}
@@ -809,7 +874,10 @@ ospf6_receive_lsa (struct ospf6_lsa_header *lsa_header,
assert (old);
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info ("LSA is not newer and on request-list of sending neighbor");
+ {
+ zlog_info ("Received is not newer, on the neighbor's request-list");
+ zlog_info ("BadLSReq, discard the received LSA");
+ }
/* BadLSReq */
thread_add_event (master, bad_lsreq, from, 0);
@@ -822,7 +890,7 @@ ospf6_receive_lsa (struct ospf6_lsa_header *lsa_header,
if (ismore_recent == 0)
{
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info ("The same instance as database copy");
+ zlog_info ("The same instance as database copy (neither recent)");
/* (a) if on retrans-list, Treat this LSA as an Ack: Implied Ack */
rem = ospf6_lsdb_lookup (new->header->type, new->header->id,
@@ -830,15 +898,18 @@ ospf6_receive_lsa (struct ospf6_lsa_header *lsa_header,
if (rem)
{
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info ("Treat as an Implied acknowledgement");
+ {
+ zlog_info ("It is on the neighbor's retrans-list.");
+ zlog_info ("Treat as an Implied acknowledgement");
+ }
SET_FLAG (new->flag, OSPF6_LSA_IMPLIEDACK);
- if (IS_OSPF6_DEBUG_LSA (DATABASE))
- zlog_info ("Remove %s from retrans_list of %s",
- rem->name, from->name);
- ospf6_decrement_onretrans (rem);
+ ospf6_decrement_retrans_count (rem);
ospf6_lsdb_remove (rem, from->retrans_list);
}
+ if (IS_OSPF6_DEBUG_LSA (RECV))
+ zlog_info ("Possibly acknowledge and then discard");
+
/* (b) possibly acknowledge */
ospf6_acknowledge_lsa (new, ismore_recent, from);
@@ -856,7 +927,10 @@ ospf6_receive_lsa (struct ospf6_lsa_header *lsa_header,
old->header->seqnum == htonl (MAX_SEQUENCE_NUMBER))
{
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info ("Database copy is in Seqnumber Wrapping");
+ {
+ zlog_info ("The LSA is in Seqnumber Wrapping");
+ zlog_info ("MaxAge & MaxSeqNum, discard");
+ }
ospf6_lsa_delete (new);
return;
}
@@ -864,13 +938,13 @@ ospf6_receive_lsa (struct ospf6_lsa_header *lsa_header,
/* Otherwise, Send database copy of this LSA to this neighbor */
{
if (IS_OSPF6_DEBUG_LSA (RECV))
- zlog_info ("Database is more recent, send back directly");
+ {
+ zlog_info ("Database copy is more recent.");
+ zlog_info ("Send back directly and then discard");
+ }
/* XXX, MinLSArrival check !? RFC 2328 13 (8) */
- if (IS_OSPF6_DEBUG_LSA (DATABASE))
- zlog_info (" Add copy of %s to lsupdate_list of %s",
- old->name, from->name);
ospf6_lsdb_add (ospf6_lsa_copy (old), from->lsupdate_list);
if (from->thread_send_lsupdate == NULL)
from->thread_send_lsupdate =