void qdr_router_node_free(qdr_core_t *core, qdr_node_t *rnode) { qd_bitmask_free(rnode->valid_origins); DEQ_REMOVE(core->routers, rnode); core->routers_by_mask_bit[rnode->mask_bit] = 0; core->cost_epoch++; free_qdr_node_t(rnode); }
static void qdr_del_router_CT(qdr_core_t *core, qdr_action_t *action, bool discard) { int router_maskbit = action->args.route_table.router_maskbit; if (router_maskbit >= qd_bitmask_width() || router_maskbit < 0) { qd_log(core->log, QD_LOG_CRITICAL, "del_router: Router maskbit out of range: %d", router_maskbit); return; } if (core->routers_by_mask_bit[router_maskbit] == 0) { qd_log(core->log, QD_LOG_CRITICAL, "del_router: Deleting nonexistent router: %d", router_maskbit); return; } qdr_node_t *rnode = core->routers_by_mask_bit[router_maskbit]; qdr_address_t *oaddr = rnode->owning_addr; assert(oaddr); // // Unlink the router node from the address record // qd_bitmask_clear_bit(oaddr->rnodes, router_maskbit); qd_bitmask_clear_bit(core->router_addr_T->rnodes, router_maskbit); qd_bitmask_clear_bit(core->routerma_addr_T->rnodes, router_maskbit); rnode->ref_count -= 3; // // While the router node has a non-zero reference count, look for addresses // to unlink the node from. // qdr_address_t *addr = DEQ_HEAD(core->addrs); while (addr && rnode->ref_count > 0) { if (qd_bitmask_clear_bit(addr->rnodes, router_maskbit)) // // If the cleared bit was originally set, decrement the ref count // rnode->ref_count--; addr = DEQ_NEXT(addr); } assert(rnode->ref_count == 0); // // Free the router node and the owning address records. // qd_bitmask_free(rnode->valid_origins); DEQ_REMOVE(core->routers, rnode); free_qdr_node_t(rnode); qd_hash_remove_by_handle(core->addr_hash, oaddr->hash_handle); DEQ_REMOVE(core->addrs, oaddr); qd_hash_handle_free(oaddr->hash_handle); core->routers_by_mask_bit[router_maskbit] = 0; free_qdr_address_t(oaddr); }