APIs and functions in preparation for receive all mode. XL710/i350 mode toggling...
authorIdo Barnea <[email protected]>
Thu, 8 Sep 2016 09:04:59 +0000 (12:04 +0300)
committerIdo Barnea <[email protected]>
Tue, 13 Sep 2016 08:54:20 +0000 (11:54 +0300)
15 files changed:
linux_dpdk/ws_main.py
src/debug.cpp
src/debug.h
src/dpdk/drivers/net/i40e/i40e_ethdev.c
src/dpdk_funcs.c [new file with mode: 0644]
src/dpdk_funcs.h [new file with mode: 0644]
src/flow_stat.cpp
src/flow_stat.h
src/flow_stat_parser.cpp
src/flow_stat_parser.h
src/main_dpdk.cpp
src/stateless/cp/trex_exception.h
src/stateless/rx/trex_stateless_rx_core.cpp
src/stateless/rx/trex_stateless_rx_core.h
src/test_pkt_gen.h

index f208fa9..f895204 100755 (executable)
@@ -247,6 +247,7 @@ version_src = SrcGroup(
 
 dpdk_src = SrcGroup(dir='src/dpdk/',
                 src_list=[
+                 '../dpdk_funcs.c',
                  'drivers/net/af_packet/rte_eth_af_packet.c',
                  'drivers/net/cxgbe/base/t4_hw.c',
                  'drivers/net/cxgbe/cxgbe_ethdev.c',
index 3cb4e3c..2e7eb5d 100644 (file)
@@ -133,6 +133,9 @@ rte_mbuf_t *CTrexDebug::create_test_pkt(int ip_ver, uint16_t l4_proto, uint8_t t
     case 6:
         l3_type = EthernetHeader::Protocol::IPv6;
         break;
+    case 1:
+        l3_type = EthernetHeader::Protocol::ARP;
+        break;
     default:
         return NULL;
         break;
@@ -280,6 +283,8 @@ struct pkt_params {
 };
 
 struct pkt_params test_pkts[] = {
+    {"ARP", 1, IPPROTO_UDP, 255, 5, 0, ZERO},
+    {"VLAN ARP", 1, IPPROTO_UDP, 255, 5, DPF_VLAN, ZERO},
     {"ipv4 TCP ttl 255", 4, IPPROTO_TCP, 255, 5, 0, STF},
     {"ipv4 TCP ttl 254", 4, IPPROTO_TCP, 254, 5, 0, STF},
     {"ipv4 TCP ttl 253", 4, IPPROTO_TCP, 253, 5, 0, ZERO},
@@ -330,7 +335,7 @@ struct pkt_params test_pkts[] = {
 // unit test for verifying hw queues rule configuration. Can be run by:
 // for stateful: --send-debug-pkt 100 -f cap2/dns.yaml -l 1
 // for stateless: --setnd-debug-pkt 100 -i
-int CTrexDebug::verify_hw_rules() {
+int CTrexDebug::verify_hw_rules(bool recv_all) {
     rte_mbuf_t *m = NULL;
     CPhyEthIF * lp;
     rte_mbuf_t * rx_pkts[32];
@@ -345,30 +350,34 @@ int CTrexDebug::verify_hw_rules() {
         uint8_t exp_q;
         uint16_t pkt_flags = test_pkts[pkt_num].pkt_flags;
         debug_expected_q_t expected_q = test_pkts[pkt_num].expected_q;
-        switch (expected_q) {
-        case ZERO:
-            exp_q = 0;
-            break;
-        case ONE:
-            exp_q = 1;
-            break;
-        case STL:
-            if ( CGlobalInfo::m_options.is_stateless() ) {
-                exp_q = 1;
-            } else {
-                exp_q = 0;
-            }
-            break;
-        case STF:
-            if ( CGlobalInfo::m_options.is_stateless() ) {
-                exp_q = 0;
-            } else {
-                exp_q = 1;
+        if (recv_all) {
+            exp_q = MAIN_DPDK_RX_Q;
+        } else {
+            switch (expected_q) {
+            case ZERO:
+                exp_q = MAIN_DPDK_DATA_Q;
+                break;
+            case ONE:
+                exp_q = MAIN_DPDK_RX_Q;
+                break;
+            case STL:
+                if ( CGlobalInfo::m_options.is_stateless() ) {
+                    exp_q = MAIN_DPDK_RX_Q;
+                } else {
+                    exp_q = MAIN_DPDK_DATA_Q;
+                }
+                break;
+            case STF:
+                if ( CGlobalInfo::m_options.is_stateless() ) {
+                    exp_q = MAIN_DPDK_DATA_Q;
+                } else {
+                    exp_q = MAIN_DPDK_RX_Q;
+                }
+                break;
+            default:
+                exp_q = MAIN_DPDK_DATA_Q;
+                break;
             }
-            break;
-        default:
-            exp_q = 0;
-            break;
         }
 
         m = create_test_pkt(ip_ver, l4_proto, ttl, ip_id, pkt_flags);
@@ -412,7 +421,9 @@ int CTrexDebug::test_send(uint pkt_type) {
     rte_mbuf_t *m, *d;
 
     if (pkt_type == D_PKT_TYPE_HW_VERIFY) {
-        return verify_hw_rules();
+        return verify_hw_rules(false);
+    } else if (pkt_type == D_PKT_TYPE_HW_VERIFY_RCV_ALL) {
+        return verify_hw_rules(true);
     }
 
     if (! (pkt_type >= 1 && pkt_type <= 4) && !(pkt_type >= 61 && pkt_type <= 63)) {
index 3ecc360..d178e3a 100644 (file)
@@ -33,7 +33,7 @@ class CTrexDebug {
     int  set_promisc_all(bool enable);
     int test_send_pkts(rte_mbuf_t *, uint16_t queue_id, int pkt, int port);
     rte_mbuf_t *create_test_pkt(int ip_ver, uint16_t l4_proto, uint8_t ttl, uint32_t ip_id, uint16_t flags);
-    int verify_hw_rules();
+    int verify_hw_rules(bool recv_all);
 
  public:
     CTrexDebug(CPhyEthIF *m_ports_arg, int max_ports);
index 778c1ec..ca1a480 100644 (file)
@@ -757,66 +757,6 @@ static inline void i40e_flex_payload_reg_init(struct i40e_hw *hw)
 
 #define TREX_PATCH
 #define TREX_PATCH_LOW_LATENCY
-#ifdef TREX_PATCH
-
-// 0 - statfull mode. 1 stateless.
-static int trex_mode=0;
-void i40e_set_trex_mode(int mode) {
-    trex_mode = mode;
-}
-
-static void i40e_dump_filter_regs(struct i40e_hw *hw)
-{
-    int reg_nums[] = {31, 33, 34, 35, 41, 43};
-    int i;
-    uint32_t reg;
-
-    for (i =0; i < sizeof (reg_nums)/sizeof(int); i++) {
-       reg = I40E_READ_REG(hw,I40E_PRTQF_FD_INSET(reg_nums[i], 0));
-        printf("I40E_PRTQF_FD_INSET(%d, 0): 0x%08x\n", reg_nums[i], reg);
-       reg = I40E_READ_REG(hw,I40E_PRTQF_FD_INSET(reg_nums[i], 1));
-        printf("I40E_PRTQF_FD_INSET(%d, 1): 0x%08x\n", reg_nums[i], reg);
-    }
-}
-
-static inline void i40e_filter_fields_reg_init(struct i40e_hw *hw)
-{
-       uint32_t reg;
-
-       I40E_WRITE_REG(hw, I40E_GLQF_ORT(12), 0x00000062);
-       I40E_WRITE_REG(hw, I40E_GLQF_PIT(2), 0x000024A0);
-       I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_UDP, 0), 0);
-       I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_TCP, 0), 0);
-       I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER, 0), 0);
-       I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_UDP, 0), 0);
-       I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_TCP, 0), 0);
-    I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER, 0), 0);
-    if (trex_mode == 1) {
-        // stateless
-        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_UDP, 1), 0x00100000);
-        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_TCP, 1), 0x00100000);
-        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER, 1), 0x00100000);
-        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_UDP, 1),   0x0000000000200000ULL);
-        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_TCP, 1),   0x0000000000200000ULL);
-        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER, 1), 0x0000000000200000ULL);
-    } else {
-        //stateful
-        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_UDP, 1), 0x00040000);
-        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_TCP, 1), 0x00040000);
-        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER, 1), 0x00040000);
-        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_UDP, 1), 0x00080000);
-        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_TCP, 1), 0x00080000);
-        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER, 1), 0x00080000);
-        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_SCTP, 0), 0);
-        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_SCTP, 1), 0x00040000);
-        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_SCTP, 0), 0);
-        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_SCTP, 1), 0x00080000);
-    }
-       I40E_WRITE_REG(hw, I40E_GLQF_FD_MSK(0, 34), 0x000DFF00);
-       I40E_WRITE_REG(hw, I40E_GLQF_FD_MSK(0,44), 0x000C00FF);
-       I40E_WRITE_FLUSH(hw);
-}
-#endif //TREX_PATCH
 
 /*
  * Add a ethertype filter to drop all flow control frames transmitted
@@ -1069,14 +1009,10 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
         * for flexible payload by software.
         * It should be removed once issues are fixed in NVM.
         */
