pre test: Code review fixes
authorIdo Barnea <[email protected]>
Tue, 27 Sep 2016 11:24:32 +0000 (14:24 +0300)
committerIdo Barnea <[email protected]>
Wed, 5 Oct 2016 07:45:29 +0000 (10:45 +0300)
16 files changed:
linux/ws_main.py
linux_dpdk/ws_main.py
src/bp_gtest.cpp
src/bp_sim.cpp
src/debug.cpp
src/flow_stat_parser.cpp
src/main_dpdk.cpp
src/main_dpdk.h
src/pkt_gen.cpp [moved from src/test_pkt_gen.cpp with 99% similarity]
src/pkt_gen.h [moved from src/test_pkt_gen.h with 93% similarity]
src/pre_test.cpp
src/pre_test.h
src/stateful_rx_core.cpp [moved from src/latency.cpp with 90% similarity]
src/stateful_rx_core.h [moved from src/latency.h with 90% similarity]
src/stateless/rx/trex_stateless_rx_core.cpp
src/stateless/rx/trex_stateless_rx_core.h

index f20afcc..2a0d728 100755 (executable)
@@ -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',
index 47c479c..0a2c9df 100755 (executable)
@@ -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',
index a1f8040..ca514c8 100755 (executable)
@@ -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(){
index 773e82f..b276d4f 100755 (executable)
@@ -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"
index 5abdbdc..542d2fa 100644 (file)
@@ -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);
     }
index b809b0f..7335a6a 100644 (file)
@@ -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() {
index a6ea387..edeeb3e 100644 (file)
@@ -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(){
index bde1065..97994c4 100644 (file)
@@ -18,6 +18,7 @@
 #define MAIN_DPDK_H
 
 #include <rte_ethdev.h>
+#include "pre_test.h"
 #include "bp_sim.h"
 
 enum {
@@ -25,8 +26,28 @@ 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. */
@@ -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;
similarity index 99%
rename from src/test_pkt_gen.cpp
rename to src/pkt_gen.cpp
index 502e84d..eb9a26f 100644 (file)
@@ -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
similarity index 93%
rename from src/test_pkt_gen.h
rename to src/pkt_gen.h
index 4257c9a..309e02b 100644 (file)
   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,
index 0639d9c..278db98 100644 (file)
 #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++;
     }
 }
 
index 7bbeb40..ad7608a 100644 (file)
 #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();
similarity index 90%
rename from src/latency.cpp
rename to src/stateful_rx_core.cpp
index 76f12b4..ebc51fc 100644 (file)
@@ -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;
similarity index 90%
rename from src/latency.h
rename to src/stateful_rx_core.h
index 2f8a113..3fa5892 100644 (file)
@@ -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
index e61fb44..d162c5b 100644 (file)
@@ -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"
index 39af819..3f9fb6c 100644 (file)
@@ -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"