diff options
-rwxr-xr-x | linux/ws_main.py | 4 | ||||
-rwxr-xr-x | linux_dpdk/ws_main.py | 4 | ||||
-rwxr-xr-x | src/bp_gtest.cpp | 2 | ||||
-rwxr-xr-x | src/bp_sim.cpp | 2 | ||||
-rw-r--r-- | src/debug.cpp | 8 | ||||
-rw-r--r-- | src/flow_stat_parser.cpp | 2 | ||||
-rw-r--r-- | src/main_dpdk.cpp | 264 | ||||
-rw-r--r-- | src/main_dpdk.h | 30 | ||||
-rw-r--r-- | src/pkt_gen.cpp (renamed from src/test_pkt_gen.cpp) | 2 | ||||
-rw-r--r-- | src/pkt_gen.h (renamed from src/test_pkt_gen.h) | 7 | ||||
-rw-r--r-- | src/pre_test.cpp | 80 | ||||
-rw-r--r-- | src/pre_test.h | 15 | ||||
-rw-r--r-- | src/stateful_rx_core.cpp (renamed from src/latency.cpp) | 140 | ||||
-rw-r--r-- | src/stateful_rx_core.h (renamed from src/latency.h) | 39 | ||||
-rw-r--r-- | src/stateless/rx/trex_stateless_rx_core.cpp | 2 | ||||
-rw-r--r-- | src/stateless/rx/trex_stateless_rx_core.h | 2 |
16 files changed, 363 insertions, 240 deletions
diff --git a/linux/ws_main.py b/linux/ws_main.py index f20afcce..2a0d7286 100755 --- a/linux/ws_main.py +++ b/linux/ws_main.py @@ -112,14 +112,14 @@ main_src = SrcGroup(dir='src', 'rx_check_header.cpp', 'nat_check.cpp', 'nat_check_flow_table.cpp', - 'test_pkt_gen.cpp', + 'pkt_gen.cpp', 'timer_wheel_pq.cpp', 'time_histogram.cpp', 'utl_json.cpp', 'utl_cpuu.cpp', 'msg_manager.cpp', 'publisher/trex_publisher.cpp', - 'latency.cpp', + 'stateful_rx_core.cpp', 'flow_stat.cpp', 'flow_stat_parser.cpp', 'trex_watchdog.cpp', diff --git a/linux_dpdk/ws_main.py b/linux_dpdk/ws_main.py index 47c479c4..0a2c9dfa 100755 --- a/linux_dpdk/ws_main.py +++ b/linux_dpdk/ws_main.py @@ -115,13 +115,13 @@ main_src = SrcGroup(dir='src', 'flow_stat.cpp', 'flow_stat_parser.cpp', 'bp_sim.cpp', - 'latency.cpp', + 'pkt_gen.cpp', 'platform_cfg.cpp', 'pre_test.cpp', 'tuple_gen.cpp', 'rx_check.cpp', 'rx_check_header.cpp', - 'test_pkt_gen.cpp', + 'stateful_rx_core.cpp', 'timer_wheel_pq.cpp', 'time_histogram.cpp', 'os_time.cpp', diff --git a/src/bp_gtest.cpp b/src/bp_gtest.cpp index a1f80407..ca514c88 100755 --- a/src/bp_gtest.cpp +++ b/src/bp_gtest.cpp @@ -31,7 +31,7 @@ limitations under the License. #include "msg_manager.h" #include <common/cgen_map.h> #include "platform_cfg.h" -#include "latency.h" +#include "stateful_rx_core.h" #include "nat_check_flow_table.h" int test_policer(){ diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp index 773e82fc..b276d4ff 100755 --- a/src/bp_sim.cpp +++ b/src/bp_sim.cpp @@ -20,7 +20,7 @@ limitations under the License. */ #include "bp_sim.h" -#include "latency.h" +#include "stateful_rx_core.h" #include "utl_json.h" #include "utl_yaml.h" #include "msg_manager.h" diff --git a/src/debug.cpp b/src/debug.cpp index 5abdbdc6..542d2fa1 100644 --- a/src/debug.cpp +++ b/src/debug.cpp @@ -27,7 +27,7 @@ #include <rte_pci.h> #include <rte_ethdev.h> #include <common/basic_utils.h> -#include "test_pkt_gen.h" +#include "pkt_gen.h" #include "main_dpdk.h" #include "debug.h" @@ -446,7 +446,7 @@ int CTrexDebug::test_send(uint pkt_type) { } else { ip_ver = 4; } - if (pkt_type > 3) { + if (pkt_type > D_PKT_TYPE_ARP) { printf("Packet type not supported\n"); exit(1); } @@ -462,6 +462,10 @@ int CTrexDebug::test_send(uint pkt_type) { case D_PKT_TYPE_TCP: l4_proto = IPPROTO_TCP; break; + case D_PKT_TYPE_ARP: + ip_ver = 1; + l4_proto = IPPROTO_TCP; //just to prevenet compilation warning. Not used in this case. + break; } d = create_test_pkt(ip_ver, l4_proto, 254, FLOW_STAT_PAYLOAD_IP_ID, 0); } diff --git a/src/flow_stat_parser.cpp b/src/flow_stat_parser.cpp index b809b0f9..7335a6a2 100644 --- a/src/flow_stat_parser.cpp +++ b/src/flow_stat_parser.cpp @@ -25,7 +25,7 @@ #include "common/Network/Packet/IPHeader.h" #include "common/Network/Packet/IPv6Header.h" #include "common/Network/Packet/TcpHeader.h" -#include "test_pkt_gen.h" +#include "pkt_gen.h" #include "flow_stat_parser.h" void CFlowStatParser::reset() { diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index a6ea3876..edeeb3ee 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -74,9 +74,9 @@ extern "C" { #include "msg_manager.h" #include "platform_cfg.h" #include "pre_test.h" -#include "latency.h" +#include "stateful_rx_core.h" #include "debug.h" -#include "test_pkt_gen.h" +#include "pkt_gen.h" #include "internal_api/trex_platform_api.h" #include "main_dpdk.h" #include "trex_watchdog.h" @@ -653,7 +653,7 @@ static int usage(){ printf(" -m : factor of bandwidth \n"); printf(" \n"); printf(" --send-debug-pkt [proto] : Do not run traffic generator. Just send debug packet and dump receive queue."); - printf(" Supported protocols are 1 for icmp, 2 for UDP, 3 for TCP, 4 for 9K UDP\n"); + printf(" Supported protocols are 1 for icmp, 2 for UDP, 3 for TCP, 4 for ARP, 5 for 9K UDP\n"); printf(" \n"); printf(" -k [sec] : run latency test before starting the test. it will wait for x sec sending packet and x sec after that \n"); printf(" \n"); @@ -1014,7 +1014,8 @@ static int parse_options(int argc, char *argv[], CParserOption* po, bool first_t "if you think it is important,open a defect \n"); } - if (po->preview.get_is_rx_check_enable() || po->is_latency_enabled() || CGlobalInfo::is_learn_mode()) { + if (po->preview.get_is_rx_check_enable() || po->is_latency_enabled() || CGlobalInfo::is_learn_mode() + || (CGlobalInfo::m_options.m_arp_ref_per != 0)) { po->set_rx_enabled(); } @@ -1212,7 +1213,7 @@ typedef struct cnt_name_ { #define MY_REG(a) {a,(char *)#a} -void CPhyEthIFStats::Clear(){ +void CPhyEthIFStats::Clear() { ipackets = 0; ibytes = 0; f_ipackets = 0; @@ -1223,13 +1224,13 @@ void CPhyEthIFStats::Clear(){ oerrors = 0; imcasts = 0; rx_nombuf = 0; + memset(&m_prev_stats, 0, sizeof(m_prev_stats)); memset(m_rx_per_flow_pkts, 0, sizeof(m_rx_per_flow_pkts)); memset(m_rx_per_flow_bytes, 0, sizeof(m_rx_per_flow_bytes)); } - -void CPhyEthIFStats::DumpAll(FILE *fd){ - +// dump all counters (even ones that equal 0) +void CPhyEthIFStats::DumpAll(FILE *fd) { #define DP_A4(f) printf(" %-40s : %llu \n",#f, (unsigned long long)f) #define DP_A(f) if (f) printf(" %-40s : %llu \n",#f, (unsigned long long)f) DP_A4(opackets); @@ -1238,18 +1239,14 @@ void CPhyEthIFStats::DumpAll(FILE *fd){ DP_A4(ibytes); DP_A(ierrors); DP_A(oerrors); - } - -void CPhyEthIFStats::Dump(FILE *fd){ - +// dump all non zero counters +void CPhyEthIFStats::Dump(FILE *fd) { DP_A(opackets); DP_A(obytes); - DP_A(f_ipackets); DP_A(f_ibytes); - DP_A(ipackets); DP_A(ibytes); DP_A(ierrors); @@ -1258,6 +1255,15 @@ void CPhyEthIFStats::Dump(FILE *fd){ DP_A(rx_nombuf); } +void CPhyEthIgnoreStats::dump(FILE *fd) { + DP_A4(opackets); + DP_A4(obytes); + DP_A4(ipackets); + DP_A4(ibytes); + DP_A4(m_tx_arp); + DP_A4(m_rx_arp); +} + // Clear the RX queue of an interface, dropping all packets void CPhyEthIF::flush_rx_queue(void){ @@ -1565,51 +1571,6 @@ void CPhyEthIF::macaddr_get(struct ether_addr *mac_addr){ rte_eth_macaddr_get(m_port_id , mac_addr); } - -void CPhyEthIF::get_stats_1g(CPhyEthIFStats *stats){ - - stats->ipackets += pci_reg_read(E1000_GPRC) ; - - stats->ibytes += (pci_reg_read(E1000_GORCL) ); - stats->ibytes += (((uint64_t)pci_reg_read(E1000_GORCH))<<32); - - - stats->opackets += pci_reg_read(E1000_GPTC); - stats->obytes += pci_reg_read(E1000_GOTCL) ; - stats->obytes += ( (((uint64_t)pci_reg_read(IXGBE_GOTCH))<<32) ); - - stats->f_ipackets += 0; - stats->f_ibytes += 0; - - - stats->ierrors += ( pci_reg_read(E1000_RNBC) + - pci_reg_read(E1000_CRCERRS) + - pci_reg_read(E1000_ALGNERRC ) + - pci_reg_read(E1000_SYMERRS ) + - pci_reg_read(E1000_RXERRC ) + - - pci_reg_read(E1000_ROC)+ - pci_reg_read(E1000_RUC)+ - pci_reg_read(E1000_RJC) + - - pci_reg_read(E1000_XONRXC)+ - pci_reg_read(E1000_XONTXC)+ - pci_reg_read(E1000_XOFFRXC)+ - pci_reg_read(E1000_XOFFTXC)+ - pci_reg_read(E1000_FCRUC) - ); - - stats->oerrors += 0; - stats->imcasts = 0; - stats->rx_nombuf = 0; - - m_last_tx_rate = m_bw_tx.add(stats->obytes); - m_last_rx_rate = m_bw_rx.add(stats->ibytes); - m_last_tx_pps = m_pps_tx.add(stats->opackets); - m_last_rx_pps = m_pps_rx.add(stats->ipackets); - -} - int CPhyEthIF::dump_fdir_global_stats(FILE *fd) { return get_ex_drv()->dump_fdir_global_stats(this, fd); } @@ -1672,8 +1633,8 @@ void dump_hw_state(FILE *fd,struct ixgbe_hw_stats *hs ){ DP_A1(mptc); DP_A1(bptc); DP_A1(xec); - DP_A2(qprc,16) - DP_A2(qptc,16); + DP_A2(qprc,16); + DP_A2(qptc,16); DP_A2(qbrc,16); DP_A2(qbtc,16); DP_A2(qprdc,16); @@ -1701,14 +1662,27 @@ void dump_hw_state(FILE *fd,struct ixgbe_hw_stats *hs ){ DP_A1(o2bspc); } - -void CPhyEthIF::update_counters(){ +void CPhyEthIF::set_ignore_stats_base(CPreTestStats &pre_stats) { + // reading m_stats, so drivers saving prev in m_stats will be updated. + // Actually, we want m_stats to be cleared get_ex_drv()->get_extended_stats(this, &m_stats); - m_last_tx_rate = m_bw_tx.add(m_stats.obytes); - m_last_rx_rate = m_bw_rx.add(m_stats.ibytes); - m_last_tx_pps = m_pps_tx.add(m_stats.opackets); - m_last_rx_pps = m_pps_rx.add(m_stats.ipackets); + m_ignore_stats.ipackets = m_stats.ipackets; + m_ignore_stats.ibytes = m_stats.ibytes; + m_ignore_stats.opackets = m_stats.opackets; + m_ignore_stats.obytes = m_stats.obytes; + m_stats.ipackets = 0; + m_stats.opackets = 0; + m_stats.ibytes = 0; + m_stats.obytes = 0; + + m_ignore_stats.m_tx_arp = pre_stats.m_tx_arp; + m_ignore_stats.m_rx_arp = pre_stats.m_rx_arp; + + if (CGlobalInfo::m_options.preview.getVMode() >= 3) { + fprintf(stdout, "Pre test statistics for port %d\n", get_port_id()); + m_ignore_stats.dump(stdout); + } } void CPhyEthIF::dump_stats(FILE *fd){ @@ -2842,7 +2816,6 @@ public: void rx_sl_configure(); bool is_all_links_are_up(bool dump=false); void pre_test(); - int reset_counters(); /** * mark for shutdown @@ -3011,7 +2984,13 @@ void CGlobalTRex::pre_test() { } pretest.send_grat_arp_all(); - pretest.resolve_all(); + bool ret; + int count = 0; + do { + ret = pretest.resolve_all(); + count++; + } while ((ret != true) && (count < 3)); + if ( CGlobalInfo::m_options.preview.getVMode() > 0) { pretest.dump(stdout); } @@ -3031,22 +3010,16 @@ void CGlobalTRex::pre_test() { CGlobalInfo::m_options.m_ip_cfg[port_id].set_grat_arp_needed(false); } + // update statistics baseline, so we can ignore what happened in pre test phase CPhyEthIF *pif = &m_ports[port_id]; + CPreTestStats pre_stats = pretest.get_stats(port_id); + pif->set_ignore_stats_base(pre_stats); + // Configure port back to normal mode. Only relevant packets handled by software. CTRexExtendedDriverDb::Ins()->get_drv()->set_rcv_all(pif, false); } } -int CGlobalTRex::reset_counters(){ - int i; - for (i=0; i<m_max_ports; i++) { - CPhyEthIF * _if=&m_ports[i]; - _if->stats_clear(); - } - - return (0); -} - /** * check for a single core * @@ -3175,8 +3148,14 @@ void CGlobalTRex::ixgbe_configure_mg(void) { if ( latency_rate ) { mg_cfg.m_cps = (double)latency_rate ; - }else{ - mg_cfg.m_cps = 1.0; + } else { + // If RX core needed, we need something to make the scheduler running. + // If nothing configured, send 1 CPS latency measurement packets. + if (CGlobalInfo::m_options.m_arp_ref_per == 0) { + mg_cfg.m_cps = 1.0; + } else { + mg_cfg.m_cps = 0; + } } if ( get_vm_one_queue_enable() ) { @@ -3657,6 +3636,8 @@ void CGlobalTRex::dump_post_test_stats(FILE *fd){ uint64_t sw_pkt_out=0; uint64_t sw_pkt_out_err=0; uint64_t sw_pkt_out_bytes=0; + uint64_t tx_arp = 0; + uint64_t rx_arp = 0; int i; for (i=0; i<get_cores_tx(); i++) { @@ -3675,6 +3656,8 @@ void CGlobalTRex::dump_post_test_stats(FILE *fd){ pkt_in_bytes +=_if->get_stats().ibytes; pkt_out +=_if->get_stats().opackets; pkt_out_bytes +=_if->get_stats().obytes; + tx_arp += _if->get_ignore_stats().get_tx_arp(); + rx_arp += _if->get_ignore_stats().get_rx_arp(); } if ( CGlobalInfo::m_options.is_latency_enabled() ){ sw_pkt_out += m_mg.get_total_pkt(); @@ -3703,6 +3686,8 @@ void CGlobalTRex::dump_post_test_stats(FILE *fd){ fprintf (fd," Total-rx-pkt : %llu pkts \n", (unsigned long long)pkt_in); fprintf (fd," Total-sw-tx-pkt : %llu pkts \n", (unsigned long long)sw_pkt_out); fprintf (fd," Total-sw-err : %llu pkts \n", (unsigned long long)sw_pkt_out_err); + fprintf (fd," Total ARP sent : %llu pkts \n", (unsigned long long)tx_arp); + fprintf (fd," Total ARP received : %llu pkts \n", (unsigned long long)rx_arp); if ( CGlobalInfo::m_options.is_latency_enabled() ){ @@ -4550,6 +4535,22 @@ int CGlobalTRex::start_master_statefull() { //////////////////////////////////////////// static CGlobalTRex g_trex; +void CPhyEthIF::update_counters() { + get_ex_drv()->get_extended_stats(this, &m_stats); + CRXCoreIgnoreStat ign_stats; + g_trex.m_mg.get_ignore_stats(m_port_id, ign_stats, true); + m_stats.obytes -= ign_stats.get_tx_bytes(); + m_stats.opackets -= ign_stats.get_tx_pkts(); + m_ignore_stats.opackets += ign_stats.get_tx_pkts(); + m_ignore_stats.obytes += ign_stats.get_tx_bytes(); + m_ignore_stats.m_tx_arp += ign_stats.get_tx_arp(); + + m_last_tx_rate = m_bw_tx.add(m_stats.obytes); + m_last_rx_rate = m_bw_rx.add(m_stats.ibytes); + m_last_tx_pps = m_pps_tx.add(m_stats.opackets); + m_last_rx_pps = m_pps_rx.add(m_stats.ipackets); +} + bool CPhyEthIF::Create(uint8_t portid) { m_port_id = portid; m_last_rx_rate = 0.0; @@ -5140,18 +5141,6 @@ int main_test(int argc , char * argv[]){ /* set dump mode */ g_trex.m_io_modes.set_mode((CTrexGlobalIoMode::CliDumpMode)CGlobalInfo::m_options.m_io_mode); - if ( CGlobalInfo::m_options.is_latency_enabled() - && (CGlobalInfo::m_options.m_latency_prev > 0)) { - uint32_t pkts = CGlobalInfo::m_options.m_latency_prev * - CGlobalInfo::m_options.m_latency_rate; - printf("Starting pre latency check for %d sec\n",CGlobalInfo::m_options.m_latency_prev); - g_trex.m_mg.start(pkts, NULL); - delay(CGlobalInfo::m_options.m_latency_prev* 1000); - printf("Finished \n"); - g_trex.m_mg.reset(); - g_trex.reset_counters(); - } - /* disable WD if needed */ bool wd_enable = (CGlobalInfo::m_options.preview.getWDDisable() ? false : true); TrexWatchDog::getInstance().init(wd_enable); @@ -5211,6 +5200,7 @@ int main_test(int argc , char * argv[]){ } g_trex.pre_test(); + // after doing all needed ARP resolution, we need to flush queues, and stop our drop queue g_trex.ixgbe_rx_queue_flush(); for (int i = 0; i < g_trex.m_max_ports; i++) { @@ -5218,6 +5208,17 @@ int main_test(int argc , char * argv[]){ _if->stop_rx_drop_queue(); } + if ( CGlobalInfo::m_options.is_latency_enabled() + && (CGlobalInfo::m_options.m_latency_prev > 0)) { + uint32_t pkts = CGlobalInfo::m_options.m_latency_prev * + CGlobalInfo::m_options.m_latency_rate; + printf("Starting warm up phase for %d sec\n",CGlobalInfo::m_options.m_latency_prev); + g_trex.m_mg.start(pkts, NULL); + delay(CGlobalInfo::m_options.m_latency_prev* 1000); + printf("Finished \n"); + g_trex.m_mg.reset(); + } + if ( CGlobalInfo::m_options.preview.getOnlyLatency() ){ rte_eal_mp_remote_launch(latency_one_lcore, NULL, CALL_MASTER); RTE_LCORE_FOREACH_SLAVE(lcore_id) { @@ -6054,20 +6055,32 @@ int CTRexExtendedDriverBase40G::dump_fdir_global_stats(CPhyEthIF * _if, FILE *fd } } -void CTRexExtendedDriverBase40G::get_extended_stats(CPhyEthIF * _if,CPhyEthIFStats *stats){ +void CTRexExtendedDriverBase40G::get_extended_stats(CPhyEthIF * _if,CPhyEthIFStats *stats) { struct rte_eth_stats stats1; + struct rte_eth_stats *prev_stats = &stats->m_prev_stats; rte_eth_stats_get(_if->get_port_id(), &stats1); - stats->ipackets = stats1.ipackets; - stats->ibytes = stats1.ibytes ; - stats->opackets = stats1.opackets; - stats->obytes = stats1.obytes + (stats1.opackets<<2); - stats->f_ipackets = 0; - stats->f_ibytes = 0; - stats->ierrors = stats1.imissed + stats1.ierrors + stats1.rx_nombuf; - stats->oerrors = stats1.oerrors;; - stats->imcasts = 0; - stats->rx_nombuf = stats1.rx_nombuf; + stats->ipackets += stats1.ipackets - prev_stats->ipackets; + stats->ibytes += stats1.ibytes - prev_stats->ibytes; + stats->opackets += stats1.opackets - prev_stats->opackets; + stats->obytes += stats1.obytes - prev_stats->obytes + + (stats1.opackets << 2) - (prev_stats->opackets << 2); + stats->f_ipackets += 0; + stats->f_ibytes += 0; + stats->ierrors += stats1.imissed + stats1.ierrors + stats1.rx_nombuf + - prev_stats->imissed - prev_stats->ierrors - prev_stats->rx_nombuf; + stats->oerrors += stats1.oerrors - prev_stats->oerrors; + stats->imcasts += 0; + stats->rx_nombuf += stats1.rx_nombuf - prev_stats->rx_nombuf; + + prev_stats->ipackets = stats1.ipackets; + prev_stats->ibytes = stats1.ibytes; + prev_stats->opackets = stats1.opackets; + prev_stats->obytes = stats1.obytes; + prev_stats->imissed = stats1.imissed; + prev_stats->oerrors = stats1.oerrors; + prev_stats->ierrors = stats1.ierrors; + prev_stats->rx_nombuf = stats1.rx_nombuf; } int CTRexExtendedDriverBase40G::wait_for_stable_link(){ @@ -6154,31 +6167,30 @@ int CTRexExtendedDriverBase1GVm::stop_queue(CPhyEthIF * _if, uint16_t q_num) { } void CTRexExtendedDriverBase1GVm::get_extended_stats(CPhyEthIF * _if,CPhyEthIFStats *stats){ - struct rte_eth_stats stats1; + struct rte_eth_stats *prev_stats = &stats->m_prev_stats; rte_eth_stats_get(_if->get_port_id(), &stats1); - - stats->ipackets = stats1.ipackets; - stats->ibytes = stats1.ibytes; - - stats->opackets = stats1.opackets; - stats->obytes = stats1.obytes; - - stats->f_ipackets = 0; - stats->f_ibytes = 0; - - - stats->ierrors = stats1.imissed + - stats1.ierrors + - stats1.oerrors + - stats1.rx_nombuf; - - - stats->oerrors = stats1.oerrors;; - stats->imcasts = 0; - stats->rx_nombuf = stats1.rx_nombuf; - + stats->ipackets += stats1.ipackets - prev_stats->ipackets; + stats->ibytes += stats1.ibytes - prev_stats->ibytes; + stats->opackets += stats1.opackets - prev_stats->opackets; + stats->obytes += stats1.obytes - prev_stats->obytes; + stats->f_ipackets += 0; + stats->f_ibytes += 0; + stats->ierrors += stats1.imissed + stats1.ierrors + stats1.rx_nombuf + - prev_stats->imissed - prev_stats->ierrors - prev_stats->rx_nombuf; + stats->oerrors += stats1.oerrors - prev_stats->oerrors; + stats->imcasts += 0; + stats->rx_nombuf += stats1.rx_nombuf - prev_stats->rx_nombuf; + + prev_stats->ipackets = stats1.ipackets; + prev_stats->ibytes = stats1.ibytes; + prev_stats->opackets = stats1.opackets; + prev_stats->obytes = stats1.obytes; + prev_stats->imissed = stats1.imissed; + prev_stats->oerrors = stats1.oerrors; + prev_stats->ierrors = stats1.ierrors; + prev_stats->rx_nombuf = stats1.rx_nombuf; } int CTRexExtendedDriverBase1GVm::wait_for_stable_link(){ diff --git a/src/main_dpdk.h b/src/main_dpdk.h index bde10659..97994c47 100644 --- a/src/main_dpdk.h +++ b/src/main_dpdk.h @@ -18,6 +18,7 @@ #define MAIN_DPDK_H #include <rte_ethdev.h> +#include "pre_test.h" #include "bp_sim.h" enum { @@ -25,9 +26,29 @@ enum { MAIN_DPDK_RX_Q = 1, }; -class CPhyEthIFStats { +// These are statistics for packets we send, and do not expect to get back (Like ARP) +// We reduce them from general statistics we report (and report them separately, so we can keep the assumption +// that tx_pkts == rx_pkts and tx_bytes==rx_bytes +class CPhyEthIgnoreStats { + friend class CPhyEthIF; public: + uint64_t get_rx_arp() {return m_rx_arp;} + uint64_t get_tx_arp() {return m_tx_arp;} + private: + uint64_t ipackets; /**< Total number of successfully received packets. */ + uint64_t ibytes; /**< Total number of successfully received bytes. */ + uint64_t opackets; /**< Total number of successfully transmitted packets.*/ + uint64_t obytes; /**< Total number of successfully transmitted bytes. */ + uint64_t m_tx_arp; /**< Total number of successfully transmitted ARP packets */ + uint64_t m_rx_arp; /**< Total number of successfully received ARP packets */ + + private: + void dump(FILE *fd); +}; + +class CPhyEthIFStats { + public: uint64_t ipackets; /**< Total number of successfully received packets. */ uint64_t ibytes; /**< Total number of successfully received bytes. */ uint64_t f_ipackets; /**< Total number of successfully received packets - filter SCTP*/ @@ -38,6 +59,7 @@ class CPhyEthIFStats { uint64_t oerrors; /**< Total number of failed transmitted packets. */ uint64_t imcasts; /**< Total number of multicast received packets. */ uint64_t rx_nombuf; /**< Total number of RX mbuf allocation failures. */ + struct rte_eth_stats m_prev_stats; uint64_t m_rx_per_flow_pkts [MAX_FLOW_STATS]; // Per flow RX pkts uint64_t m_rx_per_flow_bytes[MAX_FLOW_STATS]; // Per flow RX bytes // Previous fdir stats values read from driver. Since on xl710 this is 32 bit, we save old value, to handle wrap around. @@ -71,7 +93,6 @@ class CPhyEthIF { int reset_hw_flow_stats(); int get_flow_stats(rx_per_flow_t *rx_stats, tx_per_flow_t *tx_stats, int min, int max, bool reset); int get_flow_stats_payload(rx_per_flow_t *rx_stats, tx_per_flow_t *tx_stats, int min, int max, bool reset); - void get_stats_1g(CPhyEthIFStats *stats); void rx_queue_setup(uint16_t rx_queue_id, uint16_t nb_rx_desc, unsigned int socket_id, @@ -99,6 +120,7 @@ class CPhyEthIF { void add_mac(char * mac); bool get_promiscuous(); void dump_stats(FILE *fd); + void set_ignore_stats_base(CPreTestStats &pre_stats); void update_counters(); void stats_clear(); uint8_t get_port_id(){ @@ -120,6 +142,9 @@ class CPhyEthIF { CPhyEthIFStats & get_stats(){ return ( m_stats ); } + CPhyEthIgnoreStats & get_ignore_stats() { + return m_ignore_stats; + } void flush_dp_rx_queue(void); void flush_rx_queue(void); int add_rx_flow_stat_rule(uint8_t port_id, uint16_t l3_type, uint8_t l4_proto @@ -167,6 +192,7 @@ class CPhyEthIF { CPPSMeasure m_pps_tx; CPPSMeasure m_pps_rx; CPhyEthIFStats m_stats; + CPhyEthIgnoreStats m_ignore_stats; float m_last_tx_rate; float m_last_rx_rate; float m_last_tx_pps; diff --git a/src/test_pkt_gen.cpp b/src/pkt_gen.cpp index 502e84dc..eb9a26f9 100644 --- a/src/test_pkt_gen.cpp +++ b/src/pkt_gen.cpp @@ -29,7 +29,7 @@ #include <common/Network/Packet/EthernetHeader.h> #include <common/Network/Packet/Arp.h> #include "rx_check_header.h" -#include "test_pkt_gen.h" +#include "pkt_gen.h" // For use in tests char *CTestPktGen::create_test_pkt(uint16_t l3_type, uint16_t l4_proto, uint8_t ttl, uint32_t ip_id, uint16_t flags diff --git a/src/test_pkt_gen.h b/src/pkt_gen.h index 4257c9ae..309e02b9 100644 --- a/src/test_pkt_gen.h +++ b/src/pkt_gen.h @@ -19,14 +19,15 @@ limitations under the License. */ -#ifndef __TEST_PKT_GEN_H__ -#define __TEST_PKT_GEN_H__ +#ifndef __PKT_GEN_H__ +#define __PKT_GEN_H__ enum { D_PKT_TYPE_ICMP = 1, D_PKT_TYPE_UDP = 2, D_PKT_TYPE_TCP = 3, - D_PKT_TYPE_9k_UDP = 4, + D_PKT_TYPE_ARP = 4, + D_PKT_TYPE_9k_UDP = 5, D_PKT_TYPE_IPV6 = 60, D_PKT_TYPE_HW_VERIFY = 100, D_PKT_TYPE_HW_VERIFY_RCV_ALL = 101, diff --git a/src/pre_test.cpp b/src/pre_test.cpp index 0639d9c8..278db98b 100644 --- a/src/pre_test.cpp +++ b/src/pre_test.cpp @@ -26,10 +26,9 @@ #include "common/basic_utils.h" #include "bp_sim.h" #include "main_dpdk.h" -#include "test_pkt_gen.h" +#include "pkt_gen.h" #include "pre_test.h" - void CPretestPortInfo::set_params(CPerPortIPCfg port_cfg, const uint8_t *src_mac, bool resolve_needed) { m_ip = port_cfg.get_ip(); m_def_gw = port_cfg.get_def_gw(); @@ -73,18 +72,24 @@ void CPretestPortInfo::dump(FILE *fd) { put in mac relevant dest MAC for port/ip pair. return false if no relevant info exists, true otherwise. */ -bool CPretest::get_mac(uint16_t port, uint32_t ip, uint8_t *mac) { - assert(port < TREX_MAX_PORTS); +bool CPretest::get_mac(uint16_t port_id, uint32_t ip, uint8_t *mac) { + assert(port_id < TREX_MAX_PORTS); - if (m_port_info[port].m_state != CPretestPortInfo::RESOLVE_DONE) { + if (m_port_info[port_id].m_state != CPretestPortInfo::RESOLVE_DONE) { return false; } - memcpy(mac, &m_port_info[port].m_dst_mac, sizeof(m_port_info[port].m_dst_mac)); + memcpy(mac, &m_port_info[port_id].m_dst_mac, sizeof(m_port_info[port_id].m_dst_mac)); return true; } +CPreTestStats CPretest::get_stats(uint16_t port_id) { + assert(port_id < TREX_MAX_PORTS); + + return m_port_info[port_id].m_stats; +} + bool CPretest::is_loopback(uint16_t port) { assert(port < TREX_MAX_PORTS); @@ -104,22 +109,26 @@ int CPretest::handle_rx(int port_id, int queue_id) { uint16_t cnt; int i; int verbose = CGlobalInfo::m_options.preview.getVMode(); - - cnt = rte_eth_rx_burst(port_id, queue_id, rx_pkts, sizeof(rx_pkts)/sizeof(rx_pkts[0])); - - for (i = 0; i < cnt; i++) { - rte_mbuf_t * m = rx_pkts[i]; - int pkt_size = rte_pktmbuf_pkt_len(m); - uint8_t *p = rte_pktmbuf_mtod(m, uint8_t *); - ArpHdr *arp; - CPretestPortInfo *port = &m_port_info[port_id]; - if (is_arp(p, pkt_size, arp)) { - if (arp->m_arp_op == htons(ArpHdr::ARP_HDR_OP_REQUEST)) { - if (verbose >= 3) { - fprintf(stdout, "RX ARP request on port %d queue %d sip:0x%08x tip:0x%08x\n", port_id, queue_id - , ntohl(arp->m_arp_sip) - , ntohl(arp->m_arp_tip)); - } + int tries = 0; + + do { + cnt = rte_eth_rx_burst(port_id, queue_id, rx_pkts, sizeof(rx_pkts)/sizeof(rx_pkts[0])); + tries++; + + for (i = 0; i < cnt; i++) { + rte_mbuf_t * m = rx_pkts[i]; + int pkt_size = rte_pktmbuf_pkt_len(m); + uint8_t *p = rte_pktmbuf_mtod(m, uint8_t *); + ArpHdr *arp; + CPretestPortInfo *port = &m_port_info[port_id]; + if (is_arp(p, pkt_size, arp)) { + m_port_info[port_id].m_stats.m_rx_arp++; + if (arp->m_arp_op == htons(ArpHdr::ARP_HDR_OP_REQUEST)) { + if (verbose >= 3) { + fprintf(stdout, "RX ARP request on port %d queue %d sip:0x%08x tip:0x%08x\n", port_id, queue_id + , ntohl(arp->m_arp_sip) + , ntohl(arp->m_arp_tip)); + } // is this request for our IP? if (ntohl(arp->m_arp_tip) == port->m_ip) { // If our request(i.e. we are connected in loopback) @@ -137,23 +146,24 @@ int CPretest::handle_rx(int port_id, int queue_id) { } else { // ARP request not to our IP. At the moment, we ignore this. } - } else { - if (arp->m_arp_op == htons(ArpHdr::ARP_HDR_OP_REPLY)) { - if (verbose >= 3) { - fprintf(stdout, "RX ARP response on port %d queue %d sip:0x%08x tip:0x%08x\n", port_id, queue_id - , ntohl(arp->m_arp_sip) - , ntohl(arp->m_arp_tip)); - } - // If this is response to our request, update our tables - if (port->m_def_gw == ntohl(arp->m_arp_sip)) { - port->set_dst_mac((uint8_t *)&arp->m_arp_sha); + } else { + if (arp->m_arp_op == htons(ArpHdr::ARP_HDR_OP_REPLY)) { + if (verbose >= 3) { + fprintf(stdout, "RX ARP response on port %d queue %d sip:0x%08x tip:0x%08x\n", port_id, queue_id + , ntohl(arp->m_arp_sip) + , ntohl(arp->m_arp_tip)); + } + // If this is response to our request, update our tables + if (port->m_def_gw == ntohl(arp->m_arp_sip)) { + port->set_dst_mac((uint8_t *)&arp->m_arp_sha); + } } } } + rte_pktmbuf_free(m); } + } while ((cnt != 0) && (tries < 1000)); - rte_pktmbuf_free(m); - } return 0; } @@ -242,6 +252,8 @@ void CPretest::send_arp_req(uint16_t port_id, bool is_grat) { if (num_sent < 1) { fprintf(stderr, "Failed sending ARP to port:%d\n", port_id); exit(1); + } else { + m_port_info[port_id].m_stats.m_tx_arp++; } } diff --git a/src/pre_test.h b/src/pre_test.h index 7bbeb40d..ad7608a6 100644 --- a/src/pre_test.h +++ b/src/pre_test.h @@ -27,6 +27,18 @@ #include "bp_sim.h" #include "trex_defs.h" +class CPreTestStats { + public: + uint32_t m_rx_arp; // how many ARP packets we received + uint32_t m_tx_arp; // how many ARP packets we sent + + public: + void clear() { + m_rx_arp = 0; + m_tx_arp = 0; + } +}; + class CPretestPortInfo { friend class CPretest; @@ -41,6 +53,7 @@ class CPretestPortInfo { CPretestPortInfo() { m_state = INIT_NEEDED; m_is_loopback = false; + m_stats.clear(); } void dump(FILE *fd); uint8_t *create_arp_req(uint16_t &pkt_size, uint8_t port, bool is_grat); @@ -55,6 +68,7 @@ class CPretestPortInfo { uint8_t m_dst_mac[6]; enum CPretestPortInfoStates m_state; bool m_is_loopback; + CPreTestStats m_stats; }; @@ -64,6 +78,7 @@ class CPretest { m_max_ports = max_ports; } bool get_mac(uint16_t port, uint32_t ip, uint8_t *mac); + CPreTestStats get_stats(uint16_t port_id); bool is_loopback(uint16_t port); void set_port_params(uint16_t port_id, const CPerPortIPCfg &port_cfg, const uint8_t *src_mac, bool resolve_needed); bool resolve_all(); diff --git a/src/latency.cpp b/src/stateful_rx_core.cpp index 76f12b46..ebc51fcb 100644 --- a/src/latency.cpp +++ b/src/stateful_rx_core.cpp @@ -5,7 +5,7 @@ */ /* -Copyright (c) 2015-2015 Cisco Systems, Inc. +Copyright (c) 2015-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. @@ -23,11 +23,11 @@ limitations under the License. #include "flow_stat_parser.h" #include "utl_json.h" #include "trex_watchdog.h" -#include "test_pkt_gen.h" +#include "pkt_gen.h" #include "common/basic_utils.h" -#include "latency.h" +#include "stateful_rx_core.h" -const uint8_t sctp_pkt[]={ +const uint8_t sctp_pkt[]={ 0x00,0x04,0x96,0x08,0xe0,0x40, 0x00,0x0e,0x2e,0x24,0x37,0x5f, @@ -42,9 +42,9 @@ const uint8_t sctp_pkt[]={ 0x80,0x44,//SPORT 0x00,0x50,//DPORT - 0x00,0x00,0x00,0x00, //checksum + 0x00,0x00,0x00,0x00, //checksum - 0x11,0x22,0x33,0x44, // magic + 0x11,0x22,0x33,0x44, // magic 0x00,0x00,0x00,0x00, //64 bit counter 0x00,0x00,0x00,0x00, 0x00,0x01,0xa0,0x00, //seq @@ -63,18 +63,18 @@ const uint8_t icmp_pkt[]={ 0x9b,0xe6,0x18,0x9b, //SIP 0xcb,0xff,0xfc,0xc2, //DIP - 0x08, 0x00, + 0x08, 0x00, 0x01, 0x02, //checksum 0xaa, 0xbb, // id 0x00, 0x00, // Sequence number - 0x11,0x22,0x33,0x44, // magic + 0x11,0x22,0x33,0x44, // magic 0x00,0x00,0x00,0x00, //64 bit counter 0x00,0x00,0x00,0x00, 0x00,0x01,0xa0,0x00, //seq 0x00,0x00,0x00,0x00, -}; +}; void CLatencyPktInfo::Create(class CLatencyPktMode *m_l_pkt_info){ @@ -123,7 +123,7 @@ void CLatencyPktInfo::Create(class CLatencyPktMode *m_l_pkt_info){ m_dummy_node.m_src_port = 0x11; m_dummy_node.m_flow_id =0; m_dummy_node.m_flags =CGenNode::NODE_FLAGS_LATENCY; - + } rte_mbuf_t * CLatencyPktInfo::generate_pkt(int port_id,uint32_t extern_ip){ @@ -172,7 +172,8 @@ void CCPortLatency::reset(){ m_pad = 0; m_tx_pkt_err=0; m_tx_pkt_ok =0; - m_tx_grat_arp_ok =0; + m_ign_stats.clear(); + m_ign_stats_prev.clear(); m_pkt_ok=0; m_rx_check=0; m_no_magic=0; @@ -231,13 +232,13 @@ void CCPortLatency::update_packet(rte_mbuf_t * m, int port_id){ m_tx_seq++; CLatencyPktMode *c_l_pkt_mode = m_parent->c_l_pkt_mode; - c_l_pkt_mode->update_pkt(p + m_l4_offset, is_client_to_server, m_pkt_size - m_l4_offset, &m_icmp_tx_seq); + c_l_pkt_mode->update_pkt(p + m_l4_offset, is_client_to_server, m_pkt_size - m_l4_offset, &m_icmp_tx_seq); } -void CCPortLatency::DumpShortHeader(FILE *fd){ +void CCPortLatency::DumpShortHeader(FILE *fd){ fprintf(fd," if| tx_ok , rx_ok , rx check ,error, latency (usec) , Jitter max window \n"); - fprintf(fd," | , , , , average , max , (usec) \n"); + fprintf(fd," | , , , , average , max , (usec) \n"); fprintf(fd," ---------------------------------------------------------------------------------------------------------------- \n"); } @@ -271,7 +272,7 @@ void CCPortLatency::dump_json(std::string & json ){ void CCPortLatency::DumpShort(FILE *fd){ // m_hist.update(); <- moved to CLatencyManager::update() - fprintf(fd,"%8lu,%8lu,%10lu,%5lu,", + fprintf(fd,"%8lu,%8lu,%10lu,%5lu,", m_tx_pkt_ok, m_pkt_ok, m_rx_check, @@ -283,8 +284,8 @@ void CCPortLatency::DumpShort(FILE *fd){ m_hist.get_max_latency(), get_jitter_usec() ); - fprintf(fd," | "); - m_hist.DumpWinMax(fd); + fprintf(fd," | "); + m_hist.DumpWinMax(fd); } @@ -295,7 +296,9 @@ void CCPortLatency::dump_counters_json(std::string & json ){ json+="\"stats\" : {"; DPL_J(m_tx_pkt_ok); - DPL_J(m_tx_grat_arp_ok); + json+=add_json("tx_arp", m_ign_stats.get_tx_arp()); + json+=add_json("ipv6_n_solic", m_ign_stats.get_tx_n_solic()); + json+=add_json("ignore_bytes", m_ign_stats.get_tx_bytes()); DPL_J(m_tx_pkt_err); DPL_J(m_pkt_ok); DPL_J(m_unsup_prot); @@ -313,14 +316,14 @@ void CCPortLatency::dump_counters_json(std::string & json ){ } void CCPortLatency::DumpCounters(FILE *fd){ - #define DP_A1(f) if (f) fprintf(fd," %-40s : %llu \n",#f, (unsigned long long)f) +#define DP_A1(f) if (f) fprintf(fd," %-40s : %llu \n",#f, (unsigned long long)f) +#define DP_A2(str, f) if (f) fprintf(fd," %-40s : %llu \n", str, (unsigned long long)f) fprintf(fd," counter \n"); fprintf(fd," -----------\n"); DP_A1(m_tx_pkt_err); DP_A1(m_tx_pkt_ok); - DP_A1(m_tx_grat_arp_ok); DP_A1(m_pkt_ok); DP_A1(m_unsup_prot); DP_A1(m_no_magic); @@ -329,7 +332,9 @@ void CCPortLatency::DumpCounters(FILE *fd){ DP_A1(m_length_error); DP_A1(m_rx_check); DP_A1(m_no_ipv4_option); - + DP_A2("tx_arp", m_ign_stats.get_tx_arp()); + DP_A2("ipv6_n_solic", m_ign_stats.get_tx_n_solic()); + DP_A2("ignore_bytes", m_ign_stats.get_tx_bytes()); fprintf(fd," -----------\n"); m_hist.Dump(fd); @@ -338,8 +343,8 @@ void CCPortLatency::DumpCounters(FILE *fd){ bool CCPortLatency::dump_packet(rte_mbuf_t * m){ fprintf(stdout," %f.03 dump packet ..\n",now_sec()); - uint8_t *p=rte_pktmbuf_mtod(m, uint8_t*); - uint16_t pkt_size=rte_pktmbuf_pkt_len(m); + uint8_t *p=rte_pktmbuf_mtod(m, uint8_t*); + uint16_t pkt_size=rte_pktmbuf_pkt_len(m); utl_DumpBuffer(stdout,p,pkt_size,0); return (0); #if 0 @@ -350,7 +355,7 @@ bool CCPortLatency::dump_packet(rte_mbuf_t * m){ lp->dump(stdout); - return (0); + return (0); #endif } @@ -372,7 +377,7 @@ bool CCPortLatency::check_packet(rte_mbuf_t * m,CRx_check_header * & rx_p) { if ( !parser.Parse() ) { m_unsup_prot++; // Unsupported protocol return (false); - } + } CLatencyPktMode *c_l_pkt_mode = m_parent->c_l_pkt_mode; uint16_t pkt_size=rte_pktmbuf_pkt_len(m); uint16_t vlan_offset=parser.m_vlan_offset; @@ -492,7 +497,7 @@ void CLatencyManager::Delete(){ } /* 0->1 - 1->0 + 1->0 2->3 3->2 */ @@ -516,7 +521,7 @@ bool CLatencyManager::Create(CLatencyManagerCfg * cfg){ c_l_pkt_mode = (CLatencyPktModeICMP *) new CLatencyPktModeICMP(CGlobalInfo::m_options.get_l_pkt_mode()); break; } - + m_max_ports=cfg->m_max_ports; assert (m_max_ports <= TREX_MAX_PORTS); assert ((m_max_ports%2)==0); @@ -537,10 +542,12 @@ bool CLatencyManager::Create(CLatencyManagerCfg * cfg){ m_pkt_gen.get_pkt_size(),lpo ); } m_cps= cfg->m_cps; - m_d_time =ptime_convert_dsec_hr((1.0/m_cps)); - m_delta_sec =(1.0/m_cps); + if (m_cps != 0) { + m_delta_sec =(1.0/m_cps); + } else { + m_delta_sec = 0.0; + } - if ( get_is_rx_check_mode() ) { assert(m_rx_check_manager.Create()); m_rx_check_manager.m_cur_time= now_sec(); @@ -602,7 +609,8 @@ void CLatencyManager::send_grat_arp_all_ports() { } if ( lp->m_io->tx(m) == 0 ) { - lp->m_port.m_tx_grat_arp_ok++; + lp->m_port.m_ign_stats.m_tx_arp++; + lp->m_port.m_ign_stats.m_tot_bytes += 64; // mbuf size is smaller, but 64 bytes will be sent } else { lp->m_port.m_tx_pkt_err++; } @@ -610,26 +618,26 @@ void CLatencyManager::send_grat_arp_all_ports() { } void CLatencyManager::wait_for_rx_dump(){ - rte_mbuf_t * rx_pkts[64]; - int i; - while ( true ) { - rte_pause(); - rte_pause(); - rte_pause(); - for (i=0; i<m_max_ports; i++) { - CLatencyManagerPerPort * lp=&m_ports[i]; - rte_mbuf_t * m; - uint16_t cnt_p = lp->m_io->rx_burst(rx_pkts, 64); - if (cnt_p) { - int j; - for (j=0; j<cnt_p; j++) { - m=rx_pkts[j] ; - lp->m_port.dump_packet( m); - rte_pktmbuf_free(m); - } - } /*cnt_p*/ - }/* for*/ - } + rte_mbuf_t * rx_pkts[64]; + int i; + while ( true ) { + rte_pause(); + rte_pause(); + rte_pause(); + for (i=0; i<m_max_ports; i++) { + CLatencyManagerPerPort * lp=&m_ports[i]; + rte_mbuf_t * m; + uint16_t cnt_p = lp->m_io->rx_burst(rx_pkts, 64); + if (cnt_p) { + int j; + for (j=0; j<cnt_p; j++) { + m=rx_pkts[j] ; + lp->m_port.dump_packet( m); + rte_pktmbuf_free(m); + } + } /*cnt_p*/ + }/* for*/ + } } @@ -744,15 +752,17 @@ void CLatencyManager::start(int iter, bool activate_watchdog) { node->m_time = now_sec()+0.007; m_p_queue.push(node); - node = new CGenNode(); - node->m_type = CGenNode::FLOW_PKT; /* latency */ - node->m_time = now_sec(); /* 1/cps rate */ - m_p_queue.push(node); + if (m_delta_sec > 0) { + node = new CGenNode(); + node->m_type = CGenNode::FLOW_PKT; /* latency */ + node->m_time = now_sec(); /* 1/cps rate */ + m_p_queue.push(node); + } if (CGlobalInfo::m_options.m_arp_ref_per > 0) { node = new CGenNode(); node->m_type = CGenNode::GRAT_ARP; /* gratuitous ARP */ - node->m_time = now_sec() + CGlobalInfo::m_options.m_arp_ref_per; + node->m_time = now_sec() + (double) CGlobalInfo::m_options.m_arp_ref_per; m_p_queue.push(node); } @@ -807,7 +817,7 @@ void CLatencyManager::start(int iter, bool activate_watchdog) { m_cpu_dp_u.start_work1(); send_grat_arp_all_ports(); m_p_queue.pop(); - node->m_time += CGlobalInfo::m_options.m_arp_ref_per; + node->m_time += (double)CGlobalInfo::m_options.m_arp_ref_per; m_p_queue.push(node); m_cpu_dp_u.commit1(); break; @@ -822,7 +832,7 @@ void CLatencyManager::start(int iter, bool activate_watchdog) { printf("stop due iter %d\n",iter); break; } - } + } cnt++; } @@ -853,6 +863,20 @@ bool CLatencyManager::is_active(){ return (m_is_active); } +// return the statistics we want to ignore for port port_id +// stat - hold values we return. +// if get_diff is true, return diff from last read. Else return total. +void CLatencyManager::get_ignore_stats(int port_id, CRXCoreIgnoreStat &stat, bool get_diff) { + CLatencyManagerPerPort * lp = &m_ports[port_id]; + CRXCoreIgnoreStat temp; + temp = lp->m_port.m_ign_stats; + if (get_diff) { + stat = temp - lp->m_port.m_ign_stats_prev; + lp->m_port.m_ign_stats_prev = temp; + } else { + stat = lp->m_port.m_ign_stats; + } +} double CLatencyManager::get_max_latency(){ double l=0.0; diff --git a/src/latency.h b/src/stateful_rx_core.h index 2f8a1134..3fa5892f 100644 --- a/src/latency.h +++ b/src/stateful_rx_core.h @@ -1,5 +1,3 @@ -#ifndef LATENCY_H -#define LATENCY_H /* Hanoh Haim Ido Barnea @@ -7,7 +5,7 @@ */ /* -Copyright (c) 2015-2015 Cisco Systems, Inc. +Copyright (c) 2015-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. @@ -21,6 +19,9 @@ 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. */ +#ifndef __STATEFUL_RX_CORE_H__ +#define __STATEFUL_RX_CORE_H__ + #include "bp_sim.h" #include "flow_stat.h" @@ -30,6 +31,33 @@ limitations under the License. class TrexWatchDog; +class CRXCoreIgnoreStat { + friend class CCPortLatency; + friend class CLatencyManager; + public: + inline CRXCoreIgnoreStat operator- (const CRXCoreIgnoreStat &t_in) { + CRXCoreIgnoreStat t_out; + t_out.m_tx_arp = this->m_tx_arp - t_in.m_tx_arp; + t_out.m_tx_ipv6_n_solic = this->m_tx_ipv6_n_solic - t_in.m_tx_ipv6_n_solic; + t_out.m_tot_bytes = this->m_tot_bytes - t_in.m_tot_bytes; + return t_out; + } + uint64_t get_tx_bytes() {return m_tot_bytes;} + uint64_t get_tx_pkts() {return m_tx_arp + m_tx_ipv6_n_solic;} + uint64_t get_tx_arp() {return m_tx_arp;} + uint64_t get_tx_n_solic() {return m_tx_ipv6_n_solic;} + void clear() { + m_tx_arp = 0; + m_tx_ipv6_n_solic = 0; + m_tot_bytes = 0; + } + + private: + uint64_t m_tx_arp; + uint64_t m_tx_ipv6_n_solic; + uint64_t m_tot_bytes; +}; + class CLatencyPktInfo { public: void Create(class CLatencyPktMode *m_l_pkt_info); @@ -180,7 +208,6 @@ private: public: uint64_t m_tx_pkt_ok; - uint64_t m_tx_grat_arp_ok; uint64_t m_tx_pkt_err; uint64_t m_pkt_ok; uint64_t m_unsup_prot; @@ -190,6 +217,8 @@ public: uint64_t m_rx_check; uint64_t m_no_ipv4_option; uint64_t m_length_error; + CRXCoreIgnoreStat m_ign_stats; + CRXCoreIgnoreStat m_ign_stats_prev; CTimeHistogram m_hist; /* all window */ CJitter m_jitter; }; @@ -307,6 +336,7 @@ public: void set_mask(uint32_t mask){ m_port_mask=mask; } + void get_ignore_stats(int port_id, CRXCoreIgnoreStat &stat, bool get_diff); double get_max_latency(void); double get_avr_latency(void); bool is_any_error(); @@ -334,7 +364,6 @@ private: bool m_is_active; CLatencyPktInfo m_pkt_gen; CLatencyManagerPerPort m_ports[TREX_MAX_PORTS]; - uint64_t m_d_time; // calc tick betwen sending double m_cps; double m_delta_sec; uint64_t m_start_time; // calc tick betwen sending diff --git a/src/stateless/rx/trex_stateless_rx_core.cpp b/src/stateless/rx/trex_stateless_rx_core.cpp index e61fb448..d162c5b3 100644 --- a/src/stateless/rx/trex_stateless_rx_core.cpp +++ b/src/stateless/rx/trex_stateless_rx_core.cpp @@ -22,7 +22,7 @@ #include <stdio.h> #include "bp_sim.h" #include "flow_stat_parser.h" -#include "latency.h" +#include "stateful_rx_core.h" #include "pal/linux/sanb_atomic.h" #include "trex_stateless_messaging.h" #include "trex_stateless_rx_core.h" diff --git a/src/stateless/rx/trex_stateless_rx_core.h b/src/stateless/rx/trex_stateless_rx_core.h index 39af8199..3f9fb6cc 100644 --- a/src/stateless/rx/trex_stateless_rx_core.h +++ b/src/stateless/rx/trex_stateless_rx_core.h @@ -21,7 +21,7 @@ #ifndef __TREX_STATELESS_RX_CORE_H__ #define __TREX_STATELESS_RX_CORE_H__ #include <stdint.h> -#include "latency.h" +#include "stateful_rx_core.h" #include "os_time.h" #include "pal/linux/sanb_atomic.h" #include "utl_cpuu.h" |