/** * Load required int value from config. * @param[in] cfg Config section. * @param[in] opt Option name. * @param[out] val Value pointer. * @return Zero on success. */ static int load_int64_req(const config_setting_t *cfg, const char *opt, int64_t *val) { long long int int64_val; if (config_setting_lookup_int64(cfg, opt, &int64_val)) { *val = int64_val; return 0; } else { ZERO_LOG(LOG_ERR, "config: '%s' missing", opt); return -1; } }
long long cfgGetInt64(const config_setting_t *setting, const TCHAR *name) { long long value; char uName[CONFIG_UTF8_MAXSTRING]; UTF8_Encode(name, uName, CONFIG_UTF8_MAXSTRING); if(!config_setting_lookup_int64(setting, uName, &value)) { wcscpy_s(ConfigErrorString, CONFIG_ERROR_MAXSTRING, name); ConfigError = TRUE; return 0; } return value; }
void core_main() { PRINT_IMPORTANT("Entered"); register_to_signal(SIGRTMIN); sem_init(&control_serial_sem, 0, 1); //TODO remove after gen_control_serial_num() converted to RNG signal(SIGINT, core_termination_handler); //register termination handler int status; int i, j, k; metadata_element *list_elem; int list_num; metadata_element *elem; metadata_element *ip_elem; uint32_t ip_num; //###################################################################### overall = (struct fins_overall *) secure_malloc(sizeof(struct fins_overall)); sem_init(&overall->sem, 0, 1); //###################################################################### overall->envi = (struct envi_record *) secure_malloc(sizeof(struct envi_record)); PRINT_IMPORTANT("loading environment"); metadata *meta_envi = (metadata *) secure_malloc(sizeof(metadata)); metadata_create(meta_envi); status = config_read_file(meta_envi, "envi.cfg"); if (status == META_FALSE) { PRINT_ERROR("%s:%d - %s\n", config_error_file(meta_envi), config_error_line(meta_envi), config_error_text(meta_envi)); metadata_destroy(meta_envi); PRINT_ERROR("todo error"); exit(-1); } //############# if_list PRINT_IMPORTANT("interface list"); overall->envi->if_list = list_create(MAX_INTERFACES); list_elem = config_lookup(meta_envi, "environment.interfaces"); if (list_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } list_num = config_setting_length(list_elem); uint32_t if_index; uint8_t *name; uint64_t mac; uint32_t type; uint32_t if_status; uint32_t mtu; uint32_t flags; struct if_record *ifr; for (i = 0; i < list_num; i++) { elem = config_setting_get_elem(list_elem, i); if (elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(elem, "index", (int *) &if_index); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_string(elem, "name", (const char **) &name); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int64(elem, "mac", (long long *) &mac); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(elem, "type", (int *) &type); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(elem, "status", (int *) &if_status); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(elem, "mtu", (int *) &mtu); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(elem, "flags", (int *) &flags); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } //############# ifr = (struct if_record *) list_find1(overall->envi->if_list, ifr_index_test, &if_index); if (ifr == NULL) { ifr = (struct if_record *) secure_malloc(sizeof(struct if_record)); ifr->index = if_index; strcpy((char *) ifr->name, (char *) name); ifr->mac = mac; ifr->type = (uint16_t) type; ifr->status = (uint8_t) if_status; ifr->mtu = mtu; ifr->flags = flags; ifr->addr_list = list_create(MAX_FAMILIES); if (list_has_space(overall->envi->if_list)) { list_append(overall->envi->if_list, ifr); } else { //TODO error PRINT_ERROR("todo error"); exit(-1); } if (flags & IFF_LOOPBACK) { overall->envi->if_loopback = ifr; } } else { PRINT_ERROR("todo error"); exit(-1); } } //############# if_main PRINT_IMPORTANT("main interface"); uint32_t if_main; status = config_lookup_int(meta_envi, "environment.main_interface", (int *) &if_main); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } overall->envi->if_main = (struct if_record *) list_find1(overall->envi->if_list, ifr_index_test, &if_main); if (overall->envi->if_main == NULL) { PRINT_ERROR("todo"); } //############# addr_list PRINT_IMPORTANT("address list"); //overall->envi->addr_list = list_create(MAX_INTERFACES * MAX_FAMILIES); //TODO use? list_elem = config_lookup(meta_envi, "environment.addresses"); if (list_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } list_num = config_setting_length(list_elem); uint32_t family; //atm only AF_INET, but eventually also AF_INET6 uint32_t ip[4]; //SIOCGIFADDR //ip uint32_t mask[4]; //SIOCGIFNETMASK //mask uint32_t gw[4]; //? //(ip & mask) | 1; uint32_t bdc[4]; //SIOCGIFBRDADDR //(ip & mask) | ~mask uint32_t dst[4]; //SIOCGIFDSTADDR //dst struct addr_record *addr; for (i = 0; i < list_num; i++) { elem = config_setting_get_elem(list_elem, i); if (elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(elem, "if_index", (int *) &if_index); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(elem, "family", (int *) &family); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } ip_elem = config_setting_get_member(elem, "ip"); if (ip_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } ip_num = config_setting_length(ip_elem); for (j = 0; j < ip_num; j++) { ip[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j); } ip_elem = config_setting_get_member(elem, "mask"); if (ip_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } ip_num = config_setting_length(ip_elem); for (j = 0; j < ip_num; j++) { mask[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j); } ip_elem = config_setting_get_member(elem, "gw"); if (ip_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } ip_num = config_setting_length(ip_elem); for (j = 0; j < ip_num; j++) { gw[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j); } ip_elem = config_setting_get_member(elem, "bdc"); if (ip_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } ip_num = config_setting_length(ip_elem); for (j = 0; j < ip_num; j++) { bdc[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j); } ip_elem = config_setting_get_member(elem, "dst"); if (ip_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } ip_num = config_setting_length(ip_elem); for (j = 0; j < ip_num; j++) { dst[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j); } //############ ifr = (struct if_record *) list_find1(overall->envi->if_list, ifr_index_test, &if_index); if (ifr != NULL) { if (ifr->flags & IFF_RUNNING) { if (family == AF_INET) { addr = (struct addr_record *) list_find(ifr->addr_list, addr_is_v4); } else { addr = (struct addr_record *) list_find(ifr->addr_list, addr_is_v6); } if (addr == NULL) { addr = (struct addr_record *) secure_malloc(sizeof(struct addr_record)); addr->if_index = if_index; addr->family = AF_INET; if (family == AF_INET) { addr4_set_addr(&addr->ip, IP4_ADR_P2H(ip[0], ip[1], ip[2],ip[3])); addr4_set_addr(&addr->mask, IP4_ADR_P2H(mask[0], mask[1], mask[2],mask[3])); addr4_set_addr(&addr->gw, IP4_ADR_P2H(gw[0], gw[1], gw[2], gw[3])); addr4_set_addr(&addr->bdc, IP4_ADR_P2H(bdc[0], bdc[1], bdc[2], bdc[3])); addr4_set_addr(&addr->dst, IP4_ADR_P2H(dst[0], dst[1], dst[2], dst[3])); } else if (family == AF_INET6) { //TODO //addr_set_addr6(&addr->ip, ip); PRINT_ERROR("todo"); } else { //TODO error? PRINT_ERROR("todo error"); exit(-1); } if (list_has_space(ifr->addr_list)) { list_append(ifr->addr_list, addr); } else { //TODO error PRINT_ERROR("todo error"); exit(-1); } } else { //TODO error PRINT_ERROR("todo: replace or add new?"); } } else { //TODO error PRINT_ERROR("todo: decide just drop or add?"); } } else { //TODO error PRINT_ERROR("todo error"); exit(-1); } } //############# route_list PRINT_IMPORTANT("route list"); overall->envi->route_list = list_create(MAX_ROUTES); list_elem = config_lookup(meta_envi, "environment.routes"); if (list_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } list_num = config_setting_length(list_elem); uint32_t metric; //SIOCGIFMETRIC uint32_t timeout; //struct timeval route_stamp; struct route_record *route; for (i = 0; i < list_num; i++) { elem = config_setting_get_elem(list_elem, i); if (elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(elem, "if_index", (int *) &if_index); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(elem, "family", (int *) &family); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } ip_elem = config_setting_get_member(elem, "dst"); if (ip_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } ip_num = config_setting_length(ip_elem); for (j = 0; j < ip_num; j++) { dst[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j); } ip_elem = config_setting_get_member(elem, "mask"); if (ip_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } ip_num = config_setting_length(ip_elem); for (j = 0; j < ip_num; j++) { mask[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j); } ip_elem = config_setting_get_member(elem, "gw"); if (ip_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } ip_num = config_setting_length(ip_elem); for (j = 0; j < ip_num; j++) { gw[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j); } ////ip = IP4_ADR_P2H(192,168,1,5); status = config_setting_lookup_int(elem, "metric", (int *) &metric); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(elem, "timeout", (int *) &timeout); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } //############ ifr = (struct if_record *) list_find1(overall->envi->if_list, ifr_index_test, &if_index); if (ifr != NULL) { if (ifr->flags & IFF_RUNNING) { route = (struct route_record *) secure_malloc(sizeof(struct route_record)); route->if_index = if_index; route->family = family; if (family == AF_INET) { addr4_set_addr(&route->dst, IP4_ADR_P2H(dst[0], dst[1], dst[2], dst[3])); addr4_set_addr(&route->mask, IP4_ADR_P2H(mask[0], mask[1], mask[2],mask[3])); addr4_set_addr(&route->gw, IP4_ADR_P2H(gw[0], gw[1], gw[2], gw[3])); //addr4_set_addr(&route->ip, IP4_ADR_P2H(ip[0], ip[1], ip[2],ip[3])); } else if (family == AF_INET6) { //TODO //addr_set_addr6(&route->ip, ip); } else { //TODO error? } route->metric = metric; route->timeout = timeout; if (list_has_space(overall->envi->route_list)) { list_append(overall->envi->route_list, route); } else { //TODO error PRINT_ERROR("todo error"); exit(-1); } } else { //TODO error PRINT_ERROR("todo: decide just drop or add?"); } } } metadata_destroy(meta_envi); //###################################################################### PRINT_IMPORTANT("loading stack"); metadata *meta_stack = (metadata *) secure_malloc(sizeof(metadata)); metadata_create(meta_stack); status = config_read_file(meta_stack, "stack.cfg"); if (status == META_FALSE) { PRINT_ERROR("%s:%d - %s\n", config_error_file(meta_stack), config_error_line(meta_stack), config_error_text(meta_stack)); metadata_destroy(meta_stack); PRINT_ERROR("todo error"); exit(-1); } //############# module_list PRINT_IMPORTANT("module list"); overall->lib_list = list_create(MAX_MODULES); memset(overall->modules, 0, MAX_MODULES * sizeof(struct fins_module *)); overall->admin_list = list_create(MAX_MODULES); uint8_t base_path[100]; memset((char *) base_path, 0, 100); strcpy((char *) base_path, "."); metadata_element *mods_elem = config_lookup(meta_stack, "stack.modules"); if (mods_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } int mods_num = config_setting_length(mods_elem); metadata_element *mod_elem; uint32_t mod_id; uint8_t *mod_lib; uint8_t *mod_name; metadata_element *flows_elem; uint32_t mod_flows[MAX_MOD_FLOWS]; uint32_t mod_flows_num; metadata_element *mod_params; metadata_element *mod_admin; struct fins_library *library; struct fins_module *module; for (i = 0; i < mods_num; i++) { mod_elem = config_setting_get_elem(mods_elem, i); if (mod_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(mod_elem, "id", (int *) &mod_id); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_string(mod_elem, "lib", (const char **) &mod_lib); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_string(mod_elem, "name", (const char **) &mod_name); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } flows_elem = config_setting_get_member(mod_elem, "flows"); if (flows_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } mod_flows_num = config_setting_length(flows_elem); for (j = 0; j < mod_flows_num; j++) { mod_flows[j] = (uint32_t) config_setting_get_int_elem(flows_elem, j); } mod_params = config_setting_get_member(mod_elem, "params"); if (mod_params == NULL) { PRINT_ERROR("todo error"); exit(-1); } mod_admin = config_setting_get_member(mod_elem, "admin"); PRINT_DEBUG("admin=%u", mod_admin != NULL) //############ library = (struct fins_library *) list_find1(overall->lib_list, lib_name_test, mod_lib); if (library == NULL) { library = library_load(mod_lib, base_path); if (library == NULL) { PRINT_ERROR("todo error"); exit(-1); } if (list_has_space(overall->lib_list)) { list_append(overall->lib_list, library); } else { PRINT_ERROR("todo error"); exit(-1); } } module = library->create(i, mod_id, mod_name); if (module == NULL) { //TODO error PRINT_ERROR("todo error"); exit(-1); } library->num_mods++; //TODO move flow to update? or links here? status = module->ops->init(module, mod_flows_num, mod_flows, mod_params, overall->envi); //TODO merge init into create? if (status != 0) { overall->modules[i] = module; if (mod_admin != NULL) { list_append(overall->admin_list, module); } } else { PRINT_ERROR("todo error"); exit(-1); } //free(mod_lib); //don't free, string from libconfig points to metadata memory //free(mod_name); } //############# admin_list //TODO change to admin_list? //list_for_each(overall->admin_list, register_all); list_for_each1(overall->admin_list, assign_overall, overall); //############# linking_list PRINT_IMPORTANT("link list"); overall->link_list = list_create(MAX_TABLE_LINKS); metadata_element *links_elem = config_lookup(meta_stack, "stack.links"); if (links_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } int links_num = config_setting_length(links_elem); metadata_element *link_elem; uint32_t link_id; uint32_t link_src; metadata_element *dsts_elem; uint32_t link_dsts[MAX_MODULES]; int link_dsts_num; struct link_record *link; for (i = 0; i < links_num; i++) { link_elem = config_setting_get_elem(links_elem, i); if (link_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(link_elem, "id", (int *) &link_id); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(link_elem, "src", (int *) &link_src); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } dsts_elem = config_setting_get_member(link_elem, "dsts"); if (dsts_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } link_dsts_num = config_setting_length(dsts_elem); for (j = 0; j < link_dsts_num; j++) { link_dsts[j] = (uint32_t) config_setting_get_int_elem(dsts_elem, j); } //############ link = (struct link_record *) secure_malloc(sizeof(struct link_record)); link->id = link_id; //module = (struct fins_module *) list_find1(overall->envi->module_list, mod_id_test, &link_src); link->src_index = -1; for (j = 0; j < MAX_MODULES; j++) { if (overall->modules[j] != NULL && overall->modules[j]->id == link_src) { link->src_index = overall->modules[j]->index; } } if (link->src_index == -1) { PRINT_ERROR("todo error"); exit(-1); } link->dsts_num = link_dsts_num; for (j = 0; j < link_dsts_num; j++) { //module = (struct fins_module *) list_find1(overall->envi->module_list, mod_id_test, &link_dsts[j]); link->dsts_index[j] = -1; for (k = 0; k < MAX_MODULES; k++) { if (overall->modules[k] != NULL && overall->modules[k]->id == link_dsts[j]) { link->dsts_index[j] = overall->modules[k]->index; } } if (link->dsts_index[j] == (uint32_t) -1) { PRINT_ERROR("todo error"); exit(-1); } } if (list_has_space(overall->link_list)) { list_append(overall->link_list, link); } else { //TODO error PRINT_ERROR("todo error"); exit(-1); } } metadata_destroy(meta_stack); //###################################################################### PRINT_IMPORTANT("update modules"); //send out subset of linking table to each module as update //TODO table subset update struct linked_list *link_subset_list; metadata *meta_update; struct finsFrame *ff_update; for (i = 0; i < MAX_MODULES; i++) { if (overall->modules[i] != NULL) { link_subset_list = list_filter1(overall->link_list, link_involved_test, &overall->modules[i]->index, link_clone); //TODO is mem leak PRINT_IMPORTANT("i=%d, link_subset_list=%p, len=%d", i, link_subset_list, link_subset_list->len); meta_update = (metadata *) secure_malloc(sizeof(metadata)); metadata_create(meta_update); //TODO decide on metadata params? //uint32_t host_ip = IP4_ADR_P2H(192,168,1,8); //secure_metadata_writeToElement(meta_update, "send_src_ip", &host_ip, META_TYPE_INT32); ff_update = (struct finsFrame*) secure_malloc(sizeof(struct finsFrame)); ff_update->dataOrCtrl = FF_CONTROL; ff_update->destinationID = i; ff_update->metaData = meta_update; ff_update->ctrlFrame.sender_id = 0; ff_update->ctrlFrame.serial_num = gen_control_serial_num(); ff_update->ctrlFrame.opcode = CTRL_SET_PARAM; ff_update->ctrlFrame.param_id = MOD_SET_PARAM_LINKS; ff_update->ctrlFrame.data_len = sizeof(struct linked_list); ff_update->ctrlFrame.data = (uint8_t *) link_subset_list; module_to_switch(overall->modules[0], ff_update); } } //############ say by this point envi var completely init'd //assumed always connect/init to switch first pthread_attr_t attr; pthread_attr_init(&attr); PRINT_IMPORTANT("modules: run"); for (i = 0; i < MAX_MODULES; i++) { if (overall->modules[i] != NULL) { overall->modules[i]->ops->run(overall->modules[i], &attr); } } //############ mini test //sleep(5); char recv_data[4000]; //while (1) { PRINT_IMPORTANT("waiting..."); gets(recv_data); if (0) { metadata *meta = (metadata *) secure_malloc(sizeof(metadata)); metadata_create(meta); uint32_t host_ip = IP4_ADR_P2H(192,168,1,8); uint32_t host_port = 55454; uint32_t dst_ip = IP4_ADR_P2H(192,168,1,3); uint32_t dst_port = 44444; uint32_t ttl = 64; uint32_t tos = 64; secure_metadata_writeToElement(meta, "send_src_ip", &host_ip, META_TYPE_INT32); secure_metadata_writeToElement(meta, "send_src_port", &host_port, META_TYPE_INT32); secure_metadata_writeToElement(meta, "send_dst_ip", &dst_ip, META_TYPE_INT32); secure_metadata_writeToElement(meta, "send_dst_port", &dst_port, META_TYPE_INT32); secure_metadata_writeToElement(meta, "send_ttl", &ttl, META_TYPE_INT32); secure_metadata_writeToElement(meta, "send_tos", &tos, META_TYPE_INT32); struct finsFrame *ff = (struct finsFrame *) secure_malloc(sizeof(struct finsFrame)); ff->dataOrCtrl = FF_DATA; ff->destinationID = 1; ff->metaData = meta; ff->dataFrame.directionFlag = DIR_UP; ff->dataFrame.pduLength = 10; ff->dataFrame.pdu = (uint8_t *) secure_malloc(10); PRINT_IMPORTANT("sending: ff=%p, meta=%p, src='%s' to dst='%s'", ff, meta, overall->modules[0]->name, overall->modules[1]->name); module_to_switch(overall->modules[0], ff); } if (0) { PRINT_DEBUG("Sending ARP req"); metadata *meta_req = (metadata *) secure_malloc(sizeof(metadata)); metadata_create(meta_req); uint32_t dst_ip = IP4_ADR_P2H(192, 168, 1, 1); //uint32_t dst_ip = IP4_ADR_P2H(172, 31, 54, 169); uint32_t src_ip = IP4_ADR_P2H(192, 168, 1, 20); //uint32_t src_ip = IP4_ADR_P2H(172, 31, 50, 160); secure_metadata_writeToElement(meta_req, "dst_ip", &dst_ip, META_TYPE_INT32); secure_metadata_writeToElement(meta_req, "src_ip", &src_ip, META_TYPE_INT32); struct finsFrame *ff_req = (struct finsFrame*) secure_malloc(sizeof(struct finsFrame)); ff_req->dataOrCtrl = FF_CONTROL; ff_req->destinationID = 1; //arp ff_req->metaData = meta_req; ff_req->ctrlFrame.sender_id = 4; //ipv4 ff_req->ctrlFrame.serial_num = gen_control_serial_num(); ff_req->ctrlFrame.opcode = CTRL_EXEC; ff_req->ctrlFrame.param_id = 0; //EXEC_ARP_GET_ADDR; ff_req->ctrlFrame.data_len = 0; ff_req->ctrlFrame.data = NULL; PRINT_IMPORTANT("sending: ff=%p, meta=%p, src='%s' to dst='%s'", ff_req, meta_req, overall->modules[0]->name, overall->modules[1]->name); module_to_switch(overall->modules[0], ff_req); } if (0) { PRINT_DEBUG("Sending data"); metadata *meta_req = (metadata *) secure_malloc(sizeof(metadata)); metadata_create(meta_req); uint32_t ether_type = 0x0800; //ipv4 if_index = 3; //wlan0 uint32_t src_ip = IP4_ADR_P2H(192, 168, 1, 5); //wlan0 uint32_t dst_ip = IP4_ADR_P2H(192, 168, 1, 1); //gw secure_metadata_writeToElement(meta_req, "send_ether_type", ðer_type, META_TYPE_INT32); secure_metadata_writeToElement(meta_req, "send_if_index", &if_index, META_TYPE_INT32); secure_metadata_writeToElement(meta_req, "send_src_ipv4", &src_ip, META_TYPE_INT32); secure_metadata_writeToElement(meta_req, "send_dst_ipv4", &dst_ip, META_TYPE_INT32); struct finsFrame *ff = (struct finsFrame*) secure_malloc(sizeof(struct finsFrame)); ff->dataOrCtrl = FF_DATA; ff->destinationID = 1; //arp ff->metaData = meta_req; ff->dataFrame.directionFlag = DIR_DOWN; ff->dataFrame.pduLength = 100; ff->dataFrame.pdu = (uint8_t *) secure_malloc(ff->dataFrame.pduLength); memset(ff->dataFrame.pdu, 59, ff->dataFrame.pduLength); PRINT_IMPORTANT("sending: ff=%p, meta=%p, src='%s' to dst='%s'", ff, meta_req, overall->modules[0]->name, overall->modules[1]->name); module_to_switch(overall->modules[0], ff); } if (0) { PRINT_DEBUG("Sending data"); metadata *meta = (metadata *) secure_malloc(sizeof(metadata)); metadata_create(meta); uint32_t src_ip = IP4_ADR_P2H(192, 168, 1, 5); //wlan0 uint32_t src_port = 6666; uint32_t dst_ip = IP4_ADR_P2H(192, 168, 1, 1); //gw uint32_t dst_port = 5555; secure_metadata_writeToElement(meta, "send_src_ipv4", &src_ip, META_TYPE_INT32); secure_metadata_writeToElement(meta, "send_src_port", &src_port, META_TYPE_INT32); secure_metadata_writeToElement(meta, "send_dst_ipv4", &dst_ip, META_TYPE_INT32); secure_metadata_writeToElement(meta, "send_dst_port", &dst_port, META_TYPE_INT32); uint32_t dst_index = 4; struct finsFrame *ff = (struct finsFrame*) secure_malloc(sizeof(struct finsFrame)); ff->dataOrCtrl = FF_DATA; ff->destinationID = dst_index; //arp ff->metaData = meta; ff->dataFrame.directionFlag = DIR_DOWN; ff->dataFrame.pduLength = 10; ff->dataFrame.pdu = (uint8_t *) secure_malloc(ff->dataFrame.pduLength); memset(ff->dataFrame.pdu, 65, ff->dataFrame.pduLength); PRINT_IMPORTANT("sending: ff=%p, meta=%p, src='%s' to dst='%s'", ff, meta, overall->modules[0]->name, overall->modules[dst_index]->name); module_to_switch(overall->modules[0], ff); } if (1) { PRINT_DEBUG("Sending data"); metadata *meta = (metadata *) secure_malloc(sizeof(metadata)); metadata_create(meta); uint32_t src_ip = IP4_ADR_P2H(192, 168, 1, 5); //wlan0 uint32_t dst_ip = IP4_ADR_P2H(192, 168, 1, 1); //gw secure_metadata_writeToElement(meta, "send_src_ipv4", &src_ip, META_TYPE_INT32); secure_metadata_writeToElement(meta, "send_dst_ipv4", &dst_ip, META_TYPE_INT32); uint32_t dst_index = 4; struct finsFrame *ff = (struct finsFrame*) secure_malloc(sizeof(struct finsFrame)); ff->dataOrCtrl = FF_DATA; ff->destinationID = dst_index; ff->metaData = meta; ff->dataFrame.directionFlag = DIR_DOWN; ff->dataFrame.pduLength = 10; ff->dataFrame.pdu = (uint8_t *) secure_malloc(ff->dataFrame.pduLength); memset(ff->dataFrame.pdu, 65, ff->dataFrame.pduLength); PRINT_IMPORTANT("sending: ff=%p, meta=%p, src='%s' to dst='%s'", ff, meta, overall->modules[0]->name, overall->modules[dst_index]->name); module_to_switch(overall->modules[0], ff); } while (1) ; sleep(5); PRINT_IMPORTANT("waiting..."); char recv_data2[4000]; gets(recv_data2); //############ terminating core_termination_handler(0); }
void core_main(uint8_t *envi_name, uint8_t *stack_name, uint32_t seed) { PRINT_IMPORTANT("Core Initiation: Starting ************"); #ifdef BUILD_FOR_ANDROID library_dummies(); #endif register_to_signal(SIGRTMIN); if (seed == DEFAULT_SEED_NUM) { srand((unsigned int) time(NULL)); } else { srand(seed); } sem_init(&global_control_serial_sem, 0, 1); //TODO remove after gen_control_serial_num() converted to RNG signal(SIGINT, core_termination_handler); //register termination handler int status; int i, j, k; metadata_element *list_elem; int list_num; metadata_element *elem; metadata_element *ip_elem; uint32_t ip_num; //###################################################################### overall = (struct fins_overall *) secure_malloc(sizeof(struct fins_overall)); sem_init(&overall->sem, 0, 1); //###################################################################### overall->envi = (struct envi_record *) secure_malloc(sizeof(struct envi_record)); PRINT_IMPORTANT("########################## loading environment: '%s'", (char *) envi_name); metadata *meta_envi = (metadata *) secure_malloc(sizeof(metadata)); metadata_create(meta_envi); status = config_read_file(meta_envi, (char *) envi_name); if (status == META_FALSE) { PRINT_ERROR("file='%s', %s:%d - %s\n", envi_name, config_error_file(meta_envi), config_error_line(meta_envi), config_error_text(meta_envi)); metadata_destroy(meta_envi); PRINT_ERROR("todo error"); exit(-1); } //############# if_list PRINT_IMPORTANT("############# Configuring List of Interfaces"); overall->envi->if_list = list_create(MAX_INTERFACES); list_elem = config_lookup(meta_envi, "environment.interfaces"); if (list_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } list_num = config_setting_length(list_elem); int32_t if_index; uint8_t *name; uint64_t mac; uint32_t mode; uint32_t mtu; uint32_t flags; struct if_record *ifr; for (i = 0; i < list_num; i++) { elem = config_setting_get_elem(list_elem, i); if (elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(elem, "index", (int *) &if_index); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_string(elem, "name", (const char **) &name); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int64(elem, "mac", (long long *) &mac); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(elem, "mode", (int *) &mode); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(elem, "mtu", (int *) &mtu); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(elem, "flags", (int *) &flags); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } //############# ifr = (struct if_record *) list_find1(overall->envi->if_list, ifr_index_test, &if_index); if (ifr == NULL) { ifr = (struct if_record *) secure_malloc(sizeof(struct if_record)); ifr->index = if_index; strcpy((char *) ifr->name, (char *) name); ifr->mac = mac; ifr->mode = (uint8_t) mode; ifr->mtu = mtu; ifr->flags = flags; ifr->addr_list = list_create(MAX_FAMILIES); if (list_has_space(overall->envi->if_list)) { PRINT_IMPORTANT("Adding interface: ifr=%p, index=%u, name='%s', mac=0x%012llx", ifr, ifr->index, ifr->name, ifr->mac); list_append(overall->envi->if_list, ifr); } else { //TODO error PRINT_ERROR("todo error"); exit(-1); } if (flags & IFF_LOOPBACK) { overall->envi->if_loopback = ifr; } } else { PRINT_ERROR("todo error"); exit(-1); } } PRINT_IMPORTANT("if_list: list=%p, max=%u, len=%u", overall->envi->if_list, overall->envi->if_list->max, overall->envi->if_list->len); //############# if_loopback PRINT_IMPORTANT("############# Configuring Loopback Interface"); if (overall->envi->if_loopback != NULL) { PRINT_IMPORTANT("loopback: name='%s', addr_list->len=%u", overall->envi->if_loopback->name, overall->envi->if_loopback->addr_list->len); } else { PRINT_WARN("todo error"); } //############# if_main PRINT_IMPORTANT("############# Configuring Main Interface"); uint32_t if_main; status = config_lookup_int(meta_envi, "environment.main_interface", (int *) &if_main); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } overall->envi->if_main = (struct if_record *) list_find1(overall->envi->if_list, ifr_index_test, &if_main); if (overall->envi->if_main != NULL) { PRINT_IMPORTANT("main interface: name='%s', addr_list->len=%u", overall->envi->if_main->name, overall->envi->if_main->addr_list->len); if (!ifr_running_test(overall->envi->if_main)) { PRINT_WARN("!!!!Selected main interface is NOT running: name='%s', flagx->len=0x%x", overall->envi->if_main->name, overall->envi->if_main->flags); } } else { PRINT_WARN("todo error"); } //############# addr_list PRINT_IMPORTANT("############# Configuring List of Host Addresses"); //overall->envi->addr_list = list_create(MAX_INTERFACES * MAX_FAMILIES); //TODO use? list_elem = config_lookup(meta_envi, "environment.addresses"); if (list_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } list_num = config_setting_length(list_elem); uint32_t family; //atm only AF_INET, but eventually also AF_INET6 uint32_t ip[4]; //SIOCGIFADDR //ip uint32_t mask[4]; //SIOCGIFNETMASK //mask uint32_t gw[4]; //? //(ip & mask) | 1; uint32_t bdc[4]; //SIOCGIFBRDADDR //(ip & mask) | ~mask uint32_t dst[4]; //SIOCGIFDSTADDR //dst struct addr_record *addr; for (i = 0; i < list_num; i++) { elem = config_setting_get_elem(list_elem, i); if (elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(elem, "if_index", (int *) &if_index); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(elem, "family", (int *) &family); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } ip_elem = config_setting_get_member(elem, "ip"); if (ip_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } ip_num = config_setting_length(ip_elem); for (j = 0; j < ip_num; j++) { ip[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j); } ip_elem = config_setting_get_member(elem, "mask"); if (ip_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } ip_num = config_setting_length(ip_elem); for (j = 0; j < ip_num; j++) { mask[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j); } ip_elem = config_setting_get_member(elem, "gw"); if (ip_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } ip_num = config_setting_length(ip_elem); for (j = 0; j < ip_num; j++) { gw[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j); } ip_elem = config_setting_get_member(elem, "bdc"); if (ip_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } ip_num = config_setting_length(ip_elem); for (j = 0; j < ip_num; j++) { bdc[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j); } ip_elem = config_setting_get_member(elem, "dst"); if (ip_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } ip_num = config_setting_length(ip_elem); for (j = 0; j < ip_num; j++) { dst[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j); } //############ ifr = (struct if_record *) list_find1(overall->envi->if_list, ifr_index_test, &if_index); if (ifr != NULL) { if (ifr_running_test(ifr)) { if (family == AF_INET) { addr = (struct addr_record *) list_find(ifr->addr_list, addr_is_v4); } else { addr = (struct addr_record *) list_find(ifr->addr_list, addr_is_v6); } if (addr == NULL) { addr = (struct addr_record *) secure_malloc(sizeof(struct addr_record)); addr->if_index = if_index; addr->family = AF_INET; if (family == AF_INET) { addr4_set_ip(&addr->ip, IP4_ADR_P2H(ip[0], ip[1], ip[2],ip[3])); addr4_set_ip(&addr->mask, IP4_ADR_P2H(mask[0], mask[1], mask[2],mask[3])); addr4_set_ip(&addr->gw, IP4_ADR_P2H(gw[0], gw[1], gw[2], gw[3])); addr4_set_ip(&addr->bdc, IP4_ADR_P2H(bdc[0], bdc[1], bdc[2], bdc[3])); addr4_set_ip(&addr->dst, IP4_ADR_P2H(dst[0], dst[1], dst[2], dst[3])); } else if (family == AF_INET6) { //TODO //addr_set_addr6(&addr->ip, ip); PRINT_WARN("todo"); } else { //TODO error? PRINT_ERROR("todo error"); exit(-1); } if (list_has_space(ifr->addr_list)) { PRINT_IMPORTANT( "Adding address: if_index=%d, family=%u, ip='%u.%u.%u.%u', mask='%u.%u.%u.%u', gw='%u.%u.%u.%u', bdc='%u.%u.%u.%u', dst='%u.%u.%u.%u'", if_index, family, ip[0], ip[1], ip[2], ip[3], mask[0], mask[1], mask[2], mask[3], gw[0], gw[1], gw[2], gw[3], bdc[0], bdc[1], bdc[2], bdc[3], dst[0], dst[1], dst[2], dst[3]); list_append(ifr->addr_list, addr); } else { //TODO error PRINT_ERROR("todo error"); exit(-1); } } else { //TODO error PRINT_ERROR("todo: previous address found, replace or add new?"); } } else { if (family == AF_INET) { PRINT_WARN( "Ignoring address, no active interface: if_index=%d, family=%u, ip='%u.%u.%u.%u', mask='%u.%u.%u.%u', gw='%u.%u.%u.%u', bdc='%u.%u.%u.%u', dst='%u.%u.%u.%u'", if_index, family, ip[0], ip[1], ip[2], ip[3], mask[0], mask[1], mask[2], mask[3], gw[0], gw[1], gw[2], gw[3], bdc[0], bdc[1], bdc[2], bdc[3], dst[0], dst[1], dst[2], dst[3]); } else if (family == AF_INET6) { //TODO PRINT_WARN("todo"); } else { //TODO error? PRINT_ERROR("todo error"); exit(-1); } } } else { //TODO error PRINT_ERROR("todo error"); exit(-1); } } //############# route_list PRINT_IMPORTANT("############# Configuring List of Routes"); overall->envi->route_list = list_create(MAX_ROUTES); list_elem = config_lookup(meta_envi, "environment.routes"); if (list_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } list_num = config_setting_length(list_elem); uint32_t metric; //SIOCGIFMETRIC uint32_t timeout; //struct timeval route_stamp; struct route_record *route; for (i = 0; i < list_num; i++) { elem = config_setting_get_elem(list_elem, i); if (elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(elem, "if_index", (int *) &if_index); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(elem, "family", (int *) &family); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } ip_elem = config_setting_get_member(elem, "dst"); if (ip_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } ip_num = config_setting_length(ip_elem); for (j = 0; j < ip_num; j++) { dst[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j); } ip_elem = config_setting_get_member(elem, "mask"); if (ip_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } ip_num = config_setting_length(ip_elem); for (j = 0; j < ip_num; j++) { mask[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j); } ip_elem = config_setting_get_member(elem, "gw"); if (ip_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } ip_num = config_setting_length(ip_elem); for (j = 0; j < ip_num; j++) { gw[j] = (uint32_t) config_setting_get_int_elem(ip_elem, j); } status = config_setting_lookup_int(elem, "metric", (int *) &metric); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(elem, "timeout", (int *) &timeout); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } //############ ifr = (struct if_record *) list_find1(overall->envi->if_list, ifr_index_test, &if_index); if (ifr != NULL) { if (ifr_running_test(ifr)) { route = (struct route_record *) secure_malloc(sizeof(struct route_record)); route->if_index = if_index; route->family = family; if (family == AF_INET) { addr4_set_ip(&route->dst, IP4_ADR_P2H(dst[0], dst[1], dst[2], dst[3])); addr4_set_ip(&route->mask, IP4_ADR_P2H(mask[0], mask[1], mask[2],mask[3])); addr4_set_ip(&route->gw, IP4_ADR_P2H(gw[0], gw[1], gw[2], gw[3])); //addr4_set_addr(&route->ip, IP4_ADR_P2H(ip[0], ip[1], ip[2],ip[3])); } else if (family == AF_INET6) { //TODO //addr_set_addr6(&route->ip, ip); } else { //TODO error? } route->metric = metric; route->timeout = timeout; if (list_has_space(overall->envi->route_list)) { PRINT_IMPORTANT( "Adding route: if_index=%d, family=%u, dst='%u.%u.%u.%u', mask='%u.%u.%u.%u', gw='%u.%u.%u.%u', metric=%u, timeout=%u", route->if_index, route->family, dst[0], dst[1], dst[2], dst[3], mask[0], mask[1], mask[2], mask[3], gw[0], gw[1], gw[2], gw[3], metric, timeout); list_append(overall->envi->route_list, route); } else { //TODO error PRINT_ERROR("todo error"); exit(-1); } } else { if (family == AF_INET) { PRINT_WARN( "Ignoring route, no active interface: if_index=%d, family=%u, dst='%u.%u.%u.%u', mask='%u.%u.%u.%u', gw='%u.%u.%u.%u', metric=%u, timeout=%u", if_index, family, dst[0], dst[1], dst[2], dst[3], mask[0], mask[1], mask[2], mask[3], gw[0], gw[1], gw[2], gw[3], metric, timeout); } else if (family == AF_INET6) { //TODO PRINT_WARN("todo"); } else { //TODO error? PRINT_ERROR("todo error"); } } } } PRINT_IMPORTANT("route_list: list=%p, max=%u, len=%u", overall->envi->route_list, overall->envi->route_list->max, overall->envi->route_list->len); metadata_destroy(meta_envi); //###################################################################### PRINT_IMPORTANT("########################## loading stack: '%s'", (char *) stack_name); metadata *meta_stack = (metadata *) secure_malloc(sizeof(metadata)); metadata_create(meta_stack); status = config_read_file(meta_stack, (char *) stack_name); if (status == META_FALSE) { PRINT_ERROR("file='%s', %s:%d - %s\n", stack_name, config_error_file(meta_stack), config_error_line(meta_stack), config_error_text(meta_stack)); metadata_destroy(meta_stack); PRINT_ERROR("todo error"); exit(-1); } //############# module_list PRINT_IMPORTANT("############# Configuring List of Modules"); overall->lib_list = list_create(MAX_MODULES); memset(overall->modules, 0, MAX_MODULES * sizeof(struct fins_module *)); overall->admin_list = list_create(MAX_MODULES); struct linked_list *mt_list = list_create(MAX_MODULES); uint8_t base_path[100]; memset((char *) base_path, 0, 100); #ifdef BUILD_FOR_ANDROID strcpy((char *) base_path, FINS_TMP_ROOT); //strcpy((char *) base_path, "."); #else strcpy((char *) base_path, "."); #endif metadata_element *mods_elem = config_lookup(meta_stack, "stack.modules"); if (mods_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } int mods_num = config_setting_length(mods_elem); metadata_element *mod_elem; uint32_t mod_id; uint8_t *mod_lib; uint8_t *mod_name; metadata_element *flows_elem; uint32_t mod_flows[MAX_MOD_FLOWS]; uint32_t mod_flows_num; metadata_element *mod_params; metadata_element *mod_admin; struct fins_library *library; struct fins_module *module; struct fins_module_table *mt; for (i = 0; i < mods_num; i++) { mod_elem = config_setting_get_elem(mods_elem, i); if (mod_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(mod_elem, "id", (int *) &mod_id); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_string(mod_elem, "lib", (const char **) &mod_lib); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_string(mod_elem, "name", (const char **) &mod_name); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } flows_elem = config_setting_get_member(mod_elem, "flows"); if (flows_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } mod_flows_num = config_setting_length(flows_elem); for (j = 0; j < mod_flows_num; j++) { mod_flows[j] = (uint32_t) config_setting_get_int_elem(flows_elem, j); } mod_params = config_setting_get_member(mod_elem, "params"); if (mod_params == NULL) { PRINT_ERROR("todo error"); exit(-1); } mod_admin = config_setting_get_member(mod_elem, "admin"); PRINT_DEBUG("admin=%u", mod_admin != NULL); //############ library = (struct fins_library *) list_find1(overall->lib_list, library_name_test, mod_lib); if (library == NULL) { #ifdef BUILD_FOR_ANDROID library = library_fake_load(mod_lib, base_path); #else //library = library_load(mod_lib, base_path); library = library_fake_load(mod_lib, base_path); #endif if (library == NULL) { PRINT_ERROR("Failed in loading library: lib='%s', base_path='%s'", mod_lib, base_path); exit(-1); } if (list_has_space(overall->lib_list)) { PRINT_IMPORTANT("Adding library: library=%p, name='%s'", library, library->name); list_append(overall->lib_list, library); } else { PRINT_ERROR("Failed in init sequence, too many libraries: lib_list->len=%u", overall->lib_list->len); exit(-1); } } module = library->create(i, mod_id, mod_name); if (module == NULL) { //TODO error PRINT_ERROR("Failed to create module: library=%p, index=%u, id=%u, name='%s'", library, i, mod_id, mod_name); exit(-1); } library->num_mods++; //TODO move flow to update? or links here? status = module->ops->init(module, mod_params, overall->envi); //TODO merge init into create? if (status != 0) { overall->modules[i] = module; if (module->flows_max < mod_flows_num) { PRINT_ERROR("Loading module parameters failed, too many flows for this library: specified=%u, max=%u", mod_flows_num, module->flows_max); exit(-1); } mt = (struct fins_module_table *) secure_malloc(sizeof(struct fins_module_table)); mt->flows_num = mod_flows_num; for (j = 0; j < mt->flows_num; j++) { mt->flows[j].link_id = mod_flows[j]; } list_append(mt_list, mt); if (mod_admin != NULL) { PRINT_IMPORTANT("Adding admin module: module=%p, lib='%s', name='%s', id=%d, index=%u", module, module->lib, module->name, module->id, module->index); list_append(overall->admin_list, module); } else { PRINT_IMPORTANT("Adding module: module=%p, lib='%s', name='%s', id=%d, index=%u", module, module->lib, module->name, module->id, module->index); } } else { PRINT_ERROR("Initialization of module failed: module=%p, lib='%s', name='%s', flows_num=%u, flows=%p, params=%p, envi=%p", module, module->lib, module->name, mod_flows_num, mod_flows, mod_params, overall->envi); exit(-1); } //free(mod_lib); //don't free, string from libconfig points to metadata memory //free(mod_name); } //############# admin_list //TODO change to admin_list? list_for_each1(overall->admin_list, assign_overall, overall); //############# linking_list PRINT_IMPORTANT("############# Configuring Linking Table"); overall->link_list = list_create(MAX_TABLE_LINKS); metadata_element *links_elem = config_lookup(meta_stack, "stack.links"); if (links_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } int links_num = config_setting_length(links_elem); metadata_element *link_elem; uint32_t link_id; uint32_t link_src; metadata_element *dsts_elem; uint32_t link_dsts[MAX_MODULES]; int link_dsts_num; struct link_record *link; for (i = 0; i < links_num; i++) { link_elem = config_setting_get_elem(links_elem, i); if (link_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(link_elem, "id", (int *) &link_id); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } status = config_setting_lookup_int(link_elem, "src", (int *) &link_src); if (status == META_FALSE) { PRINT_ERROR("todo error"); exit(-1); } dsts_elem = config_setting_get_member(link_elem, "dsts"); if (dsts_elem == NULL) { PRINT_ERROR("todo error"); exit(-1); } link_dsts_num = config_setting_length(dsts_elem); for (j = 0; j < link_dsts_num; j++) { link_dsts[j] = (uint32_t) config_setting_get_int_elem(dsts_elem, j); } //############ link = (struct link_record *) secure_malloc(sizeof(struct link_record)); link->id = link_id; //module = (struct fins_module *) list_find1(overall->envi->module_list, mod_id_test, &link_src); link->src_index = -1; for (j = 0; j < MAX_MODULES; j++) { if (overall->modules[j] != NULL && overall->modules[j]->id == link_src) { link->src_index = overall->modules[j]->index; } } if (link->src_index == -1) { PRINT_ERROR("todo error"); exit(-1); } link->dsts_num = link_dsts_num; for (j = 0; j < link_dsts_num; j++) { //module = (struct fins_module *) list_find1(overall->envi->module_list, mod_id_test, &link_dsts[j]); link->dsts_index[j] = -1; for (k = 0; k < MAX_MODULES; k++) { if (overall->modules[k] != NULL && overall->modules[k]->id == link_dsts[j]) { link->dsts_index[j] = overall->modules[k]->index; } } if (link->dsts_index[j] == (uint32_t) -1) { PRINT_ERROR("todo error"); exit(-1); } } if (list_has_space(overall->link_list)) { uint8_t buf[1000]; uint8_t *pt = buf; int ret; int i; for (i = 0; i < link->dsts_num; i++) { ret = sprintf((char *) pt, "%u, ", link->dsts_index[i]); pt += ret; } *pt = '\0'; PRINT_IMPORTANT("Adding link: link=%p, id=%u, src_index=%u, dsts_num=%u, ['%s']", link, link->id, link->src_index, link->dsts_num, buf); list_append(overall->link_list, link); } else { //TODO error PRINT_ERROR("todo error"); exit(-1); } } metadata_destroy(meta_stack); //###################################################################### PRINT_IMPORTANT("############# Updating modules with correct flows & links"); //send out subset of linking table to each module as update //TODO table subset update metadata *meta_update; struct finsFrame *ff_update; for (i = 0; i < MAX_MODULES; i++) { if (overall->modules[i] != NULL) { mt = (struct fins_module_table *) list_remove_front(mt_list); mt->link_list = list_filter1(overall->link_list, link_src_test, &overall->modules[i]->index, link_clone); //was link_involved_test, decide which better? PRINT_IMPORTANT("Module link table subset: name='%s' index=%d, link_list=%p, len=%d", overall->modules[i]->name, i, mt->link_list, mt->link_list->len); for (j = 0; j < mt->flows_num; j++) { mt->flows[j].link = (struct link_record *) list_find1(mt->link_list, link_id_test, &mt->flows[j].link_id); } //#ifdef DEBUG uint8_t buf[1000]; uint8_t *pt = buf; int ret; for (j = 0; j < mt->flows_num; j++) { ret = sprintf((char *) pt, "%u (%p), ", mt->flows[j].link_id, mt->flows[j].link); pt += ret; } *pt = '\0'; PRINT_IMPORTANT("Module flows: num=%u, ['%s']", mt->flows_num, buf); list_for_each(mt->link_list, link_print); //#endif meta_update = (metadata *) secure_malloc(sizeof(metadata)); metadata_create(meta_update); ff_update = (struct finsFrame*) secure_malloc(sizeof(struct finsFrame)); ff_update->dataOrCtrl = FF_CONTROL; ff_update->destinationID = i; ff_update->metaData = meta_update; ff_update->ctrlFrame.sender_id = 0; ff_update->ctrlFrame.serial_num = gen_control_serial_num(); ff_update->ctrlFrame.opcode = CTRL_SET_PARAM; ff_update->ctrlFrame.param_id = MOD_SET_PARAM_DUAL; ff_update->ctrlFrame.data_len = sizeof(struct fins_module_table); ff_update->ctrlFrame.data = (uint8_t *) mt; module_to_switch(overall->modules[0], ff_update); //module_set_param_dual(overall->modules[i], ff_update); } } list_free(mt_list, free); //############ say by this point envi var completely init'd //assumed always connect/init to switch first pthread_attr_init(&overall->attr); pthread_attr_setdetachstate(&overall->attr, PTHREAD_CREATE_JOINABLE); PRINT_IMPORTANT("############# Calling run() for modules"); for (i = 0; i < MAX_MODULES; i++) { if (overall->modules[i] != NULL) { overall->modules[i]->ops->run(overall->modules[i], &overall->attr); } } PRINT_IMPORTANT("Core Initiation: Finished ************"); }
// TODO: stop abusing NAME_MAX ;-) // TODO: proper bounds checking for all types static void config2options(const config_t * config, struct Options * options) { // generic group struct Options_generic gn_opt; { double frequency; int logging, silent; char logfile[NAME_MAX], create[NAME_MAX]; long long processes_begin, processes_end, threads_begin, threads_end; config_setting_t * generic = config_lookup(config, FLD_GENERIC_GROUP); config_setting_lookup_float(generic, FLD_GENERIC_GPU_FREQUENCY, &frequency); config_setting_lookup_bool(generic, FLD_GENERIC_LOGGING, &logging); c2o_strncpy(logfile, config_setting_get_member(generic, FLD_GENERIC_LOGFILE), NAME_MAX); c2o_strncpy(create, config_setting_get_member(generic, FLD_GENERIC_SPAWN), NAME_MAX); config_setting_lookup_int64(generic, FLD_GENERIC_PROCESSES_BEGIN, &processes_begin); config_setting_lookup_int64(generic, FLD_GENERIC_PROCESSES_END, &processes_end); config_setting_lookup_int64(generic, FLD_GENERIC_THREADS_BEGIN, &threads_begin); config_setting_lookup_int64(generic, FLD_GENERIC_THREADS_END, &threads_end); config_setting_lookup_bool(generic, FLD_GENERIC_SILENT, &silent); gn_opt = Options_generic { spawn_typeFromString(create), frequency, (bool)logging, "", // XXX strncpy ! (log filename) (unsigned)processes_begin, (unsigned)processes_end, (bool)silent, (unsigned)threads_begin, (unsigned)threads_end }; strncpy(gn_opt.csvlogname, logfile, NAME_MAX); } // walking array group struct Options_walkarray wa_opt; { long long aaccesses, begin, repetitions, end, step; char scaling[NAME_MAX], pattern[NAME_MAX]; config_setting_t * array = config_lookup(config, FLD_WALKARRAY_GROUP); config_setting_lookup_int64(array, FLD_WALKARRAY_ACCESSES, &aaccesses); config_setting_lookup_int64(array, FLD_WALKARRAY_REPEAT, &repetitions); config_setting_lookup_int64(array, FLD_WALKARRAY_BEGINLENGTH, &begin); config_setting_lookup_int64(array, FLD_WALKARRAY_ENDLENGTH, &end); config_setting_lookup_int64(array, FLD_WALKARRAY_INCREMENT, &step); c2o_strncpy(scaling, config_setting_get_member(array, FLD_WALKARRAY_SCALING), NAME_MAX); c2o_strncpy(pattern, config_setting_get_member(array, FLD_WALKARRAY_PATTERN), NAME_MAX); wa_opt = Options_walkarray { (unsigned)aaccesses, (walking_t)begin, (walking_t)end, pattern_typeFromString(pattern), (unsigned)repetitions, (walking_t)step }; } // streaming array group struct Options_streamarray sa_opt; { long long begin, end, step; char scaling[NAME_MAX]; config_setting_t * array = config_lookup(config, FLD_STREAMARRAY_GROUP); config_setting_lookup_int64(array, FLD_STREAMARRAY_BEGINLENGTH, &begin); config_setting_lookup_int64(array, FLD_STREAMARRAY_ENDLENGTH, &end); config_setting_lookup_int64(array, FLD_STREAMARRAY_INCREMENT, &step); c2o_strncpy(scaling, config_setting_get_member(array, FLD_STREAMARRAY_SCALING), NAME_MAX); sa_opt = Options_streamarray { (unsigned)begin, (unsigned)end, (unsigned)step }; } // flops array group struct Options_flopsarray fa_opt; { long long begin, end, step, calculations; char scaling[NAME_MAX]; config_setting_t * array = config_lookup(config, FLD_FLOPSARRAY_GROUP); config_setting_lookup_int64(array, FLD_FLOPSARRAY_BEGINLENGTH, &begin); config_setting_lookup_int64(array, FLD_FLOPSARRAY_ENDLENGTH, &end); config_setting_lookup_int64(array, FLD_FLOPSARRAY_INCREMENT, &step); config_setting_lookup_int64(array, FLD_FLOPSARRAY_CALCULATIONS, &calculations); c2o_strncpy(scaling, config_setting_get_member(array, FLD_FLOPSARRAY_SCALING), NAME_MAX); fa_opt = Options_flopsarray { (unsigned)begin, (unsigned)end, (unsigned long long)calculations, (unsigned)step }; } options->generic = gn_opt; options->walkArray = wa_opt; options->streamArray = sa_opt; options->flopsArray = fa_opt; }
int consensus_read_config(node* cur_node,const char* config_path){ config_t config_file; config_init(&config_file); if(!config_read_file(&config_file,config_path)){ goto goto_config_error; } uint32_t group_size; if(!config_lookup_int(&config_file,"group_size",(int*)&group_size)){ goto goto_config_error; } cur_node->group_size = group_size; cur_node->peer_pool = (peer*)malloc(group_size*sizeof(peer)); if(NULL==cur_node->peer_pool){ goto goto_config_error; } if(group_size<=cur_node->node_id){ err_log("CONSENSUS : Configuration Reading Error : Invalid Node Id.\n"); goto goto_config_error; } config_setting_t *consensus_global_config = NULL; consensus_global_config = config_lookup(&config_file,"consensus_global_config"); if(NULL!=consensus_global_config){ long long temp; if(config_setting_lookup_int64(consensus_global_config,"progress_timeval_s",&temp)){ cur_node->config.make_progress_timeval.tv_sec = temp; } if(config_setting_lookup_int64(consensus_global_config,"progress_timeval_us",&temp)){ cur_node->config.make_progress_timeval.tv_usec = temp; } if(config_setting_lookup_int64(consensus_global_config,"reconnect_timeval_s",&temp)){ cur_node->config.reconnect_timeval.tv_sec = temp; } if(config_setting_lookup_int64(consensus_global_config,"reconnect_timeval_us",&temp)){ cur_node->config.reconnect_timeval.tv_usec = temp; } if(config_setting_lookup_int64(consensus_global_config,"ping_timeval_s",&temp)){ cur_node->config.ping_timeval.tv_sec = temp; } if(config_setting_lookup_int64(consensus_global_config,"ping_timeval_us",&temp)){ cur_node->config.ping_timeval.tv_usec = temp; } if(config_setting_lookup_int64(consensus_global_config,"expected_ping_timeval_s",&temp)){ cur_node->config.expect_ping_timeval.tv_sec = temp; } if(config_setting_lookup_int64(consensus_global_config,"expected_ping_timeval_us",&temp)){ cur_node->config.expect_ping_timeval.tv_usec = temp; } } config_setting_t *nodes_config; nodes_config = config_lookup(&config_file,"consensus_config"); if(NULL==nodes_config){ err_log("CONSENSUS : Cannot Find Nodes Settings.\n"); goto goto_config_error; } if(NULL==nodes_config){ err_log("CONSENSUS : Cannot Find Net Address Section.\n"); goto goto_config_error; } peer* peer_pool = cur_node->peer_pool; for(uint32_t i=0;i<group_size;i++){ config_setting_t *node_config = config_setting_get_elem(nodes_config,i); if(NULL==node_config){ err_log("CONSENSUS : Cannot Find Node%u's Address.\n",i); goto goto_config_error; } const char* peer_ipaddr; int peer_port; if(!config_setting_lookup_string(node_config,"ip_address",&peer_ipaddr)){ goto goto_config_error; } if(!config_setting_lookup_int(node_config,"port",&peer_port)){ goto goto_config_error; } peer_pool[i].my_node = cur_node; peer_pool[i].peer_id = i; peer_pool[i].base = cur_node->base; peer_pool[i].reconnect = NULL; peer_pool[i].active = 0; peer_pool[i].my_buff_event = NULL; peer_pool[i].sock_id = -1; peer_pool[i].peer_address = (struct sockaddr_in*)malloc(sizeof(struct sockaddr_in)); peer_pool[i].sock_len = sizeof(struct sockaddr_in); peer_pool[i].peer_address->sin_family =AF_INET; inet_pton(AF_INET,peer_ipaddr,&peer_pool[i].peer_address->sin_addr); peer_pool[i].peer_address->sin_port = htons(peer_port); if(i==cur_node->node_id){ config_setting_lookup_int(node_config,"sys_log",&cur_node->sys_log); config_setting_lookup_int(node_config,"stat_log",&cur_node->stat_log); const char* db_name; if(!config_setting_lookup_string(node_config,"db_name",&db_name)){ goto goto_config_error; } size_t db_name_len = strlen(db_name); cur_node->db_name = (char*)malloc(sizeof(char)*(db_name_len+1)); if(cur_node->db_name==NULL){ goto goto_config_error; } if(NULL==strncpy(cur_node->db_name,db_name,db_name_len)){ free(cur_node->db_name); goto goto_config_error; } cur_node->db_name[db_name_len] = '\0'; cur_node->my_address.sin_port = htons(peer_port); cur_node->my_address.sin_family = AF_INET; inet_pton(AF_INET,peer_ipaddr,&cur_node->my_address.sin_addr); } } config_destroy(&config_file); return 0; goto_config_error: err_log("CONSENSUS : %s:%d - %s\n", config_error_file(&config_file), config_error_line(&config_file), config_error_text(&config_file)); config_destroy(&config_file); return -1; };