added new files (capture) 22/5222/1
authorimarom <[email protected]>
Wed, 4 Jan 2017 07:38:19 +0000 (09:38 +0200)
committerimarom <[email protected]>
Wed, 4 Jan 2017 07:38:19 +0000 (09:38 +0200)
Signed-off-by: imarom <[email protected]>
src/stateless/rx/trex_stateless_capture.cpp [new file with mode: 0644]
src/stateless/rx/trex_stateless_capture.h [new file with mode: 0644]

diff --git a/src/stateless/rx/trex_stateless_capture.cpp b/src/stateless/rx/trex_stateless_capture.cpp
new file mode 100644 (file)
index 0000000..83bb2d3
--- /dev/null
@@ -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 (file)
index 0000000..f7cd451
--- /dev/null
@@ -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__ */
+