diff options
-rwxr-xr-x | linux/ws_main.py | 2 | ||||
-rwxr-xr-x | linux_dpdk/ws_main.py | 2 | ||||
-rwxr-xr-x | scripts/avl/sfr_branch_profile_delay_10.yaml | 2 | ||||
-rwxr-xr-x | scripts/avl/sfr_delay_10.yaml | 2 | ||||
-rwxr-xr-x | scripts/avl/sfr_delay_10_1g.yaml | 2 | ||||
-rw-r--r-- | scripts/cap2/per_template_gen1.yaml | 40 | ||||
-rw-r--r-- | scripts/cap2/per_template_gen2.yaml | 41 | ||||
-rw-r--r-- | scripts/cap2/per_template_gen3.yaml | 41 | ||||
-rw-r--r-- | scripts/cap2/per_template_gen4.yaml | 41 | ||||
-rwxr-xr-x | scripts/cap2/per_template_gen5.yaml | 51 | ||||
-rwxr-xr-x | src/bp_gtest.cpp | 42 | ||||
-rwxr-xr-x | src/bp_sim.cpp | 199 | ||||
-rwxr-xr-x | src/bp_sim.h | 42 | ||||
-rwxr-xr-x | src/gtest/tuple_gen_test.cpp | 407 | ||||
-rwxr-xr-x | src/main_dpdk.cpp | 9 | ||||
-rwxr-xr-x | src/tuple_gen.cpp | 521 | ||||
-rwxr-xr-x | src/tuple_gen.h | 718 |
17 files changed, 1448 insertions, 714 deletions
diff --git a/linux/ws_main.py b/linux/ws_main.py index a1f207ae..8ad3e5ba 100755 --- a/linux/ws_main.py +++ b/linux/ws_main.py @@ -383,7 +383,7 @@ def build_prog (bld, build_obj): bld.program(features='cxx cxxprogram', includes =includes_path, - cxxflags =build_obj.get_flags(), + cxxflags =(build_obj.get_flags()+['-std=gnu++11',]), linkflags = build_obj.get_link_flags(), source = build_obj.get_src(), use = build_obj.get_use_libs(), diff --git a/linux_dpdk/ws_main.py b/linux_dpdk/ws_main.py index fc9fc587..80db143c 100755 --- a/linux_dpdk/ws_main.py +++ b/linux_dpdk/ws_main.py @@ -616,7 +616,7 @@ def build_prog (bld, build_obj): bld.program(features='cxx cxxprogram', includes =includes_path, - cxxflags =build_obj.get_cxx_flags(), + cxxflags =(build_obj.get_cxx_flags()+['-std=gnu++11',]), linkflags = build_obj.get_link_flags() , lib=['pthread','dl'], use =[build_obj.get_dpdk_target(),'zmq'], diff --git a/scripts/avl/sfr_branch_profile_delay_10.yaml b/scripts/avl/sfr_branch_profile_delay_10.yaml index 71e69212..04671b3e 100755 --- a/scripts/avl/sfr_branch_profile_delay_10.yaml +++ b/scripts/avl/sfr_branch_profile_delay_10.yaml @@ -4,7 +4,7 @@ clients_start : "16.0.0.1" clients_end : "16.0.1.255" servers_start : "48.0.0.1" - servers_end : "48.0.62.255" + servers_end : "48.0.63.224" clients_per_gb : 201 min_clients : 101 dual_port_mask : "1.0.0.0" diff --git a/scripts/avl/sfr_delay_10.yaml b/scripts/avl/sfr_delay_10.yaml index 1a3f82c3..2bb70fe4 100755 --- a/scripts/avl/sfr_delay_10.yaml +++ b/scripts/avl/sfr_delay_10.yaml @@ -4,7 +4,7 @@ clients_start : "16.0.0.1" clients_end : "16.0.1.255" servers_start : "48.0.0.1" - servers_end : "48.0.20.255" + servers_end : "48.0.21.245" clients_per_gb : 201 min_clients : 101 dual_port_mask : "1.0.0.0" diff --git a/scripts/avl/sfr_delay_10_1g.yaml b/scripts/avl/sfr_delay_10_1g.yaml index 925531fd..065fe855 100755 --- a/scripts/avl/sfr_delay_10_1g.yaml +++ b/scripts/avl/sfr_delay_10_1g.yaml @@ -4,7 +4,7 @@ clients_start : "16.0.0.1" clients_end : "16.0.1.255" servers_start : "48.0.0.1" - servers_end : "48.0.20.255" + servers_end : "48.0.21.245" clients_per_gb : 201 min_clients : 101 dual_port_mask : "1.0.0.0" diff --git a/scripts/cap2/per_template_gen1.yaml b/scripts/cap2/per_template_gen1.yaml new file mode 100644 index 00000000..41332518 --- /dev/null +++ b/scripts/cap2/per_template_gen1.yaml @@ -0,0 +1,40 @@ +- duration : 1.0 + generator : + distribution : "seq" + clients_start : "16.0.0.1" + clients_end : "16.0.0.255" + servers_start : "48.0.0.1" + servers_end : "48.0.255.255" + clients_per_gb : 201 + min_clients : 101 + dual_port_mask : "1.0.0.0" + tcp_aging : 0 + udp_aging : 0 + generator_clients : + - name : "c1" + distribution : "seq" + ip_start : "26.0.0.1" + ip_end : "26.0.1.255" + - name : "c2" + distribution : "seq" + ip_start : "36.0.0.1" + ip_end : "36.0.1.255" + generator_servers : + - name : "s1" + distribution : "seq" + ip_start : "28.0.0.1" + ip_end : "28.0.1.255" + track_ports : false + - name : "s2" + distribution : "seq" + ip_start : "38.0.0.1" + ip_end : "38.0.1.255" + track_ports : false + mac : [0x0,0x0,0x0,0x1,0x0,0x00] + cap_info : + - name: cap2/http_get.pcap + cps : 1.0 + ipg : 100 + rtt : 10000 + w : 1 + diff --git a/scripts/cap2/per_template_gen2.yaml b/scripts/cap2/per_template_gen2.yaml new file mode 100644 index 00000000..3349087c --- /dev/null +++ b/scripts/cap2/per_template_gen2.yaml @@ -0,0 +1,41 @@ +- duration : 1.0 + generator : + distribution : "seq" + clients_start : "20.0.0.1" + clients_end : "20.0.0.255" + servers_start : "90.0.0.1" + servers_end : "90.0.255.255" + clients_per_gb : 201 + min_clients : 101 + dual_port_mask : "1.0.0.0" + tcp_aging : 0 + udp_aging : 0 + generator_clients : + - name : "c1" + distribution : "seq" + ip_start : "16.0.0.1" + ip_end : "16.0.1.255" + - name : "c2" + distribution : "seq" + ip_start : "36.0.0.1" + ip_end : "36.0.1.255" + generator_servers : + - name : "s1" + distribution : "seq" + ip_start : "48.0.0.1" + ip_end : "48.0.1.255" + track_ports : false + - name : "s2" + distribution : "seq" + ip_start : "38.0.0.1" + ip_end : "38.0.1.255" + track_ports : false + mac : [0x0,0x0,0x0,0x1,0x0,0x00] + cap_info : + - name: cap2/http_get.pcap + client_pool: "c1" + server_pool: "s1" + cps : 1.0 + ipg : 100 + rtt : 10000 + w : 1 diff --git a/scripts/cap2/per_template_gen3.yaml b/scripts/cap2/per_template_gen3.yaml new file mode 100644 index 00000000..2bf428d0 --- /dev/null +++ b/scripts/cap2/per_template_gen3.yaml @@ -0,0 +1,41 @@ +- duration : 1.0 + generator : + distribution : "seq" + clients_start : "20.0.0.1" + clients_end : "20.0.0.255" + servers_start : "90.0.0.1" + servers_end : "90.0.255.255" + clients_per_gb : 201 + min_clients : 101 + dual_port_mask : "1.0.0.0" + tcp_aging : 0 + udp_aging : 0 + generator_clients : + - name : "c1" + distribution : "seq" + ip_start : "26.0.0.1" + ip_end : "26.0.1.255" + - name : "c2" + distribution : "seq" + ip_start : "36.0.0.1" + ip_end : "36.0.1.255" + generator_servers : + - name : "s1" + distribution : "seq" + ip_start : "28.0.0.1" + ip_end : "28.0.1.255" + track_ports : false + - name : "s2" + distribution : "seq" + ip_start : "38.0.0.1" + ip_end : "38.0.1.255" + track_ports : false + mac : [0x0,0x0,0x0,0x1,0x0,0x00] + cap_info : + - name: cap2/http_get.pcap + client_pool: "c2" + server_pool: "s2" + cps : 1.0 + ipg : 100 + rtt : 10000 + w : 1 diff --git a/scripts/cap2/per_template_gen4.yaml b/scripts/cap2/per_template_gen4.yaml new file mode 100644 index 00000000..8a8a61b9 --- /dev/null +++ b/scripts/cap2/per_template_gen4.yaml @@ -0,0 +1,41 @@ +- duration : 1.0 + generator : + distribution : "seq" + clients_start : "20.0.0.1" + clients_end : "20.0.0.255" + servers_start : "90.0.0.1" + servers_end : "90.0.255.255" + clients_per_gb : 201 + min_clients : 101 + dual_port_mask : "1.0.0.0" + tcp_aging : 0 + udp_aging : 0 + generator_clients : + - name : "c1" + distribution : "seq" + ip_start : "26.0.0.1" + ip_end : "26.0.1.255" + - name : "c2" + distribution : "seq" + ip_start : "36.0.0.1" + ip_end : "36.0.1.255" + generator_servers : + - name : "s1" + distribution : "seq" + ip_start : "28.0.0.1" + ip_end : "28.0.1.255" + track_ports : false + - name : "s2" + distribution : "seq" + ip_start : "38.0.0.1" + ip_end : "38.0.1.255" + track_ports : false + mac : [0x0,0x0,0x0,0x1,0x0,0x00] + cap_info : + - name: cap2/http_get.pcap + client_pool: "c2" + server_pool: "s1" + cps : 1.0 + ipg : 100 + rtt : 10000 + w : 1 diff --git a/scripts/cap2/per_template_gen5.yaml b/scripts/cap2/per_template_gen5.yaml new file mode 100755 index 00000000..e29a2bfc --- /dev/null +++ b/scripts/cap2/per_template_gen5.yaml @@ -0,0 +1,51 @@ +- duration : 1.0 + generator : + distribution : "seq" + clients_start : "20.0.0.1" + clients_end : "20.0.0.255" + servers_start : "90.0.0.1" + servers_end : "90.0.255.255" + clients_per_gb : 201 + min_clients : 101 + dual_port_mask : "1.0.0.0" + tcp_aging : 0 + udp_aging : 0 + generator_clients : + - name : "c1" + distribution : "seq" + ip_start : "26.0.0.1" + ip_end : "26.0.1.255" + - name : "c2" + distribution : "seq" + ip_start : "36.0.0.1" + ip_end : "36.0.1.254" + generator_servers : + - name : "s1" + distribution : "seq" + ip_start : "28.0.0.1" + ip_end : "28.0.1.255" + track_ports : false + - name : "s2" + distribution : "seq" + ip_start : "38.0.0.1" + ip_end : "38.0.3.255" + track_ports : false + mac : [0x0,0x0,0x0,0x1,0x0,0x00] + cap_info : + - name: cap2/http_get.pcap + client_pool: "c2" + server_pool: "s1" + cps : 1.0 + ipg : 100 + rtt : 10000 + w : 1 + - name: avl/delay_10_rtp_160k_full.pcap + client_pool: "c1" + server_pool: "s2" + cps : 0.7 + ipg : 10000 + rtt : 10000 + w : 1 + one_app_server : false + plugin_id : 1 + diff --git a/src/bp_gtest.cpp b/src/bp_gtest.cpp index 78efbecb..a529d637 100755 --- a/src/bp_gtest.cpp +++ b/src/bp_gtest.cpp @@ -223,10 +223,10 @@ public: if ( m_req_ports ){ int i; - fl.m_threads_info[0]->m_smart_gen.FreePort(tuple.getClient(),tuple.getClientPort()); + fl.m_threads_info[0]->m_smart_gen.FreePort(0, tuple.getClientId(),tuple.getClientPort()); for (i=0 ; i<m_req_ports;i++) { - fl.m_threads_info[0]->m_smart_gen.FreePort(tuple.getClient(),ports[i]); + fl.m_threads_info[0]->m_smart_gen.FreePort(0,tuple.getClientId(),ports[i]); } delete []ports; } @@ -527,6 +527,44 @@ TEST_F(basic, sfr4) { EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; } +TEST_F(basic, per_template_gen1) { + + CTestBasic t1; + CParserOption * po =&CGlobalInfo::m_options; + po->preview.setVMode(0); + po->preview.setFileWrite(true); + po->cfg_file ="cap2/per_template_gen1.yaml"; + po->out_file ="exp/sfr_4"; + bool res=t1.init(); + EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; +} +TEST_F(basic, per_template_gen2) { + + CTestBasic t1; + CParserOption * po =&CGlobalInfo::m_options; + po->preview.setVMode(0); + po->preview.setFileWrite(true); + po->cfg_file ="cap2/per_template_gen2.yaml"; + po->out_file ="exp/sfr_4"; + bool res=t1.init(); + EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; +} + + +/* +TEST_F(basic, sfr5) { + + CTestBasic t1; + CParserOption * po =&CGlobalInfo::m_options; + po->preview.setVMode(0); + po->preview.setFileWrite(true); + po->cfg_file ="cap2/sfr5.yaml"; + po->out_file ="exp/sfr_5"; + bool res=t1.init(); + EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; +} +*/ + TEST_F(basic, ipv6_convert) { diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp index 8a8bc5f9..7cbeb09d 100755 --- a/src/bp_sim.cpp +++ b/src/bp_sim.cpp @@ -2372,6 +2372,18 @@ void operator >> (const YAML::Node& node, CVlanYamlInfo & fi) { void operator >> (const YAML::Node& node, CFlowYamlInfo & fi) { node["name"] >> fi.m_name; + + try { + node["client_pool"] >> fi.m_client_pool_name; + } catch ( const std::exception& e ) { + fi.m_client_pool_name = "default"; + } + try { + node["server_pool"] >> fi.m_server_pool_name; + } catch ( const std::exception& e ) { + fi.m_server_pool_name = "default"; + } + node["cps"] >> fi.m_k_cps; fi.m_k_cps = fi.m_k_cps/1000.0; double t; @@ -2470,7 +2482,7 @@ void operator >> (const YAML::Node& node, CFlowsYamlInfo & flows_info) { node["generator"] >> flows_info.m_tuple_gen; flows_info.m_tuple_gen_was_set =true; } catch ( const std::exception& e ) { - flows_info.m_tuple_gen_was_set =false; + flows_info.m_tuple_gen_was_set =false; } @@ -2587,6 +2599,10 @@ void operator >> (const YAML::Node& node, CFlowsYamlInfo & flows_info) { for(unsigned i=0;i<cap_info.size();i++) { CFlowYamlInfo fi; cap_info[i] >> fi; + fi.m_client_pool_idx = + flows_info.m_tuple_gen.get_client_pool_id(fi.m_client_pool_name); + fi.m_server_pool_idx = + flows_info.m_tuple_gen.get_server_pool_id(fi.m_server_pool_name); flows_info.m_vec.push_back(fi); } } @@ -2599,7 +2615,6 @@ void CVlanYamlInfo::Dump(FILE *fd){ void CFlowsYamlInfo::Dump(FILE *fd){ fprintf(fd," duration : %f sec \n",m_duration_sec); - m_tuple_gen.Dump(fd); fprintf(fd,"\n"); if (CGlobalInfo::is_ipv6_enable()) { @@ -2703,6 +2718,38 @@ bool CFlowsYamlInfo::verify_correctness(uint32_t num_threads) { if ( !m_tuple_gen.is_valid(num_threads,is_any_plugin_configured()) ){ return (false); } + /* patch defect trex-54 */ + if ( is_any_plugin_configured() ){ + /*Plugin is configured. in that case due to a limitation ( defect trex-54 ) + the number of servers should be bigger than number of clients */ + + int i; + for (i=0; i<(int)m_vec.size(); i++) { + CFlowYamlInfo * lp=&m_vec[i]; + if ( lp->m_plugin_id ){ + uint8_t c_idx = lp->m_client_pool_idx; + uint8_t s_idx = lp->m_server_pool_idx; + uint32_t total_clients = m_tuple_gen.m_client_pool[c_idx].getTotalIps(); + uint32_t total_servers = m_tuple_gen.m_server_pool[s_idx].getTotalIps(); + if ( total_servers < total_clients ){ + printf(" Plugin is configured. in that case due to a limitation ( defect trex-54 ) \n"); + printf(" the number of servers should be bigger than number of clients \n"); + printf(" client_pool_name : %s \n", lp->m_client_pool_name.c_str()); + printf(" server_pool_name : %s \n", lp->m_server_pool_name.c_str()); + return (false); + } + uint32_t mul = total_servers / total_clients; + uint32_t new_server_num = mul * total_clients; + if ( new_server_num != total_servers ) { + printf(" Plugin is configured. in that case due to a limitation ( defect trex-54 ) \n"); + printf(" the number of servers should be exact multiplication of the number of clients \n"); + printf(" client_pool_name : %s clients %d \n", lp->m_client_pool_name.c_str(),total_clients); + printf(" server_pool_name : %s servers %d should be %d \n", lp->m_server_pool_name.c_str(),total_servers,new_server_num); + return (false); + } + } + } + } return(true); } @@ -2815,18 +2862,20 @@ bool CFlowGeneratorRecPerThread::Create(CTupleGeneratorSmart * global_gen, CFlowsYamlInfo * yaml_flow_info, CCapFileFlowInfo * flow_info, uint16_t _id, - uint32_t thread_id ){ + uint32_t thread_id){ BP_ASSERT(info); m_thread_id =thread_id ; - tuple_gen.Create(global_gen); - CTupleGenYamlInfo * lpt=&yaml_flow_info->m_tuple_gen; + tuple_gen.Create(global_gen, info->m_client_pool_idx, + info->m_server_pool_idx); + CTupleGenYamlInfo * lpt; + lpt = &yaml_flow_info->m_tuple_gen; tuple_gen.SetSingleServer(info->m_one_app_server, info->m_server_addr, getDualPortId(thread_id), - lpt->m_dual_interface_mask + lpt->m_client_pool[info->m_client_pool_idx].getDualMask() ); tuple_gen.SetW(info->m_w); @@ -3128,25 +3177,39 @@ 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->is_mac_info_configured); + /* split the clients to threads using the mask */ - CClientPortion portion; - split_clients(m_thread_id, - m_max_threads, - getDualPortId(), - *tuple_gen, + CIpPortion portion; + for (int i=0;i<tuple_gen->m_client_pool.size();i++) { + split_ips(m_thread_id, m_max_threads, getDualPortId(), + tuple_gen->m_client_pool[i], portion); - init_from_global(portion); - m_smart_gen.Create(0,m_thread_id, - cdSEQ_DIST, - portion.m_client_start, - portion.m_client_end, - portion.m_server_start, - portion.m_server_end, - get_longest_flow(), - get_total_kcps()*1000, - m_flow_list); + 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, + 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(), + tuple_gen->m_server_pool[i], + portion); + m_smart_gen.add_server_pool(tuple_gen->m_server_pool[i].m_dist, + portion.m_ip_start, + portion.m_ip_end, + get_longest_flow(i,false), + get_total_kcps(i,false)*1000, + tuple_gen->m_server_pool[i].m_is_bundling); + } + + init_from_global(portion); CMessagingManager * rx_dp=CMsgIns::Ins()->getRxDp(); @@ -3163,7 +3226,8 @@ FORCE_NO_INLINE void CFlowGenListPerThread::handler_defer_job(CGenNode *p){ CGenNodeDeferPort * defer=(CGenNodeDeferPort *)p; int i; for (i=0; i<defer->m_cnt; i++) { - m_smart_gen.FreePort(defer->m_clients[i],defer->m_ports[i]); + m_smart_gen.FreePort(defer->m_pool_idx[i], + defer->m_clients[i],defer->m_ports[i]); } } @@ -3183,32 +3247,34 @@ FORCE_NO_INLINE void CFlowGenListPerThread::handler_defer_job_flush(void){ void CFlowGenListPerThread::defer_client_port_free(bool is_tcp, - uint32_t c_ip, - uint16_t port){ - /* free is not required in this case */ - if (!m_smart_gen.IsFreePortRequired() ){ + uint32_t c_idx, + uint16_t port, + uint8_t c_pool_idx, + CTupleGeneratorSmart * gen){ + /* free is not required in this case */ + if (!gen->IsFreePortRequired(c_pool_idx) ){ return; } CGenNodeDeferPort * defer; if (is_tcp) { - if (CGlobalInfo::m_options.m_tcp_aging==0) { - m_smart_gen.FreePort(c_ip,port); + if (gen->get_tcp_aging(c_pool_idx)==0) { + gen->FreePort(c_pool_idx,c_idx,port); return; } defer=get_tcp_defer(); }else{ - if (CGlobalInfo::m_options.m_udp_aging==0) { - m_smart_gen.FreePort(c_ip,port); + if (gen->get_udp_aging(c_pool_idx)==0) { + gen->FreePort(c_pool_idx, c_idx,port); return; } defer=get_udp_defer(); } - if ( defer->add_client(c_ip,port) ){ + if ( defer->add_client(c_pool_idx, c_idx,port) ){ if (is_tcp) { - m_node_gen.schedule_node((CGenNode *)defer,CGlobalInfo::m_options.m_tcp_aging); + m_node_gen.schedule_node((CGenNode *)defer,gen->get_tcp_aging(c_pool_idx)); m_tcp_dpc=0; }else{ - m_node_gen.schedule_node((CGenNode *)defer,CGlobalInfo::m_options.m_udp_aging); + m_node_gen.schedule_node((CGenNode *)defer,gen->get_udp_aging(c_pool_idx)); m_udp_dpc=0; } } @@ -3216,13 +3282,15 @@ void CFlowGenListPerThread::defer_client_port_free(bool is_tcp, void CFlowGenListPerThread::defer_client_port_free(CGenNode *p){ - defer_client_port_free(p->m_pkt_info->m_pkt_indication.m_desc.IsTcp(),p->m_src_ip,p->m_src_port); + defer_client_port_free(p->m_pkt_info->m_pkt_indication.m_desc.IsTcp(), + p->m_src_idx,p->m_src_port,p->m_template_info->m_client_pool_idx, + p->m_tuple_gen); } /* copy all info from global and div by num of threads */ -void CFlowGenListPerThread::init_from_global(CClientPortion& portion){ +void CFlowGenListPerThread::init_from_global(CIpPortion& portion){ /* copy generator , it is the same */ m_yaml_info =m_flow_list->m_yaml_info; @@ -3245,7 +3313,10 @@ void CFlowGenListPerThread::init_from_global(CClientPortion& portion){ yaml_info->m_one_app_server = lp->m_info->m_one_app_server; yaml_info->m_server_addr = lp->m_info->m_server_addr; yaml_info->m_dpPkt =lp->m_info->m_dpPkt; - + yaml_info->m_server_pool_idx=lp->m_info->m_server_pool_idx; + yaml_info->m_client_pool_idx=lp->m_info->m_client_pool_idx; + yaml_info->m_server_pool_name=lp->m_info->m_server_pool_name; + yaml_info->m_client_pool_name=lp->m_info->m_client_pool_name; /* fix this */ assert(m_max_threads>0); if ( m_max_threads == 1 ) { @@ -3267,8 +3338,7 @@ void CFlowGenListPerThread::init_from_global(CClientPortion& portion){ yaml_info->m_restart_time = ( yaml_info->m_limit_was_set ) ? (yaml_info->m_limit / (yaml_info->m_k_cps * 1000.0)) : 0; - - lp_thread->Create( &m_smart_gen, + lp_thread->Create(&m_smart_gen, yaml_info, lp->m_flows_info, &lp->m_flow_info, @@ -3303,6 +3373,12 @@ void CFlowGenListPerThread::Clean(){ int i; for (i=0; i<(int)m_cap_gen.size(); i++) { CFlowGeneratorRecPerThread * lp=m_cap_gen[i]; + if (lp->m_tuple_gen_was_set) { + CTupleGeneratorSmart *gen; + gen = lp->tuple_gen.get_gen(); + gen->Delete(); + delete gen; + } lp->Delete(); delete lp; } @@ -3559,6 +3635,27 @@ uint32_t CFlowGenListPerThread::getDualPortId(){ return ( ::getDualPortId(m_thread_id) ); } +double CFlowGenListPerThread::get_longest_flow(uint8_t pool_idx, bool is_client){ + int i; + double longest_flow = 0.0; + for (i=0;i<(int)m_cap_gen.size(); i++) { + CFlowGeneratorRecPerThread * lp=m_cap_gen[i]; + if (is_client && + lp->m_info->m_client_pool_idx != pool_idx) + continue; + if (!is_client && + lp->m_info->m_server_pool_idx != pool_idx) + continue; + double tmp_len; + tmp_len = lp->m_flow_info->get_cap_file_length_sec(); + if (longest_flow < tmp_len ) { + longest_flow = tmp_len; + } + } + return longest_flow; +} + + double CFlowGenListPerThread::get_longest_flow(){ int i; double longest_flow = 0.0; @@ -3573,6 +3670,22 @@ double CFlowGenListPerThread::get_longest_flow(){ return longest_flow; } +double CFlowGenListPerThread::get_total_kcps(uint8_t pool_idx, bool is_client){ + int i; + double total=0.0; + for (i=0; i<(int)m_cap_gen.size(); i++) { + CFlowGeneratorRecPerThread * lp=m_cap_gen[i]; + if (is_client && + lp->m_info->m_client_pool_idx != pool_idx) + continue; + if (!is_client && + lp->m_info->m_server_pool_idx != pool_idx) + continue; + total +=lp->m_info->m_k_cps; + } + return (total); +} + double CFlowGenListPerThread::get_total_kcps(){ int i; double total=0.0; @@ -3881,9 +3994,6 @@ int CFlowGenList::load_from_yaml(std::string file_name, CGlobalInfo::m_options.m_vlan_port[0] = m_yaml_info.m_vlan_info.m_vlan_per_port[0]; CGlobalInfo::m_options.m_vlan_port[1] = m_yaml_info.m_vlan_info.m_vlan_per_port[1]; CGlobalInfo::m_options.preview.set_mac_ip_overide_enable(m_yaml_info.m_mac_replace_by_ip); - CGlobalInfo::m_options.m_tcp_aging = m_yaml_info.m_tuple_gen.m_tcp_aging_sec; - CGlobalInfo::m_options.m_udp_aging = m_yaml_info.m_tuple_gen.m_udp_aging_sec; - if ( m_yaml_info.m_mac_base.size() != 6 ){ printf(" mac addr is not valid \n"); @@ -5431,8 +5541,11 @@ void CPluginCallbackSimple::on_node_last(uint8_t plugin_id,CGenNode * node){ /* free the ports */ CFlowGenListPerThread * flow_gen=(CFlowGenListPerThread *) lpP->m_gen; bool is_tcp=node->m_pkt_info->m_pkt_indication.m_desc.IsTcp(); - flow_gen->defer_client_port_free(is_tcp,node->m_src_ip,lpP->rtp_client_0); - flow_gen->defer_client_port_free(is_tcp,node->m_src_ip,lpP->rtp_client_1); + flow_gen->defer_client_port_free(is_tcp,node->m_src_idx,lpP->rtp_client_0, + node->m_template_info->m_client_pool_idx,node->m_tuple_gen); + flow_gen->defer_client_port_free(is_tcp,node->m_src_idx,lpP->rtp_client_1, + node->m_template_info->m_client_pool_idx, node->m_tuple_gen); + assert(lpP); delete lpP; node->m_plugin_info=0; diff --git a/src/bp_sim.h b/src/bp_sim.h index 7d659d1c..29b9a724 100755 --- a/src/bp_sim.h +++ b/src/bp_sim.h @@ -716,8 +716,6 @@ public: uint16_t m_vlan_port[2]; /* vlan value */ uint16_t m_src_ipv6[6]; /* Most signficant 96-bits */ uint16_t m_dst_ipv6[6]; /* Most signficant 96-bits */ - uint16_t m_tcp_aging; - uint16_t m_udp_aging; uint32_t m_latency_rate; /* pkt/sec for each thread/port zero disable */ uint32_t m_latency_mask; @@ -1249,10 +1247,14 @@ struct CFlowYamlInfo { CFlowYamlInfo(){ m_dpPkt=0; m_server_addr=0; + m_client_pool_idx = 0; + m_server_pool_idx = 0; m_cap_mode=false; } std::string m_name; + std::string m_client_pool_name; + std::string m_server_pool_name; double m_k_cps; //k CPS double m_restart_time; /* restart time of this template */ dsec_t m_ipg_sec; // ipg in sec @@ -1262,6 +1264,8 @@ struct CFlowYamlInfo { uint32_t m_limit; uint32_t m_flowcnt; uint8_t m_plugin_id; /* 0 - default , 1 - RTSP160 , 2- RTSP250 */ + uint8_t m_client_pool_idx; + uint8_t m_server_pool_idx; bool m_one_app_server; uint32_t m_server_addr; bool m_one_app_server_was_set; @@ -1372,14 +1376,17 @@ public: //private: + CTupleGeneratorSmart *m_tuple_gen; // cache line 1 - 64bytes waste of space ! uint32_t m_nat_external_ipv4; /* client */ uint32_t m_nat_external_ipv4_server; uint16_t m_nat_external_port; - uint16_t m_nat_pad; + uint16_t m_nat_pad[3]; mac_addr_align_t m_src_mac; - uint32_t m_end_of_cache_line[11]; + uint32_t m_src_idx; + uint32_t m_dest_idx; + uint32_t m_end_of_cache_line[6]; public: bool operator <(const CGenNode * rsh ) const { @@ -1585,7 +1592,7 @@ public: #if __x86_64__ /* size of 64 bytes */ - #define DEFER_CLIENTS_NUM (18) + #define DEFER_CLIENTS_NUM (16) #else #define DEFER_CLIENTS_NUM (16) #endif @@ -1601,6 +1608,7 @@ struct CGenNodeDeferPort { uint32_t m_clients[DEFER_CLIENTS_NUM]; uint16_t m_ports[DEFER_CLIENTS_NUM]; + uint8_t m_pool_idx[DEFER_CLIENTS_NUM]; public: void init(void){ m_type=CGenNode::FLOW_DEFER_PORT_RELEASE; @@ -1608,10 +1616,11 @@ public: } /* return true if object is full */ - bool add_client(uint32_t client, + bool add_client(uint8_t pool_idx, uint32_t client, uint16_t port){ m_clients[m_cnt]=client; m_ports[m_cnt]=port; + m_pool_idx[m_cnt] = pool_idx; m_cnt++; if ( m_cnt == DEFER_CLIENTS_NUM ) { return (true); @@ -3155,6 +3164,7 @@ public: CPolicer m_policer; uint16_t m_id ; uint32_t m_thread_id; + bool m_tuple_gen_was_set; } __rte_cache_aligned; @@ -3287,8 +3297,10 @@ public: uint32_t getDualPortId(); public : double get_total_kcps(); + double get_total_kcps(uint8_t pool_idx, bool is_client); double get_delta_flow_is_sec(); double get_longest_flow(); + double get_longest_flow(uint8_t pool_idx, bool is_client); void inc_current_template(void); int generate_flows_roundrobin(bool *done); int reschedule_flow(CGenNode *node); @@ -3320,9 +3332,10 @@ private: void terminate_nat_flows(CGenNode *node); - void init_from_global(CClientPortion &); + void init_from_global(CIpPortion &); void defer_client_port_free(CGenNode *p); - void defer_client_port_free(bool is_tcp,uint32_t c_ip,uint16_t port); + void defer_client_port_free(bool is_tcp,uint32_t c_ip,uint16_t port, + uint8_t pool_idx, CTupleGeneratorSmart*gen); FORCE_NO_INLINE void handler_defer_job(CGenNode *p); @@ -3417,12 +3430,6 @@ inline void CFlowGenListPerThread::free_last_flow_node(CGenNode *p){ free_node( p); } - -typedef struct mac_mapping_ { - mac_addr_align_t mac; - uint32_t ip; -} mac_mapping_t; - class CFlowGenList { public: @@ -3449,10 +3456,6 @@ public: double get_total_pps(); double get_total_tx_bps(); uint32_t get_total_repeat_flows(); - bool is_ip_legal(uint32_t ip) { - return (ip >= m_yaml_info.m_tuple_gen.m_clients_ip_start && - ip <= m_yaml_info.m_tuple_gen.m_clients_ip_end ); - } double get_delta_flow_is_sec(); public: std::vector<CFlowGeneratorRec *> m_cap_gen; /* global info */ @@ -3493,8 +3496,11 @@ inline void CCapFileFlowInfo::generate_flow(CTupleTemplateGeneratorSmart * tup node->m_flow_info = this; node->m_flags=0; node->m_template_info =template_info; + node->m_tuple_gen = tuple_gen->get_gen(); node->m_src_ip= tuple.getClient(); node->m_dest_ip = tuple.getServer(); + 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(), diff --git a/src/gtest/tuple_gen_test.cpp b/src/gtest/tuple_gen_test.cpp index 6419ced1..8791b67d 100755 --- a/src/gtest/tuple_gen_test.cpp +++ b/src/gtest/tuple_gen_test.cpp @@ -153,12 +153,12 @@ TEST(CClientInfoLTest, get_new_free_port) { -/* UIT of CTupleGeneratorSmart */ -TEST(tuple_gen,GenerateTuple) { - CTupleGeneratorSmart gen; - gen.Create(1, 1,cdSEQ_DIST, - 0x10000001, 0x10000f01, 0x30000001, 0x40000001, - MAX_PORT, MAX_PORT); +/* UIT of CClientPool, using CClientInfoL */ +TEST(tuple_gen,clientPoolL) { + CClientPool gen; + gen.Create(cdSEQ_DIST, + 0x10000001, 0x10000f01, 64000,1,NULL,false, + 0,0); CTupleBase result; uint32_t result_src; uint32_t result_dest; @@ -166,13 +166,11 @@ TEST(tuple_gen,GenerateTuple) { for(int i=0;i<10;i++) { gen.GenerateTuple(result); - printf(" C:%x S:%x P:%d \n",result.getClient(),result.getServer(),result.getClientPort()); + printf(" C:%x P:%d \n",result.getClient(),result.getClientPort()); result_src = result.getClient(); - result_dest = result.getServer(); result_port = result.getClientPort(); EXPECT_EQ(result_src, (uint32_t)(0x10000001+i)); - EXPECT_EQ(result_dest, (uint32_t) (((0x30000001+i)) ) ); EXPECT_EQ(result_port, 1024); } @@ -180,164 +178,229 @@ TEST(tuple_gen,GenerateTuple) { // EXPECT_EQ((size_t)0, gen.m_clients.size()); } -TEST(tuple_gen,GenerateTuple2) { - CTupleGeneratorSmart gen; - gen.Create(1, 1,cdSEQ_DIST, - 0x10000001, 0x1000000f, 0x30000001, 0x40000001, - MAX_PORT, MAX_PORT); +/* UIT of CClientPool, using CClientInfo */ +TEST(tuple_gen,clientPool) { + CClientPool gen; + gen.Create(cdSEQ_DIST, + 0x10000001, 0x10000021, 64000,1000,NULL,false, + 0,0); CTupleBase result; uint32_t result_src; uint32_t result_dest; uint16_t result_port; - for(int i=0;i<200;i++) { + for(int i=0;i<10;i++) { gen.GenerateTuple(result); - // gen.Dump(stdout); - // fprintf(stdout, "i:%d\n",i); + printf(" C:%x P:%d \n",result.getClient(),result.getClientPort()); + result_src = result.getClient(); - result_dest = result.getServer(); result_port = result.getClientPort(); - EXPECT_EQ(result_src, (uint32_t)(0x10000001+i%15)); - EXPECT_EQ(result_dest, (uint32_t)((0x30000001+i) ) ); - EXPECT_EQ(result_port, 1024+i/15); + EXPECT_EQ(result_src, (uint32_t)(0x10000001+i)); + EXPECT_EQ(result_port, 1024); } gen.Delete(); // EXPECT_EQ((size_t)0, gen.m_clients.size()); - gen.Create(1, 1,cdSEQ_DIST, - 0x10000001, 0x1000000f, 0x30000001, 0x40000001, - MAX_PORT,MAX_PORT); - for(int i=0;i<200;i++) { +} + +/* UIT of CServerPool */ +TEST(tuple_gen,serverPool) { + CServerPool gen; + gen.Create(cdSEQ_DIST, + 0x30000001, 0x30000ff1, 64000,10); + CTupleBase result; + uint32_t result_dest; + + for(int i=0;i<10;i++) { gen.GenerateTuple(result); - // gen.Dump(stdout); - // fprintf(stdout, "i:%d\n",i); - result_src = result.getClient(); + printf(" S:%x \n",result.getServer()); + result_dest = result.getServer(); - result_port = result.getClientPort(); - EXPECT_EQ(result_src, (uint32_t)(0x10000001+i%15)); EXPECT_EQ(result_dest, (uint32_t) (((0x30000001+i)) ) ); - EXPECT_EQ(result_port, 1024+i/15); } + gen.Delete(); + gen.Create(cdSEQ_DIST, + 0x30000001, 0x30000003, 64000,1000); -} + for(int i=0;i<10;i++) { + gen.GenerateTuple(result); + printf(" S:%x \n",result.getServer()); -TEST(tuple_gen,GenerateTupleMac) { - CFlowGenList fl; - fl.Create(); - fl.load_from_mac_file("avl/mac_uit.yaml"); - fl.m_yaml_info.m_tuple_gen.m_clients_ip_start = 0x10000001; - fl.m_yaml_info.m_tuple_gen.m_clients_ip_end = 0x1000000f; + result_dest = result.getServer(); + EXPECT_EQ(result_dest, (uint32_t) (((0x30000001+i%3)) ) ); + } + gen.Delete(); + // EXPECT_EQ((size_t)0, gen.m_clients.size()); +} - CTupleGeneratorSmart gen; - gen.Create(1, 1,cdSEQ_DIST, - 0x10000001, 0x1000000f, 0x30000001, 0x40000001, - MAX_PORT, MAX_PORT, &fl); +TEST(tuple_gen,servePoolSim) { + CServerPoolSimple gen; + gen.Create(cdSEQ_DIST, + 0x30000001, 0x40000001, 64000,10); CTupleBase result; - uint32_t result_src; uint32_t result_dest; - uint16_t result_port; for(int i=0;i<10;i++) { gen.GenerateTuple(result); - printf(" C:%x S:%x P:%d \n",result.getClient(),result.getServer(),result.getClientPort()); + printf(" S:%x \n",result.getServer()); - result_src = result.getClient(); result_dest = result.getServer(); - result_port = result.getClientPort(); - EXPECT_EQ(result_src, (uint32_t)(0x10000001+i%2)); EXPECT_EQ(result_dest, (uint32_t) (((0x30000001+i)) ) ); - EXPECT_EQ(result_port, 1024+i/2); } gen.Delete(); -// EXPECT_EQ((size_t)0, gen.m_clients.size()); + + gen.Create(cdSEQ_DIST, + 0x30000001, 0x30000003, 64000,1000); + + for(int i=0;i<10;i++) { + gen.GenerateTuple(result); + printf(" S:%x \n",result.getServer()); + + result_dest = result.getServer(); + EXPECT_EQ(result_dest, (uint32_t) (((0x30000001+i%3)) ) ); + } + + gen.Delete(); + // EXPECT_EQ((size_t)0, gen.m_clients.size()); } -TEST(tuple_gen,GenerateTupleEx) { - CTupleGeneratorSmart gen; - gen.Create(1, 1,cdSEQ_DIST, - 0x10000001, 0x1000000f, 0x30000001, 0x40000001, - MAX_PORT, MAX_PORT); + +TEST(tuple_gen,GenerateTuple2) { + CClientPool c_gen; + CClientPool c_gen_2; + c_gen.Create(cdSEQ_DIST, + 0x10000001, 0x1000000f, 64000,4,NULL,false, + 0,0); + CServerPool s_gen; + CServerPool s_gen_2; + s_gen.Create(cdSEQ_DIST, + 0x30000001, 0x30000ff1, 64000,10); CTupleBase result; + uint32_t result_src; uint32_t result_dest; uint16_t result_port; - uint16_t ex_port[2]; - for(int i=0;i<20;i++) { - gen.GenerateTupleEx(result,2,ex_port); - fprintf(stdout, "i:%d\n",i); + for(int i=0;i<200;i++) { + c_gen.GenerateTuple(result); + s_gen.GenerateTuple(result); + // gen.Dump(stdout); + // fprintf(stdout, "i:%d\n",i); result_src = result.getClient(); result_dest = result.getServer(); result_port = result.getClientPort(); + EXPECT_EQ(result_src, (uint32_t)(0x10000001+i%15)); + EXPECT_EQ(result_dest, (uint32_t)((0x30000001+i) ) ); + EXPECT_EQ(result_port, 1024+i/15); + } + s_gen.Delete(); + c_gen.Delete(); +// EXPECT_EQ((size_t)0, gen.m_clients.size()); + c_gen.Create(cdSEQ_DIST, + 0x10000001, 0x1000000f, 64000,400,NULL,false, + 0,0); + s_gen.Create(cdSEQ_DIST, + 0x30000001, 0x30000001, 64000,10); + for(int i=0;i<200;i++) { + s_gen.GenerateTuple(result); + c_gen.GenerateTuple(result); + // gen.Dump(stdout); + // fprintf(stdout, "i:%d\n",i); + result_src = result.getClient(); + result_dest = result.getServer(); + result_port = result.getClientPort(); EXPECT_EQ(result_src, (uint32_t)(0x10000001+i%15)); - EXPECT_EQ(result_dest, (uint32_t)(((0x30000001+i)) )); + EXPECT_EQ(result_dest, (uint32_t) (((0x30000001)) ) ); + EXPECT_EQ(result_port, 1024+i/15); + } + + s_gen.Delete(); + c_gen.Delete(); + + +} + +TEST(tuple_gen,GenerateTupleMac) { + CFlowGenList fl; + fl.Create(); + fl.load_from_mac_file("avl/mac_uit.yaml"); - EXPECT_EQ(result_port, 1024+(i/15)*3); - EXPECT_EQ(ex_port[0], 1025+(i/15)*3); - EXPECT_EQ(ex_port[1], 1026+(i/15)*3); + CClientPool gen; + gen.Create(cdSEQ_DIST, + 0x10000001, 0x1000000f, 64000,2, &fl,true,0,0); + CTupleBase result; + uint32_t result_src; + uint16_t result_port; + mac_addr_align_t* result_mac; + for(int i=0;i<10;i++) { + gen.GenerateTuple(result); + printf(" C:%x P:%d \n",result.getClient(),result.getClientPort()); + + result_src = result.getClient(); + result_port = result.getClientPort(); + result_mac = result.getClientMac(); + EXPECT_EQ(result_src, (uint32_t)(0x10000001+i%2)); + EXPECT_EQ(result_port, 1024+i/2); + if (i%2==0) + EXPECT_EQ(result_mac->mac[3], 5); + else + EXPECT_EQ(result_mac->mac[3], 1); } gen.Delete(); +// EXPECT_EQ((size_t)0, gen.m_clients.size()); } -TEST(tuple_gen,split1) { - CClientPortion portion; - CTupleGenYamlInfo fi; - fi.m_clients_ip_start =0x10000000; - fi.m_clients_ip_end =0x100000ff; +TEST(tuple_gen,split1) { + CIpPortion portion; - fi.m_servers_ip_start =0x20000000; - fi.m_servers_ip_end =0x200000ff; + CTupleGenPoolYaml fi; + fi.m_ip_start =0x10000000; + fi.m_ip_end =0x100000ff; fi.m_dual_interface_mask =0x01000000; - split_clients(0, + split_ips(0, 1, 0, fi, portion); - EXPECT_EQ(portion.m_client_start, (uint32_t)(0x10000000)); - EXPECT_EQ(portion.m_client_end, (uint32_t)(0x100000ff )); - EXPECT_EQ(portion.m_server_start , (uint32_t)(0x20000000)); - EXPECT_EQ(portion.m_server_end , (uint32_t)(0x200000ff)); - printf(" %x %x %x %x \n",portion.m_client_start,portion.m_client_end,portion.m_server_start,portion.m_server_end); + EXPECT_EQ(portion.m_ip_start, (uint32_t)(0x10000000)); + EXPECT_EQ(portion.m_ip_end, (uint32_t)(0x100000ff )); + printf(" %x %x \n",portion.m_ip_start,portion.m_ip_end); - split_clients(2, + split_ips(2, 4, 1, fi, portion); - EXPECT_EQ(portion.m_client_start, (uint32_t)(0x11000080)); - EXPECT_EQ(portion.m_client_end, (uint32_t)(0x110000bf )); - EXPECT_EQ(portion.m_server_start , (uint32_t)(0x21000080)); - EXPECT_EQ(portion.m_server_end , (uint32_t)(0x210000bf)); - printf(" %x %x %x %x \n",portion.m_client_start,portion.m_client_end,portion.m_server_start,portion.m_server_end); + EXPECT_EQ(portion.m_ip_start, (uint32_t)(0x11000080)); + EXPECT_EQ(portion.m_ip_end, (uint32_t)(0x110000bf )); + printf(" %x %x \n",portion.m_ip_start,portion.m_ip_end); } TEST(tuple_gen,split2) { - CClientPortion portion; + CIpPortion portion; - CTupleGenYamlInfo fi; - fi.m_clients_ip_start =0x10000000; - fi.m_clients_ip_end =0x100001ff; + CTupleGenPoolYaml fi; - fi.m_servers_ip_start =0x20000000; - fi.m_servers_ip_end =0x200001ff; + fi.m_ip_start =0x20000000; + fi.m_ip_end =0x200001ff; fi.m_dual_interface_mask =0x01000000; int i; for (i=0; i<8; i++) { - split_clients(i, + split_ips(i, 8, (i&1), fi, @@ -345,31 +408,23 @@ TEST(tuple_gen,split2) { if ( (i&1) ) { - EXPECT_EQ(portion.m_client_start, (uint32_t)(0x11000000)+(0x40*i)); - EXPECT_EQ(portion.m_client_end, (uint32_t)(0x11000000 +(0x40*i+0x40-1))); - EXPECT_EQ(portion.m_server_start , (uint32_t)(0x21000000)+ (0x40*i) ); - EXPECT_EQ(portion.m_server_end , (uint32_t)(0x21000000)+(0x40*i+0x40-1) ); + EXPECT_EQ(portion.m_ip_start , (uint32_t)(0x21000000)+ (0x40*i) ); + EXPECT_EQ(portion.m_ip_end , (uint32_t)(0x21000000)+(0x40*i+0x40-1) ); }else{ - EXPECT_EQ(portion.m_client_start, (uint32_t)(0x10000000)+ (0x40*i) ); - EXPECT_EQ(portion.m_client_end, (uint32_t)(0x10000000 + (0x40*i+0x40-1) ) ); - EXPECT_EQ(portion.m_server_start , (uint32_t)(0x20000000) + (0x40*i) ); - EXPECT_EQ(portion.m_server_end , (uint32_t)(0x20000000) + (0x40*i+0x40-1) ); + EXPECT_EQ(portion.m_ip_start , (uint32_t)(0x20000000) + (0x40*i) ); + EXPECT_EQ(portion.m_ip_end , (uint32_t)(0x20000000) + (0x40*i+0x40-1) ); } - printf(" %x %x %x %x \n",portion.m_client_start,portion.m_client_end,portion.m_server_start,portion.m_server_end); + printf(" %x %x \n",portion.m_ip_start,portion.m_ip_end); } } - - - - TEST(tuple_gen,template1) { CTupleGeneratorSmart gen; - gen.Create(1, 1,cdSEQ_DIST, - 0x10000001, 0x1000000f, 0x30000001, 0x40000001, - MAX_PORT, MAX_PORT); + gen.Create(1, 1); + gen.add_client_pool(cdSEQ_DIST,0x10000001,0x1000000f,64000,4,NULL,0,0); + gen.add_server_pool(cdSEQ_DIST,0x30000001,0x40000001,64000,4,false); CTupleTemplateGeneratorSmart template_1; - template_1.Create(&gen); + template_1.Create(&gen,0,0); template_1.SetSingleServer(true,0x12121212,0,0); CTupleBase result; @@ -391,11 +446,11 @@ TEST(tuple_gen,template1) { TEST(tuple_gen,template2) { CTupleGeneratorSmart gen; - gen.Create(1, 1,cdSEQ_DIST, - 0x10000001, 0x1000000f, 0x30000001, 0x40000001, - MAX_PORT, MAX_PORT); + gen.Create(1, 1); + gen.add_client_pool(cdSEQ_DIST,0x10000001,0x1000000f,64000,4,NULL,0,0); + gen.add_server_pool(cdSEQ_DIST,0x30000001,0x40000001,64000,4,false); CTupleTemplateGeneratorSmart template_1; - template_1.Create(&gen); + template_1.Create(&gen,0,0); template_1.SetW(10); CTupleBase result; @@ -420,11 +475,11 @@ TEST(tuple_gen,template2) { TEST(tuple_gen,no_free) { CTupleGeneratorSmart gen; - gen.Create(1, 1,cdSEQ_DIST, - 0x10000001, 0x10000001, 0x30000001, 0x300000ff, - MAX_PORT, MAX_PORT); + gen.Create(1, 1); + gen.add_client_pool(cdSEQ_DIST,0x10000001,0x10000001,64000,4,NULL,0,0); + gen.add_server_pool(cdSEQ_DIST,0x30000001,0x400000ff,64000,4,false); CTupleTemplateGeneratorSmart template_1; - template_1.Create(&gen); + template_1.Create(&gen,0,0); CTupleBase result; @@ -445,11 +500,11 @@ TEST(tuple_gen,no_free) { TEST(tuple_gen,try_to_free) { CTupleGeneratorSmart gen; - gen.Create(1, 1,cdSEQ_DIST, - 0x10000001, 0x10000001, 0x30000001, 0x300000ff, - MAX_PORT, MAX_PORT); + gen.Create(1, 1); + gen.add_client_pool(cdSEQ_DIST,0x10000001,0x10000001,64000,4,NULL,0,0); + gen.add_server_pool(cdSEQ_DIST,0x30000001,0x400000ff,64000,4,false); CTupleTemplateGeneratorSmart template_1; - template_1.Create(&gen); + template_1.Create(&gen,0,0); CTupleBase result; @@ -460,7 +515,7 @@ TEST(tuple_gen,try_to_free) { uint32_t result_src = result.getClient(); uint32_t result_dest = result.getServer(); uint16_t result_port = result.getClientPort(); - gen.FreePort(result_src,result_port); + gen.FreePort(0,result.getClientId(),result_port); } // should have error EXPECT_FALSE((gen.getErrorAllocationCounter()>0)?true:false); @@ -474,16 +529,18 @@ TEST(tuple_gen,try_to_free) { /* tuple generator using CClientInfoL*/ TEST(tuple_gen_2,GenerateTuple) { CTupleGeneratorSmart gen; - gen.Create(1, 1,cdSEQ_DIST, - 0x10000001, 0x10000f01, 0x30000001, 0x40000001, - 0,0); + gen.Create(1, 1); + gen.add_client_pool(cdSEQ_DIST,0x10000001,0x10000f01,64000,4,NULL,0,0); + gen.add_server_pool(cdSEQ_DIST,0x30000001,0x40000001,64000,4,false); + CTupleTemplateGeneratorSmart template_1; + template_1.Create(&gen,0,0); CTupleBase result; uint32_t result_src; uint32_t result_dest; uint16_t result_port; for(int i=0;i<10;i++) { - gen.GenerateTuple(result); + template_1.GenerateTuple(result); printf(" C:%x S:%x P:%d \n",result.getClient(),result.getServer(),result.getClientPort()); result_src = result.getClient(); @@ -500,16 +557,18 @@ TEST(tuple_gen_2,GenerateTuple) { TEST(tuple_gen_2,GenerateTuple2) { CTupleGeneratorSmart gen; - gen.Create(1, 1,cdSEQ_DIST, - 0x10000001, 0x1000000f, 0x30000001, 0x40000001, - 0,0); + gen.Create(1, 1); + gen.add_client_pool(cdSEQ_DIST,0x10000001,0x1000000f,64000,4,NULL,0,0); + gen.add_server_pool(cdSEQ_DIST,0x30000001,0x40000001,64000,4,false); + CTupleTemplateGeneratorSmart template_1; + template_1.Create(&gen,0,0); CTupleBase result; uint32_t result_src; uint32_t result_dest; uint16_t result_port; for(int i=0;i<200;i++) { - gen.GenerateTuple(result); + template_1.GenerateTuple(result); // gen.Dump(stdout); // fprintf(stdout, "i:%d\n",i); result_src = result.getClient(); @@ -522,11 +581,12 @@ TEST(tuple_gen_2,GenerateTuple2) { gen.Delete(); // EXPECT_EQ((size_t)0, gen.m_clients.size()); - gen.Create(1, 1,cdSEQ_DIST, - 0x10000001, 0x1000000f, 0x30000001, 0x40000001, - 0,0); + gen.Create(1, 1); + gen.add_client_pool(cdSEQ_DIST,0x10000001,0x1000000f,64000,4,NULL,0,0); + gen.add_server_pool(cdSEQ_DIST,0x30000001,0x40000001,64000,4,false); + template_1.Create(&gen,0,0); for(int i=0;i<200;i++) { - gen.GenerateTuple(result); + template_1.GenerateTuple(result); // gen.Dump(stdout); // fprintf(stdout, "i:%d\n",i); result_src = result.getClient(); @@ -542,43 +602,13 @@ TEST(tuple_gen_2,GenerateTuple2) { } - -TEST(tuple_gen_2,GenerateTupleEx) { - CTupleGeneratorSmart gen; - gen.Create(1, 1,cdSEQ_DIST, - 0x10000001, 0x1000000f, 0x30000001, 0x40000001, - 0,0); - CTupleBase result; - uint32_t result_src; - uint32_t result_dest; - uint16_t result_port; - uint16_t ex_port[2]; - for(int i=0;i<20;i++) { - - gen.GenerateTupleEx(result,2,ex_port); - fprintf(stdout, "i:%d\n",i); - result_src = result.getClient(); - result_dest = result.getServer(); - result_port = result.getClientPort(); - - EXPECT_EQ(result_src, (uint32_t)(0x10000001+i%15)); - EXPECT_EQ(result_dest, (uint32_t)(((0x30000001+i)) )); - - EXPECT_EQ(result_port, 1024+(i/15)*3); - EXPECT_EQ(ex_port[0], 1025+(i/15)*3); - EXPECT_EQ(ex_port[1], 1026+(i/15)*3); - } - - gen.Delete(); -} - TEST(tuple_gen_2,template1) { CTupleGeneratorSmart gen; - gen.Create(1, 1,cdSEQ_DIST, - 0x10000001, 0x1000000f, 0x30000001, 0x40000001, - 0,0); + gen.Create(1, 1); + gen.add_client_pool(cdSEQ_DIST,0x10000001,0x1000000f,64000,4,NULL,0,0); + gen.add_server_pool(cdSEQ_DIST,0x30000001,0x40000001,64000,4,false); CTupleTemplateGeneratorSmart template_1; - template_1.Create(&gen); + template_1.Create(&gen,0,0); template_1.SetSingleServer(true,0x12121212,0,0); CTupleBase result; @@ -601,11 +631,11 @@ TEST(tuple_gen_2,template1) { TEST(tuple_gen_2,template2) { CTupleGeneratorSmart gen; - gen.Create(1, 1,cdSEQ_DIST, - 0x10000001, 0x1000000f, 0x30000001, 0x40000001, - 0,0); + gen.Create(1, 1); + gen.add_client_pool(cdSEQ_DIST,0x10000001,0x1000000f,64000,4,NULL,0,0); + gen.add_server_pool(cdSEQ_DIST,0x30000001,0x40000001,64000,4,false); CTupleTemplateGeneratorSmart template_1; - template_1.Create(&gen); + template_1.Create(&gen,0,0); template_1.SetW(10); CTupleBase result; @@ -646,45 +676,40 @@ TEST(tuple_gen_yaml,yam_reader1) { std::cout << e.what() << "\n"; exit(-1); } - fi.Dump(stdout); } TEST(tuple_gen_yaml,yam_is_valid) { CTupleGenYamlInfo fi; + CTupleGenPoolYaml c_pool; + CTupleGenPoolYaml s_pool; + fi.m_client_pool.push_back(c_pool); + fi.m_server_pool.push_back(s_pool); + + fi.m_client_pool[0].m_ip_start = 0x10000001; + fi.m_client_pool[0].m_ip_end = 0x100000ff; - fi.m_clients_ip_start = 0x10000001; - fi.m_clients_ip_end = 0x100000ff; - - fi.m_servers_ip_start = 0x10000001; - fi.m_servers_ip_end = 0x100001ff; + fi.m_server_pool[0].m_ip_start = 0x10000001; + fi.m_server_pool[0].m_ip_end = 0x100001ff; EXPECT_EQ(fi.is_valid(8,true)?1:0, 1); - EXPECT_EQ(fi.m_servers_ip_start, 0x10000001); - EXPECT_EQ(fi.m_servers_ip_end, 0x100001fe); - printf(" start:%x end:%x \n",fi.m_servers_ip_start,fi.m_servers_ip_end); - fi.m_clients_ip_start = 0x10000001; - fi.m_clients_ip_end = 0x100000ff; + fi.m_client_pool[0].m_ip_start = 0x10000001; + fi.m_client_pool[0].m_ip_end = 0x100000ff; - fi.m_servers_ip_start = 0x10000001; - fi.m_servers_ip_end = 0x10000009; + fi.m_server_pool[0].m_ip_start = 0x10000001; + fi.m_server_pool[0].m_ip_end = 0x10000007; EXPECT_EQ(fi.is_valid(8,true)?1:0, 0); - fi.m_clients_ip_start = 0x10000001; - fi.m_clients_ip_end = 0x100000ff; + fi.m_client_pool[0].m_ip_start = 0x10000001; + fi.m_client_pool[0].m_ip_end = 0x100000ff; - fi.m_servers_ip_start = 0x10000001; - fi.m_servers_ip_end = 0x100003ff; + fi.m_server_pool[0].m_ip_start = 0x10000001; + fi.m_server_pool[0].m_ip_end = 0x100003ff; EXPECT_EQ(fi.is_valid(8,true)?1:0, 1); - EXPECT_EQ(fi.m_servers_ip_start, 0x10000001); - EXPECT_EQ(fi.m_servers_ip_end, 0x100003fc); - - printf(" start:%x end:%x \n",fi.m_servers_ip_start,fi.m_servers_ip_end); - } diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index a748178d..820fb3fa 100755 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -4115,11 +4115,10 @@ int CGlobalPortCfg::start_send_master(){ CTupleGenYamlInfo * tg=&m_fl.m_yaml_info.m_tuple_gen; - m_mg.set_ip( tg->m_clients_ip_start, - tg->m_servers_ip_start, - tg->m_dual_interface_mask - ); - + m_mg.set_ip( tg->m_client_pool[0].get_ip_start(), + tg->m_server_pool[0].get_ip_start(), + tg->m_client_pool[0].getDualMask() + ); if ( CGlobalInfo::m_options.preview.getVMode() >0 ) { m_fl.DumpCsv(stdout); diff --git a/src/tuple_gen.cpp b/src/tuple_gen.cpp index 0faa6b63..e408f275 100755 --- a/src/tuple_gen.cpp +++ b/src/tuple_gen.cpp @@ -1,6 +1,6 @@ /* - Wenxian Li + Wenxian Li Hanoh Haim Cisco Systems, Inc. */ @@ -21,287 +21,364 @@ See the License for the specific language governing permissions and limitations under the License. */ + #include "tuple_gen.h" #include <string.h> #include "utl_yaml.h" - - - -/* simple tuple genertion for one low*/ -void CTupleGeneratorSmart::GenerateTuple(CTupleBase & tuple) { - BP_ASSERT(m_was_init); - Generate_client_server(); - m_was_generated = true; - m_result_client_port = GenerateOneClientPort(m_client_ip); - tuple.setClient(m_result_client_ip); - tuple.setServer(m_result_server_ip); - tuple.setClientPort(m_result_client_port); - tuple.setClientMac(&m_result_client_mac); -// printf(" alloc %x %d mac:%x,%x\n",m_result_client_ip,m_result_client_port, m_result_client_mac.mac[0], m_result_client_mac.mac[1]); +void CServerPool::Create(IP_DIST_t dist_value, + uint32_t min_ip, + uint32_t max_ip, + double l_flow, + double t_cps) { + gen = new CIpPool(); + gen->set_dist(dist_value); + uint32_t total_ip = max_ip - min_ip +1; + gen->m_ip_info.resize(total_ip); + + if (total_ip > ((l_flow*t_cps/MAX_PORT))) { + for(int idx=0;idx<total_ip;idx++){ + gen->m_ip_info[idx] = new CServerInfoL(); + gen->m_ip_info[idx]->set_ip(min_ip+idx); + } + } else { + for(int idx=0;idx<total_ip;idx++){ + gen->m_ip_info[idx] = new CServerInfo(); + gen->m_ip_info[idx]->set_ip(min_ip+idx); + } + } + gen->CreateBase(); } +void CClientPool::Create(IP_DIST_t dist_value, + uint32_t min_ip, + uint32_t max_ip, + double l_flow, + double t_cps, + CFlowGenList* fl_list, + bool has_mac_map, + 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 && (fl_list!=NULL)) { + for(int idx=0;idx<total_ip;idx++){ + mac_addr_align_t *mac_adr = NULL; + mac_adr = get_mac_addr_by_ip(fl_list, min_ip+idx); + if (mac_adr == NULL) { + avail_ip--; + } + } + } + if (avail_ip!=0) { + m_ip_info.resize(avail_ip); + } else { + printf("\n Error, empty mac file is configured.\n" + "Will ignore the mac file configuration.\n"); + m_ip_info.resize(total_ip); + } -/* - * allocate base tuple with n exta ports, used by bundels SIP - * for example need to allocat 3 ports for this C/S - */ -void CTupleGeneratorSmart::GenerateTupleEx(CTupleBase & tuple, - uint8_t extra_ports_no, - uint16_t * extra_ports) { - GenerateTuple(tuple) ; - for (int idx=0;idx<extra_ports_no;idx++) { - extra_ports[idx] = GenerateOneClientPort(m_client_ip); + if (total_ip > ((l_flow*t_cps/MAX_PORT))) { + if (has_mac_map) { + for(int idx=0;idx<total_ip;idx++){ + mac_addr_align_t *mac_adr = NULL; + mac_adr = get_mac_addr_by_ip(fl_list, min_ip+idx); + if (mac_adr != NULL) { + m_ip_info[idx] = new CClientInfoL(has_mac_map); + m_ip_info[idx]->set_ip(min_ip+idx); + m_ip_info[idx]->set_mac(mac_adr); + } + } + } 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) { + for(int idx=0;idx<total_ip;idx++){ + mac_addr_align_t *mac_adr = NULL; + mac_adr = get_mac_addr_by_ip(fl_list, min_ip+idx); + if (mac_adr != NULL) { + m_ip_info[idx] = new CClientInfo(has_mac_map); + m_ip_info[idx]->set_ip(min_ip+idx); + m_ip_info[idx]->set_mac(mac_adr); + } + } + } 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_tcp_aging = tcp_aging; + m_udp_aging = udp_aging; + CreateBase(); } -void CTupleGeneratorSmart::Dump(FILE *fd){ - fprintf(fd," id: %x, %x:%x - %x \n client:%x - %x, server:%x-%x\n",m_id,m_result_client_ip,m_result_server_ip,m_result_client_port,m_min_client_ip, m_max_client_ip, m_min_server_ip, m_max_server_ip); +void delay(int msec); + +bool CTupleGeneratorSmart::add_client_pool(IP_DIST_t client_dist, + uint32_t min_client, + uint32_t max_client, + double l_flow, + double t_cps, + CFlowGenList* fl_list, + 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, fl_list, has_mac_mapping, + tcp_aging, udp_aging); + + m_client_pool.push_back(pool); + return(true); +} + +bool CTupleGeneratorSmart::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){ + assert(max_server>=min_server); + CServerPoolBase* pool; + if (is_bundling) + pool = new CServerPool(); + else + pool = new CServerPoolSimple(); + // we currently only supports mac mapping file for client + pool->Create(server_dist, min_server, max_server, + l_flow, t_cps); + m_server_pool.push_back(pool); + return(true); } -void delay(int msec); bool CTupleGeneratorSmart::Create(uint32_t _id, - uint32_t thread_id, - IP_DIST_t dist, - uint32_t min_client, - uint32_t max_client, - uint32_t min_server, - uint32_t max_server, - double l_flow, - double t_cps, - CFlowGenList* fl_list){ - - m_active_alloc=0; - if (dist>=cdMAX_DIST) { - m_client_dist = cdSEQ_DIST; - } else { - m_client_dist = dist; - } - m_min_client_ip = min_client; - m_max_client_ip = max_client; - m_min_server_ip = min_server; - m_max_server_ip = max_server; - assert(m_max_client_ip>=m_min_client_ip); - assert(m_max_server_ip>=m_min_server_ip); - assert((m_max_client_ip- m_min_client_ip)<50000); - - uint32_t total_clients = getTotalClients(); - /*printf("\ntotal_clients:%d, longest_flow:%f sec, total_cps:%f\n", - total_clients, l_flow, t_cps);*/ - m_client.resize(m_max_client_ip-m_min_client_ip+1); - if (fl_list == NULL || !is_mac_info_conf(fl_list)) { - if (total_clients > ((l_flow*t_cps/MAX_PORT))) { - for (int idx=0;idx<m_client.size();idx++) - m_client[idx] = new CClientInfoL(); - } else { - for (int idx=0;idx<m_client.size();idx++) - m_client[idx] = new CClientInfo(); - } - } else { - if (total_clients > ((l_flow*t_cps/MAX_PORT))) { - for (int idx=0;idx<m_client.size();idx++) { - m_client[idx] = new CClientInfoL( - get_mac_addr_by_ip(fl_list, min_client+idx)); - } - } else { - for (int idx=0;idx<m_client.size();idx++) - m_client[idx] = new CClientInfo( - get_mac_addr_by_ip(fl_list, min_client+idx)); - } - } - m_was_generated = false; + uint32_t thread_id, + bool has_mac) +{ m_thread_id = thread_id; - m_id = _id; m_was_init=true; - m_port_allocation_error=0; + has_mac_mapping = has_mac; return(true); } void CTupleGeneratorSmart::Delete(){ - m_was_generated = false; m_was_init=false; - m_client_dist = cdSEQ_DIST; + has_mac_mapping = false; - for (int idx=0;idx<m_client.size();idx++){ - delete m_client[idx]; + for (int idx=0;idx<m_client_pool.size();idx++) { + m_client_pool[idx]->Delete(); + delete m_client_pool[idx]; } - m_client.clear(); -} + m_client_pool.clear(); -void CTupleGeneratorSmart::Generate_client_server(){ - if (m_was_generated == false) { - /*first time */ - m_was_generated = true; - m_cur_client_ip = m_min_client_ip; - m_cur_server_ip = m_min_server_ip; + for (int idx=0;idx<m_server_pool.size();idx++) { + m_server_pool[idx]->Delete(); + delete m_server_pool[idx]; } + m_server_pool.clear(); +} - uint32_t client_ip; - int i=0; - for (;i<100;i++) { - if (is_client_available(m_cur_client_ip)) { - break; - } - if (m_cur_client_ip >= m_max_client_ip) { - m_cur_client_ip = m_min_client_ip; - } else { - m_cur_client_ip++; - } - } - if (i>=100) { - printf(" ERROR ! sparse mac-ip files is not supported yet !\n"); - exit(-1); - } +void CTupleGenPoolYaml::Dump(FILE *fd){ + fprintf(fd," dist : %d \n",m_dist); + fprintf(fd," IPs : %08x -%08x \n",m_ip_start,m_ip_end); + fprintf(fd," clients per gb : %d \n",m_number_of_clients_per_gb); + fprintf(fd," min clients : %d \n",m_min_clients); + fprintf(fd," tcp aging : %d sec \n",m_tcp_aging_sec); + fprintf(fd," udp aging : %d sec \n",m_udp_aging_sec); +} - m_client_ip = m_cur_client_ip; - CClientInfoBase* client = get_client_by_ip(m_client_ip); - memcpy(&m_result_client_mac, - client->get_mac_addr(), - sizeof(mac_addr_align_t)); - m_result_client_ip = m_client_ip; - m_result_server_ip = m_cur_server_ip ; -/* -printf("ip:%x,mac:%x,%x,%x,%x,%x,%x, inused:%x\n",m_client_ip, - m_result_client_mac.mac[0], - m_result_client_mac.mac[1], - m_result_client_mac.mac[2], - m_result_client_mac.mac[3], - m_result_client_mac.mac[4], - m_result_client_mac.mac[5], - m_result_client_mac.inused); -*/ - m_cur_client_ip ++; - m_cur_server_ip ++; - if (m_cur_client_ip > m_max_client_ip) { - m_cur_client_ip = m_min_client_ip; +bool CTupleGenPoolYaml::is_valid(uint32_t num_threads,bool is_plugins){ + if ( m_ip_start > m_ip_end ){ + printf(" ERROR The ip_start must be bigger than ip_end \n"); + return(false); } - if (m_cur_server_ip > m_max_server_ip) { - m_cur_server_ip = m_min_server_ip; + + uint32_t ips= (m_ip_end - m_ip_start +1); + if ( ips < num_threads ) { + printf(" ERROR The number of ips should be at least number of threads %d \n",num_threads); + return (false); } -} -void CTupleGeneratorSmart::return_all_client_ports() { - for(int idx=0;idx<m_client.size();++idx) { - m_client.at(idx)->return_all_ports(); + if (ips > 1000000) { + printf(" The number of clients requested is %d maximum supported : %d \n",ips,1000000); + return (false); } + return (true); } -void CTupleGenYamlInfo::Dump(FILE *fd){ - fprintf(fd," dist : %d \n",m_client_dist); - fprintf(fd," clients : %08x -%08x \n",m_clients_ip_start,m_clients_ip_end); - fprintf(fd," servers : %08x -%08x \n",m_servers_ip_start,m_servers_ip_end); - fprintf(fd," clients per gb : %d \n",m_number_of_clients_per_gb); - fprintf(fd," min clients : %d \n",m_min_clients); - fprintf(fd," tcp aging : %d sec \n",m_tcp_aging_sec); - fprintf(fd," udp aging : %d sec \n",m_udp_aging_sec); -} + + +void operator >> (const YAML::Node& node, CTupleGenPoolYaml & fi) { + std::string tmp; + node["name"] >> fi.m_name; + node["distribution"] >> tmp ; + if (tmp == "random") { + fi.m_dist=cdRANDOM_DIST; + }else if (tmp == "normal") { + fi.m_dist=cdNORMAL_DIST; + } else { + fi.m_dist=cdSEQ_DIST; + } + utl_yaml_read_ip_addr(node,"ip_start",fi.m_ip_start); + utl_yaml_read_ip_addr(node,"ip_end",fi.m_ip_end); + fi.m_number_of_clients_per_gb = 0; + + fi.m_min_clients = 0; + fi.m_is_bundling = false; + fi.m_tcp_aging_sec = 0; + fi.m_udp_aging_sec = 0; + fi.m_dual_interface_mask = 0; + try { + utl_yaml_read_uint32(node,"clients_per_gb",fi.m_number_of_clients_per_gb); + } catch ( const std::exception& e ) { + ;} + try { + utl_yaml_read_uint32(node,"min_clients",fi.m_min_clients); + } catch ( const std::exception& e ) { + ;} + try { + utl_yaml_read_ip_addr(node,"dual_port_mask",fi.m_dual_interface_mask); + } catch ( const std::exception& e ) { + ;} + try { + utl_yaml_read_uint16(node,"tcp_aging",fi.m_tcp_aging_sec); + } catch ( const std::exception& e ) { + ;} + try { + utl_yaml_read_uint16(node,"udp_aging",fi.m_udp_aging_sec); + } catch ( const std::exception& e ) { + ;} + try { + node["track_ports"] >> fi.m_is_bundling; + } catch ( const std::exception& e ) { + ;} +} +void copy_global_pool_para(CTupleGenPoolYaml & src, CTupleGenPoolYaml & dst) { + if (src.m_number_of_clients_per_gb == 0) + src.m_number_of_clients_per_gb = dst.m_number_of_clients_per_gb; + if (src.m_min_clients == 0) + src.m_min_clients = dst.m_min_clients; + if (src.m_dual_interface_mask == 0) + src.m_dual_interface_mask = dst.m_dual_interface_mask; + if (src.m_tcp_aging_sec == 0) + src.m_tcp_aging_sec = dst.m_tcp_aging_sec; + if (src.m_udp_aging_sec == 0) + src.m_udp_aging_sec = dst.m_udp_aging_sec; +} void operator >> (const YAML::Node& node, CTupleGenYamlInfo & fi) { std::string tmp; try { - node["distribution"] >> tmp ; - if (tmp == "seq" ) { - fi.m_client_dist=cdSEQ_DIST; - }else{ - if (tmp == "random") { - fi.m_client_dist=cdRANDOM_DIST; - }else{ - if (tmp == "normal") { - fi.m_client_dist=cdNORMAL_DIST; - } - } - } + CTupleGenPoolYaml c_pool; + CTupleGenPoolYaml s_pool; + node["distribution"] >> tmp ; + if (tmp == "random") { + c_pool.m_dist=cdRANDOM_DIST; + }else if (tmp == "normal") { + c_pool.m_dist=cdNORMAL_DIST; + } else { + c_pool.m_dist=cdSEQ_DIST; + } + s_pool.m_dist = c_pool.m_dist; + utl_yaml_read_ip_addr(node,"clients_start",c_pool.m_ip_start); + utl_yaml_read_ip_addr(node,"clients_end",c_pool.m_ip_end); + utl_yaml_read_ip_addr(node,"servers_start",s_pool.m_ip_start); + utl_yaml_read_ip_addr(node,"servers_end",s_pool.m_ip_end); + utl_yaml_read_uint32(node,"clients_per_gb",c_pool.m_number_of_clients_per_gb); + utl_yaml_read_uint32(node,"min_clients",c_pool.m_min_clients); + utl_yaml_read_ip_addr(node,"dual_port_mask",c_pool.m_dual_interface_mask); + utl_yaml_read_uint16(node,"tcp_aging",c_pool.m_tcp_aging_sec); + utl_yaml_read_uint16(node,"udp_aging",c_pool.m_udp_aging_sec); + s_pool.m_dual_interface_mask = c_pool.m_dual_interface_mask; + s_pool.m_is_bundling = false; + fi.m_client_pool.push_back(c_pool); + fi.m_server_pool.push_back(s_pool); }catch ( const std::exception& e ) { - fi.m_client_dist=cdSEQ_DIST; + printf("No default generator defined.\n"); } - utl_yaml_read_ip_addr(node,"clients_start",fi.m_clients_ip_start); - utl_yaml_read_ip_addr(node,"clients_end",fi.m_clients_ip_end); - utl_yaml_read_ip_addr(node,"servers_start",fi.m_servers_ip_start); - utl_yaml_read_ip_addr(node,"servers_end",fi.m_servers_ip_end); - utl_yaml_read_uint32(node,"clients_per_gb",fi.m_number_of_clients_per_gb); - utl_yaml_read_uint32(node,"min_clients",fi.m_min_clients); - utl_yaml_read_ip_addr(node,"dual_port_mask",fi.m_dual_interface_mask); - utl_yaml_read_uint16(node,"tcp_aging",fi.m_tcp_aging_sec); - utl_yaml_read_uint16(node,"udp_aging",fi.m_udp_aging_sec); - + try{ + const YAML::Node& c_pool_info = node["generator_clients"]; + for (uint16_t idx=0;idx<c_pool_info.size();idx++) { + CTupleGenPoolYaml pool; + try { + c_pool_info[idx] >> pool; + if (fi.m_client_pool.size()>0) { + copy_global_pool_para(pool, fi.m_client_pool[0]); + } + fi.m_client_pool.push_back(pool); + } catch ( const std::exception& e ) { + printf("client pool in YAML is wrong\n"); + } + } + }catch ( const std::exception& e ) { + printf("no client generator pool configured, using default pool\n"); + } + try { + const YAML::Node& s_pool_info = node["generator_servers"]; + for (uint16_t idx=0;idx<s_pool_info.size();idx++) { + CTupleGenPoolYaml pool; + try { + s_pool_info[idx] >> pool; + } catch ( const std::exception& e ) { + printf("server pool in YAML is wrong\n"); + } + if (fi.m_server_pool.size()>0) { + copy_global_pool_para(pool, fi.m_server_pool[0]); + } + fi.m_server_pool.push_back(pool); + } + }catch ( const std::exception& e ) { + printf("no server generator pool configured, using default pool\n"); + } } bool CTupleGenYamlInfo::is_valid(uint32_t num_threads,bool is_plugins){ - if ( m_servers_ip_start > m_servers_ip_end ){ - printf(" ERROR The servers_ip_start must be bigger than servers_ip_end \n"); - return(false); - } - - if ( m_clients_ip_start > m_clients_ip_end ){ - printf(" ERROR The clients_ip_start must be bigger than clients_ip_end \n"); - return(false); + for (int i=0;i<m_client_pool.size();i++) { + if (m_client_pool[i].is_valid(num_threads, is_plugins)==false) + return false; } - uint32_t servers= (m_servers_ip_end - m_servers_ip_start +1); - if ( servers < num_threads ) { - printf(" ERROR The number of servers should be at least number of threads %d \n",num_threads); - return (false); + for (int i=0;i<m_server_pool.size();i++) { + if (m_server_pool[i].is_valid(num_threads, is_plugins)==false) + return false; } - uint32_t clients= (m_clients_ip_end - m_clients_ip_start +1); - if ( clients < num_threads ) { - printf(" ERROR The number of clients should be at least number of threads %d \n",num_threads); - return (false); - } - - /* defect for plugin */ - if (is_plugins) { - if ( getTotalServers() < getTotalClients() ){ - printf(" Plugin is configured. in that case due to a limitation ( defect trex-54 ) \n"); - printf(" the number of servers should be bigger than number of clients \n"); - return (false); - } - - /* update number of servers in a way that it would be exact multiplication */ - uint32_t mul=getTotalServers() / getTotalClients(); - uint32_t new_server_num=mul*getTotalClients(); - m_servers_ip_end = m_servers_ip_start + new_server_num-1 ; - - assert(getTotalServers() %getTotalClients() ==0); - } - -/* if (clients > 00000) { - printf(" The number of clients requested is %d maximum supported : %d \n",clients,100000); - return (false); - } - */ return (true); + return true; } /* split the clients and server by dual_port_id and thread_id , clients is splited by threads and dual_port_id servers is spliteed by dual_port_id */ -void split_clients(uint32_t thread_id, - uint32_t total_threads, - uint32_t dual_port_id, - CTupleGenYamlInfo & fi, - CClientPortion & portion){ - - uint32_t clients_chunk = fi.getTotalClients()/total_threads; - // FIXME need to fix this when fixing the server - uint32_t servers_chunk = fi.getTotalServers()/total_threads; - - assert(clients_chunk>0); - assert(servers_chunk>0); +void split_ips(uint32_t thread_id, + uint32_t total_threads, + uint32_t dual_port_id, + CTupleGenPoolYaml& poolinfo, + CIpPortion & portion){ - uint32_t dual_if_mask=(dual_port_id*fi.m_dual_interface_mask); + uint32_t chunks = poolinfo.getTotalIps()/total_threads; - portion.m_client_start = fi.m_clients_ip_start + thread_id*clients_chunk + dual_if_mask; - portion.m_client_end = portion.m_client_start + clients_chunk -1 ; + assert(chunks>0); - portion.m_server_start = fi.m_servers_ip_start + thread_id*servers_chunk +dual_if_mask; - portion.m_server_end = portion.m_server_start + servers_chunk -1; + uint32_t dual_if_mask=(dual_port_id*poolinfo.getDualMask()); + + portion.m_ip_start = poolinfo.get_ip_start() + thread_id*chunks + dual_if_mask; + portion.m_ip_end = portion.m_ip_start + chunks -1 ; } diff --git a/src/tuple_gen.h b/src/tuple_gen.h index 96b9b01a..fb856538 100755 --- a/src/tuple_gen.h +++ b/src/tuple_gen.h @@ -1,8 +1,9 @@ #ifndef TUPLE_GEN_H_ #define TUPLE_GEN_H_ + /* - Wenxian Li - + Wenxian Li + Cisco Systems, Inc. */ @@ -22,7 +23,6 @@ See the License for the specific language governing permissions and limitations under the License. */ - #include <stdio.h> #include <stdint.h> #include <string.h> @@ -39,9 +39,14 @@ limitations under the License. #include <yaml-cpp/yaml.h> +#include <random> + + + /* * Class that handle the client info */ +#define MAX_CLIENTS 1000000 #define MAX_PORT (64000) #define MIN_PORT (1024) #define ILLEGAL_PORT (0) @@ -52,6 +57,8 @@ limitations under the License. /*FIXME*/ #define VLAN_SIZE (2) +#define FOREACH(vector) for(int i=0;i<vector.size();i++) + /* Client distribution */ @@ -62,14 +69,21 @@ typedef enum { cdMAX_DIST = 3 } IP_DIST_t ; +#define INUSED 0 +#define UNUSED 1 typedef struct mac_addr_align_ { public: uint8_t mac[6]; uint8_t inused; uint8_t pad; } mac_addr_align_t; -#define INUSED 0 -#define UNUSED 1 + +typedef struct mac_mapping_ { + mac_addr_align_t mac; + uint32_t ip; +} mac_mapping_t; + + /* For type 1, we generator port by maintaining a 64K bit array for each port. * In this case, we cannot support large number of clients due to memory exhausted. @@ -85,39 +99,31 @@ public: #define TYPE2 1 #define MAX_TYPE 3 -class CClientInfoBase { + +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 return_all_ports() = 0; - virtual bool is_client_available() = 0; - virtual mac_addr_align_t* get_mac_addr() = 0; + uint32_t get_ip() { + return m_ip; + } + void set_ip(uint32_t ip) { + m_ip = ip; + } + public: + uint32_t m_ip; }; //CClientInfo for large amount of clients support -class CClientInfoL : public CClientInfoBase { - mac_addr_align_t mac; +class CIpInfoL : public CIpInfoBase { private: uint16_t m_curr_port; public: - CClientInfoL(mac_addr_align_t* mac_adr) { - m_curr_port = MIN_PORT; - if (mac_adr) { - mac = *mac_adr; - mac.inused = INUSED; - } else { - memset(&mac, 0, sizeof(mac_addr_align_t)); - mac.inused = UNUSED; - } - } - - CClientInfoL() { + CIpInfoL() { m_curr_port = MIN_PORT; - memset(&mac, 0, sizeof(mac_addr_align_t)); - mac.inused = INUSED; - } - mac_addr_align_t* get_mac_addr() { - return &mac; } uint16_t get_new_free_port() { if (m_curr_port>MAX_PORT) { @@ -132,22 +138,13 @@ class CClientInfoL : public CClientInfoBase { void return_all_ports() { m_curr_port = MIN_PORT; } - - bool is_client_available() { - if (mac.inused == INUSED) { - return true; - } else { - return false; - } - } }; -class CClientInfo : public CClientInfoBase { +class CIpInfo : public CIpInfoBase { private: std::bitset<MAX_PORT> m_bitmap_port; uint16_t m_head_port; - mac_addr_align_t mac; friend class CClientInfoUT; private: @@ -200,27 +197,9 @@ class CClientInfo : public CClientInfoBase { public: - CClientInfo() { + CIpInfo() { m_head_port = MIN_PORT; m_bitmap_port.reset(); - memset(&mac, 0, sizeof(mac_addr_align_t)); - mac.inused = INUSED; - } - CClientInfo(mac_addr_align_t* mac_info) { - m_head_port = MIN_PORT; - m_bitmap_port.reset(); - if (mac_info) { - mac = *mac_info; - mac.inused = INUSED; - } else { - memset(&mac, 0, sizeof(mac_addr_align_t)); - mac.inused = UNUSED; - } - - } - - mac_addr_align_t* get_mac_addr() { - return &mac; } uint16_t get_new_free_port() { @@ -251,30 +230,109 @@ class CClientInfo : public CClientInfoBase { m_head_port = MIN_PORT; m_bitmap_port.reset(); } - bool is_client_available() { - if (mac.inused == INUSED) { - return true; +}; + +class CClientInfo : public CIpInfo { + public: + CClientInfo (bool has_mac) { + if (has_mac==true) { + m_mac = new mac_addr_align_t(); + } else { + m_mac = NULL; + } + } + CClientInfo () { + m_mac = NULL; + } + + 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)); + } + ~CClientInfo() { + if (m_mac!=NULL){ + delete m_mac; + } + } + 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 { - return false; + m_mac = NULL; } } + CClientInfoL () { + m_mac = NULL; + } + + 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)); + } + ~CClientInfoL() { + if (m_mac!=NULL) { + delete m_mac; + } + } +private: + mac_addr_align_t *m_mac; +}; +class CServerInfo : public CIpInfo { + ; }; +class CServerInfoL : public CIpInfoL { + ; +}; + + class CTupleBase { public: + CTupleBase() { + m_client_mac.inused = UNUSED; + } uint32_t getClient() { return m_client_ip; } void setClient(uint32_t ip) { m_client_ip = ip; } + uint32_t getClientId() { + return m_client_idx; + } + void setClientId(uint32_t id) { + m_client_idx = id; + } + uint32_t getServer(){ return m_server_ip; } void setServer(uint32_t ip) { m_server_ip = ip; } + uint32_t getServerId(){ + return m_server_idx; + } + void setServerId(uint32_t id) { + m_server_idx = id; + } + uint16_t getServerPort() { + return m_server_port; + } + void setServerPort(uint16_t port) { + m_server_port = port; + } uint16_t getClientPort() { return m_client_port; } @@ -285,16 +343,21 @@ public: return &m_client_mac; } void setClientMac(mac_addr_align_t* mac_info) { - memcpy(&m_client_mac, mac_info, sizeof(mac_addr_align_t)); + 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; + } } private: uint32_t m_client_ip; + uint32_t m_client_idx; uint32_t m_server_ip; - uint16_t m_client_port; - uint16_t pad1; - uint32_t pad2; + uint32_t m_server_idx; mac_addr_align_t m_client_mac; - uint32_t pad3[3]; + uint16_t m_client_port; + uint16_t m_server_port; }; @@ -304,43 +367,259 @@ mac_addr_align_t * get_mac_addr_by_ip(CFlowGenList *fl_list, uint32_t ip); bool is_mac_info_conf(CFlowGenList *fl_list); -/* generate for each template */ -class CTupleGeneratorSmart { +class CIpPool { + public: + uint16_t GenerateOnePort(uint32_t idx) { + CIpInfoBase* ip_info = m_ip_info[idx]; + uint16_t port; + port = ip_info->get_new_free_port(); + + //printf(" alloc extra %x %d \n",c_ip,port); + if (port==ILLEGAL_PORT) { + m_port_allocation_error++; + } + m_active_alloc++; + return (port); + } + bool is_valid_ip(uint32_t ip){ + CIpInfoBase* ip_front = m_ip_info.front(); + CIpInfoBase* ip_back = m_ip_info.back(); + if ((ip>=ip_front->get_ip()) && + (ip<=ip_back->get_ip())) { + return(true); + } + printf("invalid ip:%x, min_ip:%x, max_ip:%x, this:%x\n", + ip, ip_front->get_ip(), + ip_back->get_ip(),this); + return(false); + } + + uint32_t get_curr_ip() { + return m_ip_info[m_cur_idx]->get_ip(); + } + uint32_t get_ip(uint32_t idx) { + return m_ip_info[idx]->get_ip(); + } + CIpInfoBase* get_ip_info_by_idx(uint32_t idx) { + return m_ip_info[idx]; + } + + void inc_cur_idx() { + switch (m_dist) { + case cdRANDOM_DIST: + m_cur_idx = get_random_idx(); + break; + case cdSEQ_DIST : + default: + m_cur_idx++; + if (m_cur_idx >= m_ip_info.size()) + m_cur_idx = 0; + } + } + //return a valid client idx in this pool + uint32_t generate_ip() { + uint32_t res_idx = m_cur_idx; + inc_cur_idx(); + return res_idx; + } + void set_dist(IP_DIST_t dist) { + if (dist>=cdMAX_DIST) { + m_dist = cdSEQ_DIST; + } else { + m_dist = dist; + } + } + void Delete() { + FOREACH(m_ip_info) { + delete m_ip_info[i]; + } + m_ip_info.clear(); + } + uint32_t get_total_ips() { + return m_ip_info.size(); + } + void return_all_ports() { + FOREACH(m_ip_info) { + m_ip_info[i]->return_all_ports(); + } + } + void FreePort(uint32_t id, uint16_t port) { + // assert(id<m_ip_info.size()); + m_active_alloc--; + CIpInfoBase* client = m_ip_info[id]; + 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; + IP_DIST_t m_dist; + uint32_t m_cur_idx; + uint32_t m_active_alloc; + uint32_t m_port_allocation_error; + std::default_random_engine generator; + std::uniform_int_distribution<int> *rand_dis; + void CreateBase() { + switch (m_dist) { + case cdRANDOM_DIST: + rand_dis = new std::uniform_int_distribution<int> + (0,get_total_ips()-1); + break; + default: + break; + } + m_cur_idx = 0; + m_active_alloc = 0; + m_port_allocation_error = 0; + } + uint32_t get_random_idx() { + uint32_t res = (*rand_dis)(generator); + return (res); + } + bool IsFreePortRequired(void){ + return(true); + } + + +}; + +class CClientPool : public CIpPool { public: - /* simple tuple genertion for one low*/ - void GenerateTuple(CTupleBase & tuple); - /* - * allocate base tuple with n exta ports, used by bundels SIP - * for example need to allocat 3 ports for this C/S - */ - void GenerateTupleEx(CTupleBase & tuple,uint8_t extra_ports_no, - uint16_t * extra_ports); + void GenerateTuple(CTupleBase & tuple) { + uint32_t idx = generate_ip(); + tuple.setClientId(idx); + tuple.setClient(get_ip(idx)); + tuple.setClientMac(get_mac(idx)); + tuple.setClientPort(GenerateOnePort(idx)); + } + uint16_t get_tcp_aging() { + return m_tcp_aging; + } + 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, + CFlowGenList* fl_list, + bool has_mac_map, + uint16_t tcp_aging, + uint16_t udp_aging); +public: + uint16_t m_tcp_aging; + uint16_t m_udp_aging; +}; + +class CServerPoolBase { + public: + virtual void GenerateTuple(CTupleBase& tuple) = 0; + virtual uint16_t GenerateOnePort(uint32_t idx) = 0; + virtual void Delete() = 0; + virtual uint32_t get_total_ips()=0; + virtual void Create(IP_DIST_t dist_value, + uint32_t min_ip, + uint32_t max_ip, + double l_flow, + double t_cps) = 0; + +}; - /* free client port */ - void FreePort(uint32_t c_ip, - uint16_t port){ - //printf(" free %x %d \n",c_ip,port); - m_active_alloc--; - CClientInfoBase* client = get_client_by_ip(c_ip); - client->return_port(port); +class CServerPoolSimple : public CServerPoolBase { +public: + void Create(IP_DIST_t dist_value, + uint32_t min_ip, + uint32_t max_ip, + double l_flow, + double t_cps) { + m_max_server_ip = max_ip; + m_min_server_ip = min_ip; + m_cur_server_ip = min_ip; + } + void Delete() { + return ; + } + void GenerateTuple(CTupleBase& tuple) { + tuple.setServer(m_cur_server_ip); + m_cur_server_ip ++; + if (m_cur_server_ip > m_max_server_ip) { + m_cur_server_ip = m_min_server_ip; + } + } + uint16_t GenerateOnePort(uint32_t idx) { + // do nothing + return 0; + } + uint32_t get_total_ips() { + return (m_max_server_ip-m_min_server_ip+1); } +private: + uint32_t m_max_server_ip; + uint32_t m_min_server_ip; + uint32_t m_cur_server_ip; +}; - /* return true if this type of generator require to free resource */ - bool IsFreePortRequired(void){ - return(true); +class CServerPool : public CServerPoolBase { +public: + CIpPool *gen; + void GenerateTuple(CTupleBase & tuple) { + uint32_t idx = gen->generate_ip(); + tuple.setServerId(idx); + tuple.setServer(gen->get_ip(idx)); + } + uint16_t GenerateOnePort(uint32_t idx) { + return gen->GenerateOnePort(idx); + } + void Create(IP_DIST_t dist_value, + uint32_t min_ip, + uint32_t max_ip, + double l_flow, + double t_cps); + + void Delete() { + if (gen!=NULL) { + gen->Delete(); + delete gen; + } + } + uint32_t get_total_ips() { + return gen->m_ip_info.size(); } +}; +/* generate for each template */ +class CTupleGeneratorSmart { +public: /* return the active socket */ uint32_t ActiveSockets(void){ - return (m_active_alloc); + uint32_t total_active_alloc = 0; + FOREACH(m_client_pool) { + total_active_alloc += m_client_pool[i]->m_active_alloc; + } + return (total_active_alloc); } uint32_t getTotalClients(void){ - return (m_max_client_ip -m_min_client_ip +1); + uint32_t total_clients = 0; + FOREACH(m_client_pool) { + total_clients += m_client_pool[i]->get_total_ips(); + } + return (total_clients); } uint32_t getTotalServers(void){ - return (m_max_server_ip -m_min_server_ip +1); + uint32_t total_servers = 0; + FOREACH(m_server_pool) { + total_servers += m_server_pool[i]->get_total_ips(); + } + return total_servers; } uint32_t SocketsPerClient(void){ @@ -351,136 +630,103 @@ public: return (SocketsPerClient() * getTotalClients()); } + + void FreePort(uint8_t pool_idx, uint32_t id, uint16_t port) { + get_client_pool(pool_idx)->FreePort(id, port); + } + + bool IsFreePortRequired(uint8_t pool_idx){ + return(get_client_pool(pool_idx)->IsFreePortRequired()); + } + uint16_t get_tcp_aging(uint8_t pool_idx) { + return (get_client_pool(pool_idx)->get_tcp_aging()); + } + uint16_t get_udp_aging(uint8_t pool_idx) { + return (get_client_pool(pool_idx)->get_udp_aging()); + } public: CTupleGeneratorSmart(){ m_was_init=false; - m_client_dist = cdSEQ_DIST; + has_mac_mapping = false; } bool Create(uint32_t _id, - uint32_t thread_id, - IP_DIST_t dist, - uint32_t min_client, - uint32_t max_client, - uint32_t min_server, - uint32_t max_server, - double longest_flow, - double total_cps, - CFlowGenList * fl_list = NULL); + uint32_t thread_id, bool has_mac=false); void Delete(); - void Dump(FILE *fd); - - void SetClientDist(IP_DIST_t dist) { - m_client_dist = dist; - } - - IP_DIST_t GetClientDist() { - return (m_client_dist); - } - inline uint32_t GetThreadId(){ return ( m_thread_id ); } - bool is_valid_client(uint32_t c_ip){ - if ((c_ip>=m_min_client_ip) && (c_ip<=m_max_client_ip)) { - return(true); - } - printf("invalid client ip:%x, min_ip:%x, max_ip:%x\n", - c_ip, m_min_client_ip, m_max_client_ip); - return(false); - } - - CClientInfoBase* get_client_by_ip(uint32_t c_ip){ - BP_ASSERT( is_valid_client(c_ip) ); - return m_client.at(c_ip-m_min_client_ip); - } - - bool is_client_available (uint32_t c_ip) { - CClientInfoBase* client = get_client_by_ip(c_ip); - if (client) { - return client->is_client_available(); - } - return false; - } - - uint16_t GenerateOneClientPort(uint32_t c_ip) { - CClientInfoBase* client = get_client_by_ip(c_ip); - uint16_t port; - port = client->get_new_free_port(); - - //printf(" alloc extra %x %d \n",c_ip,port); - if (port==ILLEGAL_PORT) { - m_port_allocation_error++; - } - m_active_alloc++; - return (port); - } - uint32_t getErrorAllocationCounter(){ - return ( m_port_allocation_error ); + uint32_t total_alloc_error = 0; + FOREACH(m_client_pool) { + total_alloc_error += m_client_pool[i]->m_port_allocation_error; + } + 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, + CFlowGenList* fl_list, + 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); + CClientPool* get_client_pool(uint8_t idx) { + return m_client_pool[idx]; + } + uint8_t get_client_pool_num() { + return m_client_pool.size(); + } + uint8_t get_server_pool_num() { + return m_server_pool.size(); + } + CServerPoolBase* get_server_pool(uint8_t idx) { + return m_server_pool[idx]; } - -private: - void return_all_client_ports(); - - - void Generate_client_server(); - - private: - std::vector<CClientInfoBase*> m_client; - uint32_t m_id; - bool m_was_generated; - bool m_was_init; - - IP_DIST_t m_client_dist; - - uint32_t m_cur_server_ip; - uint32_t m_cur_client_ip; - // min-max client ip +1 and get back - uint32_t m_min_client_ip; - uint32_t m_max_client_ip; - - // min max server ip ( random ) - uint32_t m_min_server_ip; - uint32_t m_max_server_ip; - uint32_t m_thread_id; - - // result of the generator FIXME need to clean this - uint32_t m_client_ip; - uint32_t m_result_client_ip; - uint32_t m_result_server_ip; - uint32_t m_active_alloc; - mac_addr_align_t m_result_client_mac; - uint16_t m_result_client_port; - - uint32_t m_port_allocation_error; - + std::vector<CClientPool*> m_client_pool; + std::vector<CServerPoolBase*> m_server_pool; + bool m_was_init; + bool has_mac_mapping; }; - class CTupleTemplateGeneratorSmart { public: /* simple tuple genertion for one low*/ void GenerateTuple(CTupleBase & tuple){ if (m_w==1) { /* new client each tuple generate */ - m_gen->GenerateTuple(tuple); - m_cache_client_ip=tuple.getClient(); + m_client_gen->GenerateTuple(tuple); + m_server_gen->GenerateTuple(tuple); + m_cache_client_ip = tuple.getClient(); + m_cache_client_idx = tuple.getClientId(); }else{ if (m_cnt==0) { - m_gen->GenerateTuple(tuple); + m_client_gen->GenerateTuple(tuple); + m_server_gen->GenerateTuple(tuple); m_cache_client_ip = tuple.getClient(); + m_cache_client_idx = tuple.getClientId(); m_cache_server_ip = tuple.getServer(); + m_cache_server_idx = tuple.getServerId(); }else{ tuple.setServer(m_cache_server_ip); + tuple.setServerId(m_cache_server_idx); tuple.setClient(m_cache_client_ip); - tuple.setClientPort( m_gen->GenerateOneClientPort(m_cache_client_ip)); + tuple.setClientId(m_cache_client_idx); + tuple.setClientPort( + m_client_gen->GenerateOnePort(m_cache_client_idx)); } m_cnt++; if (m_cnt>=m_w) { @@ -493,7 +739,7 @@ public: } uint16_t GenerateOneSourcePort(){ - return ( m_gen->GenerateOneClientPort(m_cache_client_ip) ); + return ( m_client_gen->GenerateOnePort(m_cache_client_idx) ); } inline uint32_t GetThreadId(){ @@ -502,12 +748,13 @@ public: public: - bool Create( CTupleGeneratorSmart * gen - ){ + bool Create( CTupleGeneratorSmart * gen,uint8_t c_pool,uint8_t s_pool){ m_gen=gen; m_is_single_server=false; m_server_ip=0; SetW(1); + m_client_gen = gen->get_client_pool(c_pool); + m_server_gen = gen->get_server_pool(s_pool); return (true); } @@ -535,15 +782,21 @@ public: return (m_is_single_server); } + CTupleGeneratorSmart * get_gen() { + return m_gen; + } private: CTupleGeneratorSmart * m_gen; - bool m_is_single_server; + CClientPool * m_client_gen; + CServerPoolBase * m_server_gen; uint16_t m_w; uint16_t m_cnt; uint32_t m_server_ip; uint32_t m_cache_client_ip; + uint32_t m_cache_client_idx; uint32_t m_cache_server_ip; - + uint32_t m_cache_server_idx; + bool m_is_single_server; }; @@ -559,61 +812,70 @@ private: - dual_interface_mask : 1.0.0.0 // each dual ports will add this to the pool of clients #endif -struct CTupleGenYamlInfo { - CTupleGenYamlInfo(){ - m_client_dist=cdSEQ_DIST; - m_clients_ip_start =0x11000000; - m_clients_ip_end =0x21000000; - - m_servers_ip_start = 0x30000000; - m_servers_ip_end = 0x40000000; - m_number_of_clients_per_gb=10; - m_min_clients=100; - m_dual_interface_mask=0x10000000; - m_tcp_aging_sec=2; - m_udp_aging_sec=5; - } - - IP_DIST_t m_client_dist; - uint32_t m_clients_ip_start; - uint32_t m_clients_ip_end; - - uint32_t m_servers_ip_start; - uint32_t m_servers_ip_end; +struct CTupleGenPoolYaml { + IP_DIST_t m_dist; + uint32_t m_ip_start; + uint32_t m_ip_end; uint32_t m_number_of_clients_per_gb; uint32_t m_min_clients; uint32_t m_dual_interface_mask; uint16_t m_tcp_aging_sec; /* 0 means there is no aging */ uint16_t m_udp_aging_sec; + std::string m_name; + bool m_is_bundling; + public: + uint32_t getTotalIps(void){ + return ( m_ip_end-m_ip_start+1); + } + uint32_t getDualMask() { + return m_dual_interface_mask; + } + uint32_t get_ip_start() { + return m_ip_start; + } + bool is_valid(uint32_t num_threads,bool is_plugins); + void Dump(FILE *fd); +}; + +struct CTupleGenYamlInfo { + std::vector<CTupleGenPoolYaml> m_client_pool; + std::vector<CTupleGenPoolYaml> m_server_pool; + public: - void Dump(FILE *fd); - uint32_t getTotalClients(void){ - return ( m_clients_ip_end-m_clients_ip_start+1); + bool is_valid(uint32_t num_threads,bool is_plugins); + uint8_t get_server_pool_id(std::string name){ + for (uint8_t i=0;i<m_server_pool.size();i++) { + if (m_server_pool[i].m_name==name) + return i; + } + return 0; } - uint32_t getTotalServers(void){ - return ( m_servers_ip_end-m_servers_ip_start+1); + + uint8_t get_client_pool_id(std::string name){ + for (uint8_t i=0;i<m_client_pool.size();i++) { + if (m_client_pool[i].m_name==name) + return i; + } + return 0; } +}; - bool is_valid(uint32_t num_threads,bool is_plugins); -}; +void operator >> (const YAML::Node& node, CTupleGenPoolYaml & fi) ; void operator >> (const YAML::Node& node, CTupleGenYamlInfo & fi) ; -struct CClientPortion { - uint32_t m_client_start; - uint32_t m_client_end; - uint32_t m_server_start; - uint32_t m_server_end; +struct CIpPortion { + uint32_t m_ip_start; + uint32_t m_ip_end; }; - -void split_clients(uint32_t thread_id, - uint32_t total_threads, +void split_ips(uint32_t thread_id, + uint32_t total_threads, uint32_t dual_port_id, - CTupleGenYamlInfo & fi, - CClientPortion & portion); + CTupleGenPoolYaml& poolinfo, + CIpPortion & portion); |