diff options
-rwxr-xr-x | linux/ws_main.py | 3 | ||||
-rwxr-xr-x | src/bp_sim.cpp | 139 | ||||
-rwxr-xr-x | src/bp_sim.h | 32 | ||||
-rw-r--r-- | src/mac_mapping.h | 4 | ||||
-rwxr-xr-x | src/main.cpp | 3 | ||||
-rw-r--r-- | src/main_dpdk.cpp | 3 | ||||
-rw-r--r-- | src/sim/trex_sim_stateful.cpp | 6 | ||||
-rw-r--r-- | src/trex_client_config.cpp | 24 | ||||
-rw-r--r-- | src/trex_client_config.h | 25 | ||||
-rwxr-xr-x | src/tuple_gen.cpp | 170 | ||||
-rwxr-xr-x | src/tuple_gen.h | 190 | ||||
-rwxr-xr-x | src/utl_yaml.cpp | 69 | ||||
-rwxr-xr-x | src/utl_yaml.h | 20 |
13 files changed, 380 insertions, 308 deletions
diff --git a/linux/ws_main.py b/linux/ws_main.py index 6dccf597..0ee2fd3b 100755 --- a/linux/ws_main.py +++ b/linux/ws_main.py @@ -97,7 +97,7 @@ bp_sim_main = SrcGroup(dir='src', bp_sim_gtest = SrcGroup(dir='src', src_list=[ 'bp_gtest.cpp', - 'gtest/tuple_gen_test.cpp', + #'gtest/tuple_gen_test.cpp', 'gtest/nat_test.cpp', 'gtest/trex_stateless_gtest.cpp' ]) @@ -122,6 +122,7 @@ main_src = SrcGroup(dir='src', 'flow_stat.cpp', 'flow_stat_parser.cpp', 'trex_watchdog.cpp', + 'trex_client_config.cpp', 'pal/linux/pal_utl.cpp', 'pal/linux/mbuf.cpp', 'pal/common/common_mbuf.cpp', diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp index db90107d..abedf95c 100755 --- a/src/bp_sim.cpp +++ b/src/bp_sim.cpp @@ -2449,26 +2449,6 @@ void CCapFileFlowInfo::Delete(){ RemoveAll(); } -void operator >> (const YAML::Node& node, mac_mapping_t &fi) { - utl_yaml_read_ip_addr(node,"ip", fi.ip); - const YAML::Node& mac_info = node["mac"]; - for(unsigned i=0;i<mac_info.size();i++) { - const YAML::Node & node_2 =mac_info; - uint32_t value; - node_2[i] >> value; - fi.mac.mac[i] = value; - } -} - -void operator >> (const YAML::Node& node, std::map<uint32_t, mac_addr_align_t> &mac_info) { - const YAML::Node& mac_node = node["items"]; - mac_mapping_t mac_mapping; - for (unsigned i=0;i<mac_node.size();i++) { - mac_node[i] >> mac_mapping; - mac_info[mac_mapping.ip] = mac_mapping.mac; - } -} - void operator >> (const YAML::Node& node, CFlowYamlDpPkt & fi) { uint32_t val; node["pkt_id"] >> val; @@ -3348,7 +3328,7 @@ bool CFlowGenListPerThread::Create(uint32_t thread_id, /* split the clients to threads */ CTupleGenYamlInfo * tuple_gen = &m_flow_list->m_yaml_info.m_tuple_gen; - m_smart_gen.Create(0,m_thread_id,m_flow_list->get_is_mac_conf()); + m_smart_gen.Create(0,m_thread_id); /* split the clients to threads using the mask */ CIpPortion portion; @@ -3358,14 +3338,14 @@ bool CFlowGenListPerThread::Create(uint32_t thread_id, portion); m_smart_gen.add_client_pool(tuple_gen->m_client_pool[i].m_dist, - portion.m_ip_start, - portion.m_ip_end, - get_longest_flow(i,true), - get_total_kcps(i,true)*1000, - &m_flow_list->m_mac_info, - tuple_gen->m_client_pool[i].m_tcp_aging_sec, - tuple_gen->m_client_pool[i].m_udp_aging_sec - ); + portion.m_ip_start, + portion.m_ip_end, + get_longest_flow(i,true), + get_total_kcps(i,true)*1000, + m_flow_list->m_client_config_info, + tuple_gen->m_client_pool[i].m_tcp_aging_sec, + tuple_gen->m_client_pool[i].m_udp_aging_sec + ); } for (int i=0;i<tuple_gen->m_server_pool.size();i++) { split_ips(m_thread_id, m_max_threads, getDualPortId(), @@ -4419,32 +4399,16 @@ void CFlowGenList::clean_p_thread_info(void){ m_threads_info.clear(); } - - -int CFlowGenList::load_from_mac_file(std::string file_name) { - if ( !utl_is_file_exists (file_name) ){ - printf(" ERROR no mac_file is set, file %s does not exist \n",file_name.c_str()); - exit(-1); - } - m_mac_info.set_configured(true); - - try { - std::ifstream fin((char *)file_name.c_str()); - YAML::Parser parser(fin); - YAML::Node doc; - - parser.GetNextDocument(doc); - doc[0] >> m_mac_info.get_mac_info(); - } catch ( const std::exception& e ) { - std::cout << e.what() << "\n"; - m_mac_info.clear(); - exit(-1); - } - - return (0); +int CFlowGenList::load_client_config_file(std::string file_name) { + try { + m_client_config_info.load_yaml_file(file_name); + } catch (const std::exception& e) { + std::cout << e.what() << "\n"; + exit(-1); + } + return (0); } - int CFlowGenList::load_from_yaml(std::string file_name, uint32_t num_threads){ uint8_t idx; @@ -4756,7 +4720,7 @@ bool CParserOption::is_valid_opt_val(int val, int min, int max, const std::strin void CParserOption::dump(FILE *fd){ preview.Dump(fd); fprintf(fd," cfg file : %s \n",cfg_file.c_str()); - fprintf(fd," mac file : %s \n",mac_file.c_str()); + fprintf(fd," mac file : %s \n",client_cfg_file.c_str()); fprintf(fd," out file : %s \n",out_file.c_str()); fprintf(fd," duration : %.0f \n",m_duration); fprintf(fd," factor : %.0f \n",m_factor); @@ -5068,37 +5032,62 @@ int CErfIFStl::send_node(CGenNode * _no_to_use){ return (0); } +void CErfIF::add_vlan(uint16_t vlan_id) { + uint8_t *buffer =(uint8_t *)m_raw->raw; + uint16_t vlan_protocol = EthernetHeader::Protocol::VLAN; + uint32_t vlan_tag = (vlan_protocol << 16) | vlan_id; + vlan_tag = PKT_HTONL(vlan_tag); -int CErfIF::send_node(CGenNode * node){ + /* insert vlan tag and adjust packet size */ + memcpy(cbuff+4, buffer + 12, m_raw->pkt_len - 12); + memcpy(cbuff, &vlan_tag, 4); + memcpy(buffer + 12, cbuff, m_raw->pkt_len-8); - if ( m_preview_mode->getFileWrite() ){ + m_raw->pkt_len += 4; +} - CFlowPktInfo * lp=node->m_pkt_info; - rte_mbuf_t * m=lp->generate_new_mbuf(node); - pkt_dir_t dir=node->cur_interface_dir(); +void CErfIF::apply_client_config(CGenNode *node, pkt_dir_t dir) { + uint8_t *p =(uint8_t *)m_raw->raw; + uint16_t vlan_id; + + if (dir == CLIENT_SIDE) { + memcpy(p, node->m_client_cfg->m_init_mac, 6); + vlan_id = node->m_client_cfg->m_init_vlan; + } else { + memcpy(p, node->m_client_cfg->m_res_mac, 6); + vlan_id = node->m_client_cfg->m_res_vlan; + } + + add_vlan(vlan_id); + +} + +int CErfIF::send_node(CGenNode *node){ + + if (!m_preview_mode->getFileWrite()) { + return (0); + } - fill_raw_packet(m,node,dir); + CFlowPktInfo *lp = node->m_pkt_info; + rte_mbuf_t *m = lp->generate_new_mbuf(node); + pkt_dir_t dir = node->cur_interface_dir(); + + fill_raw_packet(m, node, dir); /* update mac addr dest/src 12 bytes */ uint8_t *p=(uint8_t *)m_raw->raw; int p_id=(int)dir; memcpy(p,CGlobalInfo::m_options.get_dst_src_mac_addr(p_id),12); - /* If vlan is enabled, add vlan header */ - if ( unlikely( CGlobalInfo::m_options.preview.get_vlan_mode_enable() ) ){ - /* retrieve vlan ID and form vlan tag */ - uint8_t vlan_port = (node->m_src_ip &1); - uint16_t vlan_protocol = EthernetHeader::Protocol::VLAN; - uint16_t vlan_id = CGlobalInfo::m_options.m_vlan_port[vlan_port]; - uint32_t vlan_tag = (vlan_protocol << 16) | vlan_id; - vlan_tag = PKT_HTONL(vlan_tag); + /* if a client configuration was provided - apply the config */ + if (node->m_client_cfg) { + apply_client_config(node, dir); - /* insert vlan tag and adjust packet size */ - memcpy(cbuff+4, p+12, m_raw->pkt_len-12); - memcpy(cbuff, &vlan_tag, 4); - memcpy(p+12, cbuff, m_raw->pkt_len-8); - m_raw->pkt_len += 4; + } else if (CGlobalInfo::m_options.preview.get_vlan_mode_enable()) { + uint8_t vlan_port = (node->m_src_ip & 1); + uint16_t vlan_id = CGlobalInfo::m_options.m_vlan_port[vlan_port]; + add_vlan(vlan_id); } //utl_DumpBuffer(stdout,p, 12,0); @@ -5107,8 +5096,8 @@ int CErfIF::send_node(CGenNode * node){ BP_ASSERT(rc == 0); rte_pktmbuf_free(m); - } - return (0); + + return (0); } int CErfIF::flush_tx_queue(void){ diff --git a/src/bp_sim.h b/src/bp_sim.h index e396a710..37263cb5 100755 --- a/src/bp_sim.h +++ b/src/bp_sim.h @@ -59,6 +59,7 @@ limitations under the License. #include "platform_cfg.h" #include "flow_stat.h" #include "trex_watchdog.h" +#include "trex_client_config.h" #include <trex_stateless_dp_core.h> @@ -182,6 +183,12 @@ inline int ip_to_str(uint32_t ip,char * str){ return(strlen(str)); } +inline std::string ip_to_str(uint32_t ip) { + char tmp[INET_ADDRSTRLEN]; + ip_to_str(ip, tmp); + return tmp; +} + // Routine to create IPv6 address string inline int ipv6_to_str(ipaddr_t *ip,char * str){ int idx=0; @@ -817,7 +824,7 @@ public: std::string cfg_file; - std::string mac_file; + std::string client_cfg_file; std::string platform_cfg_file; std::string out_file; @@ -1565,7 +1572,7 @@ public: uint16_t m_nat_external_port; uint16_t m_nat_pad[3]; - mac_addr_align_t m_src_mac; + ClientCfg *m_client_cfg; uint32_t m_src_idx; uint32_t m_dest_idx; uint32_t m_end_of_cache_line[6]; @@ -1911,7 +1918,8 @@ public: protected: - + void add_vlan(uint16_t vlan_id); + void apply_client_config(CGenNode *node, pkt_dir_t dir); virtual void fill_raw_packet(rte_mbuf_t * m,CGenNode * node,pkt_dir_t dir); CFileWriterBase * m_writer; @@ -3874,7 +3882,8 @@ public: public: int load_from_yaml(std::string csv_file,uint32_t num_threads); - int load_from_mac_file(std::string csv_file); + int load_client_config_file(std::string file_name); + public: void Dump(FILE *fd); void DumpCsv(FILE *fd); @@ -3888,12 +3897,12 @@ public: double get_total_tx_bps(); uint32_t get_total_repeat_flows(); double get_delta_flow_is_sec(); - bool get_is_mac_conf() { return m_mac_info.is_configured();} + public: - std::vector<CFlowGeneratorRec *> m_cap_gen; /* global info */ - CFlowsYamlInfo m_yaml_info; /* global yaml*/ - std::vector<CFlowGenListPerThread *> m_threads_info; - CFlowGenListMac m_mac_info; + std::vector<CFlowGeneratorRec *> m_cap_gen; /* global info */ + CFlowsYamlInfo m_yaml_info; /* global yaml*/ + std::vector<CFlowGenListPerThread *> m_threads_info; + ClientCfgDB m_client_config_info; }; @@ -3933,9 +3942,8 @@ inline void CCapFileFlowInfo::generate_flow(CTupleTemplateGeneratorSmart * tup node->m_src_idx = tuple.getClientId(); node->m_dest_idx = tuple.getServerId(); node->m_src_port = tuple.getClientPort(); - memcpy(&node->m_src_mac, - tuple.getClientMac(), - sizeof(mac_addr_align_t)); + node->m_client_cfg = tuple.getClientCfg(); + node->m_plugin_info =(void *)0; if ( unlikely( CGlobalInfo::is_learn_mode() ) ){ diff --git a/src/mac_mapping.h b/src/mac_mapping.h index 84151e8c..ed9c5d88 100644 --- a/src/mac_mapping.h +++ b/src/mac_mapping.h @@ -1,6 +1,6 @@ #ifndef MAC_MAPPING_H_ #define MAC_MAPPING_H_ - +#if 0 #define INUSED 0 #define UNUSED 1 typedef struct mac_addr_align_ { @@ -57,4 +57,6 @@ private: std::map<uint32_t, mac_addr_align_t> m_mac_info; /* global mac info loaded form mac_file*/ }; +/*********************************************************************************/ +#endif #endif //MAC_MAPPING_H_ diff --git a/src/main.cpp b/src/main.cpp index 62eee880..90e48549 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,6 +22,7 @@ limitations under the License. #include "bp_sim.h" #include "os_time.h" +#include "trex_client_config.h" #include <unordered_map> #include <string> @@ -160,7 +161,7 @@ static int parse_options(int argc, break; case OPT_MAC_FILE: - po->mac_file = args.OptionArg(); + po->client_cfg_file = args.OptionArg(); break; case OPT_FILE_OUT: diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index 941612b1..ad9858a2 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -2022,9 +2022,12 @@ void CCoreEthIF::update_mac_addr(CGenNode * node,uint8_t *p){ if ( unlikely( CGlobalInfo::m_options.preview.get_mac_ip_mapping_enable() ) ) { /* mac mapping file is configured */ + #if 0 if ( node->is_initiator_pkt() && (node->m_src_mac.inused==INUSED)) { memcpy(p+6, &node->m_src_mac.mac, 6); } + #endif + } else if ( unlikely( CGlobalInfo::m_options.preview.get_mac_ip_overide_enable() ) ){ /* client side */ if ( node->is_initiator_pkt() ){ diff --git a/src/sim/trex_sim_stateful.cpp b/src/sim/trex_sim_stateful.cpp index 88698cd1..93eda2fe 100644 --- a/src/sim/trex_sim_stateful.cpp +++ b/src/sim/trex_sim_stateful.cpp @@ -165,6 +165,12 @@ int load_list_of_cap_files(CParserOption * op){ CFlowGenList fl; fl.Create(); fl.load_from_yaml(op->cfg_file,1); + + if (op->client_cfg_file != "") { + fl.load_client_config_file(op->client_cfg_file); + CGlobalInfo::m_options.preview.set_mac_ip_mapping_enable(true); + } + if ( op->preview.getVMode() >0 ) { fl.DumpCsv(stdout); } diff --git a/src/trex_client_config.cpp b/src/trex_client_config.cpp index f9ad0e6c..9a5e4f6f 100644 --- a/src/trex_client_config.cpp +++ b/src/trex_client_config.cpp @@ -31,7 +31,7 @@ limitations under the License. #include "bp_sim.h" void -ClientGroup::dump() const { +ClientCfgEntry::dump() const { std::cout << "IP start: " << ip_to_str(m_ip_start) << "\n"; std::cout << "IP end: " << ip_to_str(m_ip_end) << "\n"; @@ -60,7 +60,7 @@ ClientGroup::dump() const { * */ void -ClientGroupsDB::load_yaml_file(const std::string &filename) { +ClientCfgDB::load_yaml_file(const std::string &filename) { std::stringstream ss; m_filename = filename; @@ -78,7 +78,7 @@ ClientGroupsDB::load_yaml_file(const std::string &filename) { for (int i = 0; i < root.size(); i++) { const YAML::Mark &mark = root[i].GetMark(); - ClientGroup group; + ClientCfgEntry group; bool rc; /* ip_start */ @@ -127,14 +127,14 @@ ClientGroupsDB::load_yaml_file(const std::string &filename) { } void -ClientGroupsDB::verify() const { +ClientCfgDB::verify() const { std::stringstream ss; uint32_t monotonic = 0; /* check that no interval overlaps */ for (const auto &p : m_groups) { - const ClientGroup &group = p.second; + const ClientCfgEntry &group = p.second; if ( (monotonic > 0 ) && (group.m_ip_start <= monotonic) ) { ss << "IP '" << ip_to_str(group.m_ip_start) << "' - '" << ip_to_str(group.m_ip_end) << "' overlaps with other groups"; @@ -150,15 +150,15 @@ ClientGroupsDB::verify() const { * should be fast * */ -ClientGroup * -ClientGroupsDB::lookup(uint32_t ip) { +ClientCfgEntry * +ClientCfgDB::lookup(uint32_t ip) { /* check the cache */ if ( (m_cache_group) && (m_cache_group->contains(ip)) ) { return m_cache_group; } - std::map<uint32_t ,ClientGroup>::iterator it; + std::map<uint32_t ,ClientCfgEntry>::iterator it; it = m_groups.upper_bound(ip); @@ -170,7 +170,7 @@ ClientGroupsDB::lookup(uint32_t ip) { /* go one back - we know it's not on begin so we have at least one back */ it--; - ClientGroup &group = (*it).second; + ClientCfgEntry &group = (*it).second; /* because this is a non overlapping intervals if IP exists it must be in this group @@ -188,8 +188,8 @@ ClientGroupsDB::lookup(uint32_t ip) { } -ClientGroup * -ClientGroupsDB::lookup(const std::string &ip) { +ClientCfgEntry * +ClientCfgDB::lookup(const std::string &ip) { uint32_t addr = (uint32_t)inet_addr(ip.c_str()); addr = PKT_NTOHL(addr); @@ -198,7 +198,7 @@ ClientGroupsDB::lookup(const std::string &ip) { void -ClientGroupsDB::yaml_parse_err(const std::string &err, const YAML::Mark *mark) const { +ClientCfgDB::yaml_parse_err(const std::string &err, const YAML::Mark *mark) const { std::stringstream ss; if (mark) { diff --git a/src/trex_client_config.h b/src/trex_client_config.h index 442d228b..f934517d 100644 --- a/src/trex_client_config.h +++ b/src/trex_client_config.h @@ -41,13 +41,14 @@ public: }; /** - * describes a single client group - * configuration + * describes a single client config + * entry loaded from the config file + * */ -class ClientGroup { +class ClientCfgEntry { public: - ClientGroup() { + ClientCfgEntry() { reset(); } @@ -104,10 +105,10 @@ private: * describes the DB of every client group * */ -class ClientGroupsDB { +class ClientCfgDB { public: - ClientGroupsDB() { + ClientCfgDB() { m_is_empty = true; m_cache_group = NULL; } @@ -134,8 +135,8 @@ public: * a group that contains this IP * */ - ClientGroup * lookup(uint32_t ip); - ClientGroup * lookup(const std::string &ip); + ClientCfgEntry * lookup(uint32_t ip); + ClientCfgEntry * lookup(const std::string &ip); private: @@ -148,10 +149,10 @@ private: void verify() const; /* maps the IP start value to client groups */ - std::map<uint32_t, ClientGroup> m_groups; - ClientGroup *m_cache_group; - std::string m_filename; - bool m_is_empty; + std::map<uint32_t, ClientCfgEntry> m_groups; + ClientCfgEntry *m_cache_group; + std::string m_filename; + bool m_is_empty; }; #endif /* __TREX_CLIENT_CONFIG_H__ */ diff --git a/src/tuple_gen.cpp b/src/tuple_gen.cpp index d221a4d9..c964955a 100755 --- a/src/tuple_gen.cpp +++ b/src/tuple_gen.cpp @@ -25,6 +25,7 @@ limitations under the License. #include "tuple_gen.h" #include <string.h> #include "utl_yaml.h" +#include "bp_sim.h" void CServerPool::Create(IP_DIST_t dist_value, uint32_t min_ip, @@ -52,81 +53,95 @@ void CServerPool::Create(IP_DIST_t dist_value, -void CClientPool::Create(IP_DIST_t dist_value, - uint32_t min_ip, - uint32_t max_ip, - double l_flow, - double t_cps, - CFlowGenListMac* mac_info, - bool has_mac_map, - uint16_t tcp_aging, - uint16_t udp_aging) { - assert(max_ip>=min_ip); +void CClientPool::Create(IP_DIST_t dist_value, + uint32_t min_ip, + uint32_t max_ip, + double l_flow, + double t_cps, + ClientCfgDB &client_info, + uint16_t tcp_aging, + uint16_t udp_aging) { + + assert(max_ip >= min_ip); + set_dist(dist_value); - uint32_t total_ip = max_ip - min_ip +1; - uint32_t avail_ip = total_ip; - if (has_mac_map && (mac_info!=NULL)) { - for(int idx=0;idx<total_ip;idx++){ - mac_addr_align_t *mac_adr = NULL; - mac_adr = mac_info->get_mac_addr_by_ip(min_ip+idx); - if (mac_adr == NULL) { - avail_ip--; - } - } - } - if (avail_ip!=0) { - m_ip_info.resize(avail_ip); + + uint32_t total_ip = max_ip - min_ip +1; + bool is_long_range = total_ip > (l_flow * t_cps / MAX_PORT); + + m_ip_info.resize(total_ip); + + /* if client info is empty - flat allocation o.w use configured clients */ + if (client_info.is_empty()) { + allocate_simple_clients(min_ip, total_ip, is_long_range); } else { - printf("\n Error, invalid mac file is configured.\n"); - assert(0); + allocate_configured_clients(min_ip, total_ip, is_long_range, client_info); } - int skip_cnt=0; - if (total_ip > ((l_flow*t_cps/MAX_PORT))) { - if (has_mac_map) { - skip_cnt=0; - for(int idx=0;idx<total_ip;idx++){ - mac_addr_align_t *mac_adr = NULL; - mac_adr = mac_info->get_mac_addr_by_ip( min_ip+idx); - if (mac_adr != NULL) { - m_ip_info[idx-skip_cnt] = new CClientInfoL(has_mac_map); - m_ip_info[idx-skip_cnt]->set_ip(min_ip+idx); - m_ip_info[idx-skip_cnt]->set_mac(mac_adr); - } else { - skip_cnt++; - } - } + m_tcp_aging = tcp_aging; + m_udp_aging = udp_aging; + + CreateBase(); +} + +/** + * simple allocation of a client - no configuration was provided + * + * @author imarom (27-Jun-16) + * + * @param ip + * @param index + * @param is_long_range + */ +void CClientPool::allocate_simple_clients(uint32_t min_ip, + uint32_t total_ip, + bool is_long_range) { + + /* simple creation of clients - no extended info */ + for (uint32_t i = 0; i < total_ip; i++) { + uint32_t ip = min_ip + i; + if (is_long_range) { + m_ip_info[i] = new CSimpleClientInfo<CIpInfoL>(ip); } else { - for(int idx=0;idx<total_ip;idx++){ - m_ip_info[idx] = new CClientInfoL(has_mac_map); - m_ip_info[idx]->set_ip(min_ip+idx); - } - } - } else { - if (has_mac_map) { - skip_cnt=0; - for(int idx=0;idx<total_ip;idx++){ - mac_addr_align_t *mac_adr = NULL; - mac_adr = mac_info->get_mac_addr_by_ip(min_ip+idx); - if (mac_adr != NULL) { - m_ip_info[idx-skip_cnt] = new CClientInfo(has_mac_map); - m_ip_info[idx-skip_cnt]->set_ip(min_ip+idx); - m_ip_info[idx-skip_cnt]->set_mac(mac_adr); - } else { - skip_cnt++; - } - } + m_ip_info[i] = new CSimpleClientInfo<CIpInfo>(ip); + } + } + +} + +/** + * simple allocation of a client - no configuration was provided + * + * @author imarom (27-Jun-16) + * + * @param ip + * @param index + * @param is_long_range + */ +void CClientPool::allocate_configured_clients(uint32_t min_ip, + uint32_t total_ip, + bool is_long_range, + ClientCfgDB &client_info) { + + for (uint32_t i = 0; i < total_ip; i++) { + uint32_t ip = min_ip + i; + + /* lookup for the right group of clients */ + ClientCfgEntry *group = client_info.lookup(ip); + if (!group) { + std::cout << "could not map " << ip_to_str(ip) << "\n"; + exit(-1); + } + + ClientCfg info; + group->assign(info); + + if (is_long_range) { + m_ip_info[i] = new CConfiguredClientInfo<CIpInfoL>(ip, info); } else { - for(int idx=0;idx<total_ip;idx++){ - m_ip_info[idx] = new CClientInfo(has_mac_map); - m_ip_info[idx]->set_ip(min_ip+idx); - } - } - + m_ip_info[i] = new CConfiguredClientInfo<CIpInfo>(ip, info); + } } - m_tcp_aging = tcp_aging; - m_udp_aging = udp_aging; - CreateBase(); } @@ -135,14 +150,19 @@ bool CTupleGeneratorSmart::add_client_pool(IP_DIST_t client_dist, uint32_t max_client, double l_flow, double t_cps, - CFlowGenListMac* mac_info, + ClientCfgDB &client_info, uint16_t tcp_aging, uint16_t udp_aging){ assert(max_client>=min_client); CClientPool* pool = new CClientPool(); - pool->Create(client_dist, min_client, max_client, - l_flow, t_cps, mac_info, m_has_mac_mapping, - tcp_aging, udp_aging); + pool->Create(client_dist, + min_client, + max_client, + l_flow, + t_cps, + client_info, + tcp_aging, + udp_aging); m_client_pool.push_back(pool); return(true); @@ -170,19 +190,17 @@ bool CTupleGeneratorSmart::add_server_pool(IP_DIST_t server_dist, bool CTupleGeneratorSmart::Create(uint32_t _id, - uint32_t thread_id, - bool has_mac) + uint32_t thread_id) + { m_thread_id = thread_id; m_id = _id; m_was_init=true; - m_has_mac_mapping = has_mac; return(true); } void CTupleGeneratorSmart::Delete(){ m_was_init=false; - m_has_mac_mapping = false; for (int idx=0;idx<m_client_pool.size();idx++) { m_client_pool[idx]->Delete(); diff --git a/src/tuple_gen.h b/src/tuple_gen.h index b2f6e34a..292d1794 100755 --- a/src/tuple_gen.h +++ b/src/tuple_gen.h @@ -38,14 +38,17 @@ limitations under the License. #include <bitset> #include <yaml-cpp/yaml.h> #include <mac_mapping.h> +#include "trex_client_config.h" #include <random> class CTupleBase { public: + CTupleBase() { - m_client_mac.inused = UNUSED; + m_client_cfg = NULL; } + uint32_t getClient() { return m_client_ip; } @@ -83,22 +86,20 @@ public: void setClientPort(uint16_t port) { m_client_port = port; } - mac_addr_align_t* getClientMac() { - return &m_client_mac; + void setClientCfg(ClientCfg *cfg) { + m_client_cfg = cfg; } - void setClientMac(mac_addr_align_t* mac_info) { - if (mac_info != NULL) { - memcpy(&m_client_mac, mac_info, sizeof(mac_addr_align_t)); - m_client_mac.inused = INUSED; - } else { - m_client_mac.inused = UNUSED; - } + ClientCfg *getClientCfg() { + return m_client_cfg; } - void setClientTuple(uint32_t ip,mac_addr_align_t*mac,uint16_t port) { + + + void setClientTuple(uint32_t ip, ClientCfg *cfg, uint16_t port) { setClient(ip); - setClientMac(mac); setClientPort(port); + setClientCfg(cfg); } + void setClientAll2(uint32_t id, uint32_t ip,uint16_t port) { setClientId(id); setClient(ip); @@ -121,9 +122,12 @@ public: private: uint32_t m_client_ip; uint32_t m_client_idx; + uint32_t m_server_ip; uint32_t m_server_idx; - mac_addr_align_t m_client_mac; + + ClientCfg *m_client_cfg; + uint16_t m_client_port; uint16_t m_server_port; }; @@ -171,8 +175,6 @@ typedef enum { class CIpInfoBase { public: - virtual mac_addr_align_t* get_mac() { return NULL;} - virtual void set_mac(mac_addr_align_t*){;} virtual uint16_t get_new_free_port() = 0; virtual void return_port(uint16_t a) = 0; virtual void generate_tuple(CTupleBase & tuple) = 0; @@ -303,76 +305,54 @@ class CIpInfo : public CIpInfoBase { } }; -class CClientInfo : public CIpInfo { + +/** + * a flat client info (no configuration) + * + * using template to avoid duplicating the code for CIpInfo and + * CIpInfoL + * + * @author imarom (27-Jun-16) + */ +template <typename T> +class CSimpleClientInfo : public T { + public: - CClientInfo (bool has_mac) { - if (has_mac==true) { - m_mac = new mac_addr_align_t(); - } else { - m_mac = NULL; - } - } - CClientInfo () { - m_mac = NULL; - } + CSimpleClientInfo(uint32_t ip) { + T::set_ip(ip); + } - mac_addr_align_t* get_mac() { - return m_mac; - } - void set_mac(mac_addr_align_t *mac) { - memcpy(m_mac, mac, sizeof(mac_addr_align_t)); + void generate_tuple(CTupleBase &tuple) { + tuple.setClientTuple(T::m_ip, + NULL, + T::get_new_free_port()); } - ~CClientInfo() { - if (m_mac!=NULL){ - delete m_mac; - m_mac=NULL; - } - } - - void generate_tuple(CTupleBase & tuple) { - tuple.setClientTuple(m_ip, m_mac, - get_new_free_port()); - } -private: - mac_addr_align_t *m_mac; }; -class CClientInfoL : public CIpInfoL { -public: - CClientInfoL (bool has_mac) { - if (has_mac==true) { - m_mac = new mac_addr_align_t(); - } else { - m_mac = NULL; - } - } - CClientInfoL () { - m_mac = NULL; - } +/** + * a configured client object + * + * @author imarom (26-Jun-16) + */ +template <typename T> +class CConfiguredClientInfo : public T { - mac_addr_align_t* get_mac() { - return m_mac; +public: + CConfiguredClientInfo(uint32_t ip, const ClientCfg &cfg) : m_cfg(cfg) { + T::set_ip(ip); } - void set_mac(mac_addr_align_t *mac) { - memcpy(m_mac, mac, sizeof(mac_addr_align_t)); + void generate_tuple(CTupleBase &tuple) { + tuple.setClientTuple(T::m_ip, + &m_cfg, + T::get_new_free_port()); } - ~CClientInfoL() { - if (m_mac!=NULL){ - delete m_mac; - m_mac=NULL; - } - } - - void generate_tuple(CTupleBase & tuple) { - tuple.setClientTuple(m_ip, m_mac, - get_new_free_port()); - } private: - mac_addr_align_t *m_mac; + ClientCfg m_cfg; }; + class CServerInfo : public CIpInfo { void generate_tuple(CTupleBase & tuple) { tuple.setServer(m_ip); @@ -475,12 +455,6 @@ class CIpPool { client->return_port(port); } - mac_addr_align_t * get_curr_mac() { - return m_ip_info[m_cur_idx]->get_mac(); - } - mac_addr_align_t *get_mac(uint32_t idx) { - return m_ip_info[idx]->get_mac(); - } public: std::vector<CIpInfoBase*> m_ip_info; @@ -536,19 +510,30 @@ public: uint16_t get_udp_aging() { return m_udp_aging; } - void Create(IP_DIST_t dist_value, - uint32_t min_ip, - uint32_t max_ip, - double l_flow, - double t_cps, - CFlowGenListMac* mac_info, - bool has_mac_map, - uint16_t tcp_aging, - uint16_t udp_aging); + + void Create(IP_DIST_t dist_value, + uint32_t min_ip, + uint32_t max_ip, + double l_flow, + double t_cps, + ClientCfgDB &client_info, + uint16_t tcp_aging, + uint16_t udp_aging); public: uint16_t m_tcp_aging; uint16_t m_udp_aging; + +private: + void allocate_simple_clients(uint32_t min_ip, + uint32_t total_ip, + bool is_long_range); + + void allocate_configured_clients(uint32_t min_ip, + uint32_t total_ip, + bool is_long_range, + ClientCfgDB &client_info); + }; class CServerPoolBase { @@ -687,8 +672,7 @@ public: m_was_init=false; m_has_mac_mapping = false; } - bool Create(uint32_t _id, - uint32_t thread_id, bool has_mac=false); + bool Create(uint32_t _id, uint32_t thread_id); void Delete(); @@ -704,20 +688,22 @@ public: return (total_alloc_error); } - bool add_client_pool(IP_DIST_t client_dist, - uint32_t min_client, - uint32_t max_client, - double l_flow, - double t_cps, - CFlowGenListMac* mac_info, - uint16_t tcp_aging, - uint16_t udp_aging); + bool add_client_pool(IP_DIST_t client_dist, + uint32_t min_client, + uint32_t max_client, + double l_flow, + double t_cps, + ClientCfgDB &client_info, + uint16_t tcp_aging, + uint16_t udp_aging); + bool add_server_pool(IP_DIST_t server_dist, - uint32_t min_server, - uint32_t max_server, - double l_flow, - double t_cps, - bool is_bundling); + uint32_t min_server, + uint32_t max_server, + double l_flow, + double t_cps, + bool is_bundling); + CClientPool* get_client_pool(uint8_t idx) { return m_client_pool[idx]; } diff --git a/src/utl_yaml.cpp b/src/utl_yaml.cpp index 828817e4..bf30d661 100755 --- a/src/utl_yaml.cpp +++ b/src/utl_yaml.cpp @@ -21,7 +21,7 @@ See the License for the specific language governing permissions and limitations under the License. */ - +#include <istream> #define INADDRSZ 4 @@ -65,8 +65,8 @@ static int my_inet_pton4(const char *src, unsigned char *dst) bool utl_yaml_read_ip_addr(const YAML::Node& node, - std::string name, - uint32_t & val){ + const std::string &name, + uint32_t & val){ std::string tmp; uint32_t ip; bool res=false; @@ -83,8 +83,61 @@ bool utl_yaml_read_ip_addr(const YAML::Node& node, return (res); } +static void +split_str_by_delimiter(std::string str, char delim, std::vector<std::string> &tokens) { + size_t pos = 0; + std::string token; + + while ((pos = str.find(delim)) != std::string::npos) { + token = str.substr(0, pos); + tokens.push_back(token); + str.erase(0, pos + 1); + } + + if (str.size() > 0) { + tokens.push_back(str); + } +} + +bool utl_yaml_read_mac_addr(const YAML::Node &node, + const std::string &name, + uint64_t &val) { + + std::string mac_str; + + if (!node.FindValue(name)) { + return false; + } + + node[name] >> mac_str; + + std::vector<std::string> tokens; + split_str_by_delimiter(mac_str, ':', tokens); + + if (tokens.size() != 6) { + throw YAML::InvalidScalar(node[name].GetMark()); + } + + val = 0; + + for (int i = 0; i < 6 ; i++) { + char *endptr = NULL; + unsigned long octet = strtoul(tokens[i].c_str(), &endptr, 16); + + if ( (*endptr != 0) || (octet > 0xff) ) { + throw YAML::InvalidScalar(node[name].GetMark()); + } + + //mac_addr[i] = (uint8_t)octet; + val = (val << 8) + octet; + } + + return true; +} + + bool utl_yaml_read_uint32(const YAML::Node& node, - std::string name, + const std::string &name, uint32_t & val){ bool res=false; if ( node.FindValue(name) ) { @@ -95,8 +148,8 @@ bool utl_yaml_read_uint32(const YAML::Node& node, } bool utl_yaml_read_uint16(const YAML::Node& node, - std::string name, - uint16_t & val){ + const std::string &name, + uint16_t & val){ uint32_t val_tmp; bool res=false; if ( node.FindValue(name) ) { @@ -109,8 +162,8 @@ bool utl_yaml_read_uint16(const YAML::Node& node, } bool utl_yaml_read_bool(const YAML::Node& node, - std::string name, - bool & val){ + const std::string &name, + bool & val){ bool res=false; if ( node.FindValue(name) ) { node[name] >> val ; diff --git a/src/utl_yaml.h b/src/utl_yaml.h index 71655488..1ada1d66 100755 --- a/src/utl_yaml.h +++ b/src/utl_yaml.h @@ -27,19 +27,23 @@ limitations under the License. bool utl_yaml_read_ip_addr(const YAML::Node& node, - std::string name, - uint32_t & val - ); + const std::string &name, + uint32_t & val); + +bool utl_yaml_read_mac_addr(const YAML::Node &node, + const std::string &name, + uint64_t &val); bool utl_yaml_read_uint32(const YAML::Node& node, - std::string name, - uint32_t & val); + const std::string &name, + uint32_t & val); + bool utl_yaml_read_uint16(const YAML::Node& node, - std::string name, - uint16_t & val); + const std::string &name, + uint16_t & val); bool utl_yaml_read_bool(const YAML::Node& node, - std::string name, + const std::string &name, bool & val); |