/***************************************************************************** * mem_handle_cmdline_opt() * --tcb-pool-sz configuration - size in K (*1024) of the tcb mempool * default: GCFG_TCB_POOL_SIZE * --ucb-pool-sz configuration - size in K (*1024) of the ucb mempool * default: GCFG_UCB_POOL_SIZE * --mbuf-pool-sz configuration - size in K (*1024) of the mbuf mempool * default: GCFG_MBUF_POOL_SIZE * --mbuf-hdr-pool-sz configuration - size in K (*1024) of the mbuf hdr mempool * default: GCFG_MBUF_HDR_POOL_SIZE ****************************************************************************/ bool mem_handle_cmdline_opt(const char *opt_name, char *opt_arg) { global_config_t *cfg = cfg_get_config(); if (!cfg) TPG_ERROR_ABORT("ERROR: Unable to get config!\n"); if (strcmp(opt_name, "tcb-pool-sz") == 0) { cfg->gcfg_tcb_pool_size = atoi(opt_arg) * 1024ULL; return true; } if (strcmp(opt_name, "ucb-pool-sz") == 0) { cfg->gcfg_ucb_pool_size = atoi(opt_arg) * 1024ULL; return true; } if (strcmp(opt_name, "mbuf-pool-sz") == 0) { cfg->gcfg_mbuf_poolsize = atoi(opt_arg) * 1024UL; return true; } if (strcmp(opt_name, "mbuf-hdr-pool-sz") == 0) { cfg->gcfg_mbuf_hdr_poolsize = atoi(opt_arg) * 1024UL; return true; } return false; }
/***************************************************************************** * tlkp_udp_init() ****************************************************************************/ bool tlkp_udp_init(void) { global_config_t *cfg; cfg = cfg_get_config(); if (cfg == NULL) return false; L4_CB_MPOOL_INIT(mem_get_ucb_pools(), &tlkp_ucb_mpool_alloc_in_use, &ucb_l4cb_max_id); return true; }
/***************************************************************************** * mem_init() ****************************************************************************/ bool mem_init(void) { global_config_t *cfg; uint32_t core; uint32_t core_divider; /* * Add Memory module CLI commands */ if (!cli_add_main_ctx(cli_ctx)) { RTE_LOG(ERR, USER1, "ERROR: Can't add mem module specific CLI commands!\n"); return false; } cfg = cfg_get_config(); if (cfg == NULL) return false; mem_init_sockets(); core_divider = (rte_lcore_count() - TPG_NR_OF_NON_PACKET_PROCESSING_CORES); RTE_LCORE_FOREACH_SLAVE(core) { if (!cfg_is_pkt_core(core)) continue; mbuf_pool[core] = mem_create_local_pool(GCFG_MBUF_POOL_NAME, core, cfg->gcfg_mbuf_poolsize / core_divider, cfg->gcfg_mbuf_size, cfg->gcfg_mbuf_cache_size, sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, rte_pktmbuf_init, MEM_MBUF_POOL_FLAGS); if (mbuf_pool[core] == NULL) return false; mbuf_pool_tx_hdr[core] = mem_create_local_pool(GCFG_MBUF_POOL_HDR_NAME, core, cfg->gcfg_mbuf_hdr_poolsize / core_divider, cfg->gcfg_mbuf_hdr_size, cfg->gcfg_mbuf_hdr_cache_size, sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, rte_pktmbuf_init, MEM_MBUF_POOL_FLAGS); if (mbuf_pool_tx_hdr[core] == NULL) return false; mbuf_pool_clone[core] = mem_create_local_pool(GCFG_MBUF_POOL_CLONE_NAME, core, cfg->gcfg_mbuf_poolsize / core_divider, cfg->gcfg_mbuf_clone_size, cfg->gcfg_mbuf_cache_size, sizeof(struct rte_pktmbuf_pool_private), rte_pktmbuf_pool_init, rte_pktmbuf_init, MEM_MBUF_POOL_FLAGS); if (mbuf_pool_clone[core] == NULL) return false; tcb_pool[core] = mem_create_local_pool(GCFG_TCB_POOL_NAME, core, cfg->gcfg_tcb_pool_size / core_divider, sizeof(tcp_control_block_t), 0, 0, NULL, NULL, MEM_TCB_POOL_FLAGS); if (tcb_pool[core] == NULL) return false; ucb_pool[core] = mem_create_local_pool(GCFG_UCB_POOL_NAME, core, cfg->gcfg_ucb_pool_size / core_divider, sizeof(udp_control_block_t), 0, 0, NULL, NULL, MEM_UCB_POOL_FLAGS); if (ucb_pool[core] == NULL) return false; } return true; }
/******************************************************************** * FUNCTION load_running_config * * Load the NV startup config into the running config * * INPUTS: * startup == startup filespec provided by the user * == NULL if not set by user * (use default name and specified search path instead) * loaded == address of return config loaded flag * * OUTPUTS: * *loaded == TRUE if some config file was loaded * * The <running> config is loaded from NV-storage, * if the NV-storage <startup> config can be found an read * RETURNS: * status *********************************************************************/ static status_t load_running_config (const xmlChar *startup, boolean *loaded) { cfg_template_t *cfg; xmlChar *fname; agt_profile_t *profile; status_t res; res = NO_ERR; *loaded = FALSE; profile = agt_get_profile(); cfg = cfg_get_config(NCX_CFG_RUNNING); if (!cfg) { log_error("\nagt: No running config found!!"); return SET_ERROR(ERR_INTERNAL_VAL); } /* use the user-set startup or default filename */ if (startup) { /* relative filespec, use search path */ fname = ncxmod_find_data_file(startup, FALSE, &res); } else { /* search for the default startup-cfg.xml filename */ fname = ncxmod_find_data_file(NCX_DEF_STARTUP_FILE, FALSE, &res); } /* check if error finding the filespec */ if (!fname) { if (startup) { if (res == NO_ERR) { res = ERR_NCX_MISSING_FILE; } log_error("\nError: Startup config file (%s) not found (%s).", startup, get_error_string(res)); return res; } else { log_info("\nDefault startup config file (%s) not found." "\n Booting with default running configuration!\n", NCX_DEF_STARTUP_FILE); return NO_ERR; } } else if (LOGDEBUG2) { log_debug2("\nFound startup config: '%s'", fname); } /* try to load the config file that was found or given */ res = agt_ncx_cfg_load(cfg, CFG_LOC_FILE, fname); if (res == ERR_XML_READER_START_FAILED) { log_error("\nagt: Error: Could not open startup config file" "\n (%s)\n", fname); } else if (res != NO_ERR) { /* if an error is returned then it was a hard error * since the startup_error and running_error profile * variables have already been accounted for. * An error in the setup or in the AGT_RPC_PH_INVOKE phase * of the <load-config> operation occurred */ log_error("\nError: load startup config failed (%s)", get_error_string(res)); if (!dlq_empty(&cfg->load_errQ)) { *loaded = TRUE; } } else { /* assume OK or startup and running continue; if 1 or both is not * set then the server will exit anyway and the config state * will not matter */ profile->agt_config_state = AGT_CFG_STATE_OK; *loaded = TRUE; boolean errdone = FALSE; boolean errcontinue = FALSE; if (profile->agt_load_validate_errors) { if (profile->agt_startup_error) { /* quit if any startup validation errors */ log_error("\nError: validation errors occurred loading the " "<running> database\n from NV-storage" " (%s)\n", fname); errdone = TRUE; } else { /* continue if any startup errors */ log_warn("\nWarning: validation errors occurred loading " "the <running> database\n from NV-storage" " (%s)\n", fname); errcontinue = TRUE; } } if (!errdone && profile->agt_load_rootcheck_errors) { if (profile->agt_startup_error) { /* quit if any startup root-check validation errors */ log_error("\nError: root-check validation errors " "occurred loading the <running> database\n" " from NV-storage (%s)\n", fname); errdone = TRUE; } else { /* continue if any root-check validation errors */ log_warn("\nWarning: root-check validation errors " "occurred loading the <running> database\n" " from NV-storage (%s)\n", fname); errcontinue = TRUE; } } if (!errdone && profile->agt_load_top_rootcheck_errors) { if (profile->agt_running_error) { /* quit if any top-level root-check validation errors */ log_error("\nError: top-node root-check validation errors " "occurred loading the <running> database\n" " from NV-storage (%s)\n", fname); errdone = TRUE; } else { /* continue if any startup errors */ log_warn("\nWarning: top-node root-check validation errors " "occurred loading the <running> database\n" " from NV-storage (%s)\n", fname); profile->agt_config_state = AGT_CFG_STATE_BAD; errcontinue = TRUE; } } if (!errdone && profile->agt_load_apply_errors) { /* quit if any apply-to-running SIL errors */ errdone = TRUE; log_error("\nError: fatal errors " "occurred loading the <running> database " "from NV-storage\n (%s)\n", fname); } if (errdone) { res = ERR_NCX_OPERATION_FAILED; } else if (errcontinue) { val_purge_errors_from_root(cfg->root); log_info("\nagt: Startup config loaded after pruning error nodes\n" "Source: %s\n", fname); } else { log_info("\nagt: Startup config loaded OK\n Source: %s\n", fname); } } if (LOGDEBUG) { log_debug("\nContents of %s configuration:", cfg->name); val_dump_value(cfg->root, 0); log_debug("\n"); } if (fname) { m__free(fname); } return res; } /* load_running_config */
/***************************************************************************** * main() ****************************************************************************/ int main(int argc, char **argv) { global_config_t *cfg; int ret; /* * Initialize DPDK infrastructure before we do anything else */ ret = rte_eal_init(argc, argv); if (ret < 0) rte_panic("Cannot init EAL\n"); /* * Initialize RTE timer library */ rte_timer_subsystem_init(); /* * Precalculate the number of cycles per us so we don't do it everytime. */ cycles_per_us = (rte_get_timer_hz() / 1000000); /* * Return value above to be used to scan app specific options */ argc -= ret; argv += ret; /* * General checks */ if (rte_lcore_count() < 3) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s\n", "WARP17 needs at least three cores!"); /* We only support at most 64 cores right now (to make parsing easier). */ if (rte_lcore_count() > (sizeof(uint64_t) * 8)) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: WARP17 supports at most %"PRIu32" cores!\n", (uint32_t)sizeof(uint64_t) * 8); if (rte_eth_dev_count() > TPG_ETH_DEV_MAX) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: WARP17 works with at most %u ports!\n", TPG_ETH_DEV_MAX); /* * Initialize various submodules */ if (!cli_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the command line interface"); if (!rpc_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the RPC server"); if (!cfg_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s\n", "Failed initializing default configuration!\n"); if (!cfg_handle_command_line(argc, argv)) exit(EXIT_FAILURE); /* Error reporting is handled by the function itself */ if (!trace_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the tracing module"); if (!trace_filter_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the trace filter module"); if (!mem_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed allocating required mbufs"); /* WARNING: Careful when adding code above this point. Up until ports are * initialized DPDK can't know that there might be ring interfaces that * still need to be created. Therefore any call to rte_eth_dev_count() * doesn't include them. */ if (!port_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the Ethernets ports"); if (!msg_sys_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the message queues"); if (!test_mgmt_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing test mgmt"); if (!test_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing tests"); if (!eth_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the Ethernets pkt handler"); if (!arp_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the ARP pkt handler"); if (!route_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the ROUTE module"); if (!ipv4_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the IPv4 pkt handler"); if (!tcp_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the TCP pkt handler"); if (!udp_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the UDP pkt handler"); if (!tlkp_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the Session lookup engine"); if (!tlkp_tcp_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the TCP lookup engine"); if (!tlkp_udp_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the UDP lookup engine"); if (!tsm_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the TSM module"); if (!timer_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the TCP timers module"); if (!pkt_loop_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the pkt loop"); if (!raw_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the RAW Application module"); if (!http_init()) TPG_ERROR_EXIT(EXIT_FAILURE, "ERROR: %s!\n", "Failed initializing the RAW Application module"); start_cores(); /* * Process startup command file, if any. */ cfg = cfg_get_config(); if (cfg != NULL && cfg->gcfg_cmd_file) { if (!cli_run_input_file(cfg->gcfg_cmd_file)) TPG_ERROR_EXIT(EXIT_FAILURE, "Failed to run command file: %s!\n", cfg->gcfg_cmd_file); } /* * Process CLI commands, and other house keeping tasks... */ cli_interact(); tpg_exit = true; /* * Exit!!! */ rte_eal_mp_wait_lcore(); /* * Destroy the CLI. */ cli_exit(); /* * Destroy the mgmt RPC server. */ rpc_destroy(); return 0; }