summaryrefslogtreecommitdiffstats
path: root/src/stateless/dp/trex_stateless_dp_core.cpp
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2017-02-15 18:26:41 +0200
committerimarom <imarom@cisco.com>2017-02-16 15:20:23 +0200
commit17d58dba43eeae9f1519248c1fd62e9e4d2dc302 (patch)
treeffbadffb292b505aea5dad6e524e5cef4bf66154 /src/stateless/dp/trex_stateless_dp_core.cpp
parentd9e19ba46d441b8e208f223add5a612183e5157c (diff)
TX packet capture - zero impact on fast path
(using wrapper when service mode is active) Signed-off-by: imarom <imarom@cisco.com>
Diffstat (limited to 'src/stateless/dp/trex_stateless_dp_core.cpp')
-rw-r--r--src/stateless/dp/trex_stateless_dp_core.cpp86
1 files changed, 86 insertions, 0 deletions
diff --git a/src/stateless/dp/trex_stateless_dp_core.cpp b/src/stateless/dp/trex_stateless_dp_core.cpp
index d8563e95..56184aeb 100644
--- a/src/stateless/dp/trex_stateless_dp_core.cpp
+++ b/src/stateless/dp/trex_stateless_dp_core.cpp
@@ -28,6 +28,53 @@ limitations under the License.
#include "mbuf.h"
+class DPCoreWrapper : public CVirtualIF {
+public:
+
+ DPCoreWrapper() {
+ m_wrapped = nullptr;
+ }
+
+ void set_wrapped_object(CVirtualIF *wrapped) {
+ m_wrapped = wrapped;
+ }
+
+ CVirtualIF *get_wrapped_object() const {
+ return m_wrapped;
+ }
+
+ virtual int close_file(void) {
+ return m_wrapped->close_file();
+ }
+
+ virtual int flush_tx_queue(void) {
+ return m_wrapped->flush_tx_queue();
+ }
+
+ virtual int open_file(std::string file_name) {
+ return m_wrapped->open_file(file_name);
+ }
+
+ /* move to service mode */
+ virtual int send_node(CGenNode *node) {
+ return m_wrapped->send_node_service_mode(node);
+ }
+
+ virtual int update_mac_addr_from_global_cfg(pkt_dir_t dir, uint8_t *p) {
+ return m_wrapped->update_mac_addr_from_global_cfg(dir, p);
+ }
+
+ virtual pkt_dir_t port_id_to_dir(uint8_t port_id) {
+ return m_wrapped->port_id_to_dir(port_id);
+ }
+
+ virtual void send_one_pkt(pkt_dir_t dir, rte_mbuf_t *m) {
+ m_wrapped->send_one_pkt(dir, m);
+ }
+
+private:
+ CVirtualIF *m_wrapped;
+};
void CGenNodeStateless::cache_mbuf_array_init(){
@@ -592,6 +639,18 @@ void TrexStatelessDpPerPort::create(CFlowGenListPerThread * core){
}
+TrexStatelessDpCore::TrexStatelessDpCore() {
+ m_thread_id = 0;
+ m_core = NULL;
+ m_duration = -1;
+ m_is_service_mode = NULL;
+ m_wrapper = new DPCoreWrapper();
+}
+
+TrexStatelessDpCore::~TrexStatelessDpCore() {
+ delete m_wrapper;
+}
+
void
TrexStatelessDpCore::create(uint8_t thread_id, CFlowGenListPerThread *core) {
@@ -717,6 +776,7 @@ void TrexStatelessDpCore::quit_main_loop(){
*/
void
TrexStatelessDpCore::start_scheduler() {
+
/* creates a maintenace job using the scheduler */
CGenNode * node_sync = m_core->create_node() ;
node_sync->m_type = CGenNode::FLOW_SYNC;
@@ -1255,6 +1315,32 @@ TrexStatelessDpCore::barrier(uint8_t port_id, int event_id) {
ring->Enqueue((CGenNode *)event_msg);
}
+void
+TrexStatelessDpCore::set_service_mode(uint8_t port_id, bool enabled) {
+ /* ignore the same message */
+ if (enabled == m_is_service_mode) {
+ return;
+ }
+
+ if (enabled) {
+ /* sanity */
+ assert(m_core->m_node_gen.m_v_if != m_wrapper);
+
+ /* set the wrapper object and make the VIF point to it */
+ m_wrapper->set_wrapped_object(m_core->m_node_gen.m_v_if);
+ m_core->m_node_gen.m_v_if = m_wrapper;
+ m_is_service_mode = true;
+
+ } else {
+ /* sanity */
+ assert(m_core->m_node_gen.m_v_if == m_wrapper);
+
+ /* restore the wrapped object and make the VIF point to it */
+ m_core->m_node_gen.m_v_if = m_wrapper->get_wrapped_object();
+ m_is_service_mode = false;
+ }
+}
+
/**
* PCAP node