-#ifdef TREX_PATCH
-       i40e_filter_fields_reg_init(hw);
-#else
        i40e_flex_payload_reg_init(hw);
 
        /* Initialize the input set for filters (hash and fd) to default value */
        i40e_filter_input_set_init(pf);
-#endif
 
        /* Initialize the parameters for adminq */
        i40e_init_adminq_parameter(hw);
diff --git a/src/dpdk_funcs.c b/src/dpdk_funcs.c
new file mode 100644 (file)
index 0000000..99d2327
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+  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 <stdint.h>
+#include <rte_byteorder.h>
+#include <rte_ethdev.h>
+#include "dpdk/drivers/net/i40e/base/i40e_register.h"
+#include "dpdk/drivers/net/i40e/base/i40e_status.h"
+#include "dpdk/drivers/net/i40e/base/i40e_osdep.h"
+#include "dpdk/drivers/net/i40e/base/i40e_type.h"
+#include "dpdk/drivers/net/i40e/i40e_ethdev.h"
+#include "dpdk_funcs.h"
+
+void i40e_trex_dump_fdir_regs(struct i40e_hw *hw)
+{
+    int reg_nums[] = {31, 33, 34, 35, 41, 43};
+    int i;
+    uint32_t reg;
+
+    for (i =0; i < sizeof (reg_nums)/sizeof(int); i++) {
+       reg = I40E_READ_REG(hw,I40E_PRTQF_FD_INSET(reg_nums[i], 0));
+        printf("I40E_PRTQF_FD_INSET(%d, 0): 0x%08x\n", reg_nums[i], reg);
+       reg = I40E_READ_REG(hw,I40E_PRTQF_FD_INSET(reg_nums[i], 1));
+        printf("I40E_PRTQF_FD_INSET(%d, 1): 0x%08x\n", reg_nums[i], reg);
+    }
+}
+    
+void i40e_trex_fdir_reg_init(int port_id, int mode)
+{
+    struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+       struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+    
+       I40E_WRITE_REG(hw, I40E_GLQF_ORT(12), 0x00000062);
+       I40E_WRITE_REG(hw, I40E_GLQF_PIT(2), 0x000024A0);
+       I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_UDP, 0), 0);
+       I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_TCP, 0), 0);
+       I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER, 0), 0);
+       I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_UDP, 0), 0);
+       I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_TCP, 0), 0);
+    I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER, 0), 0);
+    switch(mode) {
+    case I40E_TREX_INIT_STL:
+        // stateless - filter according to IP id or IPv6 identification
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_UDP, 1), 0x00100000);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_TCP, 1), 0x00100000);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER, 1), 0x00100000);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_UDP, 1),   0x0000000000200000ULL);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_TCP, 1),   0x0000000000200000ULL);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER, 1), 0x0000000000200000ULL);
+        break;
+    case I40E_TREX_INIT_RCV_ALL:
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_UDP, 1), 0);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_TCP, 1), 0);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER, 1), 0);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_UDP, 1), 0);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_TCP, 1), 0);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER, 1), 0);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_SCTP, 0), 0);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_SCTP, 1), 0);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_SCTP, 0), 0);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_SCTP, 1), 0);
+        break;
+    case I40E_TREX_INIT_STF:
+    default:
+        // stateful - Filter according to TTL or IPv6 hop limit
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_UDP, 1), 0x00040000);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_TCP, 1), 0x00040000);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_OTHER, 1), 0x00040000);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_UDP, 1), 0x00080000);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_TCP, 1), 0x00080000);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_OTHER, 1), 0x00080000);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_SCTP, 0), 0);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV4_SCTP, 1), 0x00040000);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_SCTP, 0), 0);
+        I40E_WRITE_REG(hw, I40E_PRTQF_FD_INSET(I40E_FILTER_PCTYPE_NONF_IPV6_SCTP, 1), 0x00080000);
+        break;
+    }
+       I40E_WRITE_REG(hw, I40E_GLQF_FD_MSK(0, 34), 0x000DFF00);
+       I40E_WRITE_REG(hw, I40E_GLQF_FD_MSK(0,44), 0x000C00FF);
+       I40E_WRITE_FLUSH(hw);
+}
diff --git a/src/dpdk_funcs.h b/src/dpdk_funcs.h
new file mode 100644 (file)
index 0000000..2db905f
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+  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.
+*/
+
+#ifndef __DPDK_FUNCS__
+#define __DPDK_FUNCS__
+
+enum i40e_trex_init_mode_ {
+    I40E_TREX_INIT_STL,
+    I40E_TREX_INIT_STF,
+    I40E_TREX_INIT_RCV_ALL,
+};
+
+void i40e_trex_dump_fdir_regs(struct i40e_hw *hw);
+void i40e_trex_fdir_reg_init(int port_id, int mode);
+
+#endif
index 58ff65a..84be590 100644 (file)
@@ -583,6 +583,11 @@ int CFlowStatRuleMgr::add_stream_internal(TrexStream * stream, bool do_action) {
     switch(rule_type) {
     case TrexPlatformApi::IF_STAT_IPV4_ID:
         uint16_t l3_proto;
+
+        if (m_mode == FLOW_STAT_MODE_PASS_ALL) {
+            throw TrexFStatEx("Can not add flow stat stream in 'receive all' mode", TrexException::T_FLOW_STAT_BAD_RULE_TYPE_FOR_MODE);
+        }
+
         if (m_parser->get_l3_proto(l3_proto) < 0) {
             throw TrexFStatEx("Failed determining l3 proto for packet", TrexException::T_FLOW_STAT_FAILED_FIND_L3);
         }
@@ -594,8 +599,8 @@ int CFlowStatRuleMgr::add_stream_internal(TrexStream * stream, bool do_action) {
 
         // throws exception if there is error
         if (do_action) {
-            uint8_t ipv6_next_h = l4_proto; //??? just for now
-            m_user_id_map.add_stream(stream->m_rx_check.m_pg_id, l3_proto, l4_proto, ipv6_next_h);
+            // passing 0 in ipv6_next_h. This is not used currently in stateless.
+            m_user_id_map.add_stream(stream->m_rx_check.m_pg_id, l3_proto, l4_proto, 0);
         }
         break;
     case TrexPlatformApi::IF_STAT_PAYLOAD:
@@ -930,6 +935,34 @@ int CFlowStatRuleMgr::get_active_pgids(flow_stat_active_t &result) {
     return 0;
 }
 
+int CFlowStatRuleMgr::set_mode(enum flow_stat_mode_e mode) {
+    if ( ! m_user_id_map.is_empty() )
+        return -1;
+
+    if (! m_api ) {
+        create();
+    }
+
+    switch (mode) {
+    case FLOW_STAT_MODE_PASS_ALL:
+        delete m_parser;
+        m_parser = new CPassAllParser;
+        break;
+    case FLOW_STAT_MODE_NORMAL:
+        delete m_parser;
+        m_parser = m_api->get_flow_stat_parser();
+        assert(m_parser);
+        break;
+    default:
+        return -1;
+
+    }
+
+    m_mode = mode;
+
+    return 0;
+}
+
 extern bool rx_should_stop;
 void CFlowStatRuleMgr::send_start_stop_msg_to_rx(bool is_start) {
     TrexStatelessCpToRxMsgBase *msg;
index dee1acc..e0c995a 100644 (file)
@@ -452,6 +452,11 @@ class CFlowStatRuleMgr {
         FLOW_STAT_RULE_TYPE_IPV6_FLOW_LABEL,
     };
 
+    enum flow_stat_mode_e {
+        FLOW_STAT_MODE_NORMAL,
+        FLOW_STAT_MODE_PASS_ALL,
+    };
+
     CFlowStatRuleMgr();
     ~CFlowStatRuleMgr();
     friend std::ostream& operator<<(std::ostream& os, const CFlowStatRuleMgr& cf);
@@ -463,6 +468,7 @@ class CFlowStatRuleMgr {
     int start_stream(TrexStream * stream);
     int stop_stream(TrexStream * stream);
     int get_active_pgids(flow_stat_active_t &result);
+    int set_mode(enum flow_stat_mode_e mode);
     bool dump_json(std::string & s_json, std::string & l_json, bool baseline);
 
  private:
@@ -484,6 +490,7 @@ class CFlowStatRuleMgr {
     int m_num_started_streams; // How many started (transmitting) streams we have
     CNodeRing *m_ring_to_rx; // handle for sending messages to Rx core
     CFlowStatParser *m_parser;
+    enum flow_stat_mode_e m_mode;
     uint16_t m_cap; // capabilities of the NIC driver we are using
     uint32_t m_rx_cant_count_err[TREX_MAX_PORTS];
     uint32_t m_tx_cant_count_err[TREX_MAX_PORTS];
index 2ab273a..fd0fb80 100644 (file)
@@ -433,6 +433,17 @@ int C82599Parser::parse(uint8_t *p, uint16_t len) {
     return 0;
 }
 
+int CPassAllParser::parse(uint8_t *pkt, uint16_t len) {
+    reset();
+
+    if (len < ETH_HDR_LEN)
+        return -1;
+
+    m_len = len;
+
+    return 0;
+}
+
 bool CSimplePacketParser::Parse(){
 
     rte_mbuf_t * m=m_m;
index 78bc1e6..df70e4e 100644 (file)
@@ -98,6 +98,17 @@ class C82599Parser : public CFlowStatParser {
     bool m_vlan_supported;
 };
 
+class CPassAllParser : public CFlowStatParser {
+ public:
+    virtual int parse(uint8_t *pkt, uint16_t len);
+    virtual bool is_stat_supported() {return true;}
+    virtual int get_ip_id(uint32_t &ip_id) { ip_id = 0; return 0;}
+    virtual int set_ip_id(uint32_t ip_id){return 0;}
+    virtual int get_l3_proto(uint16_t &proto){proto = 0; return 0;}
+    virtual int get_l4_proto(uint8_t &proto) {proto = 0; return 0;}
+    virtual int get_payload_len(uint8_t *p, uint16_t len, uint16_t &payload_len) {payload_len = m_len; return 0;}
+};
+
 // Used for latency statefull packets. Need to be merged with above parser
 class CSimplePacketParser {
  public:
index 1e31f3d..8a92237 100644 (file)
@@ -66,6 +66,7 @@
 #include "../linux_dpdk/version.h"
 extern "C" {
 #include "dpdk/drivers/net/ixgbe/base/ixgbe_type.h"
+#include "dpdk_funcs.h"
 }
 #include "dpdk/drivers/net/e1000/base/e1000_regs.h"
 #include "global_io_mode.h"
@@ -74,6 +75,7 @@ extern "C" {
 #include "platform_cfg.h"
 #include "latency.h"
 #include "debug.h"
+#include "test_pkt_gen.h"
 #include "internal_api/trex_platform_api.h"
 #include "main_dpdk.h"
 #include "trex_watchdog.h"
@@ -98,7 +100,6 @@ extern "C" {
 
 typedef struct rte_mbuf * (*rte_mbuf_convert_to_one_seg_t)(struct rte_mbuf *m);
 struct rte_mbuf *  rte_mbuf_convert_to_one_seg(struct rte_mbuf *m);
-extern "C" void i40e_set_trex_mode(int mode);
 extern "C" int rte_eth_dev_get_port_by_addr(const struct rte_pci_addr *addr, uint8_t *port_id);
 void reorder_dpdk_ports();
 
@@ -140,7 +141,7 @@ public:
         return(false);
     }
 
-    virtual int configure_drop_queue(CPhyEthIF * _if);
+    virtual int stop_queue(CPhyEthIF * _if, uint16_t q_num);
     virtual void get_extended_stats(CPhyEthIF * _if,CPhyEthIFStats *stats)=0;
     virtual void clear_extended_stats(CPhyEthIF * _if)=0;
     virtual int  wait_for_stable_link();
@@ -155,6 +156,7 @@ public:
     virtual int get_rx_stat_capabilities() {return 0;}
     virtual int verify_fw_ver(int i) {return 0;}
     virtual CFlowStatParser *get_flow_stat_parser();
+    virtual int set_rcv_all(CPhyEthIF * _if, bool set_on)=0;
 };
 
 
@@ -179,17 +181,16 @@ public:
         return (true);
     }
 
-    virtual int configure_drop_queue(CPhyEthIF * _if);
+    virtual int stop_queue(CPhyEthIF * _if, uint16_t q_num);
     virtual int configure_rx_filter_rules(CPhyEthIF * _if);
     virtual int configure_rx_filter_rules_statefull(CPhyEthIF * _if);
     virtual int configure_rx_filter_rules_stateless(CPhyEthIF * _if);
-
+    virtual void clear_rx_filter_rules(CPhyEthIF * _if);
     virtual bool is_hardware_support_drop_queue(){
         return(true);
     }
 
     virtual void get_extended_stats(CPhyEthIF * _if,CPhyEthIFStats *stats);
-
     virtual void clear_extended_stats(CPhyEthIF * _if);
     virtual int dump_fdir_global_stats(CPhyEthIF * _if, FILE *fd) {return 0;}
     virtual int get_stat_counters_num() {return MAX_FLOW_STATS;}
@@ -199,6 +200,7 @@ public:
     }
     virtual int wait_for_stable_link();
     virtual void wait_after_link_up();
+    virtual int set_rcv_all(CPhyEthIF * _if, bool set_on);
 };
 
 class CTRexExtendedDriverBase1GVm : public CTRexExtendedDriverBase {
@@ -236,19 +238,16 @@ public:
         return(false);
     }
 
-    virtual int configure_drop_queue(CPhyEthIF * _if);
-
-
+    virtual int stop_queue(CPhyEthIF * _if, uint16_t q_num);
     virtual void get_extended_stats(CPhyEthIF * _if,CPhyEthIFStats *stats);
-
     virtual void clear_extended_stats(CPhyEthIF * _if);
-
     virtual int wait_for_stable_link();
     virtual int get_stat_counters_num() {return MAX_FLOW_STATS;}
     virtual int get_rx_stat_capabilities() {
         return TrexPlatformApi::IF_STAT_IPV4_ID | TrexPlatformApi::IF_STAT_RX_BYTES_COUNT
             | TrexPlatformApi::IF_STAT_PAYLOAD;
     }
+    virtual int set_rcv_all(CPhyEthIF * _if, bool set_on) {return 0;}
 };
 
 
@@ -286,6 +285,7 @@ public:
             | TrexPlatformApi::IF_STAT_PAYLOAD;
     }
     virtual CFlowStatParser *get_flow_stat_parser();
+    virtual int set_rcv_all(CPhyEthIF * _if, bool set_on) {return 0;}
 };
 
 class CTRexExtendedDriverBase40G : public CTRexExtendedDriverBase10G {
@@ -329,11 +329,13 @@ public:
     virtual bool hw_rx_stat_supported(){return true;}
     virtual int verify_fw_ver(int i);
     virtual CFlowStatParser *get_flow_stat_parser();
+    virtual int set_rcv_all(CPhyEthIF * _if, bool set_on);
 
 private:
     virtual void add_del_rules(enum rte_filter_op op, uint8_t port_id, uint16_t type, uint8_t ttl
                                , uint16_t ip_id, uint16_t l4_proto, int queue, uint16_t stat_idx);
-    virtual int configure_rx_filter_rules_statfull(CPhyEthIF * _if);
+    virtual int add_del_eth_type_rule(uint8_t port_id, enum rte_filter_op op, uint16_t eth_type);
+    virtual int configure_rx_filter_rules_statefull(CPhyEthIF * _if);
 
 private:
     uint8_t m_if_per_card;
@@ -1386,7 +1388,7 @@ void CPhyEthIF::configure_rx_drop_queue(){
             exit(1);
         }
     }
-    get_ex_drv()->configure_drop_queue(this);
+    get_ex_drv()->stop_queue(this, MAIN_DPDK_DATA_Q);
 }
 
 
@@ -5024,9 +5026,6 @@ int main_test(int argc , char * argv[]){
         return (-1);
     }
 
-    // We init i40e fdir registers differently in case of stateless. Must set this before rte_eal_init which initiates the registers
-    i40e_set_trex_mode(get_is_stateless() ? 1:0 );
-
     ret = rte_eal_init(global_dpdk_args_num, (char **)global_dpdk_args);
     if (ret < 0){
         printf(" You might need to run ./trex-cfg  once  \n");
@@ -5081,10 +5080,50 @@ int main_test(int argc , char * argv[]){
         g_trex.start_master_statefull();
     }
 
+    // For unit testing of HW rules and queues configuration. Just send some packets and exit.
     if (CGlobalInfo::m_options.m_debug_pkt_proto != 0) {
         CTrexDebug debug = CTrexDebug(g_trex.m_ports, g_trex.m_max_ports);
-        debug.test_send(CGlobalInfo::m_options.m_debug_pkt_proto);
-        exit(1);
+        int ret;
+
+        if (CGlobalInfo::m_options.m_debug_pkt_proto == D_PKT_TYPE_HW_TOGGLE_TEST) {
+            // Unit test: toggle many times between receive all and stateless/stateful modes,
+            // to test resiliency of add/delete fdir filters
+            printf("Starting receive all/normal mode toggle unit test\n");
+            for (int i = 0; i < 100; i++) {
+                for (int port_id = 0; port_id < g_trex.m_max_ports; port_id++) {
+                    CPhyEthIF *pif = &g_trex.m_ports[port_id];
+                    CTRexExtendedDriverDb::Ins()->get_drv()->set_rcv_all(pif, true);
+                }
+                ret = debug.test_send(D_PKT_TYPE_HW_VERIFY_RCV_ALL);
+                if (ret != 0) {
+                    printf("Iteration %d: Receive all mode failed\n", i);
+                    exit(ret);
+                }
+
+                for (int port_id = 0; port_id < g_trex.m_max_ports; port_id++) {
+                    CPhyEthIF *pif = &g_trex.m_ports[port_id];
+                    CTRexExtendedDriverDb::Ins()->get_drv()->configure_rx_filter_rules(pif);
+                }
+
+                ret = debug.test_send(D_PKT_TYPE_HW_VERIFY);
+                if (ret != 0) {
+                    printf("Iteration %d: Normal mode failed\n", i);
+                    exit(ret);
+                }
+
+                printf("Iteration %d OK\n", i);
+            }
+            exit(0);
+        } else {
+            if (CGlobalInfo::m_options.m_debug_pkt_proto == D_PKT_TYPE_HW_VERIFY_RCV_ALL) {
+                for (int port_id = 0; port_id < g_trex.m_max_ports; port_id++) {
+                    CPhyEthIF *pif = &g_trex.m_ports[port_id];
+                    CTRexExtendedDriverDb::Ins()->get_drv()->set_rcv_all(pif, true);
+                }
+            }
+            ret = debug.test_send(CGlobalInfo::m_options.m_debug_pkt_proto);
+            exit(ret);
+        }
     }
 
     if ( CGlobalInfo::m_options.preview.getOnlyLatency() ){
@@ -5165,9 +5204,9 @@ void reorder_dpdk_ports() {
 //////////////////////////////////////////////////////////////////////////////////////////////
 // driver section
 //////////////////////////////////////////////////////////////////////////////////////////////
-int CTRexExtendedDriverBase::configure_drop_queue(CPhyEthIF * _if) {
+int CTRexExtendedDriverBase::stop_queue(CPhyEthIF * _if, uint16_t q_num) {
     uint8_t port_id=_if->get_rte_port_id();
-    return (rte_eth_dev_rx_queue_stop(port_id, 0));
+    return (rte_eth_dev_rx_queue_stop(port_id, q_num));
 }
 
 int CTRexExtendedDriverBase::wait_for_stable_link() {
@@ -5206,14 +5245,15 @@ void CTRexExtendedDriverBase1G::update_global_config_fdir(port_cfg_t * cfg){
     // Configuration is done in configure_rx_filter_rules by writing to registers
 }
 
-// e1000 driver does not support the generic stop queue API, so we need to implement ourselves
-int CTRexExtendedDriverBase1G::configure_drop_queue(CPhyEthIF * _if) {
-    // Drop packets coming to RX queue 0
-    _if->pci_reg_write( E1000_RXDCTL(0) , 0);
+#define E1000_RXDCTL_QUEUE_ENABLE      0x02000000
+// e1000 driver does not support the generic stop/start queue API, so we need to implement ourselves
+int CTRexExtendedDriverBase1G::stop_queue(CPhyEthIF * _if, uint16_t q_num) {
+    uint32_t reg_val = _if->pci_reg_read( E1000_RXDCTL(q_num));
+    reg_val &= ~E1000_RXDCTL_QUEUE_ENABLE;
+    _if->pci_reg_write( E1000_RXDCTL(q_num), reg_val);
     return 0;
 }
 
-
 int CTRexExtendedDriverBase1G::configure_rx_filter_rules(CPhyEthIF * _if){
     if ( get_is_stateless() ) {
         return configure_rx_filter_rules_stateless(_if);
@@ -5274,6 +5314,8 @@ int CTRexExtendedDriverBase1G::configure_rx_filter_rules_statefull(CPhyEthIF * _
         num_rules = sizeof(ff_rules_v4)/sizeof(ff_rules_v4[0]);
     }
 
+    clear_rx_filter_rules(_if);
+
     uint8_t len = 24;
     for (rule_id=0; rule_id<num_rules; rule_id++ ) {
         /* clear rule all */
@@ -5326,12 +5368,7 @@ int CTRexExtendedDriverBase1G::configure_rx_filter_rules_stateless(CPhyEthIF * _
     uint32_t mask = 0;
     int rule_id;
 
-    // clear registers of rules. Just in case.
-    for (rule_id = 0 ; rule_id < 8; rule_id++) {
-        for (int i=0; i<0xff; i+=4) {
-            _if->pci_reg_write( (E1000_FHFT(rule_id)+i) , 0);
-        }
-    }
+    clear_rx_filter_rules(_if);
 
     rule_id = 0;
     mask |= 0x1 << rule_id;
@@ -5394,6 +5431,39 @@ int CTRexExtendedDriverBase1G::configure_rx_filter_rules_stateless(CPhyEthIF * _
     return (0);
 }
 
+// clear registers of rules
+void CTRexExtendedDriverBase1G::clear_rx_filter_rules(CPhyEthIF * _if) {
+    for (int rule_id = 0 ; rule_id < 8; rule_id++) {
+        for (int i = 0; i < 0xff; i += 4) {
+            _if->pci_reg_write( (E1000_FHFT(rule_id) + i) , 0);
+        }
+    }
+}
+
+int CTRexExtendedDriverBase1G::set_rcv_all(CPhyEthIF * _if, bool set_on) {
+    // byte 12 equals 08 - for IPv4 and ARP
+    //                86 - For IPv6
+    //                81 - For VLAN
+    //                88 - For MPLS
+    uint8_t eth_types[] = {0x08, 0x86, 0x81, 0x88};
+    uint32_t mask = 0;
+
+    clear_rx_filter_rules(_if);
+
+    if (! set_on)
+        return 0;
+
+    for (int rule_id = 0; rule_id < sizeof(eth_types); rule_id++) {
+        mask |= 0x1 << rule_id;
+        // Filter for byte 12 of packet
+        _if->pci_reg_write( (E1000_FHFT(rule_id)+(1*16) + 4) ,  0x000000 | eth_types[rule_id]);
+        _if->pci_reg_write( (E1000_FHFT(rule_id)+(1*16) + 8) , 0x10); /* MASK */
+        // FLEX_PRIO[[18:16] = 1, RQUEUE[10:8] = 1, len = 24
+        _if->pci_reg_write( (E1000_FHFT(rule_id) + 0xFC) , (1 << 16) | (1 << 8) | 24);
+    }
+
+    return 0;
+}
 
 void CTRexExtendedDriverBase1G::get_extended_stats(CPhyEthIF * _if,CPhyEthIFStats *stats){
 
@@ -5694,16 +5764,26 @@ void CTRexExtendedDriverBase40G::add_del_rules(enum rte_filter_op op, uint8_t po
         break;
     }
 
-    ret=rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_FDIR,
-                                op, (void*)&filter);
-
-    if (  ret !=0 ){
-        rte_exit(EXIT_FAILURE, "rte_eth_dev_filter_ctrl"
-                 "err=%d, port=%u \n",
+    ret = rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_FDIR, op, (void*)&filter);
+    if ( ret != 0 ) {
+        rte_exit(EXIT_FAILURE, "rte_eth_dev_filter_ctrl: err=%d, port=%u\n",
                  ret, port_id);
     }
 }
 
+int CTRexExtendedDriverBase40G::add_del_eth_type_rule(uint8_t port_id, enum rte_filter_op op, uint16_t eth_type) {
+    int ret;
+    struct rte_eth_ethertype_filter filter;
+
+    memset(&filter, 0, sizeof(filter));
+    filter.ether_type = eth_type;
+    filter.flags = 0;
+    filter.queue = MAIN_DPDK_RX_Q;
+    ret = rte_eth_dev_filter_ctrl(port_id, RTE_ETH_FILTER_ETHERTYPE, op, (void *) &filter);
+
+    return ret;
+}
+
 extern "C" int rte_eth_fdir_stats_reset(uint8_t port_id, uint32_t *stats, uint32_t start, uint32_t len);
 
 // type - rule type. Currently we only support rules in IP ID.
@@ -5748,7 +5828,7 @@ int CTRexExtendedDriverBase40G::add_del_rx_flow_stat_rule(uint8_t port_id, enum
     return 0;
 }
 
-int CTRexExtendedDriverBase40G::configure_rx_filter_rules_statfull(CPhyEthIF * _if) {
+int CTRexExtendedDriverBase40G::configure_rx_filter_rules_statefull(CPhyEthIF * _if) {
     uint32_t port_id = _if->get_port_id();
     uint16_t hops = get_rx_check_hops();
     int i;
@@ -5772,25 +5852,31 @@ const uint32_t FDIR_TEMP_HW_ID = 511;
 const uint32_t FDIR_PAYLOAD_RULES_HW_ID = 510;
 extern const uint32_t FLOW_STAT_PAYLOAD_IP_ID;
 int CTRexExtendedDriverBase40G::configure_rx_filter_rules(CPhyEthIF * _if) {
+    uint32_t port_id = _if->get_port_id();
+
+    set_rcv_all(_if, false);
+
     if (get_is_stateless()) {
-        uint32_t port_id = _if->get_port_id();
+        i40e_trex_fdir_reg_init(port_id, I40E_TREX_INIT_STL);
+
         add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_UDP, 0
                       , FLOW_STAT_PAYLOAD_IP_ID, 0, MAIN_DPDK_RX_Q, FDIR_PAYLOAD_RULES_HW_ID);
         add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_TCP, 0
                       , FLOW_STAT_PAYLOAD_IP_ID, 0, MAIN_DPDK_RX_Q, FDIR_PAYLOAD_RULES_HW_ID);
         add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_OTHER, 0
                       , FLOW_STAT_PAYLOAD_IP_ID, IPPROTO_ICMP, MAIN_DPDK_RX_Q, FDIR_PAYLOAD_RULES_HW_ID);
-        rte_eth_fdir_stats_reset(_if->get_port_id(), NULL, FDIR_TEMP_HW_ID, 1);
-
         add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV6_UDP, 0
                       , FLOW_STAT_PAYLOAD_IP_ID, 0, MAIN_DPDK_RX_Q, 0);
         add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV6_TCP, 0
                       , FLOW_STAT_PAYLOAD_IP_ID, 0, MAIN_DPDK_RX_Q, 0);
         add_del_rules(RTE_ETH_FILTER_ADD, port_id, RTE_ETH_FLOW_NONFRAG_IPV6_OTHER, 0
                       , FLOW_STAT_PAYLOAD_IP_ID, 0, MAIN_DPDK_RX_Q, 0);
+
+        rte_eth_fdir_stats_reset(_if->get_port_id(), NULL, FDIR_TEMP_HW_ID, 1);
         return 0; // Other rules are configured dynamically in stateless
     } else {
-        return configure_rx_filter_rules_statfull(_if);
+        i40e_trex_fdir_reg_init(port_id, I40E_TREX_INIT_STF);
+        return configure_rx_filter_rules_statefull(_if);
     }
 }
 
@@ -5927,6 +6013,25 @@ CFlowStatParser *CTRexExtendedDriverBase40G::get_flow_stat_parser() {
     return parser;
 }
 
+int CTRexExtendedDriverBase40G::set_rcv_all(CPhyEthIF * _if, bool set_on) {
+    uint32_t port_id = _if->get_port_id();
+    enum rte_filter_op op = set_on ? RTE_ETH_FILTER_ADD : RTE_ETH_FILTER_DELETE;
+
+    add_del_eth_type_rule(port_id, op, EthernetHeader::Protocol::ARP);
+
+    if (set_on) {
+        i40e_trex_fdir_reg_init(port_id, I40E_TREX_INIT_RCV_ALL);
+        // In order to receive packets, we also need to configure rules for each type.
+        add_del_rules(op, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_UDP, 10, 0, 0, MAIN_DPDK_RX_Q, 0);
+        add_del_rules(op, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_TCP, 10, 0, 0, MAIN_DPDK_RX_Q, 0);
+        add_del_rules(op, port_id, RTE_ETH_FLOW_NONFRAG_IPV4_OTHER, 10, 0, 0, MAIN_DPDK_RX_Q, 0);
+        add_del_rules(op, port_id, RTE_ETH_FLOW_NONFRAG_IPV6_UDP, 10, 0, 0, MAIN_DPDK_RX_Q, 0);
+        add_del_rules(op, port_id, RTE_ETH_FLOW_NONFRAG_IPV6_TCP, 10, 0, 0, MAIN_DPDK_RX_Q, 0);
+        add_del_rules(op, port_id, RTE_ETH_FLOW_NONFRAG_IPV6_OTHER, 10, 0, 0, MAIN_DPDK_RX_Q, 0);
+    }
+    return 0;
+}
+
 /////////////////////////////////////////////////////////////////////
 
 
@@ -5952,7 +6057,7 @@ void CTRexExtendedDriverBase1GVm::clear_extended_stats(CPhyEthIF * _if){
 
 }
 
-int CTRexExtendedDriverBase1GVm::configure_drop_queue(CPhyEthIF * _if){
+int CTRexExtendedDriverBase1GVm::stop_queue(CPhyEthIF * _if, uint16_t q_num) {
     return (0);
 }
 
@@ -6239,4 +6344,3 @@ CFlowStatParser *TrexDpdkPlatformApi::get_flow_stat_parser() const {
 void TrexDpdkPlatformApi::mark_for_shutdown() const {
     g_trex.mark_for_shutdown(CGlobalTRex::SHUTDOWN_RPC_REQ);
 }
-
index 3984e7e..c12732e 100644 (file)
@@ -44,6 +44,7 @@ class TrexException : public std::runtime_error
         T_FLOW_STAT_UNSUPP_PKT_FORMAT,
         T_FLOW_STAT_BAD_RULE_TYPE,
         T_FLOW_STAT_BAD_RULE_TYPE_FOR_IF,
+        T_FLOW_STAT_BAD_RULE_TYPE_FOR_MODE,
         T_FLOW_STAT_FAILED_FIND_L3,
         T_FLOW_STAT_FAILED_FIND_L4,
         T_FLOW_STAT_PAYLOAD_TOO_SHORT,
index 577f599..e61fb44 100644 (file)
@@ -72,6 +72,8 @@ void CCPortLatencyStl::reset() {
 }
 
 void CRxCoreStateless::create(const CRxSlCfg &cfg) {
+    m_rcv_all = false;
+    m_capture = false;
     m_max_ports = cfg.m_max_ports;
 
     CMessagingManager * cp_rx = CMsgIns::Ins()->getCpRx();
@@ -190,13 +192,12 @@ void CRxCoreStateless::start() {
 void CRxCoreStateless::handle_rx_pkt(CLatencyManagerPerPortStl *lp, rte_mbuf_t *m) {
     CFlowStatParser parser;
 
-    if (parser.parse(rte_pktmbuf_mtod(m, uint8_t *), m->pkt_len) == 0) {
+    if (m_rcv_all || parser.parse(rte_pktmbuf_mtod(m, uint8_t *), m->pkt_len) == 0) {
         uint32_t ip_id;
-        if (parser.get_ip_id(ip_id) == 0) {
-            if (is_flow_stat_id(ip_id)) {
+        if (m_rcv_all || (parser.get_ip_id(ip_id) == 0)) {
+            if (m_rcv_all || is_flow_stat_id(ip_id)) {
                 uint16_t hw_id;
-
-                if (is_flow_stat_payload_id(ip_id)) {
+                if (m_rcv_all || is_flow_stat_payload_id(ip_id)) {
                     bool good_packet = true;
                     uint8_t *p = rte_pktmbuf_mtod(m, uint8_t*);
                     struct flow_stat_payload_header *fsp_head = (struct flow_stat_payload_header *)
@@ -206,7 +207,8 @@ void CRxCoreStateless::handle_rx_pkt(CLatencyManagerPerPortStl *lp, rte_mbuf_t *
 
                     if (unlikely(fsp_head->magic != FLOW_STAT_PAYLOAD_MAGIC) || hw_id >= MAX_FLOW_STATS_PAYLOAD) {
                         good_packet = false;
-                        m_err_cntrs.m_bad_header++;
+                        if (!m_rcv_all)
+                            m_err_cntrs.m_bad_header++;
                     } else {
                         curr_rfc2544 = &m_rfc2544[hw_id];
 
@@ -291,6 +293,10 @@ void CRxCoreStateless::handle_rx_pkt(CLatencyManagerPerPortStl *lp, rte_mbuf_t *
     }
 }
 
+void CRxCoreStateless::capture_pkt(rte_mbuf_t *m) {
+
+}
+
 // In VM setup, handle packets coming as messages from DP cores.
 void CRxCoreStateless::handle_rx_queue_msgs(uint8_t thread_id, CNodeRing * r) {
     while ( true ) {
@@ -314,6 +320,8 @@ void CRxCoreStateless::handle_rx_queue_msgs(uint8_t thread_id, CNodeRing * r) {
             assert( rx_port_index < m_max_ports );
             lp = &m_ports[rx_port_index];
             handle_rx_pkt(lp, (rte_mbuf_t *)l_msg->m_pkt);
+            if (m_capture)
+                capture_pkt((rte_mbuf_t *)l_msg->m_pkt);
             rte_pktmbuf_free((rte_mbuf_t *)l_msg->m_pkt);
             break;
         default:
index e86e0ee..39af819 100644 (file)
@@ -147,6 +147,7 @@ class CRxCoreStateless {
     void tickle();
     void idle_state_loop();
     void handle_rx_pkt(CLatencyManagerPerPortStl * lp, rte_mbuf_t * m);
+    void capture_pkt(rte_mbuf_t *m);
     void handle_rx_queue_msgs(uint8_t thread_id, CNodeRing * r);
     void flush_rx();
     int try_rx();
@@ -156,11 +157,10 @@ class CRxCoreStateless {
     uint16_t get_hw_id(uint16_t id);
 
  private:
-
     TrexMonitor     m_monitor;
-
     uint32_t m_max_ports;
-    bool m_has_streams;
+    bool m_capture;
+    bool m_rcv_all;
     CLatencyManagerPerPortStl m_ports[TREX_MAX_PORTS];
     state_e   m_state;
     CNodeRing *m_ring_from_cp;
index f4ac3a8..49e8e7b 100644 (file)
@@ -29,6 +29,8 @@ enum {
     D_PKT_TYPE_9k_UDP = 4,
     D_PKT_TYPE_IPV6 = 60,
     D_PKT_TYPE_HW_VERIFY = 100,
+    D_PKT_TYPE_HW_VERIFY_RCV_ALL = 101,
+    D_PKT_TYPE_HW_TOGGLE_TEST = 102,
 };
 
 enum {