summaryrefslogtreecommitdiffstats
path: root/src/stateless/rx/trex_stateless_capture.cpp
blob: 4ed126cc8e89f437f9e05f122b2a39226ed661c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
 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);
}

void
TrexStatelessCaptureMngr::update_global_filter() {
    CaptureFilter new_filter;
    
    for (TrexStatelessCapture *capture : m_captures) {
        new_filter += capture->get_filter();
    }
    
    m_global_filter = new_filter;
}

capture_id_t
TrexStatelessCaptureMngr::add(uint64_t limit, const CaptureFilter &filter) {
    
    if (m_captures.size() > MAX_CAPTURE_SIZE) {
        return CAPTURE_TOO_MANY_CAPTURES;
    }
    

    int new_id = m_id_counter++;
    TrexStatelessCapture *new_buffer = new TrexStatelessCapture(new_id, limit, filter);
    m_captures.push_back(new_buffer);
 
    /* update global filter */
    update_global_filter();
    
    return new_id;
}

capture_id_t
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) {
        return CAPTURE_ID_NOT_FOUND;
    }
    
    TrexStatelessCapture *capture =  m_captures[index];
    m_captures.erase(m_captures.begin() + index);
    
    delete capture;
    
    /* update global filter */
    update_global_filter();
    
    return id;
}

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);
    }
}