From bf83f301e4fdbf333240af7f316735e35634c5fd Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Tue, 15 Nov 2016 16:27:08 +0200 Subject: client config ARP resolve working. Still missing IPv6 support. Signed-off-by: Ido Barnea --- linux/ws_main.py | 1 + 1 file changed, 1 insertion(+) (limited to 'linux') diff --git a/linux/ws_main.py b/linux/ws_main.py index 79e26915..528d5570 100755 --- a/linux/ws_main.py +++ b/linux/ws_main.py @@ -118,6 +118,7 @@ main_src = SrcGroup(dir='src', 'time_histogram.cpp', 'utl_json.cpp', 'utl_cpuu.cpp', + 'utl_ip.cpp', 'msg_manager.cpp', 'publisher/trex_publisher.cpp', 'stateful_rx_core.cpp', -- cgit 1.2.3-korg From 31a4ef5afc56c5d6ff6870da71a954e4bcbee057 Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Tue, 22 Nov 2016 18:03:52 +0200 Subject: client config gtest Signed-off-by: Ido Barnea --- linux/ws_main.py | 1 + src/bp_sim.h | 2 +- src/gtest/client_cfg_test.cpp | 186 ++++++++++++++++++++++++++++++++++++++++++ src/trex_client_config.cpp | 46 +++++------ src/trex_client_config.h | 30 +++++-- 5 files changed, 233 insertions(+), 32 deletions(-) create mode 100644 src/gtest/client_cfg_test.cpp (limited to 'linux') diff --git a/linux/ws_main.py b/linux/ws_main.py index 528d5570..c989bb50 100755 --- a/linux/ws_main.py +++ b/linux/ws_main.py @@ -97,6 +97,7 @@ bp_sim_gtest = SrcGroup(dir='src', src_list=[ 'bp_gtest.cpp', 'gtest/tuple_gen_test.cpp', + 'gtest/client_cfg_test.cpp', 'gtest/nat_test.cpp', 'gtest/trex_stateless_gtest.cpp' ]) diff --git a/src/bp_sim.h b/src/bp_sim.h index 4e3f81fd..914a26d9 100755 --- a/src/bp_sim.h +++ b/src/bp_sim.h @@ -1849,7 +1849,7 @@ typedef std::priority_queue,CGenNodeCompare> class CErfIF : public CVirtualIF { - + friend class basic_client_cfg_test1_Test; public: CErfIF(){ m_writer=NULL; diff --git a/src/gtest/client_cfg_test.cpp b/src/gtest/client_cfg_test.cpp new file mode 100644 index 00000000..1e84e1d5 --- /dev/null +++ b/src/gtest/client_cfg_test.cpp @@ -0,0 +1,186 @@ +/* + Ido Barnea + + Cisco Systems, Inc. +*/ + +/* +Copyright (c) 2016-2016 Cisco Systems, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include +#include "../bp_sim.h" +#include +#include + +class basic_client_cfg : public testing::Test { + protected: + virtual void SetUp() { + } + virtual void TearDown() { + } + public: +}; + +TEST_F(basic_client_cfg, test1) { + uint32_t ip_start = 0x10010101; + uint32_t ip_end = 0x100101ff; + uint32_t next_hop_init = 0x01010101; + uint32_t next_hop_resp = 0x02020202; + uint16_t vlan_init = 5; + uint16_t vlan_resp = 7; + uint32_t dual_if_mask = 0x01000000; + uint32_t test_count = 2; + ClientCfgDB cfg_db; + ClientCfgDB test_db; + ClientCfgEntry cfg_ent; + ClientCfgExt cfg_ext; + std::vector ent_list; + struct CTupleGenPoolYaml c_pool; + + // Create tuple gen, so we can have ip->port translation + CTupleGenYamlInfo tg_yam_info; + struct CTupleGenPoolYaml s_pool; + s_pool.m_ip_start = ip_start; + s_pool.m_ip_end = ip_end; + s_pool.m_dual_interface_mask = dual_if_mask; + tg_yam_info.m_client_pool.push_back(s_pool); + + CGlobalInfo::m_options.m_expected_portd = 4; + printf("Expected ports %d\n", CGlobalInfo::m_options.m_expected_portd); + + std::string tmp_file_name = "/tmp/client_cfg_gtest.yaml"; + FILE *fd = fopen(tmp_file_name.c_str(), "w"); + + if (fd == NULL) { + fprintf(stderr, "Failed opening %s file for write\n", tmp_file_name.c_str()); + } + + // We create config file with 3 groups (Should match 6 ports). + cfg_ext.m_initiator.set_next_hop(next_hop_init); + cfg_ext.m_responder.set_next_hop(next_hop_resp); + cfg_ext.m_initiator.set_vlan(vlan_init); + cfg_ext.m_responder.set_vlan(vlan_resp); + + cfg_ent.set_params(ip_start, ip_end, test_count); + cfg_ent.set_cfg(cfg_ext); + + // first group + cfg_db.set_vlan(true); + cfg_db.add_group(ip_start, cfg_ent); + + //second group + cfg_ent.set_params(ip_start + dual_if_mask, ip_end + dual_if_mask + , test_count); + cfg_db.add_group(ip_start + dual_if_mask, cfg_ent); + + // third group + cfg_ent.set_params(ip_start + 2 * dual_if_mask, ip_end + 2 * dual_if_mask + , test_count); + cfg_db.add_group(ip_start + dual_if_mask * 2, cfg_ent); + + cfg_db.dump(fd); + fclose(fd); + test_db.load_yaml_file(tmp_file_name); + test_db.set_tuple_gen_info(&tg_yam_info); + test_db.get_entry_list(ent_list); + + + // We expect ports for first two groups to be found. + // This group addresses should not appear in the list, since + // we simulate system with only 4 ports + int i = 0; + for (std::vector::iterator + it = ent_list.begin(); it != ent_list.end(); it++) { + uint8_t port = (*it)->get_port(); + uint16_t vlan = (*it)->get_vlan(); + uint32_t count = (*it)->get_count(); + uint32_t dst_ip = (*it)->get_dst_ip(); + + assert(count == test_count); + switch(i) { + case 0: + case 2: + assert(port == i); + assert(vlan == vlan_init); + assert(dst_ip == next_hop_init); + break; + case 1: + case 3: + assert(port == i); + assert(vlan == vlan_resp); + assert(dst_ip == next_hop_resp); + break; + default: + fprintf(stderr, "Test failed. Too many entries returned\n"); + exit(1); + } + i++; + delete *it; + } + + // Simulate the pre test phase, and hand results to client config + CManyIPInfo many_ip; + MacAddress mac0, mac1, mac2, mac3; + mac0.set(0x0, 0x1, 0x2, 0x3, 0x4, 0); + mac1.set(0x0, 0x1, 0x2, 0x3, 0x4, 0x1); + mac2.set(0x0, 0x1, 0x2, 0x3, 0x4, 0x2); + mac3.set(0x0, 0x1, 0x2, 0x3, 0x4, 0x3); + COneIPv4Info ip0_1(next_hop_init, vlan_init, mac0, 0); + COneIPv4Info ip0_2(next_hop_init + 1, vlan_init, mac1, 0); + COneIPv4Info ip1_1(next_hop_resp, vlan_resp, mac2, 1); + COneIPv4Info ip1_2(next_hop_resp + 1, vlan_resp, mac3, 1); + + many_ip.insert(ip0_1); + many_ip.insert(ip0_2); + many_ip.insert(ip1_1); + many_ip.insert(ip1_2); + + test_db.set_resolved_macs(many_ip); + + ClientCfgBase cfg0; + + ClientCfgEntry *ent0 = test_db.lookup(ip_start); + ClientCfgEntry *ent1 = test_db.lookup(ip_start + dual_if_mask); + + assert (ent0 != NULL); + ent0->assign(cfg0); + assert (!memcmp(cfg0.m_initiator.get_dst_mac_addr() + , mac0.GetConstBuffer(), ETHER_ADDR_LEN)); + ent0->assign(cfg0); + assert (!memcmp(cfg0.m_initiator.get_dst_mac_addr() + , mac1.GetConstBuffer(), ETHER_ADDR_LEN)); + ent0->assign(cfg0); + assert (!memcmp(cfg0.m_responder.get_dst_mac_addr() + , mac2.GetConstBuffer(), ETHER_ADDR_LEN)); + ent0->assign(cfg0); + assert (!memcmp(cfg0.m_responder.get_dst_mac_addr() + , mac3.GetConstBuffer(), ETHER_ADDR_LEN)); + + assert(ent1 != NULL); + ent1->assign(cfg0); + assert (!memcmp(cfg0.m_initiator.get_dst_mac_addr() + , mac0.GetConstBuffer(), ETHER_ADDR_LEN)); + ent1->assign(cfg0); + assert (!memcmp(cfg0.m_initiator.get_dst_mac_addr() + , mac1.GetConstBuffer(), ETHER_ADDR_LEN)); + ent1->assign(cfg0); + assert (!memcmp(cfg0.m_responder.get_dst_mac_addr() + , mac2.GetConstBuffer(), ETHER_ADDR_LEN)); + ent1->assign(cfg0); + assert (!memcmp(cfg0.m_responder.get_dst_mac_addr() + , mac3.GetConstBuffer(), ETHER_ADDR_LEN)); + +} + diff --git a/src/trex_client_config.cpp b/src/trex_client_config.cpp index 0fd12e09..548d097b 100644 --- a/src/trex_client_config.cpp +++ b/src/trex_client_config.cpp @@ -32,19 +32,19 @@ limitations under the License. void ClientCfgDirBase::dump(FILE *fd) const { if (has_src_mac_addr()) { - fprintf(fd, " src MAC:%s\n", utl_macaddr_to_str(m_src_mac.GetConstBuffer()).c_str()); + fprintf(fd, " src_mac: %s\n", utl_macaddr_to_str(m_src_mac.GetConstBuffer()).c_str()); } else { - fprintf(fd, " No src MAC\n"); + fprintf(fd, "# No src MAC\n"); } if (has_dst_mac_addr()) { - fprintf(fd, " dst MAC:%s\n", utl_macaddr_to_str(m_dst_mac.GetConstBuffer()).c_str()); + fprintf(fd, " dst_mac: %s\n", utl_macaddr_to_str(m_dst_mac.GetConstBuffer()).c_str()); } else { - fprintf(fd, " No dst MAC\n"); + fprintf(fd, "# No dst MAC\n"); } if (has_vlan()) { - fprintf(fd, " vlan:%d\n", m_vlan); + fprintf(fd, " vlan: %d\n", m_vlan); } else { - fprintf(fd, " No vlan\n"); + fprintf(fd, "# No vlan\n"); } } @@ -74,20 +74,20 @@ void ClientCfgDirExt::dump(FILE *fd) const { ClientCfgDirBase::dump(fd); if (has_next_hop()) { - fprintf(fd, " next hop:%s\n", ip_to_str(m_next_hop).c_str()); + fprintf(fd, " next_hop: %s\n", ip_to_str(m_next_hop).c_str()); } else { - fprintf(fd, " No next hop\n"); + fprintf(fd, "# No next hop\n"); } if (has_ipv6_next_hop()) { - fprintf(fd, " next hop:%s\n", ip_to_str((unsigned char *)m_ipv6_next_hop).c_str()); + fprintf(fd, " ipv6_next_hop: %s\n", ip_to_str((unsigned char *)m_ipv6_next_hop).c_str()); } else { - fprintf(fd, " No IPv6 next hop\n"); + fprintf(fd, "# No IPv6 next hop\n"); } if (m_resolved_macs.size() > 0) { - fprintf(fd, " Resolved MAC list:\n"); + fprintf(fd, "# Resolved MAC list:\n"); for (int i = 0; i < m_resolved_macs.size(); i++) { - fprintf(fd, " %s\n", utl_macaddr_to_str(m_resolved_macs[i].GetConstBuffer()).c_str()); + fprintf(fd, "# %s\n", utl_macaddr_to_str(m_resolved_macs[i].GetConstBuffer()).c_str()); } } } @@ -122,11 +122,10 @@ void ClientCfgBase::update(uint32_t index, const ClientCfgExt *cfg) { void ClientCfgEntry::dump(FILE *fd) const { - std::cout << "IP start: " << ip_to_str(m_ip_start) << "\n"; - std::cout << "IP end: " << ip_to_str(m_ip_end) << "\n"; - fprintf(fd, "count %d\n", m_count); - + fprintf(fd, "- ip_start : %s\n", ip_to_str(m_ip_start).c_str()); + fprintf(fd, " ip_end : %s\n", ip_to_str(m_ip_end).c_str()); m_cfg.dump(fd); + fprintf(fd, " count : %d\n", m_count); } void ClientCfgEntry::set_resolved_macs(CManyIPInfo &pretest_result) { @@ -163,16 +162,15 @@ void ClientCfgCompactEntry::fill_from_dir(ClientCfgDirExt cfg, uint8_t port_id) void ClientCfgDB::dump(FILE *fd) { - fprintf(fd, "**********Client config file start*********\n"); - fprintf(fd, "vlan: %s is_empty: %s\n" - ,m_under_vlan ? "true" : "false" - , m_is_empty ? "true" : "false"); + //fprintf(fd, "#**********Client config file start*********\n"); + fprintf(fd, "vlan: %s\n", m_under_vlan ? "true" : "false"); + fprintf(fd, "groups:\n"); for (std::map::iterator it = m_groups.begin(); it != m_groups.end(); ++it) { - fprintf(fd, "****%s:****\n", ip_to_str(it->first).c_str()); + fprintf(fd, "# ****%s:****\n", ip_to_str(it->first).c_str()); ((ClientCfgEntry)it->second).dump(fd); } - fprintf(fd, "**********Client config end*********\n"); + //fprintf(fd, "#**********Client config end*********\n"); } void ClientCfgDB::set_resolved_macs(CManyIPInfo &pretest_result) { @@ -205,8 +203,8 @@ void ClientCfgDB::get_entry_list(std::vector &ret) { if (cfg.m_cfg.m_initiator.need_resolve()) { ClientCfgCompactEntry *init_entry = new ClientCfgCompactEntry(); assert(init_entry); - init_entry->m_count = ((ClientCfgEntry)it->second).m_count; - init_entry->fill_from_dir(((ClientCfgEntry)it->second).m_cfg.m_initiator, port); + init_entry->m_count = cfg.m_count; + init_entry->fill_from_dir(cfg.m_cfg.m_initiator, port); ret.push_back(init_entry); } diff --git a/src/trex_client_config.h b/src/trex_client_config.h index dbdfd12d..257d354f 100644 --- a/src/trex_client_config.h +++ b/src/trex_client_config.h @@ -190,9 +190,9 @@ class ClientCfgBase { public: virtual void dump (FILE *fd) const { - fprintf(fd, "initiator:\n"); + fprintf(fd, " initiator :\n"); m_initiator.dump(fd); - fprintf(fd, "responder:\n"); + fprintf(fd, " responder :\n"); m_responder.dump(fd); } virtual void update(uint32_t index, const ClientCfgExt *cfg); @@ -205,9 +205,9 @@ public: class ClientCfgExt : public ClientCfgBase { public: virtual void dump (FILE *fd) const { - fprintf(fd, "initiator:\n"); + fprintf(fd, " initiator:\n"); m_initiator.dump(fd); - fprintf(fd, "responder:\n"); + fprintf(fd, " responder:\n"); m_responder.dump(fd); } @@ -254,7 +254,7 @@ class ClientCfgCompactEntry { * */ class ClientCfgEntry { - + friend class basic_client_cfg_test1_Test; public: ClientCfgEntry() { @@ -297,6 +297,14 @@ public: uint32_t m_count; private: + void set_params(uint32_t start, uint32_t end, uint32_t count) { // for tests + m_ip_start = start; + m_ip_end = end; + m_count = count; + } + void set_cfg(const ClientCfgExt &cfg) { + m_cfg = cfg; + } uint32_t m_iterator; }; @@ -305,7 +313,8 @@ private: * */ class ClientCfgDB { -public: + friend class basic_client_cfg_test1_Test; + public: ClientCfgDB() { m_is_empty = true; @@ -314,6 +323,10 @@ public: m_tg = NULL; } + ~ClientCfgDB() { + m_groups.clear(); + } + void dump(FILE *fd) ; /** @@ -349,7 +362,10 @@ public: private: void parse_single_group(YAMLParserWrapper &parser, const YAML::Node &node); void parse_dir(YAMLParserWrapper &parser, const YAML::Node &node, ClientCfgDirExt &dir); - + void set_vlan(bool val) {m_under_vlan = val;} // for tests + void add_group(uint32_t ip, ClientCfgEntry cfg) { // for tests + m_groups.insert(std::make_pair(ip, cfg)); + } /** * verify the YAML file loaded in valid * -- cgit 1.2.3-korg