summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xlinux/ws_main.py3
-rwxr-xr-xsrc/bp_sim.cpp139
-rwxr-xr-xsrc/bp_sim.h32
-rw-r--r--src/mac_mapping.h4
-rwxr-xr-xsrc/main.cpp3
-rw-r--r--src/main_dpdk.cpp3
-rw-r--r--src/sim/trex_sim_stateful.cpp6
-rw-r--r--src/trex_client_config.cpp24
-rw-r--r--src/trex_client_config.h25
-rwxr-xr-xsrc/tuple_gen.cpp170
-rwxr-xr-xsrc/tuple_gen.h190
-rwxr-xr-xsrc/utl_yaml.cpp69
-rwxr-xr-xsrc/utl_yaml.h20
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);