summaryrefslogtreecommitdiffstats
path: root/src/stateless
diff options
context:
space:
mode:
Diffstat (limited to 'src/stateless')
-rw-r--r--src/stateless/cp/trex_api_class.h110
-rw-r--r--src/stateless/cp/trex_exception.h41
-rw-r--r--src/stateless/cp/trex_stateless.cpp3
-rw-r--r--src/stateless/cp/trex_stateless.h39
-rw-r--r--src/stateless/cp/trex_stateless_port.cpp40
-rw-r--r--src/stateless/cp/trex_stateless_port.h12
-rw-r--r--src/stateless/cp/trex_stream.cpp9
-rw-r--r--src/stateless/cp/trex_streams_compiler.cpp6
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.cpp1
-rw-r--r--src/stateless/rx/trex_stateless_rx_core.cpp43
-rw-r--r--src/stateless/rx/trex_stateless_rx_core.h8
11 files changed, 262 insertions, 50 deletions
diff --git a/src/stateless/cp/trex_api_class.h b/src/stateless/cp/trex_api_class.h
new file mode 100644
index 00000000..78933d23
--- /dev/null
+++ b/src/stateless/cp/trex_api_class.h
@@ -0,0 +1,110 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 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 __TREX_API_CLASS_H__
+#define __TREX_API_CLASS_H__
+
+#include <assert.h>
+
+#include "common/basic_utils.h"
+#include "trex_exception.h"
+
+/**
+ * API exception
+ *
+ * @author imarom (03-Apr-16)
+ */
+class TrexAPIException : public TrexException {
+public:
+ TrexAPIException(const std::string &what) : TrexException(what) {
+ }
+};
+
+/**
+ * define an API class
+ *
+ * @author imarom (03-Apr-16)
+ */
+class APIClass {
+public:
+
+ enum type_e {
+ API_CLASS_TYPE_CORE = 0,
+ API_CLASS_TYPE_MAX,
+
+ API_CLASS_TYPE_NO_API
+ };
+
+ static const char * type_to_name(type_e type) {
+ switch (type) {
+ case API_CLASS_TYPE_CORE:
+ return "core";
+ default:
+ assert(0);
+ }
+ }
+
+ APIClass() {
+ /* invalid */
+ m_type = API_CLASS_TYPE_MAX;
+ }
+
+ void init(type_e type, int major, int minor) {
+ m_type = type;
+ m_major = major;
+ m_minor = minor;
+
+ unsigned int seed = time(NULL);
+ m_handler = utl_generate_random_str(seed, 8);
+ }
+
+ std::string & verify_api(int major, int minor) {
+ std::stringstream ss;
+ ss << "API type '" << type_to_name(m_type) << "': ";
+
+ assert(m_type < API_CLASS_TYPE_MAX);
+
+ /* for now a simple major check */
+ if (major < m_major) {
+ ss << "server has a major newer API version - server: '" << m_major << "', client: '" << major << "'";
+ throw TrexAPIException(ss.str());
+ }
+
+ if (major > m_major) {
+ ss << "server has an older API version - server: '" << m_major << "', client: '" << major << "'";
+ throw TrexAPIException(ss.str());
+ }
+
+ return get_api_handler();
+ }
+
+ std::string & get_api_handler() {
+ return m_handler;
+ }
+
+private:
+ type_e m_type;
+ int m_major;
+ int m_minor;
+ std::string m_handler;
+
+};
+
+#endif /* __TREX_API_CLASS_H__ */
diff --git a/src/stateless/cp/trex_exception.h b/src/stateless/cp/trex_exception.h
new file mode 100644
index 00000000..b9e20761
--- /dev/null
+++ b/src/stateless/cp/trex_exception.h
@@ -0,0 +1,41 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 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 __TREX_EXCEPTION_H__
+#define __TREX_EXCEPTION_H__
+
+#include <stdexcept>
+#include <string>
+
+/**
+ * generic exception for errors
+ * TODO: move this to a better place
+ */
+class TrexException : public std::runtime_error
+{
+public:
+ TrexException() : std::runtime_error("") {
+
+ }
+ TrexException(const std::string &what) : std::runtime_error(what) {
+ }
+};
+
+#endif /* __TREX_EXCEPTION_H__ */
diff --git a/src/stateless/cp/trex_stateless.cpp b/src/stateless/cp/trex_stateless.cpp
index 9df57a50..f6f81b96 100644
--- a/src/stateless/cp/trex_stateless.cpp
+++ b/src/stateless/cp/trex_stateless.cpp
@@ -53,6 +53,8 @@ TrexStateless::TrexStateless(const TrexStatelessCfg &cfg) {
m_platform_api = cfg.m_platform_api;
m_publisher = cfg.m_publisher;
+ /* API core version */
+ m_api_classes[APIClass::API_CLASS_TYPE_CORE].init(APIClass::API_CLASS_TYPE_CORE, 1, 0);
}
/**
@@ -175,3 +177,4 @@ TrexStateless::generate_publish_snapshot(std::string &snapshot) {
snapshot = writer.write(root);
}
+
diff --git a/src/stateless/cp/trex_stateless.h b/src/stateless/cp/trex_stateless.h
index 6e5e0c44..b506da61 100644
--- a/src/stateless/cp/trex_stateless.h
+++ b/src/stateless/cp/trex_stateless.h
@@ -27,27 +27,18 @@ limitations under the License.
#include <mutex>
-#include <trex_stream.h>
-#include <trex_stateless_port.h>
-#include <trex_rpc_server_api.h>
-#include <publisher/trex_publisher.h>
+#include "trex_stream.h"
+#include "trex_stateless_port.h"
+#include "trex_rpc_server_api.h"
-#include <flow_stat.h>
-#include <internal_api/trex_platform_api.h>
+#include "publisher/trex_publisher.h"
+#include "internal_api/trex_platform_api.h"
-/**
- * generic exception for errors
- * TODO: move this to a better place
- */
-class TrexException : public std::runtime_error
-{
-public:
- TrexException() : std::runtime_error("") {
+#include "flow_stat.h"
- }
- TrexException(const std::string &what) : std::runtime_error(what) {
- }
-};
+
+#include "trex_exception.h"
+#include "trex_api_class.h"
class TrexStatelessPort;
@@ -81,6 +72,7 @@ public:
} m_stats;
};
+
/**
* config object for stateless object
*
@@ -167,6 +159,14 @@ public:
return m_rpc_server;
}
+ const std::string & verify_api(APIClass::type_e type, int major, int minor) {
+ return m_api_classes[type].verify_api(major, minor);
+ }
+
+ const std::string & get_api_handler(APIClass::type_e type) {
+ return m_api_classes[type].get_api_handler();
+ }
+
CFlowStatRuleMgr m_rx_flow_stat;
protected:
@@ -187,6 +187,8 @@ protected:
TrexPublisher *m_publisher;
+ /* API */
+ APIClass m_api_classes[APIClass::API_CLASS_TYPE_MAX];
};
/**
@@ -197,6 +199,7 @@ protected:
* @return TrexStateless&
*/
TrexStateless * get_stateless_obj();
+CRxCoreStateless * get_rx_sl_core_obj();
#endif /* __TREX_STATELESS_H__ */
diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp
index 90589d7a..2239f3f6 100644
--- a/src/stateless/cp/trex_stateless_port.cpp
+++ b/src/stateless/cp/trex_stateless_port.cpp
@@ -272,6 +272,22 @@ TrexStatelessPort::stop_traffic(void) {
}
/**
+ * remove all RX filters from port
+ *
+ * @author imarom (28-Mar-16)
+ */
+void
+TrexStatelessPort::remove_rx_filters(void) {
+ /* only valid when IDLE or with streams and not TXing */
+ verify_state(PORT_STATE_STREAMS);
+
+ for (auto entry : m_stream_table) {
+ get_stateless_obj()->m_rx_flow_stat.stop_stream(entry.second);
+ }
+
+}
+
+/**
* when a port stops, perform various actions
*
*/
@@ -287,9 +303,6 @@ TrexStatelessPort::common_port_stop_actions(bool async) {
get_stateless_obj()->get_publisher()->publish_event(TrexPublisher::EVENT_PORT_STOPPED, data);
}
- for (auto entry : m_stream_table) {
- get_stateless_obj()->m_rx_flow_stat.stop_stream(entry.second);
- }
}
void
@@ -768,26 +781,5 @@ TrexPortOwner::TrexPortOwner() {
m_seed = time(NULL);
}
-/**
- * generate a random connection handler
- *
- */
-std::string
-TrexPortOwner::generate_handler() {
- std::stringstream ss;
-
- static const char alphanum[] =
- "0123456789"
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz";
-
- /* generate 8 bytes of random handler */
- for (int i = 0; i < 8; ++i) {
- ss << alphanum[rand_r(&m_seed) % (sizeof(alphanum) - 1)];
- }
-
- return (ss.str());
-}
-
const std::string TrexPortOwner::g_unowned_name = "<FREE>";
const std::string TrexPortOwner::g_unowned_handler = "";
diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h
index 7e1838d4..2167e735 100644
--- a/src/stateless/cp/trex_stateless_port.h
+++ b/src/stateless/cp/trex_stateless_port.h
@@ -21,6 +21,7 @@ limitations under the License.
#ifndef __TREX_STATELESS_PORT_H__
#define __TREX_STATELESS_PORT_H__
+#include "common/basic_utils.h"
#include "internal_api/trex_platform_api.h"
#include "trex_dp_port_events.h"
#include "trex_stream.h"
@@ -65,7 +66,7 @@ public:
m_owner_name = owner_name;
/* internal data */
- m_handler = generate_handler();
+ m_handler = utl_generate_random_str(m_seed, 8);
m_is_free = false;
}
@@ -83,7 +84,6 @@ public:
private:
- std::string generate_handler();
/* is this port owned by someone ? */
bool m_is_free;
@@ -178,6 +178,14 @@ public:
void stop_traffic(void);
/**
+ * remove all RX filters
+ * valid only when port is stopped
+ *
+ * @author imarom (28-Mar-16)
+ */
+ void remove_rx_filters(void);
+
+ /**
* pause traffic
* throws TrexException in case of an error
*/
diff --git a/src/stateless/cp/trex_stream.cpp b/src/stateless/cp/trex_stream.cpp
index 9c7898a8..e3f0ba7c 100644
--- a/src/stateless/cp/trex_stream.cpp
+++ b/src/stateless/cp/trex_stream.cpp
@@ -106,6 +106,15 @@ void TrexStream::Dump(FILE *fd){
}
}
+ if (m_rx_check.m_enabled) {
+ fprintf(fd, " Flow stat enabled:\n");
+ fprintf(fd, " seq check %s latency check %s packet group id %d hw_id %d\n"
+ , m_rx_check.m_seq_enabled ? "enabled":"disabled"
+ , m_rx_check.m_latency ? "enabled":"disabled", m_rx_check.m_pg_id, m_rx_check.m_hw_id
+ );
+ } else {
+ fprintf(fd, " Flow stat disabled\n");
+ }
fprintf(fd," rate :\n\n");
fprintf(fd," pps : %f\n", m_rate.get_pps());
diff --git a/src/stateless/cp/trex_streams_compiler.cpp b/src/stateless/cp/trex_streams_compiler.cpp
index 563236c2..d6971d68 100644
--- a/src/stateless/cp/trex_streams_compiler.cpp
+++ b/src/stateless/cp/trex_streams_compiler.cpp
@@ -477,8 +477,10 @@ TrexStreamsCompiler::compile_stream(TrexStream *stream,
TrexStream *fixed_rx_flow_stat_stream = stream->clone(true);
- // not checking for errors. We assume that if add_stream succeeded, start_stream will too.
- get_stateless_obj()->m_rx_flow_stat.start_stream(fixed_rx_flow_stat_stream, fixed_rx_flow_stat_stream->m_rx_check.m_hw_id);
+ get_stateless_obj()->m_rx_flow_stat.start_stream(fixed_rx_flow_stat_stream);
+ // CFlowStatRuleMgr keeps state of the stream object. We duplicated the stream here (in order not
+ // change the packet kept in the stream). We want the state to be saved in the original stream.
+ get_stateless_obj()->m_rx_flow_stat.copy_state(fixed_rx_flow_stat_stream, stream);
/* can this stream be split to many cores ? */
if (!stream->is_splitable(dp_core_count)) {
diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp
index ba25f61d..f125a46a 100644
--- a/src/stateless/dp/trex_stateless_dp_core.cpp
+++ b/src/stateless/dp/trex_stateless_dp_core.cpp
@@ -399,6 +399,7 @@ TrexStatelessDpCore::idle_state_loop() {
int counter = 0;
while (m_state == STATE_IDLE) {
+ m_core->m_node_gen.m_v_if->flush_dp_rx_queue();
bool had_msg = periodic_check_for_cp_messages();
if (had_msg) {
counter = 0;
diff --git a/src/stateless/rx/trex_stateless_rx_core.cpp b/src/stateless/rx/trex_stateless_rx_core.cpp
index ab7c08d1..26f537f8 100644
--- a/src/stateless/rx/trex_stateless_rx_core.cpp
+++ b/src/stateless/rx/trex_stateless_rx_core.cpp
@@ -2,6 +2,7 @@
#include "bp_sim.h"
#include "flow_stat_parser.h"
#include "latency.h"
+#include "pal/linux/sanb_atomic.h"
#include "trex_stateless_messaging.h"
#include "trex_stateless_rx_core.h"
@@ -59,6 +60,8 @@ void CRxCoreStateless::idle_state_loop() {
if (had_msg) {
counter = 0;
continue;
+ } else {
+ flush_rx();
}
/* enter deep sleep only if enough time had passed */
@@ -72,8 +75,8 @@ void CRxCoreStateless::idle_state_loop() {
}
void CRxCoreStateless::start() {
- static int count = 0;
- static int i = 0;
+ int count = 0;
+ int i = 0;
bool do_try_rx_queue =CGlobalInfo::m_options.preview.get_vm_one_queue_enable() ? true : false;
while (true) {
@@ -91,7 +94,11 @@ void CRxCoreStateless::start() {
} else {
if (m_state == STATE_QUIT)
break;
+ count = 0;
+ i = 0;
+ set_working_msg_ack(false);
idle_state_loop();
+ set_working_msg_ack(true);
}
if (do_try_rx_queue) {
try_rx_queues();
@@ -101,7 +108,7 @@ void CRxCoreStateless::start() {
}
void CRxCoreStateless::handle_rx_pkt(CLatencyManagerPerPort *lp, rte_mbuf_t *m) {
- Cxl710Parser parser;
+ CFlowStatParser parser;
if (parser.parse(rte_pktmbuf_mtod(m, uint8_t *), m->pkt_len) == 0) {
uint16_t ip_id;
@@ -162,6 +169,30 @@ void CRxCoreStateless::try_rx_queues() {
}
}
+// exactly the same as try_rx, without the handle_rx_pkt
+// purpose is to flush rx queues when core is in idle state
+void CRxCoreStateless::flush_rx() {
+ rte_mbuf_t * rx_pkts[64];
+ int i, total_pkts = 0;
+ for (i = 0; i < m_max_ports; i++) {
+ CLatencyManagerPerPort * lp = &m_ports[i];
+ rte_mbuf_t * m;
+ m_cpu_dp_u.start_work();
+ /* try to read 64 packets clean up the queue */
+ uint16_t cnt_p = lp->m_io->rx_burst(rx_pkts, 64);
+ total_pkts += cnt_p;
+ if (cnt_p) {
+ int j;
+ for (j = 0; j < cnt_p; j++) {
+ m = rx_pkts[j];
+ rte_pktmbuf_free(m);
+ }
+ /* commit only if there was work to do ! */
+ m_cpu_dp_u.commit();
+ }/* if work */
+ }// all ports
+}
+
int CRxCoreStateless::try_rx() {
rte_mbuf_t * rx_pkts[64];
int i, total_pkts = 0;
@@ -211,6 +242,12 @@ int CRxCoreStateless::get_rx_stats(uint8_t port_id, rx_per_flow_t *rx_stats, int
return 0;
}
+void CRxCoreStateless::set_working_msg_ack(bool val) {
+ sanb_smp_memory_barrier();
+ m_ack_start_work_msg = val;
+ sanb_smp_memory_barrier();
+}
+
double CRxCoreStateless::get_cpu_util() {
m_cpu_cp_u.Update();
return m_cpu_cp_u.GetVal();
diff --git a/src/stateless/rx/trex_stateless_rx_core.h b/src/stateless/rx/trex_stateless_rx_core.h
index 5ab12f4e..b78256c2 100644
--- a/src/stateless/rx/trex_stateless_rx_core.h
+++ b/src/stateless/rx/trex_stateless_rx_core.h
@@ -54,6 +54,8 @@ class CRxCoreStateless {
void work() {m_state = STATE_WORKING;}
void idle() {m_state = STATE_IDLE;}
void quit() {m_state = STATE_QUIT;}
+ bool is_working() const {return (m_ack_start_work_msg == true);}
+ void set_working_msg_ack(bool val);
double get_cpu_util();
private:
@@ -62,6 +64,7 @@ class CRxCoreStateless {
void idle_state_loop();
void handle_rx_pkt(CLatencyManagerPerPort * lp, rte_mbuf_t * m);
void handle_rx_queue_msgs(uint8_t thread_id, CNodeRing * r);
+ void flush_rx();
int try_rx();
void try_rx_queues();
bool is_flow_stat_id(uint16_t id);
@@ -71,10 +74,13 @@ class CRxCoreStateless {
uint32_t m_max_ports;
bool m_has_streams;
CLatencyManagerPerPort m_ports[TREX_MAX_PORTS];
- state_e m_state; /* state of all ports */
+ state_e m_state;
CNodeRing *m_ring_from_cp;
CNodeRing *m_ring_to_cp;
CCpuUtlDp m_cpu_dp_u;
CCpuUtlCp m_cpu_cp_u;
+ // Used for acking "work" (go out of idle) messages from cp
+ volatile bool m_ack_start_work_msg __rte_cache_aligned;
+
};
#endif