summaryrefslogtreecommitdiffstats
path: root/src/stateless
diff options
context:
space:
mode:
Diffstat (limited to 'src/stateless')
-rw-r--r--src/stateless/rx/trex_stateless_capture.cpp112
-rw-r--r--src/stateless/rx/trex_stateless_capture.h181
2 files changed, 293 insertions, 0 deletions
diff --git a/src/stateless/rx/trex_stateless_capture.cpp b/src/stateless/rx/trex_stateless_capture.cpp
new file mode 100644
index 00000000..83bb2d38
--- /dev/null
+++ b/src/stateless/rx/trex_stateless_capture.cpp
@@ -0,0 +1,112 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-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 "trex_stateless_capture.h"
+#include "trex_exception.h"
+
+TrexStatelessCapture::TrexStatelessCapture(capture_id_t id, uint64_t limit, const CaptureFilter &filter) {
+ m_id = id;
+ m_pkt_buffer = new TrexPktBuffer(limit, TrexPktBuffer::MODE_DROP_TAIL);
+ m_filter = filter;
+}
+
+TrexStatelessCapture::~TrexStatelessCapture() {
+ if (m_pkt_buffer) {
+ delete m_pkt_buffer;
+ }
+}
+
+void
+TrexStatelessCapture::handle_pkt_tx(const TrexPkt *pkt) {
+
+ /* if not in filter - back off */
+ if (!m_filter.in_filter(pkt)) {
+ return;
+ }
+
+ m_pkt_buffer->push(pkt);
+}
+
+void
+TrexStatelessCapture::handle_pkt_rx(const rte_mbuf_t *m, int port) {
+ if (!m_filter.in_rx(port)) {
+ return;
+ }
+
+ m_pkt_buffer->push(m);
+}
+
+capture_id_t
+TrexStatelessCaptureMngr::add(uint64_t limit, const CaptureFilter &filter) {
+
+ if (m_captures.size() > MAX_CAPTURE_SIZE) {
+ throw TrexException(TrexException::T_CAPTURE_MAX_INSTANCES);
+ }
+
+
+ int new_id = m_id_counter++;
+ TrexStatelessCapture *new_buffer = new TrexStatelessCapture(new_id, limit, filter);
+ m_captures.push_back(new_buffer);
+
+ return new_id;
+}
+
+void
+TrexStatelessCaptureMngr::remove(capture_id_t id) {
+
+ int index = -1;
+ for (int i = 0; i < m_captures.size(); i++) {
+ if (m_captures[i]->get_id() == id) {
+ index = i;
+ break;
+ }
+ }
+
+ /* does not exist */
+ if (index == -1) {
+ throw TrexException(TrexException::T_CAPTURE_INVALID_ID);
+ }
+
+ TrexStatelessCapture *capture = m_captures[index];
+ m_captures.erase(m_captures.begin() + index);
+ delete capture;
+}
+
+void
+TrexStatelessCaptureMngr::reset() {
+ while (m_captures.size() > 0) {
+ remove(m_captures[0]->get_id());
+ }
+}
+
+void
+TrexStatelessCaptureMngr::handle_pkt_tx(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) {
+ for (TrexStatelessCapture *capture : m_captures) {
+ capture->handle_pkt_rx(m, port);
+ }
+}
+
diff --git a/src/stateless/rx/trex_stateless_capture.h b/src/stateless/rx/trex_stateless_capture.h
new file mode 100644
index 00000000..f7cd451f
--- /dev/null
+++ b/src/stateless/rx/trex_stateless_capture.h
@@ -0,0 +1,181 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-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 __TREX_STATELESS_CAPTURE_H__
+#define __TREX_STATELESS_CAPTURE_H__
+
+#include <stdint.h>
+#include "trex_stateless_pkt.h"
+
+/**
+ * capture filter
+ * specify which ports to capture and if TX/RX or both
+ */
+class CaptureFilter {
+public:
+ CaptureFilter() {
+ tx_active = 0;
+ rx_active = 0;
+ }
+
+ void add_tx(uint8_t port_id) {
+ tx_active |= (1LL << port_id);
+ }
+
+ void add_rx(uint8_t port_id) {
+ rx_active |= (1LL << port_id);
+ }
+
+ void add(uint8_t port_id) {
+ add_tx(port_id);
+ 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_rx(uint8_t port_id) const {
+ uint64_t bit = (1LL << port_id);
+ return ((rx_active & bit) == bit);
+ }
+
+ bool in_tx(uint8_t port_id) const {
+ uint64_t bit = (1LL << port_id);
+ return ((tx_active & bit) == bit);
+ }
+
+private:
+
+ uint64_t tx_active;
+ uint64_t rx_active;
+};
+
+typedef uint64_t capture_id_t;
+
+class TrexStatelessCapture {
+public:
+
+ TrexStatelessCapture(capture_id_t id, uint64_t limit, const CaptureFilter &filter);
+
+ void handle_pkt_tx(const TrexPkt *pkt);
+ void handle_pkt_rx(const rte_mbuf_t *m, int port);
+
+ ~TrexStatelessCapture();
+
+ uint64_t get_id() const {
+ return m_id;
+ }
+
+private:
+ TrexPktBuffer *m_pkt_buffer;
+ CaptureFilter m_filter;
+ uint64_t m_id;
+};
+
+class TrexStatelessCaptureMngr {
+
+public:
+
+ static TrexStatelessCaptureMngr& getInstance() {
+ static TrexStatelessCaptureMngr instance;
+
+ return instance;
+ }
+
+
+ ~TrexStatelessCaptureMngr() {
+ reset();
+ }
+
+ /**
+ * adds a capture buffer
+ * returns ID
+ */
+ capture_id_t add(uint64_t limit, const CaptureFilter &filter);
+
+
+ /**
+ * stops capture mode
+ */
+ void remove(capture_id_t id);
+
+ /**
+ * removes all captures
+ *
+ */
+ void reset();
+
+ /**
+ * return true if any filter is active
+ *
+ * @author imarom (1/3/2017)
+ *
+ * @return bool
+ */
+ bool is_active() const {
+ return (m_captures.size() != 0);
+ }
+
+ /**
+ * handle packet from TX
+ */
+ void handle_pkt_tx(const TrexPkt *pkt);
+
+ /**
+ * handle packet from RX
+ */
+ void handle_pkt_rx(const rte_mbuf_t *m, int port) {
+ /* fast path */
+ if (!is_active()) {
+ return;
+ }
+
+ /* slow path */
+ handle_pkt_rx_slow_path(m, port);
+ }
+
+private:
+
+ TrexStatelessCaptureMngr() {
+ /* init this to 1 */
+ m_id_counter = 1;
+ }
+
+ void handle_pkt_rx_slow_path(const rte_mbuf_t *m, int port);
+
+ std::vector<TrexStatelessCapture *> m_captures;
+
+ capture_id_t m_id_counter;
+
+ static const int MAX_CAPTURE_SIZE = 10;
+};
+
+#endif /* __TREX_STATELESS_CAPTURE_H__ */
+