From d9e19ba46d441b8e208f223add5a612183e5157c Mon Sep 17 00:00:00 2001 From: imarom Date: Mon, 13 Feb 2017 08:43:39 +0200 Subject: TX feature - draft Signed-off-by: imarom --- .../trex_control_plane/stl/console/trex_capture.py | 2 +- .../stl/trex_stl_lib/trex_stl_client.py | 4 -- src/main_dpdk.cpp | 5 ++ src/stateless/rx/trex_stateless_capture.cpp | 38 +++---------- src/stateless/rx/trex_stateless_capture.h | 65 ++++++++++------------ 5 files changed, 43 insertions(+), 71 deletions(-) diff --git a/scripts/automation/trex_control_plane/stl/console/trex_capture.py b/scripts/automation/trex_control_plane/stl/console/trex_capture.py index b6943912..f3b7a3c5 100644 --- a/scripts/automation/trex_control_plane/stl/console/trex_capture.py +++ b/scripts/automation/trex_control_plane/stl/console/trex_capture.py @@ -31,7 +31,7 @@ class CaptureMonitorWriterStdout(CaptureMonitorWriter): # unicode arrows self.RX_ARROW = u'\u25c0\u2500\u2500' - self.TX_ARROW = u'\u25b6\u2500\u2500' + self.TX_ARROW = u'\u2500\u2500\u25b6' # decode issues with Python 2 if sys.version_info < (3,0): diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py index e8feebbd..a3e04ab6 100755 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py @@ -3271,10 +3271,6 @@ class STLClient(object): tx_ports = tx_ports if tx_ports is not None else [] rx_ports = rx_ports if rx_ports is not None else [] - # TODO: remove this when TX is implemented - if tx_ports: - raise STLError('TX port capturing is not yet implemented') - # check arguments tx_ports = self._validate_port_list(tx_ports, allow_empty = True) rx_ports = self._validate_port_list(rx_ports, allow_empty = True) diff --git a/src/main_dpdk.cpp b/src/main_dpdk.cpp index de825b34..f227b2d8 100644 --- a/src/main_dpdk.cpp +++ b/src/main_dpdk.cpp @@ -2310,6 +2310,9 @@ int CCoreEthIF::send_pkt(CCorePerPort * lp_port, uint16_t len = lp_port->m_len; lp_port->m_table[len]=m; len++; + + TrexStatelessCaptureMngr::getInstance().handle_pkt_tx(m, lp_port->m_port->get_port_id()); + /* enough pkts to be sent */ if (unlikely(len == MAX_PKT_BURST)) { send_burst(lp_port, MAX_PKT_BURST,lp_stats); @@ -2324,6 +2327,8 @@ int CCoreEthIF::send_pkt_lat(CCorePerPort *lp_port, rte_mbuf_t *m, CVirtualIFPer // We allow sending only from first core of each port. This is serious internal bug otherwise. assert(lp_port->m_tx_queue_id_lat != INVALID_Q_ID); + TrexStatelessCaptureMngr::getInstance().handle_pkt_tx(m, lp_port->m_port->get_port_id()); + int ret = lp_port->m_port->tx_burst(lp_port->m_tx_queue_id_lat, &m, 1); #ifdef DELAY_IF_NEEDED diff --git a/src/stateless/rx/trex_stateless_capture.cpp b/src/stateless/rx/trex_stateless_capture.cpp index bf7623d5..d9813cac 100644 --- a/src/stateless/rx/trex_stateless_capture.cpp +++ b/src/stateless/rx/trex_stateless_capture.cpp @@ -45,36 +45,18 @@ TrexStatelessCapture::~TrexStatelessCapture() { } void -TrexStatelessCapture::handle_pkt_tx(const TrexPkt *pkt) { +TrexStatelessCapture::handle_pkt(const rte_mbuf_t *m, int port, TrexPkt::origin_e origin) { if (m_state != STATE_ACTIVE) { return; } /* if not in filter - back off */ - if (!m_filter.in_filter(pkt)) { + if (!m_filter.in_x(port, origin)) { return; } - if (pkt->get_ts() < m_start_ts) { - return; - } - - m_pkt_buffer->push(pkt, ++m_pkt_index); -} - -void -TrexStatelessCapture::handle_pkt_rx(const rte_mbuf_t *m, int port) { - - if (m_state != STATE_ACTIVE) { - return; - } - - if (!m_filter.in_rx(port)) { - return; - } - - m_pkt_buffer->push(m, port, TrexPkt::ORIGIN_RX, ++m_pkt_index); + m_pkt_buffer->push(m, port, origin, ++m_pkt_index); } @@ -266,16 +248,11 @@ TrexStatelessCaptureMngr::reset() { } void -TrexStatelessCaptureMngr::handle_pkt_tx_slow_path(const TrexPkt *pkt) { - for (TrexStatelessCapture *capture : m_captures) { - capture->handle_pkt_tx(pkt); - } -} - -void -TrexStatelessCaptureMngr::handle_pkt_rx_slow_path(const rte_mbuf_t *m, int port) { +TrexStatelessCaptureMngr::handle_pkt_slow_path(const rte_mbuf_t *m, int port, TrexPkt::origin_e origin) { + std::unique_lock lock(m_lock); + for (TrexStatelessCapture *capture : m_captures) { - capture->handle_pkt_rx(m, port); + capture->handle_pkt(m, port, origin); } } @@ -290,3 +267,4 @@ TrexStatelessCaptureMngr::to_json() const { return lst; } +TrexStatelessCaptureMngr TrexStatelessCaptureMngr::g_instance; diff --git a/src/stateless/rx/trex_stateless_capture.h b/src/stateless/rx/trex_stateless_capture.h index e4a2e632..6288ac56 100644 --- a/src/stateless/rx/trex_stateless_capture.h +++ b/src/stateless/rx/trex_stateless_capture.h @@ -23,6 +23,7 @@ limitations under the License. #include #include +#include #include "trex_stateless_pkt.h" #include "trex_stateless_capture_rc.h" @@ -59,17 +60,12 @@ public: add_rx(port_id); } - bool in_filter(const TrexPkt *pkt) { - switch (pkt->get_origin()) { - case TrexPkt::ORIGIN_TX: - return in_tx(pkt->get_port()); - - case TrexPkt::ORIGIN_RX: - return in_rx(pkt->get_port()); - - default: - return false; - } + bool in_x(uint8_t port_id, TrexPkt::origin_e origin) { + return ( + ( (origin == TrexPkt::ORIGIN_RX) && (in_rx(port_id)) ) + || + ( (origin == TrexPkt::ORIGIN_TX) && (in_tx(port_id)) ) + ); } bool in_rx(uint8_t port_id) const { @@ -133,14 +129,9 @@ public: ~TrexStatelessCapture(); /** - * handles a packet from the TX side - */ - void handle_pkt_tx(const TrexPkt *pkt); - - /** - * handles a packet from the RX side + * handles a packet */ - void handle_pkt_rx(const rte_mbuf_t *m, int port); + void handle_pkt(const rte_mbuf_t *m, int port, TrexPkt::origin_e origin); uint64_t get_id() const { @@ -199,10 +190,9 @@ class TrexStatelessCaptureMngr { public: + static TrexStatelessCaptureMngr g_instance; static TrexStatelessCaptureMngr& getInstance() { - static TrexStatelessCaptureMngr instance; - - return instance; + return g_instance; } @@ -257,27 +247,27 @@ public: } /** - * handle packet from TX + * handle packet on TX side */ - void handle_pkt_tx(const TrexPkt *pkt) { - if (!m_global_filter.in_filter(pkt)) { - return; + inline void handle_pkt_tx(const rte_mbuf_t *m, int port) { + + /* fast bail out IF */ + if (unlikely(m_global_filter.in_tx(port))) { + handle_pkt_slow_path(m, port, TrexPkt::ORIGIN_TX); } - handle_pkt_tx_slow_path(pkt); } /** - * handle packet from RX + * handle packet on RX side */ - void handle_pkt_rx(const rte_mbuf_t *m, int port) { - /* fast path - check the global filter */ - if (!m_global_filter.in_rx(port)) { - return; + inline void handle_pkt_rx(const rte_mbuf_t *m, int port) { + + /* fast bail out IF */ + if (unlikely(m_global_filter.in_rx(port))) { + handle_pkt_slow_path(m, port, TrexPkt::ORIGIN_RX); } - /* slow path */ - handle_pkt_rx_slow_path(m, port); } Json::Value to_json() const; @@ -293,9 +283,8 @@ private: TrexStatelessCapture * lookup(capture_id_t capture_id); int lookup_index(capture_id_t capture_id); - void handle_pkt_rx_slow_path(const rte_mbuf_t *m, int port); - void handle_pkt_tx_slow_path(const TrexPkt *pkt); - + void handle_pkt_slow_path(const rte_mbuf_t *m, int port, TrexPkt::origin_e origin) __attribute__ ((noinline)); + void update_global_filter(); std::vector m_captures; @@ -305,7 +294,11 @@ private: /* a union of all the filters curently active */ CaptureFilter m_global_filter; + /* slow path lock*/ + std::mutex m_lock; + static const int MAX_CAPTURE_SIZE = 10; + }; #endif /* __TREX_STATELESS_CAPTURE_H__ */ -- cgit 1.2.3-korg