void qdr_route_table_setup_CT(qdr_core_t *core) { DEQ_INIT(core->addrs); DEQ_INIT(core->routers); core->addr_hash = qd_hash(12, 32, 0); core->conn_id_hash = qd_hash(6, 4, 0); if (core->router_mode == QD_ROUTER_MODE_INTERIOR) { core->hello_addr = qdr_add_local_address_CT(core, 'L', "qdhello", QD_TREATMENT_MULTICAST_FLOOD); core->router_addr_L = qdr_add_local_address_CT(core, 'L', "qdrouter", QD_TREATMENT_MULTICAST_FLOOD); core->routerma_addr_L = qdr_add_local_address_CT(core, 'L', "qdrouter.ma", QD_TREATMENT_MULTICAST_ONCE); core->router_addr_T = qdr_add_local_address_CT(core, 'T', "qdrouter", QD_TREATMENT_MULTICAST_FLOOD); core->routerma_addr_T = qdr_add_local_address_CT(core, 'T', "qdrouter.ma", QD_TREATMENT_MULTICAST_ONCE); core->neighbor_free_mask = qd_bitmask(1); core->routers_by_mask_bit = NEW_PTR_ARRAY(qdr_node_t, qd_bitmask_width()); core->control_links_by_mask_bit = NEW_PTR_ARRAY(qdr_link_t, qd_bitmask_width()); core->data_links_by_mask_bit = NEW_PTR_ARRAY(qdr_link_t, qd_bitmask_width()); for (int idx = 0; idx < qd_bitmask_width(); idx++) { core->routers_by_mask_bit[idx] = 0; core->control_links_by_mask_bit[idx] = 0; core->data_links_by_mask_bit[idx] = 0; } } }
static PyObject* qd_set_valid_origins(PyObject *self, PyObject *args) { RouterAdapter *adapter = (RouterAdapter*) self; qd_router_t *router = adapter->router; int router_maskbit; PyObject *origin_list; Py_ssize_t idx; char *error = 0; if (!PyArg_ParseTuple(args, "iO", &router_maskbit, &origin_list)) return 0; do { if (router_maskbit >= qd_bitmask_width() || router_maskbit < 0) { error = "Router bit mask out of range"; break; } if (!PyList_Check(origin_list)) { error = "Expected List as argument 2"; break; } Py_ssize_t origin_count = PyList_Size(origin_list); qd_bitmask_t *core_bitmask = qd_bitmask(0); int maskbit; for (idx = 0; idx < origin_count; idx++) { maskbit = PyInt_AS_LONG(PyList_GetItem(origin_list, idx)); if (maskbit >= qd_bitmask_width() || maskbit < 0) { error = "Origin bit mask out of range"; break; } } if (error == 0) { qd_bitmask_set_bit(core_bitmask, 0); // This router is a valid origin for all destinations for (idx = 0; idx < origin_count; idx++) { maskbit = PyInt_AS_LONG(PyList_GetItem(origin_list, idx)); qd_bitmask_set_bit(core_bitmask, maskbit); } } else { qd_bitmask_free(core_bitmask); break; } qdr_core_set_valid_origins(router->router_core, router_maskbit, core_bitmask); } while (0); if (error) { PyErr_SetString(PyExc_Exception, error); return 0; } Py_INCREF(Py_None); return Py_None; }
qdr_address_t *qdr_address_CT(qdr_core_t *core, qd_address_treatment_t treatment) { qdr_address_t *addr = new_qdr_address_t(); ZERO(addr); addr->treatment = treatment; addr->forwarder = qdr_forwarder_CT(core, treatment); addr->rnodes = qd_bitmask(0); return addr; }
qdr_address_t *qdr_address_CT(qdr_core_t *core, qd_address_treatment_t treatment) { if (treatment == QD_TREATMENT_UNAVAILABLE) return 0; qdr_address_t *addr = new_qdr_address_t(); ZERO(addr); addr->treatment = treatment; addr->forwarder = qdr_forwarder_CT(core, treatment); addr->rnodes = qd_bitmask(0); return addr; }
qdr_address_t *qdr_address_CT(qdr_core_t *core, qd_address_treatment_t treatment, qdr_address_config_t *config) { if (treatment == QD_TREATMENT_UNAVAILABLE) return 0; qdr_address_t *addr = new_qdr_address_t(); ZERO(addr); addr->config = config; addr->treatment = treatment; addr->forwarder = qdr_forwarder_CT(core, treatment); addr->rnodes = qd_bitmask(0); addr->add_prefix = 0; addr->del_prefix = 0; addr->priority = -1; if (config) config->ref_count++; return addr; }
qd_bitmask_t *qd_tracemask_create(qd_tracemask_t *tm, qd_parsed_field_t *tracelist) { qd_bitmask_t *bm = qd_bitmask(0); int idx = 0; assert(qd_parse_is_list(tracelist)); sys_rwlock_rdlock(tm->lock); qd_parsed_field_t *item = qd_parse_sub_value(tracelist, idx); qdtm_router_t *router = 0; while (item) { qd_field_iterator_t *iter = qd_parse_raw(item); qd_address_iterator_reset_view(iter, ITER_VIEW_NODE_HASH); qd_hash_retrieve(tm->hash, iter, (void*) &router); if (router && router->link_maskbit >= 0) qd_bitmask_set_bit(bm, router->link_maskbit); idx++; item = qd_parse_sub_value(tracelist, idx); } sys_rwlock_unlock(tm->lock); return bm; }
static void qdr_add_router_CT(qdr_core_t *core, qdr_action_t *action, bool discard) { int router_maskbit = action->args.route_table.router_maskbit; qdr_field_t *address = action->args.route_table.address; if (discard) { qdr_field_free(address); return; } do { if (router_maskbit >= qd_bitmask_width() || router_maskbit < 0) { qd_log(core->log, QD_LOG_CRITICAL, "add_router: Router maskbit out of range: %d", router_maskbit); break; } if (core->routers_by_mask_bit[router_maskbit] != 0) { qd_log(core->log, QD_LOG_CRITICAL, "add_router: Router maskbit already in use: %d", router_maskbit); break; } // // Hash lookup the address to ensure there isn't an existing router address. // qd_field_iterator_t *iter = address->iterator; qdr_address_t *addr; qd_address_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; } // // 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 // remote router is looked up. // 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); // // Create a router-node record to represent the remote router. // qdr_node_t *rnode = new_qdr_node_t(); DEQ_ITEM_INIT(rnode); rnode->owning_addr = addr; rnode->mask_bit = router_maskbit; rnode->next_hop = 0; rnode->peer_control_link = 0; rnode->peer_data_link = 0; rnode->ref_count = 0; rnode->valid_origins = qd_bitmask(0); DEQ_INSERT_TAIL(core->routers, rnode); // // Link the router record to the address record. // qd_bitmask_set_bit(addr->rnodes, router_maskbit); // // Link the router record to the router address records. // Use the T-class addresses only. // qd_bitmask_set_bit(core->router_addr_T->rnodes, router_maskbit); qd_bitmask_set_bit(core->routerma_addr_T->rnodes, router_maskbit); // // Bump the ref-count by three for each of the above links. // rnode->ref_count += 3; // // Add the router record to the mask-bit index. // core->routers_by_mask_bit[router_maskbit] = rnode; } while (false); qdr_field_free(address); }