summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIdo Barnea <ibarnea@cisco.com>2016-09-08 12:04:59 +0300
committerIdo Barnea <ibarnea@cisco.com>2016-09-13 11:54:20 +0300
commit58f1ee52761a489322036f111793ddd8e85e197a (patch)
tree0381145a5b44e685c94a9723f6d75e3cfe924004
parent34a6b9050f9179e8000e54b0b3c07f054322c5a2 (diff)
APIs and functions in preparation for receive all mode. XL710/i350 mode toggling work.
-rwxr-xr-xlinux_dpdk/ws_main.py1
-rw-r--r--src/debug.cpp61
-rw-r--r--src/debug.h2
-rw-r--r--src/dpdk/drivers/net/i40e/i40e_ethdev.c64
-rw-r--r--src/dpdk_funcs.c94
-rw-r--r--src/dpdk_funcs.h29
-rw-r--r--src/flow_stat.cpp37
-rw-r--r--src/flow_stat.h7
-rw-r--r--src/flow_stat_parser.cpp11
-rw-r--r--src/flow_stat_parser.h11
-rw-r--r--src/main_dpdk.cpp190
-rw-r--r--src/stateless/cp/trex_exception.h1
-rw-r--r--src/stateless/rx/trex_stateless_rx_core.cpp20
-rw-r--r--src/stateless/rx/trex_stateless_rx_core.h6
-rw-r--r--src/test_pkt_gen.h2
15 files changed, 392 insertions, 144 deletions
diff --git a/linux_dpdk/ws_main.py b/linux_dpdk/ws_main.py
index f208fa9c..f895204c 100755
--- a/linux_dpdk/ws_main.py
+++ b/linux_dpdk/ws_main.py
@@ -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',
diff --git a/src/debug.cpp b/src/debug.cpp
index 3cb4e3cb..2e7eb5db 100644
--- a/src/debug.cpp
+++ b/src/debug.cpp
@@ -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)) {
diff --git a/src/debug.h b/src/debug.h
index 3ecc3604..d178e3af 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -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);
diff --git a/src/dpdk/drivers/net/i40e/i40e_ethdev.c b/src/dpdk/drivers/net/i40e/i40e_ethdev.c
index 778c1eca..ca1a4808 100644
--- a/src/dpdk/drivers/net/i40e/i40e_ethdev.c
+++ b/src/dpdk/drivers/net/i40e/i40e_ethdev.c
@@ -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
index 00000000..99d23276
--- /dev/null
+++ b/src/dpdk_funcs.c
@@ -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
index 00000000..2db905ff
--- /dev/null
+++ b/src/dpdk_funcs.h
@@ -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
diff --git a/src/flow_stat.cpp b/src/flow_stat.cpp
index 58ff65a4..84be590f 100644
--- a/src/flow_stat.cpp
+++ b/src/flow_stat.cpp
@@ -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;
diff --git a/src/flow_stat.h b/src/flow_stat.h
index dee1acc8..e0c995ab 100644
--- a/src/flow_stat.h
+++ b/src/flow_stat.h
@@ -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];
diff --git a/src/flow_stat_parser.cpp b/src/flow_stat_parser.cpp
index 2ab273a6..fd0fb80a 100644
--- a/src/flow_stat_parser.cpp
+++ b/src/flow_stat_parser.cpp
@@ -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;
diff --git a/src/flow_stat_parser.h b/src/flow_stat_parser.h
index 78bc1e6a..df70e4ec 100644
--- a/src/flow_stat_parser.h
+++ b/src/flow_stat_parser.h
@@ -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:
diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp
index 1e31f3df..8a92237d 100644
--- a/src/main_dpdk.cpp
+++ b/src/main_dpdk.cpp
@@ -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);
}
-
diff --git a/src/stateless/cp/trex_exception.h b/src/stateless/cp/trex_exception.h
index 3984e7e3..c12732ef 100644
--- a/src/stateless/cp/trex_exception.h
+++ b/src/stateless/cp/trex_exception.h
@@ -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,
diff --git a/src/stateless/rx/trex_stateless_rx_core.cpp b/src/stateless/rx/trex_stateless_rx_core.cpp
index 577f5992..e61fb448 100644
--- a/src/stateless/rx/trex_stateless_rx_core.cpp
+++ b/src/stateless/rx/trex_stateless_rx_core.cpp
@@ -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:
diff --git a/src/stateless/rx/trex_stateless_rx_core.h b/src/stateless/rx/trex_stateless_rx_core.h
index e86e0eea..39af8199 100644
--- a/src/stateless/rx/trex_stateless_rx_core.h
+++ b/src/stateless/rx/trex_stateless_rx_core.h
@@ -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;
diff --git a/src/test_pkt_gen.h b/src/test_pkt_gen.h
index f4ac3a83..49e8e7b0 100644
--- a/src/test_pkt_gen.h
+++ b/src/test_pkt_gen.h
@@ -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 {