summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xlinux_dpdk/ws_main.py1
-rwxr-xr-xsrc/bp_sim.cpp24
-rw-r--r--src/main_dpdk.cpp10
-rw-r--r--src/trex_client_config.cpp66
-rw-r--r--src/trex_client_config.h159
-rwxr-xr-xsrc/utl_yaml.cpp26
-rwxr-xr-xsrc/utl_yaml.h3
7 files changed, 210 insertions, 79 deletions
diff --git a/linux_dpdk/ws_main.py b/linux_dpdk/ws_main.py
index dde94dc4..5bc00719 100755
--- a/linux_dpdk/ws_main.py
+++ b/linux_dpdk/ws_main.py
@@ -100,6 +100,7 @@ main_src = SrcGroup(dir='src',
'global_io_mode.cpp',
'main_dpdk.cpp',
'trex_watchdog.cpp',
+ 'trex_client_config.cpp',
'debug.cpp',
'flow_stat.cpp',
'flow_stat_parser.cpp',
diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp
index 2ebffb0d..95f9e2fa 100755
--- a/src/bp_sim.cpp
+++ b/src/bp_sim.cpp
@@ -5049,17 +5049,25 @@ void CErfIF::add_vlan(uint16_t vlan_id) {
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_initiator.m_dst_mac, 6);
- vlan_id = node->m_client_cfg->m_responder.m_vlan;
- } else {
- memcpy(p, node->m_client_cfg->m_responder.m_dst_mac, 6);
- vlan_id = node->m_client_cfg->m_responder.m_vlan;
+ ClientCfgDir &cfg_dir = ( (dir == CLIENT_SIDE) ? node->m_client_cfg->m_initiator : node->m_client_cfg->m_responder);
+
+ /* dst mac */
+ if (cfg_dir.has_dst_mac_addr()) {
+ memcpy(p, cfg_dir.get_dst_mac_addr(), 6);
+ }
+
+ /* src mac */
+ if (cfg_dir.has_src_mac_addr()) {
+ memcpy(p + 6, cfg_dir.get_src_mac_addr(), 6);
}
- add_vlan(vlan_id);
+ /* VLAN */
+ if (cfg_dir.has_vlan()) {
+ add_vlan(cfg_dir.get_vlan());
+ }
+
+
}
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp
index 0200df92..21612901 100644
--- a/src/main_dpdk.cpp
+++ b/src/main_dpdk.cpp
@@ -1016,7 +1016,7 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t
"if you think it is important,open a defect \n");
}
- if (CGlobalInfo::get_vlan_mode_enable() && (po->client_cfg_file != "") ) {
+ if (po->preview.get_vlan_mode_enable() && (po->client_cfg_file != "") ) {
parse_err("--vlan and --client_cfg cannot be combined");
}
@@ -4204,12 +4204,10 @@ int CGlobalTRex::start_master_statefull() {
m_fl.Create();
m_fl.load_from_yaml(CGlobalInfo::m_options.cfg_file,get_cores_tx());
- if (CGlobalInfo::m_options.mac_file != "") {
+
+ if (CGlobalInfo::m_options.client_cfg_file != "") {
+ m_fl.load_client_config_file(CGlobalInfo::m_options.client_cfg_file);
CGlobalInfo::m_options.preview.set_mac_ip_mapping_enable(true);
- m_fl.load_from_mac_file(CGlobalInfo::m_options.mac_file);
- m_fl.m_mac_info.set_configured(true);
- } else {
- m_fl.m_mac_info.set_configured(false);
}
m_expected_pps = m_fl.get_total_pps();
diff --git a/src/trex_client_config.cpp b/src/trex_client_config.cpp
index e726d47d..bb2b7772 100644
--- a/src/trex_client_config.cpp
+++ b/src/trex_client_config.cpp
@@ -36,6 +36,9 @@ 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";
+ //m_cfg.dump();
+
+ #if 0
std::cout << "Init. MAC addr: ";
for (int i = 0; i < 6; i++) {
printf("%lx:", ( (m_initiator.m_dst_mac >> ( (6-i) * 8)) & 0xFF ) );
@@ -51,6 +54,7 @@ ClientCfgEntry::dump() const {
std::cout << "\n";
std::cout << "Res. VLAN: " << m_responder.m_vlan << "\n";
+ #endif
}
@@ -69,7 +73,7 @@ ClientCfgDB::load_yaml_file(const std::string &filename) {
m_filename = filename;
if (!utl_is_file_exists(filename)){
- ss << "file does not exists";
+ ss << "*** file '" << filename << "' does not exists";
throw std::runtime_error(ss.str());
}
@@ -98,7 +102,7 @@ ClientCfgDB::load_yaml_file(const std::string &filename) {
parse_single_group(parser, groups[i]);
}
- verify();
+ verify(parser);
m_is_empty = false;
@@ -126,37 +130,43 @@ ClientCfgDB::parse_single_group(YAMLParserWrapper &parser, const YAML::Node &nod
const YAML::Node &init = parser.parse_map(node, "initiator");
const YAML::Node &resp = parser.parse_map(node, "responder");
- /* parse MACs */
- group.m_initiator.m_dst_mac = parser.parse_mac_addr(init, "dst_mac");
- group.m_responder.m_dst_mac = parser.parse_mac_addr(resp, "dst_mac");
+ parse_dir(parser, init, group.m_cfg.m_initiator);
+ parse_dir(parser, resp, group.m_cfg.m_responder);
- if (m_under_vlan) {
- group.m_initiator.m_vlan = parser.parse_uint(init, "vlan", 0, 0xfff);
- group.m_responder.m_vlan = parser.parse_uint(resp, "vlan", 0, 0xfff);
- } else {
- if (init.FindValue("vlan")) {
- parser.parse_err("VLAN config was disabled", init["vlan"]);
- }
- if (resp.FindValue("vlan")) {
- parser.parse_err("VLAN config was disabled", resp["vlan"]);
- }
- }
-
-
- group.m_count = parser.parse_uint(node, "count");
+
+ group.m_count = parser.parse_uint(node, "count", 0, UINT64_MAX, 1);
/* add to map with copying */
m_groups[group.m_ip_start] = group;
}
+void
+ClientCfgDB::parse_dir(YAMLParserWrapper &parser, const YAML::Node &node, ClientCfgDir &dir) {
+ if (node.FindValue("src_mac")) {
+ dir.set_dst_mac_addr(parser.parse_mac_addr(node, "src_mac"));
+ }
+
+ if (node.FindValue("dst_mac")) {
+ dir.set_dst_mac_addr(parser.parse_mac_addr(node, "dst_mac"));
+ }
+
+ if (m_under_vlan) {
+ dir.set_vlan(parser.parse_uint(node, "vlan", 0, 0xfff));
+ } else {
+ if (node.FindValue("vlan")) {
+ parser.parse_err("VLAN config was disabled", node["vlan"]);
+ }
+ }
+}
+
/**
* sanity checks
*
* @author imarom (28-Jun-16)
*/
void
-ClientCfgDB::verify() const {
+ClientCfgDB::verify(const YAMLParserWrapper &parser) const {
std::stringstream ss;
uint32_t monotonic = 0;
@@ -168,7 +178,7 @@ ClientCfgDB::verify() const {
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";
- yaml_parse_err(ss.str());
+ parser.parse_err(ss.str());
}
monotonic = group.m_ip_end;
@@ -240,17 +250,3 @@ ClientCfgDB::lookup(const std::string &ip) {
}
-void
-ClientCfgDB::yaml_parse_err(const std::string &err, const YAML::Mark *mark) const {
- std::stringstream ss;
-
- if (mark) {
- ss << "\n*** '" << m_filename << "' - YAML parsing error at line " << mark->line << ": ";
- } else {
- ss << "\n*** '" << m_filename << "' - YAML parsing error: ";
- }
-
- ss << err;
- throw std::runtime_error(ss.str());
-}
-
diff --git a/src/trex_client_config.h b/src/trex_client_config.h
index b6e7d32d..a0c883d8 100644
--- a/src/trex_client_config.h
+++ b/src/trex_client_config.h
@@ -27,27 +27,138 @@ limitations under the License.
class YAMLParserWrapper;
+
+/**
+ * client configuration per direction
+ *
+ * @author imarom (29-Jun-16)
+ */
+class ClientCfgDir {
+
+private:
+ enum {
+ HAS_SRC_MAC = 0x1,
+ HAS_DST_MAC = 0x2,
+ HAS_VLAN = 0x4,
+ };
+
+ uint8_t m_src_mac[6];
+ uint8_t m_dst_mac[6];
+ uint16_t m_vlan;
+ uint8_t m_bitfield;
+
+
+public:
+ ClientCfgDir() {
+ m_bitfield = 0;
+ }
+
+ bool has_src_mac_addr() const {
+ return (m_bitfield & HAS_SRC_MAC);
+ }
+
+ bool has_dst_mac_addr() const {
+ return (m_bitfield & HAS_DST_MAC);
+ }
+ bool has_vlan() const {
+ return (m_bitfield & HAS_VLAN);
+ }
+
+ void set_src_mac_addr(uint64_t mac_addr) {
+ for (int i = 0; i < 6; i++) {
+ m_src_mac[i] = ( mac_addr >> ((5 - i) * 8) ) & 0xFF;
+ }
+ m_bitfield |= HAS_SRC_MAC;
+ }
+
+ void set_dst_mac_addr(uint64_t mac_addr) {
+ for (int i = 0; i < 6; i++) {
+ m_dst_mac[i] = ( mac_addr >> ((5 - i) * 8) ) & 0xFF;
+ }
+ m_bitfield |= HAS_DST_MAC;
+ }
+
+ void set_vlan(uint16_t vlan_id) {
+ m_vlan = vlan_id;
+ m_bitfield |= HAS_VLAN;
+ }
+
+ /* updates a configuration with a group index member */
+
+ void update(uint32_t index) {
+ if (has_src_mac_addr()) {
+ mac_add(m_src_mac, index);
+ }
+
+ if (has_dst_mac_addr()) {
+ mac_add(m_dst_mac, index);
+ }
+ }
+
+ const uint8_t *get_src_mac_addr() {
+ assert(has_src_mac_addr());
+ return m_src_mac;
+ }
+
+ const uint8_t *get_dst_mac_addr() {
+ assert(has_dst_mac_addr());
+ return m_dst_mac;
+ }
+
+ uint16_t get_vlan() {
+ assert(has_vlan());
+ return m_vlan;
+ }
+
+private:
+ /**
+ * transform MAC address to uint64_t
+ * performs add and return to MAC format
+ *
+ */
+ void mac_add(uint8_t *mac, uint32_t i) {
+ uint64_t tmp = 0;
+
+ for (int i = 0; i < 6; i++) {
+ tmp <<= 8;
+ tmp |= mac[i];
+ }
+
+ tmp += i;
+
+ for (int i = 0; i < 6; i++) {
+ mac[i] = ( tmp >> ((5 - i) * 8) ) & 0xFF;
+ }
+
+ }
+};
+
/**
* single client config
*
*/
class ClientCfg {
+
public:
- struct dir_st {
- uint8_t m_dst_mac[6];
- uint16_t m_vlan;
- };
-
- dir_st m_initiator;
- dir_st m_responder;
+
+ void update(uint32_t index) {
+ m_initiator.update(index);
+ m_responder.update(index);
+ }
+
+ ClientCfgDir m_initiator;
+ ClientCfgDir m_responder;
};
+/******************************** internal section ********************************/
+
/**
* describes a single client config
* entry loaded from the config file
*
*/
class ClientCfgEntry {
+
public:
ClientCfgEntry() {
@@ -65,6 +176,7 @@ public:
m_iterator = 0;
}
+
/**
* assings a client config from the group
* it will advance MAC addresses andf etc.
@@ -74,37 +186,23 @@ public:
* @param info
*/
void assign(ClientCfg &info) {
-
- /* assigns MAC addrs as big endian */
- for (int i = 0; i < 6; i++) {
- info.m_initiator.m_dst_mac[i] = ( (m_initiator.m_dst_mac + m_iterator) >> ((5 - i) * 8) ) & 0xFF;
- info.m_responder.m_dst_mac[i] = ( (m_responder.m_dst_mac + m_iterator) >> ((5 - i) * 8) ) & 0xFF;
- }
-
- info.m_initiator.m_vlan = m_initiator.m_vlan;
- info.m_responder.m_vlan = m_responder.m_vlan;
-
+ info = m_cfg;
+ info.update(m_iterator);
+
/* advance for the next assign */
m_iterator = (m_iterator + 1) % m_count;
}
public:
- uint32_t m_ip_start;
- uint32_t m_ip_end;
-
- struct cfg_dir_st {
- //uint64_t m_src_mac;
- uint64_t m_dst_mac;
- uint16_t m_vlan;
- };
+ uint32_t m_ip_start;
+ uint32_t m_ip_end;
- cfg_dir_st m_initiator;
- cfg_dir_st m_responder;
+ ClientCfg m_cfg;
uint32_t m_count;
private:
- uint32_t m_iterator;
+ uint32_t m_iterator;
};
/**
@@ -147,13 +245,13 @@ public:
private:
void parse_single_group(YAMLParserWrapper &parser, const YAML::Node &node);
- void yaml_parse_err(const std::string &err, const YAML::Mark *mark = NULL) const;
+ void parse_dir(YAMLParserWrapper &parser, const YAML::Node &node, ClientCfgDir &dir);
/**
* verify the YAML file loaded in valid
*
*/
- void verify() const;
+ void verify(const YAMLParserWrapper &parser) const;
/* maps the IP start value to client groups */
std::map<uint32_t, ClientCfgEntry> m_groups;
@@ -165,3 +263,4 @@ private:
};
#endif /* __TREX_CLIENT_CONFIG_H__ */
+
diff --git a/src/utl_yaml.cpp b/src/utl_yaml.cpp
index 22772ffe..444031c6 100755
--- a/src/utl_yaml.cpp
+++ b/src/utl_yaml.cpp
@@ -250,6 +250,15 @@ YAMLParserWrapper::parse_ip(const YAML::Node &node, const std::string &name) {
}
uint64_t
+YAMLParserWrapper::parse_mac_addr(const YAML::Node &node, const std::string &name, uint64_t def) {
+ if (!node.FindValue(name)) {
+ return def;
+ }
+
+ return parse_mac_addr(node, name);
+}
+
+uint64_t
YAMLParserWrapper::parse_mac_addr(const YAML::Node &node, const std::string &name) {
std::string mac_str;
@@ -275,6 +284,15 @@ YAMLParserWrapper::parse_mac_addr(const YAML::Node &node, const std::string &nam
}
uint64_t
+YAMLParserWrapper::parse_uint(const YAML::Node &node, const std::string &name, uint64_t low, uint64_t high, uint64_t def) {
+ if (!node.FindValue(name)) {
+ return def;
+ }
+
+ return parse_uint(node, name, low, high);
+}
+
+uint64_t
YAMLParserWrapper::parse_uint(const YAML::Node &node, const std::string &name, uint64_t low, uint64_t high) {
try {
@@ -310,3 +328,11 @@ YAMLParserWrapper::parse_err(const std::string &err, const YAML::Node &node) con
throw std::runtime_error(ss.str());
}
+void
+YAMLParserWrapper::parse_err(const std::string &err) const {
+ std::stringstream ss;
+
+ ss << "\n*** '" << m_header << "' - YAML parsing error: " << err;
+
+ throw std::runtime_error(ss.str());
+}
diff --git a/src/utl_yaml.h b/src/utl_yaml.h
index 8088c497..2547b666 100755
--- a/src/utl_yaml.h
+++ b/src/utl_yaml.h
@@ -57,12 +57,15 @@ public:
uint32_t parse_ip(const YAML::Node &node, const std::string &name);
uint64_t parse_mac_addr(const YAML::Node &node, const std::string &name);
+ uint64_t parse_mac_addr(const YAML::Node &node, const std::string &name, uint64_t def);
uint64_t parse_uint(const YAML::Node &node, const std::string &name, uint64_t low = 0, uint64_t high = UINT64_MAX);
+ uint64_t parse_uint(const YAML::Node &node, const std::string &name, uint64_t low, uint64_t high, uint64_t def);
public:
void parse_err(const std::string &err, const YAML::Node &node) const;
+ void parse_err(const std::string &err) const;
private: