Merge "Add support for counting non dataplane related packets"
[samplevnf.git] / VNFs / DPPD-PROX / task_base.h
1 /*
2 // Copyright (c) 2010-2017 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16
17 #ifndef _TASK_BASE_H_
18 #define _TASK_BASE_H_
19
20 #include <rte_common.h>
21 #ifndef __rte_cache_aligned
22 #include <rte_memory.h>
23 #endif
24
25 #include "defaults.h"
26 #include "prox_globals.h"
27 #include "stats_task.h"
28 #include "packet_utils.h"
29
30 // runtime_flags 16 bits only
31 #define TASK_MPLS_TAGGING              0x0001
32 #define TASK_ROUTING                   0x0002
33 #define TASK_CLASSIFY                  0x0004
34 #define TASK_CTRL_HANDLE_ARP           0x0008
35 #define TASK_MARK                      0x0020
36 #define TASK_FP_HANDLE_ARP             0x0040
37 #define TASK_TX_CRC                    0x0080
38 #define TASK_L3                        0x0100
39
40 // flag_features 64 bits
41 #define TASK_FEATURE_ROUTING           0x0001
42 #define TASK_FEATURE_CLASSIFY          0x0002
43 #define TASK_FEATURE_MULTI_RX                  0x0004
44 #define TASK_FEATURE_NEVER_DISCARDS            0x0008
45 #define TASK_FEATURE_NO_RX                     0x0010
46 #define TASK_FEATURE_TXQ_FLAGS_NOOFFLOADS      0x0020
47 #define TASK_FEATURE_TXQ_FLAGS_MULTSEGS        0x0040
48 #define TASK_FEATURE_ZERO_RX                   0x0080
49 #define TASK_FEATURE_TXQ_FLAGS_REFCOUNT        0x0100
50 #define TASK_FEATURE_TSC_RX                    0x0200
51 #define TASK_FEATURE_THROUGHPUT_OPT            0x0400
52 #define TASK_FEATURE_GRE_ID                    0x1000
53 #define TASK_FEATURE_LUT_QINQ_RSS              0x2000
54 #define TASK_FEATURE_LUT_QINQ_HASH             0x4000
55 #define TASK_FEATURE_RX_ALL                    0x8000
56 #define TASK_MULTIPLE_MAC                      0x10000
57 #define TASK_FEATURE_TXQ_FLAGS_MULTIPLE_MEMPOOL 0x20000
58
59 #define FLAG_TX_FLUSH                  0x01
60 #define FLAG_NEVER_FLUSH               0x02
61 // Task specific flags
62 #define BASE_FLAG_LUT_QINQ_HASH         0x08
63 #define BASE_FLAG_LUT_QINQ_RSS          0x10
64
65 #define OUT_DISCARD 0xFF
66 #define OUT_HANDLED 0xFE
67
68 #define WS_MBUF_MASK (2 * MAX_PKT_BURST - 1)
69
70 /* struct ws_mbuf stores the working set of mbufs. It starts with a
71    prod/cons index to keep track of the number of elemenets. */
72 struct ws_mbuf {
73         struct {
74                 uint16_t        prod;
75                 uint16_t        cons;
76                 uint16_t        nb_rx;
77                 uint16_t        pad; /* reserved */
78         } idx[MAX_RINGS_PER_TASK];
79         struct rte_mbuf *mbuf[][MAX_RING_BURST * 3]  __rte_cache_aligned;
80 };
81
82 struct port_queue {
83         uint8_t port;
84         uint8_t queue;
85 } __attribute__((packed));
86
87 struct rx_params_hw {
88         union {
89                 uint8_t           nb_rxports;
90                 uint8_t           rxport_mask;
91         };
92         uint8_t           last_read_portid;
93         struct port_queue *rx_pq;
94 } __attribute__((packed));
95
96 struct rx_params_hw1 {
97         struct port_queue rx_pq;
98 } __attribute__((packed));
99
100 struct rx_params_sw {
101         union {
102                 uint8_t         nb_rxrings;
103                 uint8_t         rxrings_mask; /* Used if rte_is_power_of_2(nb_rxrings)*/
104         };
105         uint8_t         last_read_ring;
106         struct rte_ring **rx_rings;
107 } __attribute__((packed));
108
109 /* If there is only one input ring, the pointer to it can be stored
110    directly into the task_base instead of having to use a pointer to a
111    set of rings which would require two dereferences. */
112 struct rx_params_sw1 {
113         struct rte_ring *rx_ring;
114 } __attribute__((packed));
115
116 struct tx_params_hw {
117         uint16_t          nb_txports;
118         struct port_queue *tx_port_queue;
119 } __attribute__((packed));
120
121 struct tx_params_sw {
122         uint16_t         nb_txrings;
123         struct rte_ring **tx_rings;
124 } __attribute__((packed));
125
126 struct tx_params_hw_sw {        /* Only one port supported in this mode */
127         uint16_t         nb_txrings;
128         struct rte_ring **tx_rings;
129         struct port_queue tx_port_queue;
130 } __attribute__((packed));
131
132 struct task_rt_dump {
133         uint32_t n_print_rx;
134         uint32_t n_print_tx;
135         struct input *input;
136         uint32_t n_trace;
137         uint32_t cur_trace;
138         void     *pkt_mbuf_addr[MAX_RING_BURST]; /* To track reordering */
139         uint8_t  pkt_cpy[MAX_RING_BURST][DUMP_PKT_LEN];
140         uint16_t pkt_cpy_len[MAX_RING_BURST];
141 };
142
143 struct task_base;
144
145 #define MAX_RX_PKT_ALL 16384
146
147 #define RX_BUCKET_SIZE (2 * MAX_RING_BURST + 1) /* Limit RX bucket size */
148 #define TX_BUCKET_SIZE  (MAX_RING_BURST +1)
149
150 #define MAX_STACKED_RX_FUCTIONS 16
151
152 typedef uint16_t (*rx_pkt_func) (struct task_base *tbase, struct rte_mbuf ***mbufs);
153
154 struct task_base_aux {
155         /* Not used when PROX_STATS is not defined */
156         struct task_rt_stats stats;
157
158         /* Used if TASK_TSC_RX is enabled*/
159         struct {
160                 uint64_t before;
161                 uint64_t after;
162         } tsc_rx;
163
164         struct  rte_mbuf **all_mbufs;
165
166         uint16_t      rx_prev_count;
167         uint16_t      rx_prev_idx;
168         uint16_t (*rx_pkt_prev[MAX_STACKED_RX_FUCTIONS])(struct task_base *tbase, struct rte_mbuf ***mbufs);
169
170         uint32_t rx_bucket[RX_BUCKET_SIZE];
171         uint32_t tx_bucket[TX_BUCKET_SIZE];
172         int (*tx_pkt_l2)(struct task_base *tbase, struct rte_mbuf **mbufs, const uint16_t n_pkts, uint8_t *out);
173         int (*tx_pkt_orig)(struct task_base *tbase, struct rte_mbuf **mbufs, const uint16_t n_pkts, uint8_t *out);
174         int (*tx_pkt_hw)(struct task_base *tbase, struct rte_mbuf **mbufs, const uint16_t n_pkts, uint8_t *out);
175         uint16_t (*tx_pkt_try)(struct task_base *tbase, struct rte_mbuf **mbufs, const uint16_t n_pkts);
176         void (*stop)(struct task_base *tbase);
177         void (*start)(struct task_base *tbase);
178         void (*stop_last)(struct task_base *tbase);
179         void (*start_first)(struct task_base *tbase);
180         struct task_rt_dump task_rt_dump;
181 };
182
183 /* The task_base is accessed for _all_ task types. In case
184    no debugging or l3 is needed, it has been optimized to fit
185    into a single cache line to minimize cache pollution */
186 struct task_base {
187         int (*handle_bulk)(struct task_base *tbase, struct rte_mbuf **mbufs, const uint16_t n_pkts);
188         int (*tx_pkt)(struct task_base *tbase, struct rte_mbuf **mbufs, const uint16_t n_pkts, uint8_t *out);
189         uint16_t (*rx_pkt)(struct task_base *tbase, struct rte_mbuf ***mbufs);
190
191         struct task_base_aux* aux;
192         /* The working set of mbufs contains mbufs that are currently
193            being handled. */
194         struct ws_mbuf *ws_mbuf;
195
196         uint16_t flags;
197
198         union {
199                 struct rx_params_hw rx_params_hw;
200                 struct rx_params_hw1 rx_params_hw1;
201                 struct rx_params_sw rx_params_sw;
202                 struct rx_params_sw1 rx_params_sw1;
203         };
204
205         union {
206                 struct tx_params_hw tx_params_hw;
207                 struct tx_params_sw tx_params_sw;
208                 struct tx_params_hw_sw tx_params_hw_sw;
209         };
210         struct l3_base l3;
211         uint32_t local_ipv4;
212 } __attribute__((packed)) __rte_cache_aligned;
213
214 static void task_base_add_rx_pkt_function(struct task_base *tbase, rx_pkt_func to_add)
215 {
216         if (tbase->aux->rx_prev_count == MAX_STACKED_RX_FUCTIONS) {
217                 return;
218         }
219
220         for (int16_t i = tbase->aux->rx_prev_count; i > 0; --i) {
221                 tbase->aux->rx_pkt_prev[i] = tbase->aux->rx_pkt_prev[i - 1];
222         }
223         tbase->aux->rx_pkt_prev[0] = tbase->rx_pkt;
224         tbase->rx_pkt = to_add;
225         tbase->aux->rx_prev_count++;
226 }
227
228 static void task_base_del_rx_pkt_function(struct task_base *tbase, rx_pkt_func to_del)
229 {
230         int cur = 0;
231         int found = 0;
232
233         if (unlikely(tbase->aux->rx_prev_count == 0)) {
234                 return;
235         } else if (tbase->rx_pkt == to_del) {
236                 tbase->rx_pkt = tbase->aux->rx_pkt_prev[0];
237                 for (int16_t i = 0; i < tbase->aux->rx_prev_count - 1; ++i) {
238                         tbase->aux->rx_pkt_prev[i] = tbase->aux->rx_pkt_prev[i + 1];
239                 }
240                 found = 1;
241         } else {
242                 for (int16_t i = 0; i < tbase->aux->rx_prev_count; ++i) {
243                         if (found || tbase->aux->rx_pkt_prev[i] != to_del)
244                                 tbase->aux->rx_pkt_prev[cur++] = tbase->aux->rx_pkt_prev[i];
245                         else
246                                 found = 1;
247                 }
248         }
249         if (found)
250                 tbase->aux->rx_prev_count--;
251 }
252
253 static rx_pkt_func task_base_get_original_rx_pkt_function(struct task_base *tbase)
254 {
255         if (tbase->aux->rx_prev_count == 0)
256                 return tbase->rx_pkt;
257         else
258                 return tbase->aux->rx_pkt_prev[tbase->aux->rx_prev_count - 1];
259 }
260
261 #endif /* _TASK_BASE_H_ */