Properly handle the lifecycle of router addresses that may have associated incoming links.
@@ -273,12 +273,7 @@ static void qdr_add_router_CT(qdr_core_t *core, qdr_action_t *action, bool disca
qd_iterator_reset_view(iter, ITER_VIEW_ADDRESS_HASH);
qd_hash_retrieve(core->addr_hash, iter, (void**) &addr);
- if (addr) {
- qd_log(core->log, QD_LOG_CRITICAL, "add_router: Data inconsistency for router-maskbit %d", router_maskbit);
- assert(addr == 0); // Crash in debug mode. This should never happen
- break;
- }
-
+ if (!addr) {
//
// Create an address record for this router and insert it in the hash table.
// This record will be found whenever a "foreign" topological address to this
@@ -287,6 +282,13 @@ static void qdr_add_router_CT(qdr_core_t *core, qdr_action_t *action, bool disca
addr = qdr_address_CT(core, QD_TREATMENT_ANYCAST_CLOSEST);
qd_hash_insert(core->addr_hash, iter, addr, &addr->hash_handle);
DEQ_INSERT_TAIL(core->addrs, addr);
+ }
+
+ //
+ // Set the block-deletion flag on this address for the time that it is associated
+ // with an existing remote router node.
+ //
+ addr->block_deletion = true;
//
// Create a router-node record to represent the remote router.
@@ -378,10 +380,15 @@ static void qdr_del_router_CT(qdr_core_t *core, qdr_action_t *action, bool disca
assert(rnode->ref_count == 0);
//
- // Free the router node and the owning address records.
+ // Free the router node.
//
qdr_router_node_free(core, rnode);
- qdr_core_remove_address(core, oaddr);
+
+ //
+ // Check the address and free it if there are no other interested parties tracking it
+ //
+ oaddr->block_deletion = false;
+ qdr_check_addr_CT(core, oaddr, false);
}
@@ -415,6 +422,7 @@ static void qdr_set_link_CT(qdr_core_t *core, qdr_action_t *action, bool discard
//
qdr_node_t *rnode = core->routers_by_mask_bit[router_maskbit];
rnode->link_mask_bit = link_maskbit;
+ qdr_addr_start_inlinks_CT(core, rnode->owning_addr);
}
@@ -465,6 +473,7 @@ static void qdr_set_next_hop_CT(qdr_core_t *core, qdr_action_t *action, bool dis
if (router_maskbit != nh_router_maskbit) {
qdr_node_t *rnode = core->routers_by_mask_bit[router_maskbit];
rnode->next_hop = core->routers_by_mask_bit[nh_router_maskbit];
+ qdr_addr_start_inlinks_CT(core, rnode->owning_addr);
}
}
