summaryrefslogtreecommitdiffstats
path: root/src/flow_stat.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/flow_stat.cpp')
-rw-r--r--src/flow_stat.cpp74
1 files changed, 58 insertions, 16 deletions
diff --git a/src/flow_stat.cpp b/src/flow_stat.cpp
index 98b9494b..8c2f2566 100644
--- a/src/flow_stat.cpp
+++ b/src/flow_stat.cpp
@@ -227,7 +227,7 @@ CFlowStatUserIdMap::add_user_id(uint32_t user_id, uint8_t proto) {
<< std::endl;
#endif
- CFlowStatUserIdInfo *new_id = new CFlowStatUserIdInfo(proto);
+ CFlowStatUserIdInfo *new_id;
if (proto == PAYLOAD_RULE_PROTO) {
new_id = new CFlowStatUserIdInfoPayload(proto);
@@ -390,7 +390,8 @@ uint16_t CFlowStatUserIdMap::unmap(uint32_t user_id) {
/************** class CFlowStatHwIdMap ***************/
CFlowStatHwIdMap::CFlowStatHwIdMap() {
- m_map = NULL;
+ m_map = NULL; // must call create in order to work with the class
+ m_num_free = 0; // to make coverity happy, init this here too.
}
CFlowStatHwIdMap::~CFlowStatHwIdMap() {
@@ -466,10 +467,21 @@ CFlowStatRuleMgr::CFlowStatRuleMgr() {
m_hw_id_map_payload.create(MAX_FLOW_STATS_PAYLOAD);
memset(m_rx_cant_count_err, 0, sizeof(m_rx_cant_count_err));
memset(m_tx_cant_count_err, 0, sizeof(m_tx_cant_count_err));
+ m_num_ports = 0; // need to call create to init
}
CFlowStatRuleMgr::~CFlowStatRuleMgr() {
delete m_parser;
+#ifdef TREX_SIM
+ // In simulator, nobody handles the messages to RX, so need to free them to have clean valgrind run.
+ if (m_ring_to_rx) {
+ CGenNode *msg = NULL;
+ while (! m_ring_to_rx->isEmpty()) {
+ m_ring_to_rx->Dequeue(msg);
+ delete msg;
+ }
+ }
+#endif
}
void CFlowStatRuleMgr::create() {
@@ -480,7 +492,7 @@ void CFlowStatRuleMgr::create() {
m_api = tstateless->get_platform_api();
assert(m_api);
m_api->get_interface_stat_info(0, num_counters, cap);
- m_api->get_port_num(m_num_ports);
+ m_api->get_port_num(m_num_ports); // This initialize m_num_ports
for (uint8_t port = 0; port < m_num_ports; port++) {
assert(m_api->reset_hw_flow_stats(port) == 0);
}
@@ -537,7 +549,20 @@ void CFlowStatRuleMgr::init_stream(TrexStream * stream) {
stream->m_rx_check.m_hw_id = HW_ID_INIT;
}
+int CFlowStatRuleMgr::verify_stream(TrexStream * stream) {
+ return add_stream_internal(stream, false);
+}
+
int CFlowStatRuleMgr::add_stream(TrexStream * stream) {
+ return add_stream_internal(stream, true);
+}
+
+/*
+ * Helper function for adding/verifying streams
+ * stream - stream to act on
+ * do_action - if false, just verify. Do not change any state, or add to database.
+ */
+int CFlowStatRuleMgr::add_stream_internal(TrexStream * stream, bool do_action) {
#ifdef __DEBUG_FUNC_ENTRY__
std::cout << __METHOD_NAME__ << " user id:" << stream->m_rx_check.m_pg_id << std::endl;
stream_dump(stream);
@@ -570,7 +595,9 @@ int CFlowStatRuleMgr::add_stream(TrexStream * stream) {
}
// throws exception if there is error
- m_user_id_map.add_stream(stream->m_rx_check.m_pg_id, l4_proto);
+ if (do_action) {
+ m_user_id_map.add_stream(stream->m_rx_check.m_pg_id, l4_proto);
+ }
break;
case TrexPlatformApi::IF_STAT_PAYLOAD:
uint16_t payload_len;
@@ -582,14 +609,17 @@ int CFlowStatRuleMgr::add_stream(TrexStream * stream) {
+ " payload bytes for payload rules. Packet only has " + std::to_string(payload_len) + " bytes"
, TrexException::T_FLOW_STAT_PAYLOAD_TOO_SHORT);
}
- m_user_id_map.add_stream(stream->m_rx_check.m_pg_id, PAYLOAD_RULE_PROTO);
+ if (do_action) {
+ m_user_id_map.add_stream(stream->m_rx_check.m_pg_id, PAYLOAD_RULE_PROTO);
+ }
break;
default:
throw TrexFStatEx("Wrong rule_type", TrexException::T_FLOW_STAT_BAD_RULE_TYPE);
break;
}
-
- stream->m_rx_check.m_hw_id = HW_ID_FREE;
+ if (do_action) {
+ stream->m_rx_check.m_hw_id = HW_ID_FREE;
+ }
return 0;
}
@@ -754,10 +784,6 @@ int CFlowStatRuleMgr::start_stream(TrexStream * stream) {
m_parser->set_ip_id(IP_ID_RESERVE_BASE + hw_id);
stream->m_rx_check.m_hw_id = hw_id;
} else {
- struct flow_stat_payload_header *fsp_head = (struct flow_stat_payload_header *)
- (stream->m_pkt.binary + stream->m_pkt.len - sizeof(struct flow_stat_payload_header));
- fsp_head->hw_id = hw_id;
- fsp_head->magic = FLOW_STAT_PAYLOAD_MAGIC;
m_parser->set_ip_id(FLOW_STAT_PAYLOAD_IP_ID);
// for payload rules, we use the range right after ip id rules
stream->m_rx_check.m_hw_id = hw_id + MAX_FLOW_STATS;
@@ -770,6 +796,9 @@ int CFlowStatRuleMgr::start_stream(TrexStream * stream) {
if (m_num_started_streams == 0) {
send_start_stop_msg_to_rx(true); // First transmitting stream. Rx core should start reading packets;
+ //also good time to zero global counters
+ memset(m_rx_cant_count_err, 0, sizeof(m_rx_cant_count_err));
+ memset(m_tx_cant_count_err, 0, sizeof(m_tx_cant_count_err));
// wait to make sure that message is acknowledged. RX core might be in deep sleep mode, and we want to
// start transmitting packets only after it is working, otherwise, packets will get lost.
@@ -884,7 +913,7 @@ int CFlowStatRuleMgr::stop_stream(TrexStream * stream) {
m_num_started_streams--;
assert (m_num_started_streams >= 0);
if (m_num_started_streams == 0) {
- send_start_stop_msg_to_rx(false); // No more transmittig streams. Rx core shoulde get into idle loop.
+ send_start_stop_msg_to_rx(false); // No more transmittig streams. Rx core should get into idle loop.
}
return 0;
}
@@ -921,6 +950,7 @@ bool CFlowStatRuleMgr::dump_json(std::string & s_json, std::string & l_json, boo
tx_per_flow_t tx_stats[MAX_FLOW_STATS];
tx_per_flow_t tx_stats_payload[MAX_FLOW_STATS_PAYLOAD];
rfc2544_info_t rfc2544_info[MAX_FLOW_STATS_PAYLOAD];
+ CRxCoreErrCntrs rx_err_cntrs;
Json::FastWriter writer;
Json::Value s_root;
Json::Value l_root;
@@ -947,6 +977,7 @@ bool CFlowStatRuleMgr::dump_json(std::string & s_json, std::string & l_json, boo
}
m_api->get_rfc2544_info(rfc2544_info, 0, m_max_hw_id_payload, false);
+ m_api->get_rx_err_cntrs(&rx_err_cntrs);
// read hw counters, and update
for (uint8_t port = 0; port < m_num_ports; port++) {
@@ -1020,10 +1051,21 @@ bool CFlowStatRuleMgr::dump_json(std::string & s_json, std::string & l_json, boo
// general per port data
for (uint8_t port = 0; port < m_num_ports; port++) {
std::string str_port = static_cast<std::ostringstream*>( &(std::ostringstream() << int(port) ) )->str();
- if (m_rx_cant_count_err[port] != 0)
- s_data_section["port_data"][str_port]["rx_err"] = m_rx_cant_count_err[port];
- if (m_tx_cant_count_err[port] != 0)
- s_data_section["port_data"][str_port]["tx_err"] = m_tx_cant_count_err[port];
+ if ((m_rx_cant_count_err[port] != 0) || baseline)
+ s_data_section["global"]["rx_err"][str_port] = m_rx_cant_count_err[port];
+ if ((m_tx_cant_count_err[port] != 0) || baseline)
+ s_data_section["global"]["tx_err"][str_port] = m_tx_cant_count_err[port];
+ }
+
+ // payload rules rx errors
+ uint64_t tmp_cnt;
+ tmp_cnt = rx_err_cntrs.get_bad_header();
+ if (tmp_cnt || baseline) {
+ l_data_section["global"]["bad_hdr"] = Json::Value::UInt64(tmp_cnt);
+ }
+ tmp_cnt = rx_err_cntrs.get_old_flow();
+ if (tmp_cnt || baseline) {
+ l_data_section["global"]["old_flow"] = Json::Value::UInt64(tmp_cnt);
}
flow_stat_user_id_map_it_t it;